KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fri > patterns > interpreter > parsergenerator > util > SemanticSkeletonGenerator


1 package fri.patterns.interpreter.parsergenerator.util;
2
3 import java.util.*;
4 import java.io.*;
5 import fri.patterns.interpreter.parsergenerator.syntax.*;
6
7 /**
8     This class can be called using SourceGenerator by commandline.
9     <p>
10     Generates Java code that contains empty method bodies for the
11     implementation of a given Syntax. For every rule there will
12     be a method with the name of the nonterminal on the left side
13     and one argument for each symbol on the right side. All arguments
14     are of type Object.
15     The created implementation derives <i>ReflectSemantic</i>.
16     <pre>
17         File in = new File("MySyntax.grammar);
18         String basename = "MySemantic";
19         Writer out = new FileWriter(basename+".java");
20         new SemanticSkeletonGenerator(in, basename, "my.pkg.name", out);
21         // the Java source "my/pkg/name/MySemantic.java" will be generated
22     </pre>
23     
24     @see fri.patterns.interpreter.parsergenerator.semantics.ReflectSemantic
25     @see fri.patterns.interpreter.parsergenerator.util.SourceGenerator
26     @author (c) 2002, Fritz Ritzberger
27 */

28
29 public class SemanticSkeletonGenerator
30 {
31     private static Hashtable keyWords;
32     private BufferedWriter bw;
33     
34     /**
35         Reads the passed Syntax and turns it into a semantic skeleton implementation.
36         The passed Write will be closed.
37         @param syntax Syntax the semantc is meant for
38         @param className basname of the class to generate (without package)
39         @param pkgName name of package, can be null
40         @param skeletonOutput Writer where Java source should be written to
41     */

42     public SemanticSkeletonGenerator(Syntax syntax, String JavaDoc className, String JavaDoc pkgName, Writer skeletonOutput)
43         throws Exception JavaDoc
44     {
45         if (skeletonOutput instanceof BufferedWriter)
46             bw = (BufferedWriter)skeletonOutput;
47         else
48             bw = new BufferedWriter(skeletonOutput);
49         
50         // start of java file
51
if (pkgName != null && pkgName.length() > 0) {
52             writeLine("package "+pkgName+";");
53             writeLine();
54         }
55         writeLine("/** ");
56         writeLine(" * IMPLEMENT ME: Semantic skeleton will not be overwritten, generated");
57         writeLine(" * at "+new Date()+"\n");
58         writeLine(" * by fri.patterns.interpreter.parsergenerator.util.SemanticSkeletonGenerator.");
59         writeLine(" */");
60         writeLine();
61         writeLine("import fri.patterns.interpreter.parsergenerator.semantics.ReflectSemantic;");
62         writeLine();
63         writeLine("public class "+className+" extends ReflectSemantic");
64         writeLine("{");
65         
66         Map methods = new Hashtable();
67         
68         // output default method bodies
69
for (int i = 0; i < syntax.size(); i++) {
70             Rule rule = syntax.getRule(i);
71
72             String JavaDoc nonterminal = rule.getNonterminal();
73             
74             // check if methodname candidate is a Java keyword - refuse when it is
75
checkMethodNameAgainstKeywords(nonterminal); // throws IllegalArgumentException
76

77             // check if already used, argument types are always Object
78
int countArgs = rule.rightSize();
79             String JavaDoc signature = nonterminal+"("+countArgs+")";
80             boolean alreadyHaveMethod = false;
81
82             write("\t");
83             
84             if (methods.get(signature) != null) {
85                 alreadyHaveMethod = true;
86                 // already have this method, make comment
87
write("//");
88             }
89             
90             // open method and argument list
91
write("public Object "+nonterminal+"("); // must be public to be found by reflection
92

93             List args = new ArrayList(countArgs);
94
95             for (int j = 0; j < rule.rightSize(); j++) {
96                 String JavaDoc s = rule.getRightSymbol(j);
97
98                 if (j > 1 || s != null && s.trim().length() > 0)
99                     write((j == 1 ? "" : ", ")+"Object "+getValidParamName(s, args, j));
100             }
101             // close argument list
102
writeLine(")");
103
104             if (alreadyHaveMethod == false) {
105                 writeLine("\t{");
106                 
107                 write("\t\tSystem.err.println(\""+nonterminal+" (");
108                 for (int j = 0; j < args.size(); j++) {
109                     write((j == 0 ? "" : ", ")+"'\"+"+args.get(j)+"+\"'");
110                 }
111                 writeLine(")\");");
112                 
113                 writeLine("\t\treturn \""+signature+"\";"); // return name of method
114
writeLine("\t}");
115
116                 methods.put(signature, signature);
117             }
118
119             writeLine();
120         }
121
122         // end of java file
123
writeLine();
124         writeLine("}");
125         writeLine();
126         
127         bw.close();
128     }
129
130
131
132     private void writeLine()
133         throws IOException
134     {
135         bw.newLine();
136     }
137
138     private void writeLine(String JavaDoc line)
139         throws IOException
140     {
141         bw.write(line, 0, line.length());
142         writeLine();
143     }
144
145     private void write(String JavaDoc s)
146         throws IOException
147     {
148         bw.write(s, 0, s.length());
149     }
150     
151
152     // Make a compileable parameter name from syntax symbol.
153
// Returns words for standard symbols.
154
private String JavaDoc getValidParamName(String JavaDoc symbol, List argsUntilNow, int position) {
155         String JavaDoc s = SymbolToName.makeIdentifier(symbol, true);
156
157         if (argsUntilNow.indexOf(s) >= 0)
158             s = s+position;
159         
160         argsUntilNow.add(s);
161         
162         return s;
163     }
164
165     // Check against Java key words.
166
private void checkMethodNameAgainstKeywords(String JavaDoc method) {
167         if (keyWords == null) {
168             keyWords = new Hashtable();
169             keyWords.put("boolean", "");
170             keyWords.put("byte", "");
171             keyWords.put("short", "");
172             keyWords.put("int", "");
173             keyWords.put("long", "");
174             keyWords.put("char", "");
175             keyWords.put("float", "");
176             keyWords.put("double", "");
177             keyWords.put("abstract", "");
178             keyWords.put("break", "");
179             keyWords.put("case", "");
180             keyWords.put("catch", "");
181             keyWords.put("class", "");
182             keyWords.put("const", "");
183             keyWords.put("continue", "");
184             keyWords.put("default", "");
185             keyWords.put("do", "");
186             keyWords.put("else", "");
187             keyWords.put("extends", "");
188             keyWords.put("false", "");
189             keyWords.put("final", "");
190             keyWords.put("finally", "");
191             keyWords.put("for", "");
192             keyWords.put("goto", "");
193             keyWords.put("if", "");
194             keyWords.put("implements", "");
195             keyWords.put("import", "");
196             keyWords.put("instanceof", "");
197             keyWords.put("interface", "");
198             keyWords.put("native", "");
199             keyWords.put("new", "");
200             keyWords.put("null", "");
201             keyWords.put("package", "");
202             keyWords.put("public", "");
203             keyWords.put("protected", "");
204             keyWords.put("private", "");
205             keyWords.put("return", "");
206             keyWords.put("static", "");
207             keyWords.put("strictfp", "");
208             keyWords.put("super", "");
209             keyWords.put("switch", "");
210             keyWords.put("synchronized", "");
211             keyWords.put("this", "");
212             keyWords.put("throw", "");
213             keyWords.put("throws", "");
214             keyWords.put("transient", "");
215             keyWords.put("true", "");
216             keyWords.put("try", "");
217             keyWords.put("volatile", "");
218             keyWords.put("void", "");
219             keyWords.put("while", "");
220         }
221         
222         if (keyWords.get(method) != null)
223             throw new IllegalArgumentException JavaDoc("Nonterminal \""+method+"\" is a Java keyword and can not be used as methodname with AbstractSemantic!");
224     }
225
226 }
227
Popular Tags