示例#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
文件: 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)
示例#3
0
 def setUp(self):
   self.parser = GrammarParser()
   self.parser.compileGrammar()
示例#4
0
class GrammarParserTest(unittest.TestCase):

  def setUp(self):
    self.parser = GrammarParser()
    self.parser.compileGrammar()

  def equalNodes(self, left, right):
    if len(left) != len(right):
      return False

    return True

  def testImport(self):
    importNode = mt.ValueNode('import')
    paramNode = mt.ParamNode('module')
    paramNode.childs = [mt.NamedNode('namespace_name')]
    asNode = mt.ValueNode('as')
    aliasNode = mt.ParamNode('alias')
    aliasNode.childs = [mt.ValueNode('name')]
    endNode = mt.ValueNode(';')

    expected = [importNode, paramNode, asNode, aliasNode, endNode]
    actual = grammar.compiled['import']
    
    self.assertEquals(True, self.equalNodes(actual, expected))
    self.assertEquals(0, len(actual[0].childs))
    self.assertEquals(1, len(actual[1].childs))
    self.assertEquals('as', actual[2].value)

  def testVariable(self):
    actual = grammar.getRule('variable')

    self.assertIsNotNone(actual)
    self.assertEqual(len(actual), 3)

    typeNode = actual[0]
    nameNode = actual[1]
    handleNode = actual[2]

    self.assertEqual(typeNode.name, 'type')
    self.assertEqual(len(typeNode.childs), 1)
    altNode = typeNode.childs[0]
    self.assertEqual(len(altNode.childs), 2)
    self.assertEqual(altNode.childs[0].value, 'var')
    self.assertEqual(altNode.childs[1].name, 'type')

    # self.assertEqual(nameNode.name, 'name')
    # self.assertEqual(len(nameNode.childs), 1)
    # self.assertEqual(nameNode.childs[0].value, 'name')

  def testType(self):
    expected = mt.ParamNode('type')

    altNode = mt.AltNode()
    altNode.childs.append(mt.NamedNode('array_type'))
    altNode.childs.append(mt.NamedNode('simple_type'))

    expected.childs.append(altNode)

    actual = grammar.getRule('type')

    self.assertIsNotNone(actual)
    self.assertEqual(len(actual), 1)
    typeNode = actual[0]
    self.assertEqual(len(typeNode.childs), 3)
    self.assertEqual(typeNode.childs[0].name, 'dict_type')
    self.assertEqual(typeNode.childs[1].name, 'array_type')
    self.assertEqual(typeNode.childs[2].name, 'simple_type')