KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > antlr > Tool


1 package antlr;
2
3 /* ANTLR Translator Generator
4  * Project led by Terence Parr at http://www.jGuru.com
5  * Software rights: http://www.antlr.org/RIGHTS.html
6  *
7  * $Id: //depot/code/org.antlr/main/main/antlr/Tool.java#23 $
8  */

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

44     protected static String JavaDoc literalsPrefix = "LITERAL_";
45     protected static boolean upperCaseMangledLiterals = false;
46
47     /** C++ file level options */
48     protected NameSpace nameSpace = null;
49     protected String JavaDoc namespaceAntlr = null;
50     protected String JavaDoc namespaceStd = null;
51     protected boolean genHashLines = true;
52
53     private BitSet cmdLineArgValid = new BitSet();
54
55     /** Construct a new Tool. */
56     public Tool() {
57         errorHandler = new DefaultToolErrorHandler();
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
antlr.preprocessor.Tool preTool = new 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                 System.err.println("Exiting due to errors.");
238                 return 1;
239             }
240             checkForInvalidArguments(modifiedArgs, cmdLineArgValid);
241
242             // Create the right code generator according to the "language" option
243
CodeGenerator codeGen;
244
245             // SAS: created getLanguage() method so subclass can override
246
// (necessary for VAJ interface)
247
String JavaDoc codeGenClassName = "antlr." + getLanguage(behavior) + "CodeGenerator";
248             try {
249                 Class JavaDoc codeGenClass = Class.forName(codeGenClassName);
250                 codeGen = (CodeGenerator)codeGenClass.newInstance();
251                 codeGen.setBehavior(behavior);
252                 codeGen.setAnalyzer(analyzer);
253                 codeGen.setTool(this);
254                 codeGen.gen();
255             }
256             catch (ClassNotFoundException JavaDoc cnfe) {
257                 panic("Cannot instantiate code-generator: " + codeGenClassName);
258             }
259             catch (InstantiationException JavaDoc ie) {
260                 panic("Cannot instantiate code-generator: " + codeGenClassName);
261             }
262             catch (IllegalArgumentException JavaDoc ie) {
263                 panic("Cannot instantiate code-generator: " + codeGenClassName);
264             }
265             catch (IllegalAccessException JavaDoc iae) {
266                 panic("code-generator class '" + codeGenClassName + "' is not accessible");
267             }
268         }
269         catch (RecognitionException pe) {
270             System.err.println("Unhandled parser error: " + pe.getMessage());
271             return 1;
272         }
273         catch (TokenStreamException io) {
274             System.err.println("TokenStreamException: " + io.getMessage());
275             return 1;
276         }
277         return 0;
278     }
279
280     /** Issue an error
281      * @param s The message
282      */

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

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

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

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

409     public PrintWriter openOutputFile(String JavaDoc f) throws IOException {
410         return new PrintWriter(new PreservingFileWriter(outputDir + System.getProperty("file.separator") + f));
411     }
412
413     public Reader getGrammarReader() {
414         try {
415             if (grammarFile != null) {
416                 f = new BufferedReader(new FileReader(grammarFile));
417             }
418         }
419         catch (IOException e) {
420             panic("Error: cannot open grammar file " + grammarFile);
421             help();
422             System.exit(1);
423         }
424         return f;
425     }
426
427     /** Issue an unknown fatal error */
428     public void panic() {
429         System.err.println("panic");
430         System.exit(1);
431     }
432
433     /** Issue a fatal error message
434      * @param s The message
435      */

436     public void panic(String JavaDoc s) {
437         System.err.println("panic: " + s);
438         System.exit(1);
439     }
440
441     // File.getParent() can return null when the file is specified without
442
// a directory or is in the root directory.
443
// This method handles those cases.
444
public File parent(File f) {
445         String JavaDoc dirname = f.getParent();
446         if (dirname == null) {
447             if (f.isAbsolute())
448                 return new File(File.separator);
449             else
450                 return new File(System.getProperty("user.dir"));
451         }
452         return new File(dirname);
453     }
454
455     /** Parse a list such as "f1.g;f2.g;..." and return a Vector
456      * of the elements.
457      */

