python2.6-compiler-package

Annotated compiler/visitor.py

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