2016-08-02 194 views
0

我搜索很難,但很難找到任何關於如何使用python編譯器包(https://docs.python.org/2/library/compiler.html)以及如何創建一個Visitor類的信息,該類可以饋入到compiler.walk(https://docs.python.org/2/library/compiler.html#compiler.walk)方法中。python編譯器包解釋

有人可以幫我嗎?提前致謝。

+0

「[使用訪問者走AST」](https://docs.python.org/2/library/compiler.html#module-compiler.visitor)「給了你麻煩? –

+0

@ KevinJ.Chase在compiler.visitor.walk()方法中,它接受2個參數,樹和訪問者。那些是什麼?我怎樣才能獲得這些? – lionel319

+1

請注意,正如鏈接文檔所述,'編譯器'軟件包已棄用。你可能應該使用'ast'包來代替。 – sepp2k

回答

2

您可以通過定義的compiler.visitor.ASTVisitor一個子類,然後定義你希望你的訪問者來處理每種類型節點的方法visitXXX創建一個訪問者類(其中XXX是節點類型的名稱 - 可能的類型的節點列在您鏈接的文檔中的表格中)。

任何這樣的方法將採用一個參數(如果您計數爲self,則爲兩個參數),它將是表示訪問節點的節點對象。這個對象上可用的屬性也列在表中。如果您希望訪問者繼續進入該樹,則應在該節點的每個子節點上調用visit

在compiler.visitor.walk()方法中,它接受2個參數,tree和visitor。那些是什麼?

tree是要處理和visitor是您創建來處理AST訪問者類的一個實例的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) 
相關問題