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.

enhancements/Ast/Visitor (last edited 2009-03-01 01:02:24 by localhost)