예제 #1
0
파일: compiler.py 프로젝트: hzx/pymutant
  def __init__(self):
    self.grammarParser = GrammarParser()
    self.loader = Loader()
    self.lexer = Lexer()
    self.parser = Parser()
    self.checker = Checker()

    self.genFactory = GenFactory()

    # compile grammar rules
    self.grammarParser.compileGrammar()

    self.compiledModules = {}
예제 #2
0
파일: lexer_test.py 프로젝트: hzx/pymutant
 def setUp(self):
   self.lexer = Lexer()
   self.lines_re = re.compile('\n')
예제 #3
0
파일: lexer_test.py 프로젝트: hzx/pymutant
class LexerTest(unittest.TestCase):

  def setUp(self):
    self.lexer = Lexer()
    self.lines_re = re.compile('\n')

  def tokensToWords(self, tokens):
    return [token.word for token in tokens]

  def tokensToWordtypes(self, tokens):
    return [token.wordtype for token in tokens]

  def checkWordsWordtypes(self, code, expectedWords, expectedWordtypes):
    lines = self.lines_re.split(code)
    source = Source('test.mut', lines, [])
    self.assertEqual(source.tokens, None)

    self.lexer.parseSource(source)

    actualWords = self.tokensToWords(source.tokens)
    actualWordtypes = self.tokensToWordtypes(source.tokens)

    self.assertListEqual(actualWords, expectedWords)
    self.assertListEqual(actualWordtypes, expectedWordtypes)

  def testParseSource(self):
    data = [
          # Variable
          [
              """
              bool flag = true;
              """,
              ['bool', 'flag', '=', 'true', ';'],
              ['bool', 'name', '=', 'litbool', ';'],
              ],
          [
              """
              int num = 32;
              """,
              ['int', 'num', '=', '32', ';'],
              ['int', 'name', '=', 'litint', ';'],
              ],
          [
              """
              float num = 32.54;
              """,
              ['float', 'num', '=', '32.54', ';'],
              ['float', 'name', '=', 'litfloat', ';'],
              ],
          [
              """
              string label = 'User label';
              """,
              ['string', 'label', '=', "'User label'", ';'],
              ['string', 'name', '=', 'litstring', ';'],
              ],
          [
              """
              App app = App();
              """,
              ['App', 'app', '=', 'App', '(', ')', ';'],
              ['name', 'name', '=', 'name', '(', ')', ';'],
              ],
          [
              """
              tasker.App app = App();
              """,
              ['tasker.App', 'app', '=', 'App', '(', ')', ';'],
              ['name', 'name', '=', 'name', '(', ')', ';'],
              ],
          # Select from
          [
              """
              var openMessages = select from messages where status is TaskStatus.OPEN;
              """,
              ['var', 'openMessages', '=', 'select', 'from', 'messages',
                  'where', 'status', 'is', 'TaskStatus.OPEN', ';'],
              ['var', 'name', '=', 'select', 'from', 'name', 'where', 'name',
                  'is', 'name', ';'],
              ],
          # Select concat
          [
              """
              var messages = select concat newMessages, openMessages;
              """,
              ['var', 'messages', '=', 'select', 'concat', 'newMessages', ',',
                  'openMessages', ';'],
              ['var', 'name', '=', 'select', 'concat', 'name', ',', 'name', ';'],
              ],
          # Tag
          [
              """
              tag content = <div class=['item', 'foo']></div>;
              """,
              ['tag', 'content', '=', '<', 'div', 'class', '=', '[', "'item'",
              ',', "'foo'", ']', '>', '</', 'div', '>', ';'],
              ['tag', 'name', '=', '<', 'name', 'class', '=', '[', 'litstring', ',',
                  'litstring', ']', '>', '</', 'name', '>', ';'],
              ],
          # Function
          [
              """
              int main() {
                return 0;
              }
              """,
              ['int', 'main', '(', ')', '{', 'return', '0', ';', '}'],
              ['int', 'name', '(', ')', '{', 'return', 'litint', ';', '}'],
              ],
          [
              """
              (string[] messages) {
                map(messages, renderMessage);
              }
              """,
              ['(', 'string', '[', ']', 'messages', ')', '{', 'map', '(',
                  'messages', ',', 'renderMessage', ')', ';', '}'],
              ['(', 'string', '[', ']', 'name', ')', '{', 'map', '(', 'name', ',',
                  'name', ')', ';', '}'],
              ],
          # Enum
          [
              """
              enum TaskStatus {
                NEW = 1;
                OPEN = 2;
              }
              """,
              ['enum', 'TaskStatus', '{', 'NEW', '=', '1', ';', 'OPEN', '=',
                  '2', ';', '}'],
              ['enum', 'name', '{', 'name', '=', 'litint', ';', 'name', '=',
                  'litint', ';', '}'],
              ],
          # Struct
          [
              """
              struct Task {
                string id;
                string name;
              }
              """,
              ['struct', 'Task', '{', 'string', 'id', ';', 'string', 'name',
                  ';', '}'],
              ['struct', 'name', '{', 'string', 'name', ';', 'string', 'name',
                  ';', '}'],
              ],
          # Class
          [
              """
              class App {
                () {
                }
              }
              """,
              ['class', 'App', '{', '(', ')', '{', '}', '}'],
              ['class', 'name', '{', '(', ')', '{', '}', '}'],
              ],
        ]

    for code, expectedWords, expectedWordtypes in data:
      self.checkWordsWordtypes(code, expectedWords, expectedWordtypes)
