KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > persistence > antlr > Tool


1 package persistence.antlr;
2
3 /* ANTLR Translator Generator
4  * Project led by Terence Parr at http://www.jGuru.com
5  * Software rights: http://www.antlr.org/license.html
6  *
7  */

8
9 import java.io.*;
10
11 import persistence.antlr.collections.impl.BitSet;
12 import persistence.antlr.collections.impl.Vector;
13 import persistence.antlr.PreservingFileWriter;
14 import persistence.antlr.Version;
15
16 public class Tool {
17     public static String JavaDoc version = "";
18
19     /** Object that handles analysis errors */
20     ToolErrorHandler errorHandler;
21
22     /** Was there an error during parsing or analysis? */
23     protected boolean hasError = false;
24
25     /** Generate diagnostics? (vs code) */
26     boolean genDiagnostics = false;
27
28     /** Generate DocBook vs code? */
29     boolean genDocBook = false;
30
31     /** Generate HTML vs code? */
32     boolean genHTML = false;
33
34     /** Current output directory for generated files */
35     protected static String JavaDoc outputDir = ".";
36
37     // Grammar input
38
protected String JavaDoc grammarFile;
39     transient Reader f = new InputStreamReader(System.in);
40     // SAS: changed for proper text io
41
// transient DataInputStream in = null;
42

43     protected static String JavaDoc literalsPrefix = "LITERAL_";
44     protected static boolean upperCaseMangledLiterals = false;
45
46     /** C++ file level options */
47     protected NameSpace nameSpace = null;
48     protected String JavaDoc namespaceAntlr = null;
49     protected String JavaDoc namespaceStd = null;
50     protected boolean genHashLines = true;
51     protected boolean noConstructors = false;
52
53     private BitSet cmdLineArgValid = new BitSet();
54
55     /** Construct a new Tool. */
56     public Tool() {
57         errorHandler = new DefaultToolErrorHandler(this);
58     }
59
60     public String JavaDoc getGrammarFile() {
61         return grammarFile;
62     }
63
64     public boolean hasError() {
65         return hasError;
66     }
67
68     public NameSpace getNameSpace() {
69         return nameSpace;
70     }
71
72     public String JavaDoc getNamespaceStd() {
73         return namespaceStd;
74     }
75
76     public String JavaDoc getNamespaceAntlr() {
77         return namespaceAntlr;
78     }
79
80     public boolean getGenHashLines() {
81         return genHashLines;
82     }
83
84     public String JavaDoc getLiteralsPrefix() {
85         return literalsPrefix;
86     }
87
88     public boolean getUpperCaseMangledLiterals() {
89         return upperCaseMangledLiterals;
90     }
91
92     public void setFileLineFormatter(FileLineFormatter formatter) {
93         FileLineFormatter.setFormatter(formatter);
94     }
95
96     protected void checkForInvalidArguments(String JavaDoc[] args, BitSet cmdLineArgValid) {
97         // check for invalid command line args
98
for (int a = 0; a < args.length; a++) {
99             if (!cmdLineArgValid.member(a)) {
100                 warning("invalid command-line argument: " + args[a] + "; ignored");
101             }
102         }
103     }
104
105     /** This example is from the book _Java in a Nutshell_ by David
106      * Flanagan. Written by David Flanagan. Copyright (c) 1996
107      * O'Reilly & Associates. You may study, use, modify, and
108      * distribute this example for any purpose. This example is
109      * provided WITHOUT WARRANTY either expressed or implied. */

110     public void copyFile(String JavaDoc source_name, String JavaDoc dest_name)
111         throws IOException {
112         File source_file = new File(source_name);
113         File destination_file = new File(dest_name);
114         Reader source = null;
115         Writer destination = null;
116         char[] buffer;
117         int bytes_read;
118
119         try {
120             // First make sure the specified source file
121
// exists, is a file, and is readable.
122
if (!source_file.exists() || !source_file.isFile())
123                 throw new FileCopyException("FileCopy: no such source file: " +
124                                             source_name);
125             if (!source_file.canRead())
126                 throw new FileCopyException("FileCopy: source file " +
127                                             "is unreadable: " + source_name);
128
129             // If the destination exists, make sure it is a writeable file
130
// and ask before overwriting it. If the destination doesn't
131
// exist, make sure the directory exists and is writeable.
132
if (destination_file.exists()) {
133                 if (destination_file.isFile()) {
134                     DataInputStream in = new DataInputStream(System.in);
135                     String JavaDoc response;
136
137                     if (!destination_file.canWrite())
138                         throw new FileCopyException("FileCopy: destination " +
139                                                     "file is unwriteable: " + dest_name);
140                     /*
141                       System.out.print("File " + dest_name +
142                       " already exists. Overwrite? (Y/N): ");
143                       System.out.flush();
144                       response = in.readLine();
145                       if (!response.equals("Y") && !response.equals("y"))
146                       throw new FileCopyException("FileCopy: copy cancelled.");
147                     */

148                 }
149                 else {
150                     throw new FileCopyException("FileCopy: destination "
151                                                 + "is not a file: " + dest_name);
152                 }
153             }
154             else {
155                 File parentdir = parent(destination_file);
156                 if (!parentdir.exists())
157                     throw new FileCopyException("FileCopy: destination "
158                                                 + "directory doesn't exist: " + dest_name);
159                 if (!parentdir.canWrite())
160                     throw new FileCopyException("FileCopy: destination "
161                                                 + "directory is unwriteable: " + dest_name);
162             }
163
164             // If we've gotten this far, then everything is okay; we can
165
// copy the file.
166
source = new BufferedReader(new FileReader(source_file));
167             destination = new BufferedWriter(new FileWriter(destination_file));
168
169             buffer = new char[1024];
170             while (true) {
171                 bytes_read = source.read(buffer, 0, 1024);
172                 if (bytes_read == -1) break;
173                 destination.write(buffer, 0, bytes_read);
174             }
175         }
176             // No matter what happens, always close any streams we've opened.
177
finally {
178             if (source != null) {
179                 try {
180                     source.close();
181                 }
182                 catch (IOException e) {
183                     ;
184                 }
185             }
186             if (destination != null) {
187                 try {
188                     destination.close();
189                 }
190                 catch (IOException e) {
191                     ;
192                 }
193             }
194         }
195     }
196
197     /** Perform processing on the grammar file. Can only be called
198      * from main() @param args The command-line arguments passed to
199      * main(). This wrapper does the System.exit for use with command-line.
200      */

201     public void doEverythingWrapper(String JavaDoc[] args) {
202         int exitCode = doEverything(args);
203         System.exit(exitCode);
204     }
205
206     /** Process args and have ANTLR do it's stuff without calling System.exit.
207      * Just return the result code. Makes it easy for ANT build tool.
208      */

209     public int doEverything(String JavaDoc[] args) {
210         // run the preprocessor to handle inheritance first.
211

212         // Start preprocessor. This strips generates an argument list
213
// without -glib options (inside preTool)
214
persistence.antlr.preprocessor.Tool preTool = new persistence.antlr.preprocessor.Tool(this, args);
215
216         boolean preprocess_ok = preTool.preprocess();
217         String JavaDoc[] modifiedArgs = preTool.preprocessedArgList();
218
219         // process arguments for the Tool
220
processArguments(modifiedArgs);
221         if (!preprocess_ok) {
222             return 1;
223         }
224
225         f = getGrammarReader();
226
227         ANTLRLexer lexer = new ANTLRLexer(f);
228         TokenBuffer tokenBuf = new TokenBuffer(lexer);
229         LLkAnalyzer analyzer = new LLkAnalyzer(this);
230         MakeGrammar behavior = new MakeGrammar(this, args, analyzer);
231
232         try {
233             ANTLRParser p = new ANTLRParser(tokenBuf, behavior, this);
234             p.setFilename(grammarFile);
235             p.grammar();
236             if (hasError()) {
237                 fatalError("Exiting due to errors.");
238             }
239             checkForInvalidArguments(modifiedArgs, cmdLineArgValid);
240
241             // Create the right code generator according to the "language" option
242
CodeGenerator codeGen;
243
244             // SAS: created getLanguage() method so subclass can override
245
// (necessary for VAJ interface)
246
String JavaDoc codeGenClassName = "persistence.antlr." + getLanguage(behavior) + "CodeGenerator";
247             try {
248                 Class JavaDoc codeGenClass = Class.forName(codeGenClassName);
249                 codeGen = (CodeGenerator)codeGenClass.newInstance();
250                 codeGen.setBehavior(behavior);
251                 codeGen.setAnalyzer(analyzer);
252                 codeGen.setTool(this);
253                 codeGen.gen();
254             }
255             catch (ClassNotFoundException JavaDoc cnfe) {
256                 panic("Cannot instantiate code-generator: " + codeGenClassName);
257             }
258             catch (InstantiationException JavaDoc ie) {
259                 panic("Cannot instantiate code-generator: " + codeGenClassName);
260             }
261             catch (IllegalArgumentException JavaDoc ie) {
262                 panic("Cannot instantiate code-generator: " + codeGenClassName);
263             }
264             catch (IllegalAccessException JavaDoc iae) {
265                 panic("code-generator class '" + codeGenClassName + "' is not accessible");
266             }
267         }
268         catch (RecognitionException pe) {
269             fatalError("Unhandled parser error: " + pe.getMessage());
270         }
271         catch (TokenStreamException io) {
272             fatalError("TokenStreamException: " + io.getMessage());
273         }
274         return 0;
275     }
276
277     /** Issue an error
278      * @param s The message
279      */

280     public void error(String JavaDoc s) {
281         hasError = true;
282         System.err.println("error: " + s);
283     }
284
285     /** Issue an error with line number information
286      * @param s The message
287      * @param file The file that has the error (or null)
288      * @param line The grammar file line number on which the error occured (or -1)
289      * @param column The grammar file column number on which the error occured (or -1)
290      */

291     public void error(String JavaDoc s, String JavaDoc file, int line, int column) {
292         hasError = true;
293         System.err.println(FileLineFormatter.getFormatter().
294                            getFormatString(file, line, column) + s);
295     }
296
297     /** When we are 1.1 compatible...
298 public static Object factory2 (String p, Object[] initargs) {
299      Class c;
300      Object o = null;
301      try {
302      int argslen = initargs.length;
303      Class cl[] = new Class[argslen];
304      for (int i=0;i&lt;argslen;i++) {
305      cl[i] = Class.forName(initargs[i].getClass().getName());
306      }
307      c = Class.forName (p);
308      Constructor con = c.getConstructor (cl);
309      o = con.newInstance (initargs);
310      } catch (Exception e) {
311      System.err.println ("Can't make a " + p);
312      }
313      return o;
314      }
315      */

316     public Object JavaDoc factory(String JavaDoc p) {
317         Class JavaDoc c;
318         Object JavaDoc o = null;
319         try {
320             c = Class.forName(p);// get class def
321
o = c.newInstance(); // make a new one
322
}
323         catch (Exception JavaDoc e) {
324             // either class not found,
325
// class is interface/abstract, or
326
// class or initializer is not accessible.
327
warning("Can't create an object of type " + p);
328             return null;
329         }
330         return o;
331     }
332
333     public String JavaDoc fileMinusPath(String JavaDoc f) {
334         String JavaDoc separator = System.getProperty("file.separator");
335         int endOfPath = f.lastIndexOf(separator);
336         if (endOfPath == -1) {
337             return f; // no path found
338
}
339         return f.substring(endOfPath + 1);
340     }
341
342     /** Determine the language used for this run of ANTLR
343      * This was made a method so the subclass can override it
344      */

345     public String JavaDoc getLanguage(MakeGrammar behavior) {
346         if (genDiagnostics) {
347             return "Diagnostic";
348         }
349         if (genHTML) {
350             return "HTML";
351         }
352         if (genDocBook) {
353             return "DocBook";
354         }
355         return behavior.language;
356     }
357
358     public String JavaDoc getOutputDirectory() {
359         return outputDir;
360     }
361
362     private static void help() {
363         System.err.println("usage: java persistence.antlr.Tool [args] file.g");
364         System.err.println(" -o outputDir specify output directory where all output generated.");
365         System.err.println(" -glib superGrammar specify location of supergrammar file.");
366         System.err.println(" -debug launch the ParseView debugger upon parser invocation.");
367         System.err.println(" -html generate a html file from your grammar.");
368         System.err.println(" -docbook generate a docbook sgml file from your grammar.");
369         System.err.println(" -diagnostic generate a textfile with diagnostics.");
370         System.err.println(" -trace have all rules call traceIn/traceOut.");
371         System.err.println(" -traceLexer have lexer rules call traceIn/traceOut.");
372         System.err.println(" -traceParser have parser rules call traceIn/traceOut.");
373         System.err.println(" -traceTreeParser have tree parser rules call traceIn/traceOut.");
374         System.err.println(" -h|-help|--help this message");
375     }
376
377     public static void main(String JavaDoc[] args) {
378         System.err.println("ANTLR Parser Generator Version " +
379                            Version.project_version + " 1989-2004 jGuru.com");
380         version = Version.project_version;
381
382         try {
383             if (args.length == 0) {
384                 help();
385                 System.exit(1);
386             }
387             for (int i = 0; i < args.length; ++i) {
388                 if (args[i].equals("-h")
389                     || args[i].equals("-help")
390                     || args[i].equals("--help")
391                 ) {
392                     help();
393                     System.exit(1);
394                 }
395             }
396
397             Tool theTool = new Tool();
398             theTool.doEverything(args);
399             theTool = null;
400         }
401         catch (Exception JavaDoc e) {
402             System.err.println(System.getProperty("line.separator") +
403                                System.getProperty("line.separator"));
404             System.err.println("#$%%*&@# internal error: " + e.toString());
405             System.err.println("[complain to nearest government official");
406             System.err.println(" or send hate-mail to parrt@jguru.com;");
407             System.err.println(" please send stack trace with report.]" +
408                                System.getProperty("line.separator"));
409             e.printStackTrace();
410         }
411 System.exit(0);
412     }
413
414     /** This method is used by all code generators to create new output
415      * files. If the outputDir set by -o is not present it will be created here.
416      */

417     public PrintWriter openOutputFile(String JavaDoc f) throws IOException {
418         if( outputDir != "." ) {
419             File out_dir = new File(outputDir);
420             if( ! out_dir.exists() )
421                 out_dir.mkdirs();
422         }
423         return new PrintWriter(new PreservingFileWriter(outputDir + System.getProperty("file.separator") + f));
424     }
425
426     public Reader getGrammarReader() {
427         Reader f = null;
428         try {
429             if (grammarFile != null) {
430                 f = new BufferedReader(new FileReader(grammarFile));
431             }
432         }
433         catch (IOException e) {
434             fatalError("cannot open grammar file " + grammarFile);
435         }
436         return f;
437     }
438
439     /** @since 2.7.2
440      */

441     public void reportException(Exception JavaDoc e, String JavaDoc message) {
442         System.err.println(message == null ? e.getMessage()
443                                            : message + ": " + e.getMessage());
444     }
445
446     /** @since 2.7.2
447      */

448     public void reportProgress(String JavaDoc message) {
449         System.out.println(message);
450     }
451
452     /** An error occured that should stop the Tool from doing any work.
453      * The default implementation currently exits (via
454      * {@link java.lang.System.exit(int)} after printing an error message to
455      * <var>stderr</var>. However, the tools should expect that a subclass
456      * will override this to throw an unchecked exception such as
457      * {@link java.lang.IllegalStateException} or another subclass of
458      * {@link java.lang.RuntimeException}. <em>If this method is overriden,
459      * <strong>it must never return normally</strong>; i.e. it must always
460      * throw an exception or call System.exit</em>.
461      * @since 2.7.2
462      * @param s The message
463      */

464     public void fatalError(String JavaDoc message) {
465         System.err.println(message);
466         System.exit(1);
467     }
468
469     /** Issue an unknown fatal error. <em>If this method is overriden,
470      * <strong>it must never return normally</strong>; i.e. it must always
471      * throw an exception or call System.exit</em>.
472      * @deprecated as of 2.7.2 use {@link #fatalError(String)}. By default
473      * this method executes <code>fatalError("panic");</code>.
474      */

475     public void panic() {
476         fatalError("panic");
477     }
478
479     /** Issue a fatal error message. <em>If this method is overriden,
480      * <strong>it must never return normally</strong>; i.e. it must always
481      * throw an exception or call System.exit</em>.
482      * @deprecated as of 2.7.2 use {@link #fatalError(String)}. By defaykt
483      * this method executes <code>fatalError("panic: " + s);</code>.
484      * @param s The message
485      */

486     public void panic(String JavaDoc s) {
487         fatalError("panic: " + s);
488     }
489
490     // File.getParent() can return null when the file is specified without
491
// a directory or is in the root directory.
492
// This method handles those cases.
493
public File parent(File f) {
494         String JavaDoc dirname = f.getParent();
495         if (dirname == null) {
496             if (f.isAbsolute())
497                 return new File(File.separator);
498             else
499                 return new File(System.getProperty("user.dir"));
500         }
501         return new File(dirname);
502     }
503
504     /** Parse a list such as "f1.g;f2.g;..." and return a Vector
505      * of the elements.
506      */

507     public static Vector parseSeparatedList(String JavaDoc list, char separator) {
508         java.util.StringTokenizer JavaDoc st =
509         new java.util.StringTokenizer JavaDoc(list, String.valueOf(separator));
510         Vector v = new Vector(10);
511         while ( st.hasMoreTokens() ) {
512              v.appendElement(st.nextToken());
513         }
514         if (v.size() == 0) return null;
515         return v;
516     }
517
518     /** given a filename, strip off the directory prefix (if any)
519      * and return it. Return "./" if f has no dir prefix.
520      */

521     public String JavaDoc pathToFile(String JavaDoc f) {
522         String JavaDoc separator = System.getProperty("file.separator");
523         int endOfPath = f.lastIndexOf(separator);
524         if (endOfPath == -1) {
525             // no path, use current directory
526
return "." + System.getProperty("file.separator");
527         }
528         return f.substring(0, endOfPath + 1);
529     }
530
531     /** <p>Process the command-line arguments. Can only be called by Tool.
532      * A bitset is collected of all correct arguments via setArgOk.</p>
533      * @param args The command-line arguments passed to main()
534      *
535      */

536     protected void processArguments(String JavaDoc[] args) {
537         for (int i = 0; i < args.length; i++) {
538             if (args[i].equals("-diagnostic")) {
539                 genDiagnostics = true;
540                 genHTML = false;
541                 setArgOK(i);
542             }
543             else if (args[i].equals("-o")) {
544                 setArgOK(i);
545                 if (i + 1 >= args.length) {
546                     error("missing output directory with -o option; ignoring");
547                 }
548                 else {
549                     i++;
550                     setOutputDirectory(args[i]);
551                     setArgOK(i);
552                 }
553             }
554             else if (args[i].equals("-html")) {
555                 genHTML = true;
556                 genDiagnostics = false;
557                 setArgOK(i);
558             }
559             else if (args[i].equals("-docbook")) {
560                 genDocBook = true;
561                 genDiagnostics = false;
562                 setArgOK(i);
563             }
564             else {
565                 if (args[i].charAt(0) != '-') {
566                     // Must be the grammar file
567
grammarFile = args[i];
568                     setArgOK(i);
569                 }
570             }
571         }
572     }
573
574     public void setArgOK(int i) {
575         cmdLineArgValid.add(i);
576     }
577
578     public void setOutputDirectory(String JavaDoc o) {
579         outputDir = o;
580     }
581
582     /** Issue an error; used for general tool errors not for grammar stuff
583      * @param s The message
584      */

585     public void toolError(String JavaDoc s) {
586         System.err.println("error: " + s);
587     }
588
589     /** Issue a warning
590      * @param s the message
591      */

592     public void warning(String JavaDoc s) {
593         System.err.println("warning: " + s);
594     }
595
596     /** Issue a warning with line number information
597      * @param s The message
598      * @param file The file that has the warning (or null)
599      * @param line The grammar file line number on which the warning occured (or -1)
600      * @param column The grammar file line number on which the warning occured (or -1)
601      */

602     public void warning(String JavaDoc s, String JavaDoc file, int line, int column) {
603         System.err.println(FileLineFormatter.getFormatter().
604                            getFormatString(file, line, column) + "warning:" + s);
605     }
606
607     /** Issue a warning with line number information
608      * @param s The lines of the message
609      * @param file The file that has the warning
610      * @param line The grammar file line number on which the warning occured
611      */

612     public void warning(String JavaDoc[] s, String JavaDoc file, int line, int column) {
613         if (s == null || s.length == 0) {
614             panic("bad multi-line message to Tool.warning");
615         }
616         System.err.println(FileLineFormatter.getFormatter().
617                            getFormatString(file, line, column) + "warning:" + s[0]);
618         for (int i = 1; i < s.length; i++) {
619             System.err.println(FileLineFormatter.getFormatter().
620                                getFormatString(file, line, column) + " " + s[i]);
621         }
622     }
623
624     /**
625      * Support C++ & C# namespaces (for now).
626      * C++: Add a nested namespace name to the current namespace.
627      * C# : Specify an enclosing namespace for the generated code.
628      * DAW: David Wagner -- C# support by kunle odutola
629      */

630     public void setNameSpace(String JavaDoc name) {
631         if (null == nameSpace)
632             nameSpace = new NameSpace(StringUtils.stripFrontBack(name, "\"", "\""));
633     }
634 }
635
Popular Tags