2011-02-09 14 views
9

Estoy jugando con python ast (árbol de sintaxis abstracta).Nodos de visita en un árbol de sintaxis con Python ast módulo

Escribí lo siguiente y visitó todos los nodos de la 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) 

Luego añade algunos métodos a la clase Py2Neko

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

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

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

Pero luego, cuando se encuentra con una "impresión" declaración o una asignacion o una expresión que parece que se detiene y no va más allá.

Genera:

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

¿Puede alguien decirme lo que hice mal.

estoy usando Python 2.6.6

Respuesta

10

Dado que su método visit_Assign no procesa explícitamente los nodos secundarios del nodo Asignar, el recorrido del árbol de sintaxis se detiene allí.

Si echas un vistazo al método NodeVisitor.generic_visit en la implementación de ast.py, verás que pasa por los elementos secundarios del nodo actual. Por lo tanto, se puede llamar explícitamente al método generic_visit clase base de cada uno de los métodos que necesita para procesar los niños:

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

bien, obtuve lo que me explicaste, está claro ahora, ¡muchas gracias! – narke

4

Para nodos no terminales, la función de su visita tiene que visitar a los niños. Consulte Simple example of how to use ast.NodeVisitor? para obtener más información.

+0

D'oh - Estaba pensando en esto, pero de alguna manera (irracionalmente) asumió la 'NodeVisitor' manejaría este por sí mismo. – delnan

+0

Vi el ejemplo que proporcionó pero ¿cómo especificar para visitar a los niños? Por ejemplo aquí: http://dev.pocoo.org/hg/sandbox/file/98ce1ce17c7c/ast/codegen.py tienen visit_Print() y otros y parece funcionar, pero no para mí. – narke

Cuestiones relacionadas