1 #!/usr/bin/env python 2 3 from compiler import ast 4 5 class ASTVisitor: 6 7 """ 8 Performs a depth-first walk of the AST. 9 10 The ASTVisitor is responsible for walking over the tree in the correct 11 order. For each node, it calls the 'visit' method on the node, and this 12 method is then responsible to calling an appropriate method on the visitor. 13 14 For example, where 'Class' is the name of the node's class, the node's 15 'visit' method might invoke a 'visitClass' method on the visitor, although 16 it need not follow this particular naming convention. 17 """ 18 19 def __init__(self): 20 self.node = None 21 self.visitor = self 22 23 def default(self, node, *args): 24 for child in node.getChildNodes(): 25 self.dispatch(child, *args) 26 27 def dispatch(self, node, *args): 28 self.node = node 29 try: 30 return node.visit(self.visitor, *args) 31 except AttributeError: 32 return self.visitor.default(node, *args) 33 34 def preorder(self, tree, visitor, *args): 35 36 "Do preorder walk of tree using visitor." 37 38 self.visitor = visitor 39 visitor.visit = self.dispatch 40 41 # NOTE: *args not exposed by the walk function. 42 43 self.dispatch(tree, *args) 44 45 _walker = ASTVisitor 46 47 def walk(tree, visitor, walker=None): 48 if walker is None: 49 walker = _walker() 50 walker.preorder(tree, visitor) 51 return walker.visitor 52 53 # vim: tabstop=4 expandtab shiftwidth=4