2011-02-09 13 views
9

Python ast (soyut sözdizimi ağacı) ile oynuyorum.Python ast modülüyle bir sözdizimi ağacındaki düğümleri ziyaret etme

Aşağıdakileri yazdım ve AST'nin tüm düğümlerini ziyaret ettim.

import ast 

class Py2Neko(ast.NodeVisitor): 
    def generic_visit(self, node): 
       print type(node).__name__ 
       ast.NodeVisitor.generic_visit(self, node) 

     def visit_Name(self, node): 
       print 'Name :', node.id 

     def visit_Num(self, node): 
       print 'Num :', node.__dict__['n'] 

     def visit_Str(self, node): 
       print "Str :", node.s 

if __name__ == '__main__': 

    node = ast.parse("a = 1 + 2") 

    print ast.dump(node) 

    v = Py2Neko() 
    v.visit(node) 

Sonra Py2Neko sınıfına bazı yöntemler

def visit_Print(self, node): 
    print "Print :" 

def visit_Assign(self, node): 
    print "Assign :" 

def visit_Expr(self, node): 
    print "Expr :" 

Ama "baskı" deyimi veya assignement veya bir ifade ile karşılaştığında o zaman durana ve daha fazla gitmiyor gibi görünüyor ekledi.

O çıkarır:

Module(body=[Assign(targets=[Name(id='a', ctx=Store())], value=BinOp(left=Num(n=1), op=Add(),  right=Num(n=2)))]) 
Module 
Assign : 

birisi ne yanlış söyleyebilir.

Ben terminal dışı düğümler için Python 2.6.6

cevap

10

Visit_Assign yönteminiz, Assign düğümünün çocuk düğümlerini açıkça işlemediğinden, sözdizimi ağacının geçişi burada durur.

Ast.py'nin uygulanmasında NodeVisitor.generic_visit yöntemine bakarsanız, geçerli düğümün alt öğelerini dolaştığını görürsünüz. Yani, açıkça çocukları işlemesi gerektiği için yöntemlerin her birinden temel sınıf generic_visit yöntemini çağırabilirsiniz:

import ast 

class Py2Neko(ast.NodeVisitor): 
    def generic_visit(self, node): 
     print type(node).__name__ 
     ast.NodeVisitor.generic_visit(self, node) 

    def visit_Name(self, node): 
     print 'Name :', node.id 

    def visit_Num(self, node): 
     print 'Num :', node.__dict__['n'] 

    def visit_Str(self, node): 
     print "Str :", node.s 

    def visit_Print(self, node): 
     print "Print :" 
     ast.NodeVisitor.generic_visit(self, node) 

    def visit_Assign(self, node): 
     print "Assign :" 
     ast.NodeVisitor.generic_visit(self, node) 

    def visit_Expr(self, node): 
     print "Expr :" 
     ast.NodeVisitor.generic_visit(self, node) 

if __name__ == '__main__': 
    node = ast.parse("a = 1 + 2") 

    print ast.dump(node) 

    v = Py2Neko() 
    v.visit(node) 
+0

tamam, açıkladığın şeyi aldım, şimdi açık, çok teşekkür ederim! – narke

4

kullanıyorum, ziyaret fonksiyon çocukları ziyaret etmesi gerekiyor. Daha fazla bilgi için bkz. Simple example of how to use ast.NodeVisitor?.

+0

D'oh - Bu düşünüyorum ama bir şekilde (mantıksız) kabul edilmiştir 'NodeVisitor' bu bakacaklarını kendi başına. – delnan

+0

Sağladığınız örneği gördüm, ancak çocukları ziyaret etmek için nasıl belirtilir? Örneğin burada: http://dev.pocoo.org/hg/sandbox/file/98ce1ce17c7c/ast/codegen.py visit_Print() ve diğerleri var ve işe yarayacak gibi görünüyor. – narke

İlgili konular