mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
simplify visitor walker class
- remove postorder - remove protocol for automatically walking children based on visitor method return value; now only walks if there is no method
This commit is contained in:
parent
b631b8ede5
commit
f635abee3a
2 changed files with 46 additions and 66 deletions
|
|
@ -47,31 +47,19 @@ class ASTVisitor:
|
||||||
self._preorder(tree)
|
self._preorder(tree)
|
||||||
|
|
||||||
def _preorder(self, node, *args):
|
def _preorder(self, node, *args):
|
||||||
stop = apply(self.dispatch, (node,) + args)
|
return apply(self.dispatch, (node,) + args)
|
||||||
if stop:
|
|
||||||
return
|
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):
|
||||||
self._preorder(child)
|
apply(self._preorder, (child,) + args)
|
||||||
|
|
||||||
def postorder(self, tree, visitor):
|
|
||||||
"""Do preorder walk of tree using visitor"""
|
|
||||||
self.visitor = visitor
|
|
||||||
visitor.visit = self._postorder
|
|
||||||
self._postorder(tree)
|
|
||||||
|
|
||||||
def _postorder(self, tree, *args):
|
|
||||||
for child in node.getChildren():
|
|
||||||
if isinstance(child, ast.Node):
|
|
||||||
self._postorder(child)
|
|
||||||
apply(self.dispatch, (node,) + args)
|
|
||||||
|
|
||||||
def dispatch(self, node, *args):
|
def dispatch(self, node, *args):
|
||||||
self.node = node
|
self.node = node
|
||||||
meth = self._cache.get(node.__class__, None)
|
meth = self._cache.get(node.__class__, None)
|
||||||
className = node.__class__.__name__
|
className = node.__class__.__name__
|
||||||
if meth is None:
|
if meth is None:
|
||||||
meth = getattr(self.visitor, 'visit' + className, 0)
|
meth = getattr(self.visitor, 'visit' + className, self.default)
|
||||||
self._cache[node.__class__] = meth
|
self._cache[node.__class__] = meth
|
||||||
if self.VERBOSE > 0:
|
if self.VERBOSE > 0:
|
||||||
if self.VERBOSE == 1:
|
if self.VERBOSE == 1:
|
||||||
|
|
@ -79,7 +67,6 @@ class ASTVisitor:
|
||||||
print "dispatch", className
|
print "dispatch", className
|
||||||
else:
|
else:
|
||||||
print "dispatch", className, (meth and meth.__name__ or '')
|
print "dispatch", className, (meth and meth.__name__ or '')
|
||||||
if meth:
|
|
||||||
return apply(meth, (node,) + args)
|
return apply(meth, (node,) + args)
|
||||||
|
|
||||||
class ExampleASTVisitor(ASTVisitor):
|
class ExampleASTVisitor(ASTVisitor):
|
||||||
|
|
@ -93,24 +80,27 @@ class ExampleASTVisitor(ASTVisitor):
|
||||||
|
|
||||||
def dispatch(self, node, *args):
|
def dispatch(self, node, *args):
|
||||||
self.node = node
|
self.node = node
|
||||||
|
meth = self._cache.get(node.__class__, None)
|
||||||
className = node.__class__.__name__
|
className = node.__class__.__name__
|
||||||
meth = getattr(self.visitor, 'visit' + className, None)
|
if meth is None:
|
||||||
if self.VERBOSE > 0:
|
meth = getattr(self.visitor, 'visit' + className, 0)
|
||||||
|
self._cache[node.__class__] = meth
|
||||||
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)
|
return apply(meth, (node,) + args)
|
||||||
elif self.VERBOSE > 0:
|
elif self.VERBOSE > 0:
|
||||||
klass = node.__class__
|
klass = node.__class__
|
||||||
if self.examples.has_key(klass):
|
if not self.examples.has_key(klass):
|
||||||
return
|
|
||||||
self.examples[klass] = klass
|
self.examples[klass] = klass
|
||||||
print
|
print
|
||||||
|
print self.visitor
|
||||||
print klass
|
print klass
|
||||||
for attr in dir(node):
|
for attr in dir(node):
|
||||||
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)
|
||||||
|
|
||||||
_walker = ASTVisitor
|
_walker = ASTVisitor
|
||||||
def walk(tree, visitor, verbose=None):
|
def walk(tree, visitor, verbose=None):
|
||||||
|
|
|
||||||
|
|
@ -47,31 +47,19 @@ class ASTVisitor:
|
||||||
self._preorder(tree)
|
self._preorder(tree)
|
||||||
|
|
||||||
def _preorder(self, node, *args):
|
def _preorder(self, node, *args):
|
||||||
stop = apply(self.dispatch, (node,) + args)
|
return apply(self.dispatch, (node,) + args)
|
||||||
if stop:
|
|
||||||
return
|
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):
|
||||||
self._preorder(child)
|
apply(self._preorder, (child,) + args)
|
||||||
|
|
||||||
def postorder(self, tree, visitor):
|
|
||||||
"""Do preorder walk of tree using visitor"""
|
|
||||||
self.visitor = visitor
|
|
||||||
visitor.visit = self._postorder
|
|
||||||
self._postorder(tree)
|
|
||||||
|
|
||||||
def _postorder(self, tree, *args):
|
|
||||||
for child in node.getChildren():
|
|
||||||
if isinstance(child, ast.Node):
|
|
||||||
self._postorder(child)
|
|
||||||
apply(self.dispatch, (node,) + args)
|
|
||||||
|
|
||||||
def dispatch(self, node, *args):
|
def dispatch(self, node, *args):
|
||||||
self.node = node
|
self.node = node
|
||||||
meth = self._cache.get(node.__class__, None)
|
meth = self._cache.get(node.__class__, None)
|
||||||
className = node.__class__.__name__
|
className = node.__class__.__name__
|
||||||
if meth is None:
|
if meth is None:
|
||||||
meth = getattr(self.visitor, 'visit' + className, 0)
|
meth = getattr(self.visitor, 'visit' + className, self.default)
|
||||||
self._cache[node.__class__] = meth
|
self._cache[node.__class__] = meth
|
||||||
if self.VERBOSE > 0:
|
if self.VERBOSE > 0:
|
||||||
if self.VERBOSE == 1:
|
if self.VERBOSE == 1:
|
||||||
|
|
@ -79,7 +67,6 @@ class ASTVisitor:
|
||||||
print "dispatch", className
|
print "dispatch", className
|
||||||
else:
|
else:
|
||||||
print "dispatch", className, (meth and meth.__name__ or '')
|
print "dispatch", className, (meth and meth.__name__ or '')
|
||||||
if meth:
|
|
||||||
return apply(meth, (node,) + args)
|
return apply(meth, (node,) + args)
|
||||||
|
|
||||||
class ExampleASTVisitor(ASTVisitor):
|
class ExampleASTVisitor(ASTVisitor):
|
||||||
|
|
@ -93,24 +80,27 @@ class ExampleASTVisitor(ASTVisitor):
|
||||||
|
|
||||||
def dispatch(self, node, *args):
|
def dispatch(self, node, *args):
|
||||||
self.node = node
|
self.node = node
|
||||||
|
meth = self._cache.get(node.__class__, None)
|
||||||
className = node.__class__.__name__
|
className = node.__class__.__name__
|
||||||
meth = getattr(self.visitor, 'visit' + className, None)
|
if meth is None:
|
||||||
if self.VERBOSE > 0:
|
meth = getattr(self.visitor, 'visit' + className, 0)
|
||||||
|
self._cache[node.__class__] = meth
|
||||||
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)
|
return apply(meth, (node,) + args)
|
||||||
elif self.VERBOSE > 0:
|
elif self.VERBOSE > 0:
|
||||||
klass = node.__class__
|
klass = node.__class__
|
||||||
if self.examples.has_key(klass):
|
if not self.examples.has_key(klass):
|
||||||
return
|
|
||||||
self.examples[klass] = klass
|
self.examples[klass] = klass
|
||||||
print
|
print
|
||||||
|
print self.visitor
|
||||||
print klass
|
print klass
|
||||||
for attr in dir(node):
|
for attr in dir(node):
|
||||||
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)
|
||||||
|
|
||||||
_walker = ASTVisitor
|
_walker = ASTVisitor
|
||||||
def walk(tree, visitor, verbose=None):
|
def walk(tree, visitor, verbose=None):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue