Skip to content

Commit

Permalink
Improve NodeVisitor performance, add iterator on Node children (Issue #…
Browse files Browse the repository at this point in the history
…219). (#220)

Improve NodeVisitor performance, add iterator on Node children.
  • Loading branch information
ldore authored and eliben committed Nov 21, 2017
1 parent 7547e85 commit 5da662c
Show file tree
Hide file tree
Showing 2 changed files with 296 additions and 8 deletions.
48 changes: 44 additions & 4 deletions pycparser/_ast_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def __init__(self, name, contents):
def generate_source(self):
src = self._gen_init()
src += '\n' + self._gen_children()
src += '\n' + self._gen_iter()
src += '\n' + self._gen_attr_names()
return src

Expand Down Expand Up @@ -131,6 +132,35 @@ def _gen_children(self):

return src

def _gen_iter(self):
src = ' def __iter__(self):\n'

if self.all_entries:
for child in self.child:
src += (
' if self.%(child)s is not None:\n' +
' yield self.%(child)s\n') % (dict(child=child))

for seq_child in self.seq_child:
src += (
' for child in (self.%(child)s or []):\n'
' yield child\n') % (dict(child=seq_child))

if not (self.child or self.seq_child):
# Empty generator
src += (
' return\n' +
' yield\n'
)
else:
# Empty generator
src += (
' return\n' +
' yield\n'
)

return src

def _gen_attr_names(self):
src = " attr_names = (" + ''.join("%r, " % nm for nm in self.attr) + ')'
return src
Expand Down Expand Up @@ -253,21 +283,31 @@ def visit_Constant(self, node):
* Modeled after Python's own AST visiting facilities
(the ast module of Python 3.0)
"""
_method_cache = None
def visit(self, node):
""" Visit a node.
"""
method = 'visit_' + node.__class__.__name__
visitor = getattr(self, method, self.generic_visit)
if self._method_cache is None:
self._method_cache = {}
visitor = self._method_cache.get(node.__class__.__name__, None)
if visitor is None:
method = 'visit_' + node.__class__.__name__
visitor = getattr(self, method, self.generic_visit)
self._method_cache[node.__class__.__name__] = visitor
return visitor(node)
def generic_visit(self, node):
""" Called if no explicit visitor function exists for a
node. Implements preorder visiting of the node.
"""
for c_name, c in node.children():
for c in node:
self.visit(c)
'''


Expand Down

0 comments on commit 5da662c

Please sign in to comment.