KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > antlr > ASTFactory


1 package antlr;
2
3 /* ANTLR Translator Generator
4  * Project led by Terence Parr at http://www.jGuru.com
5  * Software rights: http://www.antlr.org/RIGHTS.html
6  *
7  * $Id: //depot/code/org.antlr/main/main/antlr/ASTFactory.java#5 $
8  */

9
10 import antlr.collections.AST;
11 import antlr.collections.impl.ASTArray;
12
13 /** AST Support code shared by TreeParser and Parser.
14  * We use delegation to share code (and have only one
15  * bit of code to maintain) rather than subclassing
16  * or superclassing (forces AST support code to be
17  * loaded even when you don't want to do AST stuff).
18  *
19  * Typically, setASTNodeType is used to specify the
20  * type of node to create, but you can override
21  * create to make heterogeneous nodes etc...
22  */

23 public class ASTFactory {
24     /** Name of AST class to create during tree construction.
25      * Null implies that the create method should create
26      * a default AST type such as CommonAST.
27      */

28     protected String JavaDoc theASTNodeType = null;
29     protected Class JavaDoc theASTNodeTypeClass = null;
30
31
32     /** Add a child to the current AST */
33     public void addASTChild(ASTPair currentAST, AST child) {
34         if (child != null) {
35             if (currentAST.root == null) {
36                 // Make new child the current root
37
currentAST.root = child;
38             }
39             else {
40                 if (currentAST.child == null) {
41                     // Add new child to current root
42
currentAST.root.setFirstChild(child);
43                 }
44                 else {
45                     currentAST.child.setNextSibling(child);
46                 }
47             }
48             // Make new child the current child
49
currentAST.child = child;
50             currentAST.advanceChildToEnd();
51         }
52     }
53
54     /** Create a new empty AST node; if the user did not specify
55      * an AST node type, then create a default one: CommonAST.
56      */

57     public AST create() {
58         AST t = null;
59         if (theASTNodeTypeClass == null) {
60             t = new CommonAST();
61         }
62         else {
63             try {
64                 t = (AST)theASTNodeTypeClass.newInstance(); // make a new one
65
}
66             catch (Exception JavaDoc e) {
67                 error("Can't create AST Node " + theASTNodeType);
68                 return null;
69             }
70         }
71         return t;
72     }
73
74     public AST create(int type) {
75         AST t = create();
76         t.initialize(type, "");
77         return t;
78     }
79
80     public AST create(int type, String JavaDoc txt) {
81         AST t = create();
82         t.initialize(type, txt);
83         return t;
84     }
85
86     /** Create a new empty AST node; if the user did not specify
87      * an AST node type, then create a default one: CommonAST.
88      */

89     public AST create(AST tr) {
90         if (tr == null) return null; // create(null) == null
91
AST t = create();
92         t.initialize(tr);
93         return t;
94     }
95
96     public AST create(Token tok) {
97         AST t = create();
98         t.initialize(tok);
99         return t;
100     }
101
102     /** Copy a single node. clone() is not used because
103      * we want to return an AST not a plain object...a type
104      * safety issue. Further, we want to have all AST node
105      * creation go through the factory so creation can be
106      * tracked. Returns null if t is null.
107      */

108     public AST dup(AST t) {
109         return create(t); // if t==null, create returns null
110
}
111
112     /** Duplicate tree including siblings of root. */
113     public AST dupList(AST t) {
114         AST result = dupTree(t); // if t == null, then result==null
115
AST nt = result;
116         while (t != null) { // for each sibling of the root
117
t = t.getNextSibling();
118             nt.setNextSibling(dupTree(t)); // dup each subtree, building new tree
119
nt = nt.getNextSibling();
120         }
121         return result;
122     }
123
124     /**Duplicate a tree, assuming this is a root node of a tree--
125      * duplicate that node and what's below; ignore siblings of root node.
126      */

127     public AST dupTree(AST t) {
128         AST result = dup(t); // make copy of root
129
// copy all children of root.
130
if (t != null) {
131             result.setFirstChild(dupList(t.getFirstChild()));
132         }
133         return result;
134     }
135
136     /** Make a tree from a list of nodes. The first element in the
137      * array is the root. If the root is null, then the tree is
138      * a simple list not a tree. Handles null children nodes correctly.
139      * For example, build(a, b, null, c) yields tree (a b c). build(null,a,b)
140      * yields tree (nil a b).
141      */

142     public AST make(AST[] nodes) {
143         if (nodes == null || nodes.length == 0) return null;
144         AST root = nodes[0];
145         AST tail = null;
146         if (root != null) {
147             root.setFirstChild(null); // don't leave any old pointers set
148
}
149         // link in children;
150
for (int i = 1; i < nodes.length; i++) {
151             if (nodes[i] == null) continue; // ignore null nodes
152
if (root == null) {
153                 // Set the root and set it up for a flat list
154
root = tail = nodes[i];
155             }
156             else if (tail == null) {
157                 root.setFirstChild(nodes[i]);
158                 tail = root.getFirstChild();
159             }
160             else {
161                 tail.setNextSibling(nodes[i]);
162                 tail = tail.getNextSibling();
163             }
164             // Chase tail to last sibling
165
while (tail.getNextSibling() != null) {
166                 tail = tail.getNextSibling();
167             }
168         }
169         return root;
170     }
171
172     /** Make a tree from a list of nodes, where the nodes are contained
173      * in an ASTArray object
174      */

175     public AST make(ASTArray nodes) {
176         return make(nodes.array);
177     }
178
179     /** Make an AST the root of current AST */
180     public void makeASTRoot(ASTPair currentAST, AST root) {
181         if (root != null) {
182             // Add the current root as a child of new root
183
root.addChild(currentAST.root);
184             // The new current child is the last sibling of the old root
185
currentAST.child = currentAST.root;
186             currentAST.advanceChildToEnd();
187             // Set the new root
188
currentAST.root = root;
189         }
190     }
191
192     public void setASTNodeType(String JavaDoc t) {
193         theASTNodeType = t;
194         try {
195             theASTNodeTypeClass = Class.forName(t); // get class def
196
}
197         catch (Exception JavaDoc e) {
198             // either class not found,
199
// class is interface/abstract, or
200
// class or initializer is not accessible.
201
error("Can't find/access AST Node type" + t);
202         }
203     }
204
205     /** To change where error messages go, can subclass/override this method
206      * and then setASTFactory in Parser and TreeParser. This method removes
207      * a prior dependency on class antlr.Tool.
208      */

209     public void error(String JavaDoc e) {
210         System.err.println(e);
211     }
212 }
213
Popular Tags