Main Page Modules Namespace List Class Hierarchy Compound List File List Compound Members File Members Related Pages
Changer Class Reference
A functional class to traverse an AST, and perform some transformation at each of its Nodes.
More...
#include <changer.h>
Inheritance diagram for Changer::
List of all members.
Public Types |
enum | Order { Preorder,
Postorder,
Both
} |
enum | Depth { Subtree,
NodeOnly
} |
Public Methods |
| Changer (Order the_order, Depth depth, bool delete_old) |
| Create a new instance of a Changer. More...
|
|
Methods to get and set fields in the class.
|
Order | order () const |
| Return the order in which Nodes of an AST should be visited. More...
|
Depth | depth () const |
| Return which Nodes of an AST should be visited. More...
|
bool | delete_old () const |
| Return whether this Changer deletes Nodes which are removed from the AST by "at_" methods. More...
|
|
These methods define the functions that should be performed when different classes of Nodes are encountered in the AST. The most specific "at_" method that matches a given Node's class will be called. |
virtual Node * | at_node (Node *the_node, Order ord) |
virtual Node * | at_unit (unitNode *the_unit, Order ord) |
virtual Node * | at_def (defNode *the_def, Order ord) |
virtual Node * | at_decl (declNode *the_decl, Order ord) |
virtual Node * | at_subdecl (subdeclNode *the_subdecl, Order ord) |
virtual Node * | at_proc (procNode *the_proc, Order ord) |
virtual Node * | at_type (typeNode *the_type, Order ord) |
virtual Node * | at_prim (primNode *the_prim, Order ord) |
virtual Node * | at_tdef (tdefNode *the_tdef, Order ord) |
virtual Node * | at_ptr (ptrNode *the_ptr, Order ord) |
virtual Node * | at_array (arrayNode *the_array, Order ord) |
virtual Node * | at_func (funcNode *the_func, Order ord) |
virtual Node * | at_sue (sueNode *the_sue, Order ord) |
virtual Node * | at_struct (structNode *the_struct, Order ord) |
virtual Node * | at_union (unionNode *the_union, Order ord) |
virtual Node * | at_enum (enumNode *the_enum, Order ord) |
virtual Node * | at_suespec (suespecNode *the_suespec, Order ord) |
virtual Node * | at_expr (exprNode *the_expr, Order ord) |
virtual Node * | at_const (constNode *the_const, Order ord) |
virtual Node * | at_id (idNode *the_id, Order ord) |
virtual Node * | at_binary (binaryNode *the_binary, Order ord) |
virtual Node * | at_unary (unaryNode *the_unary, Order ord) |
virtual Node * | at_cast (castNode *the_cast, Order ord) |
virtual Node * | at_comma (commaNode *the_comma, Order ord) |
virtual Node * | at_ternary (ternaryNode *the_ternary, Order ord) |
virtual Node * | at_call (callNode *the_call, Order ord) |
virtual Node * | at_initializer (initializerNode *the_initializer, Order ord) |
virtual Node * | at_stmt (stmtNode *the_stmt, Order ord) |
virtual Node * | at_block (blockNode *the_block, Order ord) |
virtual Node * | at_basicblock (basicblockNode *the_basicblock, Order ord) |
virtual Node * | at_exprstmt (exprstmtNode *the_exprstmt, Order ord) |
virtual Node * | at_target (targetNode *the_target, Order ord) |
virtual Node * | at_label (labelNode *the_label, Order ord) |
virtual Node * | at_case (caseNode *the_case, Order ord) |
virtual Node * | at_selection (selectionNode *the_selection, Order ord) |
virtual Node * | at_if (ifNode *the_if, Order ord) |
virtual Node * | at_switch (switchNode *the_switch, Order ord) |
virtual Node * | at_loop (loopNode *the_loop, Order ord) |
virtual Node * | at_while (whileNode *the_while, Order ord) |
virtual Node * | at_do (doNode *the_do, Order ord) |
virtual Node * | at_for (forNode *the_for, Order ord) |
virtual Node * | at_jump (jumpNode *the_jump, Order ord) |
virtual Node * | at_goto (gotoNode *the_goto, Order ord) |
virtual Node * | at_continue (continueNode *the_continue, Order ord) |
virtual Node * | at_break (breakNode *the_break, Order ord) |
virtual Node * | at_return (returnNode *the_return, Order ord) |
virtual Node * | at_attrib (attribNode *the_attrib, Order ord) |
virtual Node * | at_text (textNode *the_text, Order ord) |
Private Attributes |
Order | _order |
| The order in which AST Nodes should be visited. More...
|
Depth | _depth |
| Which Nodes in the AST should be visited. More...
|
bool | _delete_old |
| Whether old Nodes should be deleted. More...
|
Detailed Description
A functional class to traverse an AST, and perform some transformation at each of its Nodes.
A Changer is a functional class that traverses an abstract syntax tree, and performs some transformation at each of its Nodes. At each Node, the transformation it performs depends on the class of the Node.
Corresponding to each class in the Node hierarchy, Changer defines an "at_" method. To specify the transformation that should be performed for Nodes of a particular class, create a subclass of Changer that overrides the "at_" method corresponding to that class. These "at_" methods take a Node, and return a transformed Node. By default, the "at_" methods simply return the Node they are passed. Thus, a Changer subclass only needs to override the "at_" methods corresponding to Node types that are relevant to that changer.
As the AST is traversed, the most specific "at_" method that has been defined for each Node will be called on that Node. For example, if a Changer subclass overrides "at_decl()", but not "at_subdecl()," then the "at_decl()" method wil be called for all declNodes and subDeclnodes encountered in the AST. However, if a Changer subclass overrides both "at_decl()" and "at_subdecl," then the "at_decl()" method will be called for all declNodes encountered in the AST, and the "at_subdecl()" method will be called for all subdeclNodes encountered in the AST. If you wish for both "at_subdecl()" and "at_decl()" to be called for subdeclNodes, then you should explicitly call the "at_decl()" method from "at_subdecl()."
As the changer traverses the AST, the "at_" methods for a Node can be called before its children have been visited, after its children have been visited, or both before and after its children have been visited. When the "at_" methods for a Node are called before its children, they are said to be called in "preorder." When the "at_" methods for a Node are called after its children, they are said to be called in "postorder." If "at_" methods are called both in preorder and in postorder, then the preorder call will always preceed the postorder call.
When a new Changer is created, the order(s) that Nodes are visited in should be specified. In general, all instances of a given subclass of Changer will visit Nodes in the same order. However, it may occasionally be useful to specify different orders for two different instances of the same subclass of Changer.
New instances of Changer can also specify the "depth" of the traversal. If the depth is "SubTree," then a Changer will visit the entire AST rooted at the Node that it is called on. If the depth is "NodeOnly," then the Changer will only call the "at_" method for Node it is called on, and not for any of its sub-Nodes. A Changer with a depth of NodeOnly is different from a Visitor, because the "Node.change()" method will return a transformed Node, whereas "Node.visit()" cannot return a transformed Node.
Changers may modify any fields of the Nodes it visits, including fields that contain sub-Nodes. If a field containing a sub-Node is changed in a preorder call to an "at_" method, then the AST rooted at the new sub-Node will be traversed. If a field containing a sub-Node is changed in a postorder call to an "at_" method, then the AST rooted at the new sub-Node will not be traversed.
Currently, Changers traverse the AST in a depth-first order. Preorder calls to the "at_" methods are called before descending into a Node's children, and postorder calls to the "at_" method are called after returning from the children in the traversal. At the leaves, the postorder calls to the "at_" methods immediately follow the preorder calls. However, this ordering is subject to change, and should not be relied upon. The only aspects of the AST traversal ordering which are guaranteed are:
- The preorder call to a Node's "at_" method is called before any of the calls to the "at_" methods of the Node's descendants.
- The postorder call to a Node's "at_" method is called after any of the calls to the "at_" methods of the Node's descendants.
- The preorder call to a Node's "at_" method is called before the postorder call to a Node's "at_" method is called.
Changers should never be used to traverse ASTs containing cycles; since they detect no mechanism to detect cycles, this would cause an infinite loop.
To use a changer "my_changer" to traverse an AST rooted at "my_node," use the code:
my_node = my_node->change(my_changer);
-
See also:
-
Visitor , Walker , Node::change
Member Enumeration Documentation
Constructor & Destructor Documentation
Changer::Changer |
( |
Order |
the_order, |
|
|
Depth |
depth, |
|
|
bool |
delete_old |
|
) |
[inline] |
|
|
Create a new instance of a Changer.
This constructor is usually called by a subclass. -
Parameters:
-
the_order |
The order in which AST Nodes should be visited. Nodes can be visited before their children (Preorder), after their children (Postorder), or both (Both). |
depth |
Specifies which Nodes in the AST should be visited. A value of SubTree specifies that the entire AST should be traversed. A value of NodeOnly specifies that only the root Node in the AST should be visited. |
delete_old |
Whether this changer deletes Nodes which are removed from the AST by "at_" methods. |
|
Member Function Documentation
virtual Node* Changer::at_def |
( |
defNode * |
the_def, |
|
|
Order |
ord |
|
) |
[inline, virtual] |
|
virtual Node* Changer::at_do |
( |
doNode * |
the_do, |
|
|
Order |
ord |
|
) |
[inline, virtual] |
|
virtual Node* Changer::at_for |
( |
forNode * |
the_for, |
|
|
Order |
ord |
|
) |
[inline, virtual] |
|
virtual Node* Changer::at_node |
( |
Node * |
the_node, |
|
|
Order |
ord |
|
) |
[inline, virtual] |
|
virtual Node* Changer::at_ptr |
( |
ptrNode * |
the_ptr, |
|
|
Order |
ord |
|
) |
[inline, virtual] |
|
virtual Node* Changer::at_sue |
( |
sueNode * |
the_sue, |
|
|
Order |
ord |
|
) |
[inline, virtual] |
|
bool Changer::delete_old |
( |
|
) |
const [inline] |
|
|
Return whether this Changer deletes Nodes which are removed from the AST by "at_" methods.
|
Depth Changer::depth |
( |
|
) |
const [inline] |
|
|
Return which Nodes of an AST should be visited.
A value of SubTree specifies that the entire AST should be traversed. A value of NodeOnly specifies that only the root Node in the AST should be visited. |
Order Changer::order |
( |
|
) |
const [inline] |
|
|
Return the order in which Nodes of an AST should be visited.
Nodes can be visited before their children (Preorder), after their children (Postorder), or both (Both). |
Member Data Documentation
bool Changer::_delete_old [private]
|
|
|
Whether old Nodes should be deleted.
|
Depth Changer::_depth [private]
|
|
|
Which Nodes in the AST should be visited.
|
Order Changer::_order [private]
|
|
|
The order in which AST Nodes should be visited.
|
The documentation for this class was generated from the following file:
Generated on Thu Jan 10 12:06:25 2002 for C-Breeze by
1.2.13.1 written by Dimitri van Heesch,
© 1997-2001