1 package antlr;
2
3 * <b>SOFTWARE RIGHTS</b>
5 * <p>
6 * ANTLR 2.5.0 MageLang Institute, 1998
7 * <p>
8 * We reserve no legal rights to the ANTLR--it is fully in the
9 * public domain. An individual or company may do whatever
10 * they wish with source code distributed with ANTLR or the
11 * code generated by ANTLR, including the incorporation of
12 * ANTLR, or its output, into commerical software.
13 * <p>
14 * We encourage users to develop software with ANTLR. However,
15 * we do ask that credit is given to us for developing
16 * ANTLR. By "credit", we mean that if you use ANTLR or
17 * incorporate any source code into one of your programs
18 * (commercial product, research project, or otherwise) that
19 * you acknowledge this fact somewhere in the documentation,
20 * research report, etc... If you like ANTLR and have
21 * developed a nice tool with the output, please mention that
22 * you developed it using ANTLR. In addition, we ask that the
23 * headers remain intact in our source code. As long as these
24 * guidelines are kept, we expect to continue enhancing this
25 * system and expect to make other tools available as they are
26 * completed.
27 * <p>
28 * The ANTLR gang:
29 * @version ANTLR 2.5.0 MageLang Institute, 1998
30 * @author Terence Parr, <a href=http://www.MageLang.com>MageLang Institute</a>
31 * @author <br>John Lilley, <a href=http://www.Empathy.com>Empathy Software</a>
32 */
33
34 import java.io.*;
35 import antlr.collections.impl.BitSet;
36 import antlr.collections.impl.Vector;
37 public class Tool {
38 ToolErrorHandler errorHandler;
40
41 protected boolean hasError = false;
43
44 boolean genDiagnostics = false;
46
47
48 boolean genHTML = false;
49
50
51 protected static String outputDir = ".";
52
53 String grammarFile;
55 transient Reader f = new InputStreamReader(System.in);
56
59 protected static String literalsPrefix = "LITERAL_";
60 protected static boolean upperCaseMangledLiterals = false;
61
62 private static BitSet cmdLineArgValid = new BitSet();
63
64
65
66 public Tool() {
67 errorHandler = new DefaultToolErrorHandler();
69 }
70 private static void checkForInvalidArguments(String[] args, BitSet cmdLineArgValid) {
71 for (int a = 0; a < args.length; a++) {
73 if (!cmdLineArgValid.member(a)) {
74 warning("invalid command-line argument: " + args[a] + "; ignored");
75 }
76 }
77 }
78
83 public static void copyFile(String source_name, String dest_name)
84 throws IOException
85 {
86 File source_file = new File(source_name);
87 File destination_file = new File(dest_name);
88 FileReader source = null; FileWriter destination = null;
90 char[] buffer;
91 int bytes_read;
92
93 try {
94 if (!source_file.exists() || !source_file.isFile())
97 throw new FileCopyException("FileCopy: no such source file: " +
98 source_name);
99 if (!source_file.canRead())
100 throw new FileCopyException("FileCopy: source file " +
101 "is unreadable: " + source_name);
102
103 if (destination_file.exists()) {
107 if (destination_file.isFile()) {
108 DataInputStream in = new DataInputStream(System.in);
109 String response;
110
111 if (!destination_file.canWrite())
112 throw new FileCopyException("FileCopy: destination " +
113 "file is unwriteable: " + dest_name);
114 System.out.print("File " + dest_name +
116 " already exists. Overwrite? (Y/N): ");
117 System.out.flush();
118 response = in.readLine();
119 if (!response.equals("Y") && !response.equals("y"))
120 throw new FileCopyException("FileCopy: copy cancelled.");
121 */
122 }
123 else{
124 throw new FileCopyException("FileCopy: destination "
125 + "is not a file: " + dest_name);
126 }
127 }
128 else {
129 File parentdir = parent(destination_file);
130 if (!parentdir.exists())
131 throw new FileCopyException("FileCopy: destination "
132 + "directory doesn't exist: " + dest_name);
133 if (!parentdir.canWrite())
134 throw new FileCopyException("FileCopy: destination "
135 + "directory is unwriteable: " + dest_name);
136 }
137
138 source = new FileReader(source_file);
141 destination = new FileWriter(destination_file);
142 buffer = new char[1024];
143 while(true) {
144 bytes_read = source.read(buffer,0,1024);
145 if (bytes_read == -1) break;
146 destination.write(buffer, 0, bytes_read);
147 }
148 }
149 finally {
151 if (source != null)
152 try { source.close(); } catch (IOException e) { ; }
153 if (destination != null)
154 try { destination.close(); } catch (IOException e) { ; }
155 }
156 }
157 * @param args The command-line arguments passed to main()
159 */
160 void doEverything(String[] args) {
161 Toolr.preprocessor.Tool preTool = new antlr.preprocessor.Tool(this, args);
165 if ( !preTool.preprocess() ) {
166 System.exit(1);
167 }
168 String[] modifiedArgs = preTool.preprocessedArgList();
169
170 processArguments(modifiedArgs);
172
173 try {
174 if (grammarFile != null) {
175 f = new FileReader(grammarFile);
176 }
177 }
178 catch (IOException e) {
179 System.err.println("Error: cannot open grammar file " + grammarFile);
180 help();
181 System.exit(1);
182 }
183
184 TokenBuffer tokenBuf = new TokenBuffer(new ANTLRLexer(f));
185 LLkAnalyzer analyzer = new LLkAnalyzer(this);
186 MakeGrammar behavior = new MakeGrammar(this, args, analyzer);
187
188 try {
189 ANTLRParser p = new ANTLRParser(tokenBuf, behavior, this);
190 p.grammar();
191 if (hasError) {
192 System.out.println("Exiting due to errors.");
193 System.exit(1);
194 }
195 checkForInvalidArguments(modifiedArgs, cmdLineArgValid);
196
197 CodeGenerator codeGen;
199
200 String codeGenClassName = "antlr." + getLanguage(behavior) + "CodeGenerator";
203 try {
204 Class codeGenClass = Class.forName(codeGenClassName);
205 codeGen = (CodeGenerator)codeGenClass.newInstance();
206 codeGen.setBehavior(behavior);
207 codeGen.setAnalyzer(analyzer);
208 codeGen.setTool(this);
209 codeGen.gen();
210 }
211 catch (ClassNotFoundException cnfe) {
212 panic("Cannot instantiate code-generator: " + codeGenClassName);
213 }
214 catch (InstantiationException ie) {
215 panic("Cannot instantiate code-generator: " + codeGenClassName);
216 }
217 catch (IllegalArgumentException ie) {
218 panic("Cannot instantiate code-generator: " + codeGenClassName);
219 }
220 catch (IllegalAccessException iae) {
221 panic("code-generator class '" + codeGenClassName + "' is not accessible");
222 }
223 }
224 catch (MismatchedTokenException mt) {
225 System.err.println("Unhandled parser error: " + mt.getMessage());
226 }
227 catch (NoViableAltException nva) {
228 System.err.println("Unhandled parser error: " + nva.getMessage());
229 }
230 catch (ParserException pe) {
231 System.err.println("Unhandled parser error: " + pe.getMessage());
232 }
233 catch (IOException io) {
234 System.err.println("IOException: " + io.getMessage());
235 }
236 }
237 * @param s The message
239 */
240 public void error(String s) {
241 hasError = true;
242 System.out.println("error: "+s);
243 }
244 * @param s The message
246 * @param line The grammar file line number on which the error occured
247 */
248 public void error(String s, int line) {
249 hasError = true;
250 System.out.println("error: line "+line+": "+s);
251 }
252 public static Object factory2 (String p, Object[] initargs) {
254 Class c;
255 Object o = null;
256 try {
257 int argslen = initargs.length;
258 Class cl[] = new Class[argslen];
259 for (int i=0;i<argslen;i++) {
260 cl[i] = Class.forName(initargs[i].getClass().getName());
261 }
262 c = Class.forName (p);
263 Constructor con = c.getConstructor (cl);
264 o = con.newInstance (initargs);
265 } catch (Exception e) {
266 System.err.println ("Can't make a " + p);
267 }
268 return o;
269 }
270 */
271 public static Object factory(String p) {
272 Class c;
273 Object o=null;
274 try {
275 c = Class.forName(p); o = c.newInstance(); }
278 catch (Exception e) {
279 warning("Can't create an object of type " + p);
283 return null;
284 }
285 return o;
286 }
287 public static String fileMinusPath(String f) {
288 String separator = System.getProperty("file.separator");
289 int endOfPath = f.lastIndexOf(separator);
290 if ( endOfPath == -1 ) {
291 return f; }
293 return f.substring(endOfPath+1);
294 }
295 * This was made a method so the subclass can override it
297 */
298 public String getLanguage(MakeGrammar behavior) {
299 if (genDiagnostics) {
300 return "Diagnostic";
301 }
302 if (genHTML) {
303 return "HTML";
304 }
305 return behavior.language;
306 }
307 public static String getOutputDirectory() { return outputDir; }
308 private static void help() {
309 System.err.println("usage: java antlr.Tool [args] file.g");
310 System.err.println(" -o outputDir specify output directory where all output generated.");
311 System.err.println(" -debug launch the ParseView debugger upon parser invocation.");
312 System.err.println(" -html generate an html file from your grammar (minus actions).");
313 System.err.println(" -trace have all rules call traceIn/traceOut.");
314 System.err.println(" -traceParser have parser rules call traceIn/traceOut.");
315 System.err.println(" -traceLexer have lexer rules call traceIn/traceOut.");
316 System.err.println(" -traceTreeWalker have tree walker rules call traceIn/traceOut.");
317 }
318 public static void main(String[] args) {
319 System.err.println("ANTLR Parser Generator Version "+
320 ANTLRParser.version+" 1989-1998 MageLang Institute");
321 try {
322 if ( args.length==0 ) {
323 help();
324 }
325 Tool theTool = new Tool();
326 theTool.doEverything(args);
327 theTool = null;
328 }
329 catch (Exception e) {
330 System.err.println(System.getProperty("line.separator")+
331 System.getProperty("line.separator"));
332 System.err.println("#$%%*&@# internal error: "+e.toString());
333 System.err.println("[complain to nearest government official");
334 System.err.println(" or send hate-mail to parrt@parr-research.com;");
335 System.err.println(" please send stack trace with report.]"+
336 System.getProperty("line.separator"));
337 e.printStackTrace();
338 }
339 System.exit(0);
340 }
341 public static PrintWriter openOutputFile(String f) throws IOException {
342 return new PrintWriter(new FileWriter(outputDir+System.getProperty("file.separator")+f));
343 }
344
345 public static void panic() {
346 System.err.println("panic");
347 System.exit(1);
348 }
349 * @param s The message
351 */
352 public static void panic(String s) {
353 System.err.println("panic: "+s);
354 System.exit(1);
355 }
356 public static File parent(File f) {
360 String dirname = f.getParent();
361 if (dirname == null) {
362 if (f.isAbsolute()) return new File(File.separator);
363 else return new File(System.getProperty("user.dir"));
364 }
365 return new File(dirname);
366 }
367 * of the elements.
369 */
370 public static Vector parseSeparatedList(String list, char separator) {
371 Vector v = new Vector(10);
372 StringBuffer buf = new StringBuffer(100);
373 int i=0;
374 while ( i<list.length() ) {
375 while ( i<list.length() && list.charAt(i)!=separator ) {
376 buf.append(list.charAt(i));
377 i++;
378 }
379 v.appendElement(buf.toString());
381 buf.setLength(0);
382 if ( i<list.length() ) { i++; }
386 }
387 if ( v.size()==0 ) return null;
388 return v;
389 }
390 * and return it. Return "./" if f has no dir prefix.
392 */
393 public static String pathToFile(String f) {
394 String separator = System.getProperty("file.separator");
395 int endOfPath = f.lastIndexOf(separator);
396 if ( endOfPath == -1 ) {
397 return "."+System.getProperty("file.separator");
399 }
400 return f.substring(0, endOfPath+1);
401 }
402 * @param args The command-line arguments passed to main()
404 */
405 private void processArguments(String[] args) {
406 for (int i = 0; i < args.length; i++) {
407 if (args[i].equals("-diagnostic")) {
408 genDiagnostics = true;
409 genHTML = false;
410 Tool.setArgOK(i);
411 } else {
412 if (args[i].equals("-o")) {
413 Tool.setArgOK(i);
414 if (i + 1 >= args.length) {
415 error("missing output directory with -o option; ignoring");
416 } else {
417 i++;
418 setOutputDirectory(args[i]);
419 Tool.setArgOK(i);
420 }
421 } else
422 if (args[i].equals("-html")) {
423 genHTML = true;
424 genDiagnostics = false;
425 Tool.setArgOK(i);
426 } else {
427 if (args[i].charAt(0) != '-') {
428 grammarFile = args[i];
430 Tool.setArgOK(i);
431 }
432 }
433 }
434 }
435 }
436 public static void setArgOK(int i) {
437 cmdLineArgValid.add(i);
438 }
439 public static void setOutputDirectory(String o) { outputDir = o; }
440 * characters from back of string
442 * @param s The string to process
443 * @param c The character to remove
444 * @return The resulting string
445 */
446 static public String stripBack(String s, char c) {
447 while (s.length() > 0 && s.charAt(s.length()-1) == c)
448 {
449 s = s.substring(0, s.length()-1);
450 }
451 return s;
452 }
453 * characters from back of string
455 * @param s The string to process
456 * @param remove A string containing the set of characters to remove
457 * @return The resulting string
458 */
459 static public String stripBack(String s, String remove) {
460 boolean changed;
461 do {
462 changed = false;
463 for (int i = 0; i < remove.length(); i++) {
464 char c = remove.charAt(i);
465 while (s.length() > 0 && s.charAt(s.length()-1) == c)
466 {
467 changed = true;
468 s = s.substring(0, s.length()-1);
469 }
470 }
471 } while (changed);
472 return s;
473 }
474 * characters from front of string
476 * @param s The string to process
477 * @param c The character to remove
478 * @return The resulting string
479 */
480 static public String stripFront(String s, char c) {
481 while (s.length() > 0 && s.charAt(0) == c) {
482 s = s.substring(1);
483 }
484 return s;
485 }
486 * characters from front of string
488 * @param s The string to process
489 * @param remove A string containing the set of characters to remove
490 * @return The resulting string
491 */
492 static public String stripFront(String s, String remove) {
493 boolean changed;
494 do {
495 changed = false;
496 for (int i = 0; i < remove.length(); i++) {
497 char c = remove.charAt(i);
498 while (s.length() > 0 && s.charAt(0) == c) {
499 changed = true;
500 s = s.substring(1);
501 }
502 }
503 } while (changed);
504 return s;
505 }
506 * characters from the front and back of string
508 * @param s The string to process
509 * @param head exact string to strip from head
510 * @param tail exact string to strip from tail
511 * @return The resulting string
512 */
513 public static String stripFrontBack(String src, String head, String tail) {
514 int h = src.indexOf(head);
515 int t = src.lastIndexOf(tail);
516 if ( h==-1 || t==-1 ) return src;
517 return src.substring(h+1,t);
518 }
519 * @param s The message
521 */
522 public static void toolError(String s) {
523 System.out.println("error: "+s);
524 }
525 * @param s the message
527 */
528 public static void warning(String s) {
529 System.out.println("warning: "+s);
530 }
531 * @param s The message
533 * @param line The grammar file line number on which the error occured
534 */
535 public static void warning(String s, int line) {
536 System.out.println("warning; line "+line+": "+s);
537 }
538 }
539