Skip to content

Commit f3f9053

Browse files
committed
Add a read-only visitor pattern.
This includes some performance tests to compare the visitor and a traversal. Locally, the visitor is twice as fast. This is the most basic Visitor pattern. I've had versions that were more generic, and performance gains vanished quickly. In particular optionally collecting results on exit halfed the performance benefits. If we want to factor that in, we should have an independent base class for that.
1 parent cf4d4b0 commit f3f9053

File tree

3 files changed

+524
-0
lines changed

3 files changed

+524
-0
lines changed

fluent.syntax/fluent/syntax/ast.py

+30
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,36 @@
33
import json
44

55

6+
class Visitor(object):
7+
'''Read-only visitor pattern.
8+
9+
Subclass this to gather information from an AST.
10+
To generally define which nodes not to descend in to, overload
11+
`generic_visit`.
12+
To handle specific node types, add methods like `visit_Pattern`.
13+
The boolean value of the returned value determines if the visitor
14+
descends into the children of the given AST node.
15+
'''
16+
def visit(self, value):
17+
if isinstance(value, BaseNode):
18+
self.visit_node(value)
19+
if isinstance(value, list):
20+
for node in value:
21+
self.visit(node)
22+
23+
def visit_node(self, node):
24+
nodename = type(node).__name__
25+
visit = getattr(self, 'visit_{}'.format(nodename), self.generic_visit)
26+
should_descend = visit(node)
27+
if not should_descend:
28+
return
29+
for propname, propvalue in vars(node).items():
30+
self.visit(propvalue)
31+
32+
def generic_visit(self, node):
33+
return True
34+
35+
636
def to_json(value, fn=None):
737
if isinstance(value, BaseNode):
838
return value.to_json(fn)

0 commit comments

Comments
 (0)