【问题标题】:python compiler package explainpython编译包说明
【发布时间】:2016-08-02 02:11:01
【问题描述】:

我苦苦搜索,但几乎找不到任何关于如何使用 python 编译器包 (https://docs.python.org/2/library/compiler.html) 以及如何创建可以输入 compiler.walk(https://docs.python.org/2/library/compiler.html#compiler.walk) 方法的访问者类的信息。

有人可以帮帮我吗?提前致谢。

【问题讨论】:

  • Using Visitors to Walk ASTs”的哪一部分给你带来了麻烦?
  • @KevinJ.Chase 在 compiler.visitor.walk() 方法中,它接受 2 个参数,树和访问者。那些是什么?我怎样才能获得这些?
  • 请注意,正如链接文档所述,compiler 包已被弃用。您可能应该改用 ast 包。

标签: python compiler-construction abstract-syntax-tree


【解决方案1】:

由于compiler 包已被弃用,您可能还应该看看ast package

关于 Python ast 的优秀文档可以在“Green Tree Snakes - The Missing Python AST docs”中找到。 一个非常广泛的使用示例是Transcrypt's Generator class

【讨论】:

    【解决方案2】:

    您通过定义compiler.visitor.ASTVisitor 的子类然后为您希望访问者处理的每种节点类型定义一个方法visitXXX 来创建访问者类(其中XXX 是节点类型的名称 -您链接的文档中的表格中列出了可能的节点类型)。

    任何此类方法都将采用一个参数(如果算上self,则为两个),它将是代表访问节点的节点对象。此类对象上可用的属性也列在表中。如果您希望访问者进一步进入树,您应该在节点的每个子节点上调用 visit

    在 compiler.visitor.walk() 方法中,它接受 2 个参数,树和访问者。那些是什么?

    tree 是您要处理的 AST,visitor 是您为处理该 AST 而创建的访问者类的一个实例。

    我怎样才能获得这些?

    您通过在某些 Python 源代码上调用 compiler.parse 来获取 AST,并通过编写访问者类并创建它的实例来获取访问者。

    这是一个使用访问者的示例,它简单地计算一段 Python 代码中加法运算符的数量:

    import compiler
    
    class PlusCounter(compiler.visitor.ASTVisitor):
        def __init__(self):
            self.count = 0
    
        def visitAdd(self, node):
            self.count += 1
            self.visit(node.left)
            self.visit(node.right)
    
    plus_counter = PlusCounter()
    compiler.walk(compiler.parse("1 + 2 * (3 + 4)"), plus_counter)
    print(plus_counter.count)
    

    这是使用未弃用的 ast 包的相同示例,它的工作方式基本相同,但 AST 结构略有不同。与上面的代码不同,这个代码实际上可以在 Python 3 中工作:

    import ast
    
    class PlusCounter(ast.NodeVisitor):
        def __init__(self):
            self.pluses = 0
    
        def visit_Add(self, node):
            # We don't need to visit any child nodes here because in the ast package
            # the AST is structured slightly differently and Add is merely a child
            # node of the BinOp node, which holds the operands. So Add itself has
            # no children that need to be visited
            self.pluses += 1
    
    plus_counter = PlusCounter()
    plus_counter.visit(ast.parse("1 + 2 * (3 + 4)"))
    print(plus_counter.pluses)
    

    【讨论】:

      猜你喜欢
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      • 2015-12-07
      相关资源
      最近更新 更多