The base class of an AST is the Node:
1 class Node(object):
2 """Abstract base class for ast nodes."""
3 def getChildren(self):
4 pass # implemented by subclasses
5 def __iter__(self):
6 for n in self.getChildren():
7 yield n
8 def getChildNodes(self):
9 pass # implemented by subclasses
10
11 def accept(self, visitor):
12 raise NotImplementedError
13 #...
and here a possible subclass
1 class Stmt(Node):
2 def __init__(self, nodes, lineno=None):
3 self.nodes = nodes
4 self.lineno = lineno
5
6 def getChildren(self):
7 return tuple(flatten(self.nodes))
8
9 def getChildNodes(self):
10 nodelist = []
11 nodelist.extend(flatten_nodes(self.nodes))
12 return tuple(nodelist)
13
14 def accept(self, visitor):
15 return visitor.visitStmt(self)
16
17 #...
All the nodes have an "accept" function that takes a visitor instance.
An example of AST Visitor that simply traverse the tree doing nothing
1 class ASTVisitor(object):
2
3 def default(self, node):
4 for child in node.getChildNodes():
5 child.accept(self)
6
7 def visitExpression(self, node):
8 return self.default(node)
9 def visitEmptyNode(self, node):
10 return self.default(node)
11 def visitAdd(self, node):
12 return self.default( node )
13 def visitAnd(self, node):
14 return self.default( node )
15 # ... and so on for each node type
Of course this could be done in a more dynamic way, but this form should be more simple to understand.
