1 package antlr;
2
3 import antlr.collections.AST;
4 import antlr.collections.impl.ASTArray;
5
6 * We use delegation to share code (and have only one
8 * bit of code to maintain) rather than subclassing
9 * or superclassing (forces AST support code to be
10 * loaded even when you don't want to do AST stuff).
11 *
12 * Typically, setASTNodeType is used to specify the
13 * type of node to create, but you can override
14 * create to make heterogeneous nodes etc...
15 */
16 public class ASTFactory {
17 * Null implies that the create method should create
19 * a default AST type such as CommonAST.
20 */
21 protected String theASTNodeType = null;
22 protected Class theASTNodeTypeClass = null;
23
24
25
26 public void addASTChild(ASTPair currentAST, AST child) {
27 if (child != null) {
28 if (currentAST.root == null) {
29 currentAST.root = child;
31 }
32 else {
33 if (currentAST.child == null) {
34 currentAST.root.setFirstChild(child);
36 }
37 else {
38 currentAST.child.setNextSibling(child);
39 }
40 }
41 currentAST.child = child;
43 currentAST.advanceChildToEnd();
44 }
45 }
46 * an AST node type, then create a default one: CommonAST.
48 */
49 public AST create() {
50 AST t = null;
51 if (theASTNodeTypeClass == null) {
52 t = new CommonAST();
53 } else {
54 try {
55 t = (AST) theASTNodeTypeClass.newInstance(); } catch (Exception e) {
57 antlr.Tool.warning("Can't create AST Node " + theASTNodeType);
58 return null;
59 }
60 }
61 return t;
62 }
63 public AST create(int type) {
64 AST t = create();
65 t.initialize(type,"");
66 return t;
67 }
68 public AST create(int type, String txt) {
69 AST t = create();
70 t.initialize(type,txt);
71 return t;
72 }
73 * an AST node type, then create a default one: CommonAST.
75 */
76 public AST create(AST tr) {
77 if ( tr==null ) return null; AST t = create();
79 t.initialize(tr);
80 return t;
81 }
82 public AST create(Token tok) {
83 AST t = create();
84 t.initialize(tok);
85 return t;
86 }
87 * we want to return an AST not a plain object...a type
89 * safety issue. Further, we want to have all AST node
90 * creation go through the factory so creation can be
91 * tracked. Returns null if t is null.
92 */
93 public AST dup(AST t) {
94 return create(t); }
96
97 public AST dupList(AST t) {
98 AST result = dupTree(t); AST nt = result;
100 while (t != null) { t = t.getNextSibling();
102 nt.setNextSibling(dupTree(t)); nt = nt.getNextSibling();
104 }
105 return result;
106 }
107 * duplicate that node and what's below; ignore siblings of root node.
109 */
110 public AST dupTree(AST t) {
111 AST result = dup(t); if ( t!=null ) {
114 result.setFirstChild( dupList(t.getFirstChild()) );
115 }
116 return result;
117 }
118 * array is the root. If the root is null, then the tree is
120 * a simple list not a tree. Handles null children nodes correctly.
121 * For example, build(a, b, null, c) yields tree (a b c). build(null,a,b)
122 * yields tree (nil a b).
123 */
124 public AST make(AST[] nodes) {
125 if ( nodes==null || nodes.length==0 ) return null;
126 AST root = nodes[0];
127 AST tail = null;
128 if (root != null) {
129 root.setFirstChild(null); }
131 for (int i=1; i<nodes.length; i++) {
133 if ( nodes[i]==null ) continue; if (root == null) {
135 root = tail = nodes[i];
137 }
138 else if ( tail==null ) {
139 root.setFirstChild(nodes[i]);
140 tail = root.getFirstChild();
141 }
142 else {
143 tail.setNextSibling(nodes[i]);
144 tail = tail.getNextSibling();
145 }
146 while (tail.getNextSibling() != null) {
148 tail = tail.getNextSibling();
149 }
150 }
151 return root;
152 }
153 * in an ASTArray object
155 */
156 public AST make(ASTArray nodes) {
157 return make(nodes.array);
158 }
159
160 public void makeASTRoot(ASTPair currentAST, AST root) {
161 if (root != null) {
162 root.addChild(currentAST.root);
164 currentAST.child = currentAST.root;
166 currentAST.advanceChildToEnd();
167 currentAST.root = root;
169 }
170 }
171 public void setASTNodeType(String t) {
172 theASTNodeType = t;
173 try {
174 theASTNodeTypeClass = Class.forName(t); } catch (Exception e) {
176 antlr.Tool.warning("Can't find/access AST Node type"+t);
180 }
181 }
182 }
183