Two changes to visitor API:

Remove _preorder as alias for dispatch and call dispatch directly.
    Add an extra optional argument to walk()

XXX Also comment out some code that does debugging prints.
This commit is contained in:
Jeremy Hylton 2001-08-27 20:47:08 +00:00
parent cccc478577
commit 058a5adad0
2 changed files with 46 additions and 40 deletions

View file

@ -1,6 +1,8 @@
import sys
from compiler import ast from compiler import ast
# XXX should probably rename ASTVisitor to ASTWalker
# XXX can it be made even more generic?
class ASTVisitor: class ASTVisitor:
"""Performs a depth-first walk of the AST """Performs a depth-first walk of the AST
@ -44,7 +46,7 @@ class ASTVisitor:
def default(self, node, *args): def default(self, node, *args):
for child in node.getChildren(): for child in node.getChildren():
if isinstance(child, ast.Node): if isinstance(child, ast.Node):
apply(self._preorder, (child,) + args) self.dispatch(child, *args)
def dispatch(self, node, *args): def dispatch(self, node, *args):
self.node = node self.node = node
@ -54,22 +56,20 @@ class ASTVisitor:
className = klass.__name__ className = klass.__name__
meth = getattr(self.visitor, 'visit' + className, self.default) meth = getattr(self.visitor, 'visit' + className, self.default)
self._cache[klass] = meth self._cache[klass] = meth
if self.VERBOSE > 0: ## if self.VERBOSE > 0:
className = klass.__name__ ## className = klass.__name__
if self.VERBOSE == 1: ## if self.VERBOSE == 1:
if meth == 0: ## if meth == 0:
print "dispatch", className ## print "dispatch", className
else: ## else:
print "dispatch", className, (meth and meth.__name__ or '') ## print "dispatch", className, (meth and meth.__name__ or '')
return meth(node, *args) return meth(node, *args)
def preorder(self, tree, visitor, *args): def preorder(self, tree, visitor, *args):
"""Do preorder walk of tree using visitor""" """Do preorder walk of tree using visitor"""
self.visitor = visitor self.visitor = visitor
visitor.visit = self._preorder visitor.visit = self.dispatch
self._preorder(tree, *args) # XXX *args make sense? self.dispatch(tree, *args) # XXX *args make sense?
_preorder = dispatch
class ExampleASTVisitor(ASTVisitor): class ExampleASTVisitor(ASTVisitor):
"""Prints examples of the nodes that aren't visited """Prints examples of the nodes that aren't visited
@ -90,7 +90,7 @@ class ExampleASTVisitor(ASTVisitor):
if self.VERBOSE > 1: if self.VERBOSE > 1:
print "dispatch", className, (meth and meth.__name__ or '') print "dispatch", className, (meth and meth.__name__ or '')
if meth: if meth:
return apply(meth, (node,) + args) meth(node, *args)
elif self.VERBOSE > 0: elif self.VERBOSE > 0:
klass = node.__class__ klass = node.__class__
if not self.examples.has_key(klass): if not self.examples.has_key(klass):
@ -102,15 +102,18 @@ class ExampleASTVisitor(ASTVisitor):
if attr[0] != '_': if attr[0] != '_':
print "\t", "%-12.12s" % attr, getattr(node, attr) print "\t", "%-12.12s" % attr, getattr(node, attr)
print print
return apply(self.default, (node,) + args) return self.default(node, *args)
# XXX this is an API change
_walker = ASTVisitor _walker = ASTVisitor
def walk(tree, visitor, verbose=None): def walk(tree, visitor, walker=None, verbose=None):
w = _walker() if walker is None:
walker = _walker()
if verbose is not None: if verbose is not None:
w.VERBOSE = verbose walker.VERBOSE = verbose
w.preorder(tree, visitor) walker.preorder(tree, visitor)
return w.visitor return walker.visitor
def dumpNode(node): def dumpNode(node):
print node.__class__ print node.__class__

View file

@ -1,6 +1,8 @@
import sys
from compiler import ast from compiler import ast
# XXX should probably rename ASTVisitor to ASTWalker
# XXX can it be made even more generic?
class ASTVisitor: class ASTVisitor:
"""Performs a depth-first walk of the AST """Performs a depth-first walk of the AST
@ -44,7 +46,7 @@ class ASTVisitor:
def default(self, node, *args): def default(self, node, *args):
for child in node.getChildren(): for child in node.getChildren():
if isinstance(child, ast.Node): if isinstance(child, ast.Node):
apply(self._preorder, (child,) + args) self.dispatch(child, *args)
def dispatch(self, node, *args): def dispatch(self, node, *args):
self.node = node self.node = node
@ -54,22 +56,20 @@ class ASTVisitor:
className = klass.__name__ className = klass.__name__
meth = getattr(self.visitor, 'visit' + className, self.default) meth = getattr(self.visitor, 'visit' + className, self.default)
self._cache[klass] = meth self._cache[klass] = meth
if self.VERBOSE > 0: ## if self.VERBOSE > 0:
className = klass.__name__ ## className = klass.__name__
if self.VERBOSE == 1: ## if self.VERBOSE == 1:
if meth == 0: ## if meth == 0:
print "dispatch", className ## print "dispatch", className
else: ## else:
print "dispatch", className, (meth and meth.__name__ or '') ## print "dispatch", className, (meth and meth.__name__ or '')
return meth(node, *args) return meth(node, *args)
def preorder(self, tree, visitor, *args): def preorder(self, tree, visitor, *args):
"""Do preorder walk of tree using visitor""" """Do preorder walk of tree using visitor"""
self.visitor = visitor self.visitor = visitor
visitor.visit = self._preorder visitor.visit = self.dispatch
self._preorder(tree, *args) # XXX *args make sense? self.dispatch(tree, *args) # XXX *args make sense?
_preorder = dispatch
class ExampleASTVisitor(ASTVisitor): class ExampleASTVisitor(ASTVisitor):
"""Prints examples of the nodes that aren't visited """Prints examples of the nodes that aren't visited
@ -90,7 +90,7 @@ class ExampleASTVisitor(ASTVisitor):
if self.VERBOSE > 1: if self.VERBOSE > 1:
print "dispatch", className, (meth and meth.__name__ or '') print "dispatch", className, (meth and meth.__name__ or '')
if meth: if meth:
return apply(meth, (node,) + args) meth(node, *args)
elif self.VERBOSE > 0: elif self.VERBOSE > 0:
klass = node.__class__ klass = node.__class__
if not self.examples.has_key(klass): if not self.examples.has_key(klass):
@ -102,15 +102,18 @@ class ExampleASTVisitor(ASTVisitor):
if attr[0] != '_': if attr[0] != '_':
print "\t", "%-12.12s" % attr, getattr(node, attr) print "\t", "%-12.12s" % attr, getattr(node, attr)
print print
return apply(self.default, (node,) + args) return self.default(node, *args)
# XXX this is an API change
_walker = ASTVisitor _walker = ASTVisitor
def walk(tree, visitor, verbose=None): def walk(tree, visitor, walker=None, verbose=None):
w = _walker() if walker is None:
walker = _walker()
if verbose is not None: if verbose is not None:
w.VERBOSE = verbose walker.VERBOSE = verbose
w.preorder(tree, visitor) walker.preorder(tree, visitor)
return w.visitor return walker.visitor
def dumpNode(node): def dumpNode(node):
print node.__class__ print node.__class__