KickJava   Java API By Example, From Geeks To Geeks.

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


1 package fri.patterns.interpreter.parsergenerator.util;
2
3 import java.io.*;
4 import java.util.*;
5 import fri.patterns.interpreter.parsergenerator.Token;
6 import fri.patterns.interpreter.parsergenerator.parsertables.*;
7 import fri.patterns.interpreter.parsergenerator.syntax.*;
8 import fri.patterns.interpreter.parsergenerator.syntax.builder.SyntaxBuilder;
9
10 /**
11     Java source generator. Following code generations are supported:
12     <ul>
13         <li>SemanticSkeleton, code base for a Semantic-implementation of big syntaxes.</li>
14         <li>Turn ParserTables (built from a Syntax) into compileable Java-code (for faster loading).</li>
15         <li>Turn a Syntax object into compileable Java code (for faster loading).</li>
16     </ul>
17     <pre>
18     SYNTAX: java fri.patterns.interpreter.parsergenerator.util.SourceGenerator [semantic|LALR|SLR|LR] file.syntax [file.syntax ...]
19             LALR|SLR|LR: Generates ParserTable implementation(s) of passed grammar file(s).
20                    else: Generates Syntax implementation(s) of passed grammar file(s).
21     CAUTION: Files MUST have relative pathes!
22     </pre>
23
24     @author (c) 2002, Fritz Ritzberger
25 */