예제 #4
0
파일: compiler.py 프로젝트: hzx/pymutant
class Compiler(object):

  def __init__(self):
    self.grammarParser = GrammarParser()
    self.loader = Loader()
    self.lexer = Lexer()
    self.parser = Parser()
    self.checker = Checker()

    self.genFactory = GenFactory()

    # compile grammar rules
    self.grammarParser.compileGrammar()

    self.compiledModules = {}

  def compile(self, srcPaths, moduleName):
    """
    Create mutant lang source code tree.
    Load module and all referenced modules.
    Tokenize and parse source code.
    Always cache modules by moduleName (import name).
    output:
      module - common.Module instance.
    """
    # check if moduleName already compiled
    if moduleName in self.compiledModules:
      return self.compiledModules[moduleName]

    self.loader.setPaths(srcPaths)

    # loader, lexer and parser all change module object
    mainModule = self.loader.loadModule(moduleName)

    # parse each module in lexer.modules cache
    for name, module in self.loader.modules.items():
      # check cache
      if name in self.compiledModules:
        continue
      self.lexer.parse(module)
      self.parser.parse(module)

    # check and set functioncall as constructor
    for name, module in self.loader.modules.items():
      self.markConstructors(module)

    # check and add module to cache
    for name, module in self.loader.modules.items():
      self.checker.check(module)
      self.compiledModules[name] = module

    return mainModule

  def mutate(self, module, destPath, genName):
    """
    Translate module and referenced modules to genName
    language modules.
    Create generated module sources formatted.
    Save generated sources to disk.
    """
    gen = self.genFactory.createGen(genName)

  def save(self, filename, lines):
    with open(filename, 'w') as f:
      f.writelines(lines)

  def markConstructors(self, module):
    """
    Find and mark constructor among functioncall nodes
    """
    # find in variables body
    for name, va in module.variables.items():
      self.markConstructorInVariable(module, va)

    # find in functions
    for name, fn in module.functions.items():
      self.markConstructorInNodes(module, fn.bodyNodes)

    for cn, cl in module.classes.items():
      # find in class variables body
      for name, va in cl.variables.items():
        self.markConstructorInVariable(module, va)

      # find in class functions variables body
      for name, fn in cl.functions.items():
        self.markConstructorInNodes(module, fn.bodyNodes)

  def markConstructorInVariable(self, module, va):
    if va.body and (va.body.nodetype == 'functioncall'):
      self.markConstructorFunctioncall(module, va.body)

  def markConstructorFunctioncall(self, module, fc):
    if common.isClassName(module, fc.name):
      fc.isConstructorCall = True
    # mark constructor in params
    for node in fc.params:
      if node.nodetype == 'functioncall':
        self.markConstructorFunctioncall(module, node)

  def markConstructorInNodes(self, module, nodes):
    for node in nodes:
      if (node.nodetype == 'variable') and node.body:
        if node.body.nodetype == 'functioncall':
          self.markConstructorFunctioncall(module, node.body)
      elif (node.nodetype == 'value') and node.body and (node.body.nodetype == 'functioncall'):
        self.markConstructorFunctioncall(module, node.body)
      elif node.nodetype == 'return':
        if node.body.nodetype == 'functioncall':
          self.markConstructorFunctioncall(module, node.body)
      elif node.nodetype == 'if':
        if node.body: self.markConstructorInNodes(module, node.body)
        if node.elseBody: self.markConstructorInNodes(module, node.elseBody)