KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * CSharpAnalyzerFile.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.csharp.CSharpClass;
27 import net.percederberg.grammatica.code.csharp.CSharpComment;
28 import net.percederberg.grammatica.code.csharp.CSharpFile;
29 import net.percederberg.grammatica.code.csharp.CSharpMethod;
30 import net.percederberg.grammatica.code.csharp.CSharpNamespace;
31 import net.percederberg.grammatica.code.csharp.CSharpUsing;
32 import net.percederberg.grammatica.parser.ProductionPattern;
33 import net.percederberg.grammatica.parser.TokenPattern;
34
35 /**
36  * The C# analyzer file generator. This class encapsulates all the
37  * C# code necessary for creating a analyzer class file.
38  *
39  * @author Per Cederberg, <per at percederberg dot net>
40  * @version 1.5
41  */

42 class CSharpAnalyzerFile {
43
44     /**
45      * The class comment.
46      */

47     private static final String JavaDoc TYPE_COMMENT =
48         "<remarks>A class providing callback methods for the\n" +
49         "parser.</remarks>";
50
51     /**
52      * The enter method comment.
53      */

54     private static final String JavaDoc ENTER_COMMENT =
55         "<summary>Called when entering a parse tree node.</summary>\n\n" +
56         "<param name='node'>the node being entered</param>\n\n" +
57         "<exception cref='ParseException'>if the node analysis\n" +
58         "discovered errors</exception>";
59
60     /**
61      * The exit method comment.
62      */

63     private static final String JavaDoc EXIT_COMMENT =
64         "<summary>Called when exiting a parse tree node.</summary>\n\n" +
65         "<param name='node'>the node being exited</param>\n\n" +
66         "<returns>the node to add to the parse tree, or\n" +
67         " null if no parse tree should be created</returns>\n\n" +
68         "<exception cref='ParseException'>if the node analysis\n" +
69         "discovered errors</exception>";
70
71     /**
72      * The child method comment.
73      */

74     private static final String JavaDoc CHILD_COMMENT =
75         "<summary>Called when adding a child to a parse tree\n" +
76         "node.</summary>\n\n" +
77         "<param name='node'>the parent node</param>\n" +
78         "<param name='child'>the child node, or null</param>\n\n" +
79         "<exception cref='ParseException'>if the node analysis\n" +
80         "discovered errors</exception>";
81
82     /**
83      * The parser generator.
84      */

85     private CSharpParserGenerator gen;
86
87     /**
88      * The file to write.
89      */

90     private CSharpFile file;
91
92     /**
93      * The class.
94      */

95     private CSharpClass cls;
96
97     /**
98      * The enter method.
99      */

100     private CSharpMethod enter;
101
102     /**
103      * The exit method.
104      */

105     private CSharpMethod exit;
106
107     /**
108      * The child method.
109      */

110     private CSharpMethod child;
111
112     /**
113      * Creates a new analyzer file.
114      *
115      * @param gen the parser generator to use
116      */

117     public CSharpAnalyzerFile(CSharpParserGenerator gen) {
118         String JavaDoc name = gen.getBaseName() + "Analyzer";
119         int modifiers;
120
121         this.gen = gen;
122         this.file = new CSharpFile(gen.getBaseDir(), name);
123         if (gen.getPublicAccess()) {
124             modifiers = CSharpClass.PUBLIC + CSharpClass.ABSTRACT;
125         } else {
126             modifiers = CSharpClass.INTERNAL + CSharpClass.ABSTRACT;
127         }
128         this.cls = new CSharpClass(modifiers, name, "Analyzer");
129         modifiers = CSharpMethod.PUBLIC + CSharpMethod.OVERRIDE;
130         this.enter = new CSharpMethod(modifiers,
131                                       "Enter",
132                                       "Node node",
133                                       "void");
134         this.exit = new CSharpMethod(modifiers,
135                                      "Exit",
136                                      "Node node",
137                                      "Node");
138         this.child = new CSharpMethod(modifiers,
139                                       "Child",
140                                       "Production node, Node child",
141                                       "void");
142         initializeCode();
143     }
144
145     /**
146      * Initializes the source code objects.
147      */

148     private void initializeCode() {
149         String JavaDoc str;
150
151         // Add using
152
file.addUsing(new CSharpUsing("PerCederberg.Grammatica.Runtime"));
153
154         // Add namespace
155
if (gen.getNamespace() == null) {
156             file.addClass(cls);
157         } else {
158             CSharpNamespace n = new CSharpNamespace(gen.getNamespace());
159             n.addClass(cls);
160             file.addNamespace(n);
161         }
162
163         // Add file comment
164
str = file.toString() + "\n\n" + gen.getFileComment();
165         file.addComment(new CSharpComment(CSharpComment.BLOCK, str));
166
167         // Add type comment
168
cls.addComment(new CSharpComment(TYPE_COMMENT));
169
170         // Add enter method
171
enter.addComment(new CSharpComment(ENTER_COMMENT));
172         enter.addCode("switch (node.Id) {");
173         cls.addMethod(enter);
174
175         // Add exit method
176
exit.addComment(new CSharpComment(EXIT_COMMENT));
177         exit.addCode("switch (node.Id) {");
178         cls.addMethod(exit);
179
180         // Add child method
181
child.addComment(new CSharpComment(CHILD_COMMENT));
182         child.addCode("switch (node.Id) {");
183         cls.addMethod(child);
184     }
185
186     /**
187      * Adds the token analysis methods to this file.
188      *
189      * @param pattern the token pattern
190      * @param constants the constants file
191      */

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

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

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

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

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

274     private void addEnterMethod(String JavaDoc name, String JavaDoc type) {
275         CSharpMethod m;
276
277         m = new CSharpMethod(CSharpMethod.PUBLIC + CSharpMethod.VIRTUAL,
278                              "Enter" + name,
279                              type + " node",
280                              "void");
281         m.addComment(new CSharpComment(ENTER_COMMENT));
282         cls.addMethod(m);
283     }
284
285     /**
286      * Adds an exit node method to this file.
287      *
288      * @param name the node name
289      * @param type the node type
290      */

291     private void addExitMethod(String JavaDoc name, String JavaDoc type) {
292         CSharpMethod m;
293
294         m = new CSharpMethod(CSharpMethod.PUBLIC + CSharpMethod.VIRTUAL,
295                              "Exit" + name,
296                              type + " node",
297                              "Node");
298         m.addComment(new CSharpComment(EXIT_COMMENT));
299         m.addCode("return node;");
300         cls.addMethod(m);
301     }
302
303     /**
304      * Adds an add child method to this file.
305      *
306      * @param name the node name
307      */

308     private void addChildMethod(String JavaDoc name) {
309         CSharpMethod m;
310
311         m = new CSharpMethod(CSharpMethod.PUBLIC + CSharpMethod.VIRTUAL,
312                              "Child" + name,
313                              "Production node, Node child",
314                              "void");
315         m.addComment(new CSharpComment(CHILD_COMMENT));
316         m.addCode("node.AddChild(child);");
317         cls.addMethod(m);
318     }
319
320     /**
321      * Writes the file source code.
322      *
323      * @throws IOException if the output file couldn't be created
324      * correctly
325      */

326     public void writeCode() throws IOException JavaDoc {
327         enter.addCode("}");
328         exit.addCode("}");
329         exit.addCode("return node;");
330         child.addCode("}");
331         file.writeCode(gen.getCodeStyle());
332     }
333 }
334
Popular Tags