KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > percederberg > grammatica > output > JavaAnalyzerFile


1 /*
2  * JavaAnalyzerFile.java
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2.1
7  * of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307, USA.
18  *
19  * Copyright (c) 2003-2005 Per Cederberg. All rights reserved.
20  */

21
22 package net.percederberg.grammatica.output;
23
24 import java.io.IOException JavaDoc;
25
26 import net.percederberg.grammatica.code.java.JavaClass;
27 import net.percederberg.grammatica.code.java.JavaComment;
28 import net.percederberg.grammatica.code.java.JavaFile;
29 import net.percederberg.grammatica.code.java.JavaImport;
30 import net.percederberg.grammatica.code.java.JavaMethod;
31 import net.percederberg.grammatica.parser.ProductionPattern;
32 import net.percederberg.grammatica.parser.TokenPattern;
33
34 /**
35  * The Java analyzer file generator. This class encapsulates all the
36  * Java code necessary for creating a analyzer class file.
37  *
38  * @author Per Cederberg, <per at percederberg dot net>
39  * @version 1.0
40  */

41 class JavaAnalyzerFile {
42
43     /**
44      * The class comment.
45      */

46     private static final String JavaDoc TYPE_COMMENT =
47         "A class providing callback methods for the parser.";
48
49     /**
50      * The enter method comment.
51      */

52     private static final String JavaDoc ENTER_COMMENT =
53         "Called when entering a parse tree node.\n\n" +
54         "@param node the node being entered\n\n" +
55         "@throws ParseException if the node analysis discovered errors";
56
57     /**
58      * The exit method comment.
59      */

60     private static final String JavaDoc EXIT_COMMENT =
61         "Called when exiting a parse tree node.\n\n" +
62         "@param node the node being exited\n\n" +
63         "@return the node to add to the parse tree, or\n" +
64         " null if no parse tree should be created\n\n" +
65         "@throws ParseException if the node analysis discovered errors";
66
67     /**
68      * The child method comment.
69      */

70     private static final String JavaDoc CHILD_COMMENT =
71         "Called when adding a child to a parse tree node.\n\n" +
72         "@param node the parent node\n" +
73         "@param child the child node, or null\n\n" +
74         "@throws ParseException if the node analysis discovered errors";
75
76     /**
77      * The Java parser generator.
78      */

79     private JavaParserGenerator gen;
80
81     /**
82      * The Java file to write.
83      */

84     private JavaFile file;
85
86     /**
87      * The Java class.
88      */

89     private JavaClass cls;
90
91     /**
92      * The Java enter method.
93      */

94     private JavaMethod enter;
95
96     /**
97      * The Java exit method.
98      */

99     private JavaMethod exit;
100
101     /**
102      * The Java child method.
103      */

104     private JavaMethod child;
105
106     /**
107      * Creates a new analyzer file.
108      *
109      * @param gen the parser generator to use
110      */

111     public JavaAnalyzerFile(JavaParserGenerator gen) {
112         int modifiers;
113
114         this.gen = gen;
115         this.file = gen.createJavaFile();
116         if (gen.getPublicAccess()) {
117             modifiers = JavaClass.PUBLIC + JavaClass.ABSTRACT;
118         } else {
119             modifiers = JavaClass.PACKAGE_LOCAL + JavaClass.ABSTRACT;
120         }
121         this.cls = new JavaClass(modifiers,
122                                  gen.getBaseName() + "Analyzer",
123                                  "Analyzer");
124         this.enter = new JavaMethod(JavaMethod.PROTECTED,
125                                     "enter",
126                                     "Node node",
127                                     "void");
128         this.exit = new JavaMethod(JavaMethod.PROTECTED,
129                                    "exit",
130                                    "Node node",
131                                    "Node");
132         this.child = new JavaMethod(JavaMethod.PROTECTED,
133                                     "child",
134                                     "Production node, Node child",
135                                     "void");
136         initializeCode();
137     }
138
139     /**
140      * Initializes the source code objects.
141      */

142     private void initializeCode() {
143         String JavaDoc str;
144
145         // Add class
146
file.addClass(cls);
147
148         // Add file comment
149
str = file.toString() + "\n\n" + gen.getFileComment();
150         file.addComment(new JavaComment(JavaComment.BLOCK, str));
151
152         // Add imports
153
file.addImport(new JavaImport("net.percederberg.grammatica.parser",
154                                       "Analyzer"));
155         file.addImport(new JavaImport("net.percederberg.grammatica.parser",
156                                       "Node"));
157         file.addImport(new JavaImport("net.percederberg.grammatica.parser",
158                                       "ParseException"));
159         file.addImport(new JavaImport("net.percederberg.grammatica.parser",
160                                       "Production"));
161         file.addImport(new JavaImport("net.percederberg.grammatica.parser",
162                                       "Token"));
163
164         // Add class comment
165
str = TYPE_COMMENT;
166         if (gen.getClassComment() != null) {
167             str += "\n\n" + gen.getClassComment();
168         }
169         cls.addComment(new JavaComment(str));
170
171         // Add enter method
172
enter.addComment(new JavaComment(ENTER_COMMENT));
173         enter.addThrows("ParseException");
174         enter.addCode("switch (node.getId()) {");
175         cls.addMethod(enter);
176
177         // Add exit method
178
exit.addComment(new JavaComment(EXIT_COMMENT));
179         exit.addThrows("ParseException");
180         exit.addCode("switch (node.getId()) {");
181         cls.addMethod(exit);
182
183         // Add child method
184
child.addComment(new JavaComment(CHILD_COMMENT));
185         child.addThrows("ParseException");
186         child.addCode("switch (node.getId()) {");
187         cls.addMethod(child);
188     }
189
190     /**
191      * Adds the token analysis methods to this file.
192      *
193      * @param pattern the token pattern
194      * @param constants the constants file
195      */

196     public void addToken(TokenPattern pattern,
197                          JavaConstantsFile constants) {
198
199         String JavaDoc constant = constants.getConstant(pattern.getId());
200         String JavaDoc name;
201
202         if (!pattern.isIgnore()) {
203             name = gen.getCodeStyle().getMixedCase(pattern.getName(), true);
204             addEnterCase(constant, name, "Token");
205             addEnterMethod(name, "Token");
206             addExitCase(constant, name, "Token");
207             addExitMethod(name, "Token");
208         }
209     }
210
211     /**
212      * Adds the production analysis methods to this file.
213      *
214      * @param pattern the production pattern
215      * @param constants the constants file
216      */

217     public void addProduction(ProductionPattern pattern,
218                               JavaConstantsFile constants) {
219
220         String JavaDoc constant = constants.getConstant(pattern.getId());
221         String JavaDoc name;
222
223         if (!pattern.isSynthetic()) {
224             name = gen.getCodeStyle().getMixedCase(pattern.getName(),
225                                                    true);
226             addEnterCase(constant, name, "Production");
227             addEnterMethod(name, "Production");
228             addExitCase(constant, name, "Production");
229             addExitMethod(name, "Production");
230             addChildCase(constant, name);
231             addChildMethod(name);
232         }
233     }
234
235     /**
236      * Adds an enter method switch case.
237      *
238      * @param constant the node constant
239      * @param name the node name
240      * @param type the node type
241      */

242     private void addEnterCase(String JavaDoc constant, String JavaDoc name, String JavaDoc type) {
243         enter.addCode("case " + constant + ":");
244         enter.addCode(" enter" + name + "((" + type + ") node);");
245         enter.addCode(" break;");
246     }
247
248     /**
249      * Adds an exit method switch case.
250      *
251      * @param constant the node constant
252      * @param name the node name
253      * @param type the node type
254      */

255     private void addExitCase(String JavaDoc constant, String JavaDoc name, String JavaDoc type) {
256         exit.addCode("case " + constant + ":");
257         exit.addCode(" return exit" + name + "((" + type + ") node);");
258     }
259
260     /**
261      * Adds a child method switch case.
262      *
263      * @param constant the node constant
264      * @param name the node name
265      */

266     private void addChildCase(String JavaDoc constant, String JavaDoc name) {
267         child.addCode("case " + constant + ":");
268         child.addCode(" child" + name + "(node, child);");
269         child.addCode(" break;");
270     }
271
272     /**
273      * Adds an enter node method to this file.
274      *
275      * @param name the node name
276      * @param type the node type
277      */

278     private void addEnterMethod(String JavaDoc name, String JavaDoc type) {
279         JavaMethod m;
280
281         m = new JavaMethod(JavaMethod.PROTECTED,
282                            "enter" + name,
283                            type + " node",
284                            "void");
285         m.addComment(new JavaComment(ENTER_COMMENT));
286         m.addThrows("ParseException");
287         cls.addMethod(m);
288     }
289
290     /**
291      * Adds an exit node method to this file.
292      *
293      * @param name the node name
294      * @param type the node type
295      */

296     private void addExitMethod(String JavaDoc name, String JavaDoc type) {
297         JavaMethod m;
298
299         m = new JavaMethod(JavaMethod.PROTECTED,
300                            "exit" + name,
301                            type + " node",
302                            "Node");
303         m.addComment(new JavaComment(EXIT_COMMENT));
304         m.addThrows("ParseException");
305         m.addCode("return node;");
306         cls.addMethod(m);
307     }
308
309     /**
310      * Adds an add child method to this file.
311      *
312      * @param name the node name
313      */

314     private void addChildMethod(String JavaDoc name) {
315         JavaMethod m;
316
317         m = new JavaMethod(JavaMethod.PROTECTED,
318                            "child" + name,
319                            "Production node, Node child",
320                            "void");
321         m.addComment(new JavaComment(CHILD_COMMENT));
322         m.addThrows("ParseException");
323         m.addCode("node.addChild(child);");
324         cls.addMethod(m);
325     }
326
327     /**
328      * Writes the file source code.
329      *
330      * @throws IOException if the output file couldn't be created
331      * correctly
332      */

333     public void writeCode() throws IOException JavaDoc {
334         enter.addCode("}");
335         exit.addCode("}");
336         exit.addCode("return node;");
337         child.addCode("}");
338         file.writeCode(gen.getCodeStyle());
339     }
340 }
341
Popular Tags