26
27 public abstract class SourceGenerator
28 {
29     /**
30         Generates a semantic skeleton implementation for a given syntax.
31         @param input syntax the semantic is meant for
32         @param className basename of class to generate, semantic will be named className+"Semantic.java"
33         @param pkgName package-name of class to generate
34     */

35     public static void generateSemanticSkeleton(Syntax syntax, String JavaDoc className, String JavaDoc pkgName)
36         throws Exception JavaDoc
37     {
38         String JavaDoc fileName = className+"Semantic.java";
39
40         String JavaDoc dirName = pkgName != null && pkgName.length() > 0
41                 ? pkgName.replace('.', File.separatorChar)
42                 : System.getProperty("user.dir");
43
44         File out = new File(dirName, fileName);
45                 
46         if (out.exists()) {
47             throw new IllegalStateException JavaDoc("Will not overwrite "+out.getAbsolutePath()+". Please check the file for implementation and remove it!");
48         }
49         else {
50             new File(dirName).mkdirs(); // ensure directory exists
51
FileWriter fw = new FileWriter(out);
52             new SemanticSkeletonGenerator(syntax, className, pkgName, fw);
53             System.err.println("Wrote semantic skeleton to file: "+out);
54         }
55     }
56
57
58     /**
59         Generates Java code from parser tables. makes the output filename and calls <i>parserTables.toSourceFile()</i> then.
60         @param parserTables ParserTables for which the source should stand
61         @param className basename of class to generate
62         @param pkgName name of package of class to generate, can be null
63     */

64     public static void generateParserTable(AbstractParserTables parserTables, String JavaDoc className, String JavaDoc pkgName)
65         throws Exception JavaDoc
66     {
67         String JavaDoc fullName = (pkgName != null ? pkgName+"." : "")+className;
68         parserTables.toSourceFile(fullName);
69     }
70
71
72     /**
73         Generates a Java implementation from the passed Syntax object.
74         @param syntax Syntax to convert to Java code.
75         @param className basename of class to generate
76         @param pkgName name of package of class to generate
77     */

78     public static void generateSyntaxImpl(
79         Syntax syntax,
80         String JavaDoc className,
81         String JavaDoc pkgName,
82         List initialNonterminals)
83         throws IOException
84     {
85         String JavaDoc origClsName = className;
86         className = className+"Syntax";
87         String JavaDoc fileName = (pkgName != null ? pkgName+"."+className : className);
88         fileName = fileName.replace('.', File.separatorChar)+".java";
89         Writer f = new BufferedWriter(new FileWriter(fileName));
90         
91         if (pkgName != null)
92             fwrite("package "+pkgName+";\n\n", f);
93
94         fwrite("/**\n", f);
95         fwrite(" * DO NOT EDIT - Syntax generated from "+origClsName+".syntax\n", f);
96         fwrite(" * at "+new Date()+"\n", f);
97         fwrite(" * by fri.patterns.interpreter.parsergenerator.util.SourceGenerator.\n", f);
98         fwrite(" */\n\n", f);
99
100         fwrite("import fri.patterns.interpreter.parsergenerator.syntax.*;\n\n", f);
101         fwrite("public final class "+className+" extends Syntax\n", f); // class definition
102
fwrite("{\n", f);
103         
104         for (int i = 0; i < initialNonterminals.size(); i++) // define String constants for every nonterminal
105
fwrite(" public static final String "+initialNonterminals.get(i)+" = \""+initialNonterminals.get(i)+"\";\n", f);
106         fwrite("\n", f);
107         
108         fwrite(" public "+className+"() {\n", f); // constructor
109
fwrite(" super("+syntax.size()+");\n\n", f);
110         fwrite(" Rule rule;\n", f);
111
112         for (int i = 0; i < syntax.size(); i++) {
113             Rule rule = syntax.getRule(i);
114             String JavaDoc nt = rule.getNonterminal();
115             if (initialNonterminals.indexOf(nt) < 0) // have not been defined as String constant
116
nt = "\""+nt+"\"";
117             fwrite("\n rule = new Rule("+nt+", "+rule.rightSize()+"); // "+i+"\n", f);
118             
119             for (int j = 0; j < rule.rightSize(); j++) {
120                 String JavaDoc rightSymbol = rule.getRightSymbol(j);
121                 if (Token.isTerminal(rightSymbol))
122                     fwrite(" rule.addRightSymbol(\""+SyntaxUtil.maskQuoteAndBackslash(rightSymbol)+"\");\n", f);
123                 else
124                     if (initialNonterminals.indexOf(rightSymbol) >= 0) // have been defined as String constants
125
fwrite(" rule.addRightSymbol("+rightSymbol+");\n", f);
126                     else
127                         fwrite(" rule.addRightSymbol(\""+rightSymbol+"\");\n", f);
128             }
129             fwrite(" addRule(rule);\n", f);
130         }
131         fwrite(" }\n", f);
132         fwrite("}\n", f);
133
134         f.close();
135         System.err.println("Generated Syntax source file: "+fileName);
136     }
137
138     private static void fwrite(String JavaDoc line, Writer f)
139         throws IOException
140     {
141         f.write(line, 0, line.length());
142     }
143
144
145
146     private SourceGenerator() {} // do not instantiate
147

148
149
150     /** Source generator main. Writes syntax to stderr when launched with no arguments or -h. */
151     public static void main(String JavaDoc [] args) {
152         if (args.length <= 0 || args[0].startsWith("-h")) {
153             System.err.println("SYNTAX: java "+SourceGenerator.class.getName()+" [semantic|LALR|SLR|LR] file.syntax [file.syntax ...]");
154             System.err.println(" LALR|SLR|LR: Generates ParserTable implementation(s) of passed grammar file(s).");
155             System.err.println(" else: Generates syntax implementation(s) of passed grammar file(s).");
156             System.err.println(" CAUTION: Files MUST have relative pathes!");
157             System.exit(1);
158         }
159         else {
160             String JavaDoc type = args[0].equals("SLR") || args[0].equals("LR") || args[0].equals("LALR") ? args[0] : null;
161             boolean semantic = args[0].equals("semantic");
162             int i = (type != null || semantic) ? 1 : 0;
163             
164             for (; i < args.length; i++) {
165                 File f = new File(args[i]);
166                 
167                 if (f.exists() == false || f.isFile() == false || f.canRead() == false) {
168                     System.err.println("ERROR: Can not open syntax specification: "+f);
169                 }
170                 else {
171                     if (f.getAbsolutePath().equals(f.getPath())) {
172                         throw new IllegalArgumentException JavaDoc("File MUST have relative path (to make package name): "+f);
173                     }
174                     
175                     String JavaDoc clsName = f.getName(); // make class name
176
int idx = clsName.indexOf("."); // cut extension
177
if (idx > 0)
178                         clsName = clsName.substring(0, idx);
179                     
180                     String JavaDoc pkgName = f.getParent(); // make package name
181
if (pkgName != null) {
182                         if (pkgName.endsWith(File.separator))
183                             pkgName = pkgName.substring(0, pkgName.length() - 1);
184                         pkgName = pkgName.replace(File.separatorChar, '.');
185                     }
186                     
187                     try {
188                         SyntaxBuilder builder = new SyntaxBuilder(new File(args[i]));
189                         if (semantic) {
190                             Syntax syntax = builder.getParserSyntax();
191                             generateSemanticSkeleton(syntax, clsName, pkgName);
192                         }
193                         else
194                         if (type != null) {
195                             Syntax syntax = builder.getParserSyntax();
196                             AbstractParserTables pt = type.equals("SLR")
197                                 ? new SLRParserTables(syntax)
198                                 : type.equals("LR")
199                                     ? new LRParserTables(syntax)
200                                     : new LALRParserTables(syntax);
201                             generateParserTable(pt, clsName, pkgName);
202                         }
203                         else {
204                             Syntax syntax = builder.getSyntax();
205                             generateSyntaxImpl(syntax, clsName, pkgName, builder.getInitialNonterminals());
206                         }
207                     }
208                     catch (Exception JavaDoc e) {
209                         e.printStackTrace();
210                     }
211                 }
212             }
213         }
214     }
215     
216 }
217
Popular Tags