2011-02-09 12 views
9

Gram z python ast (abstrakcyjne drzewo składniowe).Zwiedzanie węzłów w drzewie składni z modułem Python ast

Napisałem poniżej i odwiedziłem wszystkie węzły AST.

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) 

Następnie dodano kilka metod do klasy Py2Neko

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

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

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

Ale wtedy, gdy napotka „print” oświadczenie lub ASSIGNMENT lub wyrażenie wydaje się, że zatrzymuje się i nie idzie dalej.

To Wyjścia:

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

Czy ktoś może mi powiedzieć co zrobiłem źle.

Używam Python 2.6.6

Odpowiedz

10

Ponieważ metoda visit_Assign nie przetwarza jawnie węzłów potomnych węzła Przypisz, przejście drzewa składni zatrzymuje się w tym miejscu.

Jeśli przyjrzeć się metodzie NodeVisitor.generic_visit w implementacji ast.py, zobaczysz, że pętle przechodzą przez elementy potomne bieżącego węzła. Tak, można jawnie wywołać metodę klasy bazowej generic_visit z każdej z metod, które musi przetworzyć dzieci:

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

OK, dostałem to, co wyjaśniłeś, teraz jest jasne, bardzo dziękuję! – narke

4

dla węzłów nieterminalnymi, czynność wizyta musi odwiedzić dzieci. Aby uzyskać więcej informacji, patrz Simple example of how to use ast.NodeVisitor?.

+0

D'oh - Myślałam o tym, ale jakoś (irracjonalnie) przyjęto 'NodeVisitor' będzie obsługiwać ten na własną rękę. – delnan

+0

Widziałem przykład, który podałeś, ale jak określić, aby odwiedzić dzieci? Na przykład tutaj: http://dev.pocoo.org/hg/sandbox/file/98ce1ce17c7c/ast/codegen.py mają one visit_Print() i inne i wydaje się, że działa, ale nie dla mnie. – narke

Powiązane problemy