Source code: org/sablecc/sablecc/GenTools.java
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * This file is part of SableCC. *
3 * See the file "LICENSE" for copyright information and the *
4 * terms and conditions for copying, distribution and *
5 * modification of SableCC. *
6 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
7
8 package org.sablecc.sablecc;
9
10 import org.sablecc.sablecc.GenAnalyses.*;
11 import org.sablecc.sablecc.analysis.*;
12 import org.sablecc.sablecc.node.*;
13 import java.util.*;
14 import com.sun.java.util.collections.*;
15 import java.io.*;
16
17 public class GenTools extends DepthFirstAdapter
18 {
19 private MacroExpander macros;
20 private ResolveIds ids;
21 private File pkgDir;
22 private String pkgName;
23 private List elemList;
24 private List altList = new TypedLinkedList(AltInfoCast.instance);
25 private List tokenList = new TypedLinkedList(StringCast.instance);
26
27 ElemInfo info;
28
29 public GenTools(ResolveIds ids)
30 {
31 this.ids = ids;
32
33 try
34 {
35 macros = new MacroExpander(
36 new InputStreamReader(
37 getClass().getResourceAsStream("tools.txt")));
38 }
39 catch(IOException e)
40 {
41 throw new RuntimeException("unable to open tools.txt.");
42 }
43
44 pkgDir = new File(ids.pkgDir, "tool");
45 pkgName = ids.pkgName.equals("") ? "tool" : ids.pkgName + ".tool";
46
47 if(!pkgDir.exists())
48 {
49 if(!pkgDir.mkdir())
50 {
51 throw new RuntimeException("Unable to create " + pkgDir.getAbsolutePath());
52 }
53 }
54 }
55
56 public void inTokenDef1(TokenDef1 node)
57 {
58 tokenList.add(ids.names.get(node));
59 }
60
61 public void inAlt1(Alt1 node)
62 {
63 inAlt(node);
64 }
65
66 public void inAlt2(Alt2 node)
67 {
68 inAlt(node);
69 }
70
71 public void inAlt(Alt node)
72 {
73 elemList = new TypedLinkedList(ElemInfoCast.instance);
74 }
75
76 public void inElem1(Elem1 tnode)
77 {
78 info = new ElemInfo();
79
80 info.name = (String) ids.names.get(tnode);
81 info.type = (String) ids.elemTypes.get(tnode);
82 info.operator = ElemInfo.NONE;
83
84 tnode.getNode4().apply(new DepthFirstAdapter()
85 {
86 public void caseUnOp1(UnOp1 node)
87 {
88 info.operator = ElemInfo.STAR;
89 }
90
91 public void caseUnOp2(UnOp2 node)
92 {
93 info.operator = ElemInfo.QMARK;
94 }
95
96 public void caseUnOp3(UnOp3 node)
97 {
98 info.operator = ElemInfo.PLUS;
99 }
100 });
101
102 elemList.add(info);
103 info = null;
104 }
105
106 public void outAlt1(Alt1 node)
107 {
108 outAlt(node);
109 }
110
111 public void outAlt2(Alt2 node)
112 {
113 outAlt(node);
114 }
115
116 public void outAlt(Alt node)
117 {
118 AltInfo info = new AltInfo();
119
120 info.name = (String) ids.names.get(node);
121 info.elems.addAll(elemList);
122 elemList = null;
123
124 altList.add(info);
125 }
126
127 public void outStart1(Start1 node)
128 {
129 createDisplayTree();
130 generateFile("TreeBuilder");
131 generateFile("PrintWalker");
132 generateFile("PrintTree");
133 generateVersion();
134
135 System.out.println();
136 }
137
138 private void generateFile(String macro)
139 {
140 BufferedWriter file;
141 try
142 {
143 file = new BufferedWriter(
144 new FileWriter(
145 new File(pkgDir, macro+".java")));
146 macros.apply(file, macro, new String[] { pkgName,ids.pkgName });
147 file.flush();
148 file.close();
149 }
150 catch(IOException e)
151 {
152 throw new RuntimeException("Unable to create " + new File(pkgDir, macro + ".java").getAbsolutePath());
153 }
154 System.out.print(".");
155 }
156
157
158 private void generateVersion()
159 {
160 BufferedWriter file;
161 try
162 {
163 file = new BufferedWriter(
164 new FileWriter(
165 new File(pkgDir, "Version.java")));
166 macros.apply(file, "Version", new String[] { pkgName,ids.pkgName });
167 file.flush();
168 file.close();
169 file = new BufferedWriter(
170 new FileWriter(
171 new File(pkgDir, "Version.java.in")));
172 macros.apply(file, "Version", new String[] { pkgName,ids.pkgName });
173 file.flush();
174 file.close();
175 }
176 catch(IOException e)
177 {
178 throw new RuntimeException("Unable to create " + new File(pkgDir, "Version.java").getAbsolutePath());
179 }
180 System.out.print(".");
181 }
182
183
184 private void createDisplayTree()
185 {
186 System.out.print(".");
187 BufferedWriter file;
188
189 try
190 {
191 file = new BufferedWriter(
192 new FileWriter(
193 new File(pkgDir, "DisplayTree.java")));
194 }
195 catch(IOException e)
196 {
197 throw new RuntimeException("Unable to create " + new File(pkgDir, "DisplayTree.java").getAbsolutePath());
198 }
199
200 try
201 {
202 macros.apply(file, "DisplayTreeHeader", new String[] {pkgName, ids.pkgName});
203
204 for(Iterator i = altList.iterator(); i.hasNext();)
205 {
206 AltInfo info = (AltInfo) i.next();
207
208 macros.apply(file, "DisplayTreeNodeHeader",
209 new String[] {info.name});
210
211 for(Iterator j = info.elems.iterator(); j.hasNext();)
212 {
213 ElemInfo eInfo = (ElemInfo) j.next();
214
215 switch(eInfo.operator)
216 {
217 case ElemInfo.QMARK:
218 case ElemInfo.NONE:
219 {
220 macros.apply(file, "DisplayTreeCaseBodyNode",
221 new String[] {eInfo.name});
222 }
223 break;
224 case ElemInfo.STAR:
225 case ElemInfo.PLUS:
226 {
227 macros.apply(file, "DisplayTreeCaseBodyList",
228 new String[] {eInfo.name, eInfo.type});
229 }
230 break;
231 }
232 }
233
234 macros.apply(file, "DisplayTreeNodeFooter",
235 new String[] {info.name});
236
237 }
238
239 macros.apply(file, "DisplayTreeFooter", null);
240 }
241 catch(IOException e)
242 {
243 throw new RuntimeException("An error occured while writing to " +
244 new File(pkgDir, "DisplayTree.java").getAbsolutePath());
245 }
246 catch(Exception e){
247 e.printStackTrace();
248 }
249
250 try
251 {
252 file.flush();
253 file.close();
254 }
255 catch(IOException e)
256 {
257 }
258
259 }
260
261 private static class AltInfoCast implements Cast
262 {
263 final static AltInfoCast instance = new AltInfoCast();
264
265 private AltInfoCast()
266 {
267 }
268
269 public Object cast(Object o)
270 {
271 return (AltInfo) o;
272 }
273 }
274
275 private static class ElemInfo
276 {
277 final static int NONE = 0;
278 final static int STAR = 1;
279 final static int QMARK = 2;
280 final static int PLUS = 3;
281
282 String name;
283 String type;
284 int operator;
285 }
286
287 private static class ElemInfoCast implements Cast
288 {
289 public final static ElemInfoCast instance = new ElemInfoCast();
290
291 private ElemInfoCast()
292 {
293 }
294
295 public Object cast(Object o)
296 {
297 return (ElemInfo) o;
298 }
299 }
300
301 private static class AltInfo
302 {
303 String name;
304 final List elems = new TypedLinkedList(ElemInfoCast.instance);
305 }
306 }
307
308