458     public static Vector parseSeparatedList(String JavaDoc list, char separator) {
459         Vector v = new Vector(10);
460         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(100);
461         int i = 0;
462         while (i < list.length()) {
463             while (i < list.length() && list.charAt(i) != separator) {
464                 buf.append(list.charAt(i));
465                 i++;
466             }
467             // add element to vector
468
v.appendElement(buf.toString());
469             buf.setLength(0);
470             // must be a separator or finished.
471
if (i < list.length()) {
472                 // not done?
473
i++; // skip separator
474
}
475         }
476         if (v.size() == 0) return null;
477         return v;
478     }
479
480     /** given a filename, strip off the directory prefix (if any)
481      * and return it. Return "./" if f has no dir prefix.
482      */

483     public String JavaDoc pathToFile(String JavaDoc f) {
484         String JavaDoc separator = System.getProperty("file.separator");
485         int endOfPath = f.lastIndexOf(separator);
486         if (endOfPath == -1) {
487             // no path, use current directory
488
return "." + System.getProperty("file.separator");
489         }
490         return f.substring(0, endOfPath + 1);
491     }
492
493     /** Process the command-line arguments. Can only be called by Tool.
494      * A bitset is collected of all correct arguments via setArgOk.
495      * @param args The command-line arguments passed to main()
496      */

497     protected void processArguments(String JavaDoc[] args) {
498         for (int i = 0; i < args.length; i++) {
499             if (args[i].equals("-diagnostic")) {
500                 genDiagnostics = true;
501                 genHTML = false;
502                 setArgOK(i);
503             }
504             else if (args[i].equals("-o")) {
505                 setArgOK(i);
506                 if (i + 1 >= args.length) {
507                     error("missing output directory with -o option; ignoring");
508                 }
509                 else {
510                     i++;
511                     setOutputDirectory(args[i]);
512                     setArgOK(i);
513                 }
514             }
515             else if (args[i].equals("-html")) {
516                 genHTML = true;
517                 genDiagnostics = false;
518                 setArgOK(i);
519             }
520             else if (args[i].equals("-docbook")) {
521                 genDocBook = true;
522                 genDiagnostics = false;
523                 setArgOK(i);
524             }
525             else if (args[i].equals("-h")
526                 || args[i].equals("-help")
527                 || args[i].equals("--help")
528             ) {
529                 help();
530                 System.exit(0);
531             }
532             else {
533                 if (args[i].charAt(0) != '-') {
534                     // Must be the grammar file
535
grammarFile = args[i];
536                     setArgOK(i);
537                 }
538             }
539         }
540     }
541
542     public void setArgOK(int i) {
543         cmdLineArgValid.add(i);
544     }
545
546     public void setOutputDirectory(String JavaDoc o) {
547         outputDir = o;
548     }
549
550     /** Issue an error; used for general tool errors not for grammar stuff
551      * @param s The message
552      */

553     public void toolError(String JavaDoc s) {
554         System.err.println("error: " + s);
555     }
556
557     /** Issue a warning
558      * @param s the message
559      */

560     public void warning(String JavaDoc s) {
561         System.err.println("warning: " + s);
562     }
563
564     /** Issue a warning with line number information
565      * @param s The message
566      * @param file The file that has the warning (or null)
567      * @param line The grammar file line number on which the warning occured (or -1)
568      * @param column The grammar file line number on which the warning occured (or -1)
569      */

570     public void warning(String JavaDoc s, String JavaDoc file, int line, int column) {
571         System.err.println(FileLineFormatter.getFormatter().
572                            getFormatString(file, line, column) + "warning:" + s);
573     }
574
575     /** Issue a warning with line number information
576      * @param s The lines of the message
577      * @param file The file that has the warning
578      * @param line The grammar file line number on which the warning occured
579      */

580     public void warning(String JavaDoc[] s, String JavaDoc file, int line, int column) {
581         if (s == null || s.length == 0) {
582             panic("bad multi-line message to Tool.warning");
583         }
584         System.err.println(FileLineFormatter.getFormatter().
585                            getFormatString(file, line, column) + "warning:" + s[0]);
586         for (int i = 1; i < s.length; i++) {
587             System.err.println(FileLineFormatter.getFormatter().
588                                getFormatString(file, line, column) + s[i]);
589         }
590     }
591
592     /**
593      * Support C++ namespaces (for now). Add a nested namespace name to the
594      * current namespace.
595      * DAW: David Wagner
596      */

597     public void setNameSpace(String JavaDoc name) {
598         if (null == nameSpace)
599             nameSpace = new NameSpace(StringUtils.stripFrontBack(name, "\"", "\""));
600     }
601 }
602
Popular Tags