PageRenderTime 64ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/Dependencies/boo/lib/antlr-2.7.5/antlr/Tool.java

https://github.com/w4x/boolangstudio
Java | 635 lines | 408 code | 69 blank | 158 comment | 66 complexity | df2036b92313f665bb81f20612aed88b MD5 | raw file
Possible License(s): GPL-2.0
  1. package antlr;
  2. /* ANTLR Translator Generator
  3. * Project led by Terence Parr at http://www.jGuru.com
  4. * Software rights: http://www.antlr.org/license.html
  5. *
  6. * $Id: //depot/code/org.antlr/release/antlr-2.7.5/antlr/Tool.java#1 $
  7. */
  8. import java.io.*;
  9. import antlr.collections.impl.BitSet;
  10. import antlr.collections.impl.Vector;
  11. import antlr.PreservingFileWriter;
  12. import antlr.Version;
  13. public class Tool {
  14. public static String version = "";
  15. /** Object that handles analysis errors */
  16. ToolErrorHandler errorHandler;
  17. /** Was there an error during parsing or analysis? */
  18. protected boolean hasError = false;
  19. /** Generate diagnostics? (vs code) */
  20. boolean genDiagnostics = false;
  21. /** Generate DocBook vs code? */
  22. boolean genDocBook = false;
  23. /** Generate HTML vs code? */
  24. boolean genHTML = false;
  25. /** Current output directory for generated files */
  26. protected static String outputDir = ".";
  27. // Grammar input
  28. protected String grammarFile;
  29. transient Reader f = new InputStreamReader(System.in);
  30. // SAS: changed for proper text io
  31. // transient DataInputStream in = null;
  32. protected static String literalsPrefix = "LITERAL_";
  33. protected static boolean upperCaseMangledLiterals = false;
  34. /** C++ file level options */
  35. protected NameSpace nameSpace = null;
  36. protected String namespaceAntlr = null;
  37. protected String namespaceStd = null;
  38. protected boolean genHashLines = true;
  39. protected boolean noConstructors = false;
  40. private BitSet cmdLineArgValid = new BitSet();
  41. /** Construct a new Tool. */
  42. public Tool() {
  43. errorHandler = new DefaultToolErrorHandler(this);
  44. }
  45. public String getGrammarFile() {
  46. return grammarFile;
  47. }
  48. public boolean hasError() {
  49. return hasError;
  50. }
  51. public NameSpace getNameSpace() {
  52. return nameSpace;
  53. }
  54. public String getNamespaceStd() {
  55. return namespaceStd;
  56. }
  57. public String getNamespaceAntlr() {
  58. return namespaceAntlr;
  59. }
  60. public boolean getGenHashLines() {
  61. return genHashLines;
  62. }
  63. public String getLiteralsPrefix() {
  64. return literalsPrefix;
  65. }
  66. public boolean getUpperCaseMangledLiterals() {
  67. return upperCaseMangledLiterals;
  68. }
  69. public void setFileLineFormatter(FileLineFormatter formatter) {
  70. FileLineFormatter.setFormatter(formatter);
  71. }
  72. protected void checkForInvalidArguments(String[] args, BitSet cmdLineArgValid) {
  73. // check for invalid command line args
  74. for (int a = 0; a < args.length; a++) {
  75. if (!cmdLineArgValid.member(a)) {
  76. warning("invalid command-line argument: " + args[a] + "; ignored");
  77. }
  78. }
  79. }
  80. /** This example is from the book _Java in a Nutshell_ by David
  81. * Flanagan. Written by David Flanagan. Copyright (c) 1996
  82. * O'Reilly & Associates. You may study, use, modify, and
  83. * distribute this example for any purpose. This example is
  84. * provided WITHOUT WARRANTY either expressed or implied. */
  85. public void copyFile(String source_name, String dest_name)
  86. throws IOException {
  87. File source_file = new File(source_name);
  88. File destination_file = new File(dest_name);
  89. Reader source = null;
  90. Writer destination = null;
  91. char[] buffer;
  92. int bytes_read;
  93. try {
  94. // First make sure the specified source file
  95. // exists, is a file, and is readable.
  96. 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. // If the destination exists, make sure it is a writeable file
  103. // and ask before overwriting it. If the destination doesn't
  104. // exist, make sure the directory exists and is writeable.
  105. if (destination_file.exists()) {
  106. if (destination_file.isFile()) {
  107. DataInputStream in = new DataInputStream(System.in);
  108. String response;
  109. if (!destination_file.canWrite())
  110. throw new FileCopyException("FileCopy: destination " +
  111. "file is unwriteable: " + dest_name);
  112. /*
  113. System.out.print("File " + dest_name +
  114. " already exists. Overwrite? (Y/N): ");
  115. System.out.flush();
  116. response = in.readLine();
  117. if (!response.equals("Y") && !response.equals("y"))
  118. throw new FileCopyException("FileCopy: copy cancelled.");
  119. */
  120. }
  121. else {
  122. throw new FileCopyException("FileCopy: destination "
  123. + "is not a file: " + dest_name);
  124. }
  125. }
  126. else {
  127. File parentdir = parent(destination_file);
  128. if (!parentdir.exists())
  129. throw new FileCopyException("FileCopy: destination "
  130. + "directory doesn't exist: " + dest_name);
  131. if (!parentdir.canWrite())
  132. throw new FileCopyException("FileCopy: destination "
  133. + "directory is unwriteable: " + dest_name);
  134. }
  135. // If we've gotten this far, then everything is okay; we can
  136. // copy the file.
  137. source = new BufferedReader(new FileReader(source_file));
  138. destination = new BufferedWriter(new FileWriter(destination_file));
  139. buffer = new char[1024];
  140. while (true) {
  141. bytes_read = source.read(buffer, 0, 1024);
  142. if (bytes_read == -1) break;
  143. destination.write(buffer, 0, bytes_read);
  144. }
  145. }
  146. // No matter what happens, always close any streams we've opened.
  147. finally {
  148. if (source != null) {
  149. try {
  150. source.close();
  151. }
  152. catch (IOException e) {
  153. ;
  154. }
  155. }
  156. if (destination != null) {
  157. try {
  158. destination.close();
  159. }
  160. catch (IOException e) {
  161. ;
  162. }
  163. }
  164. }
  165. }
  166. /** Perform processing on the grammar file. Can only be called
  167. * from main() @param args The command-line arguments passed to
  168. * main(). This wrapper does the System.exit for use with command-line.
  169. */
  170. public void doEverythingWrapper(String[] args) {
  171. int exitCode = doEverything(args);
  172. System.exit(exitCode);
  173. }
  174. /** Process args and have ANTLR do it's stuff without calling System.exit.
  175. * Just return the result code. Makes it easy for ANT build tool.
  176. */
  177. public int doEverything(String[] args) {
  178. // run the preprocessor to handle inheritance first.
  179. // Start preprocessor. This strips generates an argument list
  180. // without -glib options (inside preTool)
  181. antlr.preprocessor.Tool preTool = new antlr.preprocessor.Tool(this, args);
  182. boolean preprocess_ok = preTool.preprocess();
  183. String[] modifiedArgs = preTool.preprocessedArgList();
  184. // process arguments for the Tool
  185. processArguments(modifiedArgs);
  186. if (!preprocess_ok) {
  187. return 1;
  188. }
  189. f = getGrammarReader();
  190. ANTLRLexer lexer = new ANTLRLexer(f);
  191. TokenBuffer tokenBuf = new TokenBuffer(lexer);
  192. LLkAnalyzer analyzer = new LLkAnalyzer(this);
  193. MakeGrammar behavior = new MakeGrammar(this, args, analyzer);
  194. try {
  195. ANTLRParser p = new ANTLRParser(tokenBuf, behavior, this);
  196. p.setFilename(grammarFile);
  197. p.grammar();
  198. if (hasError()) {
  199. fatalError("Exiting due to errors.");
  200. }
  201. checkForInvalidArguments(modifiedArgs, cmdLineArgValid);
  202. // Create the right code generator according to the "language" option
  203. CodeGenerator codeGen;
  204. // SAS: created getLanguage() method so subclass can override
  205. // (necessary for VAJ interface)
  206. String codeGenClassName = "antlr." + getLanguage(behavior) + "CodeGenerator";
  207. try {
  208. Class codeGenClass = Class.forName(codeGenClassName);
  209. codeGen = (CodeGenerator)codeGenClass.newInstance();
  210. codeGen.setBehavior(behavior);
  211. codeGen.setAnalyzer(analyzer);
  212. codeGen.setTool(this);
  213. codeGen.gen();
  214. }
  215. catch (ClassNotFoundException cnfe) {
  216. panic("Cannot instantiate code-generator: " + codeGenClassName);
  217. }
  218. catch (InstantiationException ie) {
  219. panic("Cannot instantiate code-generator: " + codeGenClassName);
  220. }
  221. catch (IllegalArgumentException ie) {
  222. panic("Cannot instantiate code-generator: " + codeGenClassName);
  223. }
  224. catch (IllegalAccessException iae) {
  225. panic("code-generator class '" + codeGenClassName + "' is not accessible");
  226. }
  227. }
  228. catch (RecognitionException pe) {
  229. fatalError("Unhandled parser error: " + pe.getMessage());
  230. }
  231. catch (TokenStreamException io) {
  232. fatalError("TokenStreamException: " + io.getMessage());
  233. }
  234. return 0;
  235. }
  236. /** Issue an error
  237. * @param s The message
  238. */
  239. public void error(String s) {
  240. hasError = true;
  241. System.err.println("error: " + s);
  242. }
  243. /** Issue an error with line number information
  244. * @param s The message
  245. * @param file The file that has the error (or null)
  246. * @param line The grammar file line number on which the error occured (or -1)
  247. * @param column The grammar file column number on which the error occured (or -1)
  248. */
  249. public void error(String s, String file, int line, int column) {
  250. hasError = true;
  251. System.err.println(FileLineFormatter.getFormatter().
  252. getFormatString(file, line, column) + s);
  253. }
  254. /** When we are 1.1 compatible...
  255. public static Object factory2 (String p, Object[] initargs) {
  256. Class c;
  257. Object o = null;
  258. try {
  259. int argslen = initargs.length;
  260. Class cl[] = new Class[argslen];
  261. for (int i=0;i&lt;argslen;i++) {
  262. cl[i] = Class.forName(initargs[i].getClass().getName());
  263. }
  264. c = Class.forName (p);
  265. Constructor con = c.getConstructor (cl);
  266. o = con.newInstance (initargs);
  267. } catch (Exception e) {
  268. System.err.println ("Can't make a " + p);
  269. }
  270. return o;
  271. }
  272. */
  273. public Object factory(String p) {
  274. Class c;
  275. Object o = null;
  276. try {
  277. c = Class.forName(p);// get class def
  278. o = c.newInstance(); // make a new one
  279. }
  280. catch (Exception e) {
  281. // either class not found,
  282. // class is interface/abstract, or
  283. // class or initializer is not accessible.
  284. warning("Can't create an object of type " + p);
  285. return null;
  286. }
  287. return o;
  288. }
  289. public String fileMinusPath(String f) {
  290. String separator = System.getProperty("file.separator");
  291. int endOfPath = f.lastIndexOf(separator);
  292. if (endOfPath == -1) {
  293. return f; // no path found
  294. }
  295. return f.substring(endOfPath + 1);
  296. }
  297. /** Determine the language used for this run of ANTLR
  298. * This was made a method so the subclass can override it
  299. */
  300. public String getLanguage(MakeGrammar behavior) {
  301. if (genDiagnostics) {
  302. return "Diagnostic";
  303. }
  304. if (genHTML) {
  305. return "HTML";
  306. }
  307. if (genDocBook) {
  308. return "DocBook";
  309. }
  310. return behavior.language;
  311. }
  312. public String getOutputDirectory() {
  313. return outputDir;
  314. }
  315. private static void help() {
  316. System.err.println("usage: java antlr.Tool [args] file.g");
  317. System.err.println(" -o outputDir specify output directory where all output generated.");
  318. System.err.println(" -glib superGrammar specify location of supergrammar file.");
  319. System.err.println(" -debug launch the ParseView debugger upon parser invocation.");
  320. System.err.println(" -html generate a html file from your grammar.");
  321. System.err.println(" -docbook generate a docbook sgml file from your grammar.");
  322. System.err.println(" -diagnostic generate a textfile with diagnostics.");
  323. System.err.println(" -trace have all rules call traceIn/traceOut.");
  324. System.err.println(" -traceLexer have lexer rules call traceIn/traceOut.");
  325. System.err.println(" -traceParser have parser rules call traceIn/traceOut.");
  326. System.err.println(" -traceTreeParser have tree parser rules call traceIn/traceOut.");
  327. System.err.println(" -h|-help|--help this message");
  328. }
  329. public static void main(String[] args) {
  330. System.err.println("ANTLR Parser Generator Version " +
  331. Version.project_version + " 1989-2005 jGuru.com");
  332. version = Version.project_version;
  333. try {
  334. if (args.length == 0) {
  335. help();
  336. System.exit(1);
  337. }
  338. for (int i = 0; i < args.length; ++i) {
  339. if (args[i].equals("-h")
  340. || args[i].equals("-help")
  341. || args[i].equals("--help")
  342. ) {
  343. help();
  344. System.exit(1);
  345. }
  346. }
  347. Tool theTool = new Tool();
  348. theTool.doEverything(args);
  349. theTool = null;
  350. }
  351. catch (Exception e) {
  352. System.err.println(System.getProperty("line.separator") +
  353. System.getProperty("line.separator"));
  354. System.err.println("#$%%*&@# internal error: " + e.toString());
  355. System.err.println("[complain to nearest government official");
  356. System.err.println(" or send hate-mail to parrt@jguru.com;");
  357. System.err.println(" please send stack trace with report.]" +
  358. System.getProperty("line.separator"));
  359. e.printStackTrace();
  360. }
  361. System.exit(0);
  362. }
  363. /** This method is used by all code generators to create new output
  364. * files. If the outputDir set by -o is not present it will be created here.
  365. */
  366. public PrintWriter openOutputFile(String f) throws IOException {
  367. if( outputDir != "." ) {
  368. File out_dir = new File(outputDir);
  369. if( ! out_dir.exists() )
  370. out_dir.mkdirs();
  371. }
  372. return new PrintWriter(new PreservingFileWriter(outputDir + System.getProperty("file.separator") + f));
  373. }
  374. public Reader getGrammarReader() {
  375. Reader f = null;
  376. try {
  377. if (grammarFile != null) {
  378. f = new BufferedReader(new FileReader(grammarFile));
  379. }
  380. }
  381. catch (IOException e) {
  382. fatalError("cannot open grammar file " + grammarFile);
  383. }
  384. return f;
  385. }
  386. /** @since 2.7.2
  387. */
  388. public void reportException(Exception e, String message) {
  389. System.err.println(message == null ? e.getMessage()
  390. : message + ": " + e.getMessage());
  391. }
  392. /** @since 2.7.2
  393. */
  394. public void reportProgress(String message) {
  395. System.out.println(message);
  396. }
  397. /** An error occured that should stop the Tool from doing any work.
  398. * The default implementation currently exits (via
  399. * {@link java.lang.System.exit(int)} after printing an error message to
  400. * <var>stderr</var>. However, the tools should expect that a subclass
  401. * will override this to throw an unchecked exception such as
  402. * {@link java.lang.IllegalStateException} or another subclass of
  403. * {@link java.lang.RuntimeException}. <em>If this method is overriden,
  404. * <strong>it must never return normally</strong>; i.e. it must always
  405. * throw an exception or call System.exit</em>.
  406. * @since 2.7.2
  407. * @param s The message
  408. */
  409. public void fatalError(String message) {
  410. System.err.println(message);
  411. System.exit(1);
  412. }
  413. /** Issue an unknown fatal error. <em>If this method is overriden,
  414. * <strong>it must never return normally</strong>; i.e. it must always
  415. * throw an exception or call System.exit</em>.
  416. * @deprecated as of 2.7.2 use {@link #fatalError(String)}. By default
  417. * this method executes <code>fatalError("panic");</code>.
  418. */
  419. public void panic() {
  420. fatalError("panic");
  421. }
  422. /** Issue a fatal error message. <em>If this method is overriden,
  423. * <strong>it must never return normally</strong>; i.e. it must always
  424. * throw an exception or call System.exit</em>.
  425. * @deprecated as of 2.7.2 use {@link #fatalError(String)}. By defaykt
  426. * this method executes <code>fatalError("panic: " + s);</code>.
  427. * @param s The message
  428. */
  429. public void panic(String s) {
  430. fatalError("panic: " + s);
  431. }
  432. // File.getParent() can return null when the file is specified without
  433. // a directory or is in the root directory.
  434. // This method handles those cases.
  435. public File parent(File f) {
  436. String dirname = f.getParent();
  437. if (dirname == null) {
  438. if (f.isAbsolute())
  439. return new File(File.separator);
  440. else
  441. return new File(System.getProperty("user.dir"));
  442. }
  443. return new File(dirname);
  444. }
  445. /** Parse a list such as "f1.g;f2.g;..." and return a Vector
  446. * of the elements.
  447. */
  448. public static Vector parseSeparatedList(String list, char separator) {
  449. java.util.StringTokenizer st =
  450. new java.util.StringTokenizer(list, String.valueOf(separator));
  451. Vector v = new Vector(10);
  452. while ( st.hasMoreTokens() ) {
  453. v.appendElement(st.nextToken());
  454. }
  455. if (v.size() == 0) return null;
  456. return v;
  457. }
  458. /** given a filename, strip off the directory prefix (if any)
  459. * and return it. Return "./" if f has no dir prefix.
  460. */
  461. public String pathToFile(String f) {
  462. String separator = System.getProperty("file.separator");
  463. int endOfPath = f.lastIndexOf(separator);
  464. if (endOfPath == -1) {
  465. // no path, use current directory
  466. return "." + System.getProperty("file.separator");
  467. }
  468. return f.substring(0, endOfPath + 1);
  469. }
  470. /** <p>Process the command-line arguments. Can only be called by Tool.
  471. * A bitset is collected of all correct arguments via setArgOk.</p>
  472. * @param args The command-line arguments passed to main()
  473. *
  474. */
  475. protected void processArguments(String[] args) {
  476. for (int i = 0; i < args.length; i++) {
  477. if (args[i].equals("-diagnostic")) {
  478. genDiagnostics = true;
  479. genHTML = false;
  480. setArgOK(i);
  481. }
  482. else if (args[i].equals("-o")) {
  483. setArgOK(i);
  484. if (i + 1 >= args.length) {
  485. error("missing output directory with -o option; ignoring");
  486. }
  487. else {
  488. i++;
  489. setOutputDirectory(args[i]);
  490. setArgOK(i);
  491. }
  492. }
  493. else if (args[i].equals("-html")) {
  494. genHTML = true;
  495. genDiagnostics = false;
  496. setArgOK(i);
  497. }
  498. else if (args[i].equals("-docbook")) {
  499. genDocBook = true;
  500. genDiagnostics = false;
  501. setArgOK(i);
  502. }
  503. else {
  504. if (args[i].charAt(0) != '-') {
  505. // Must be the grammar file
  506. grammarFile = args[i];
  507. setArgOK(i);
  508. }
  509. }
  510. }
  511. }
  512. public void setArgOK(int i) {
  513. cmdLineArgValid.add(i);
  514. }
  515. public void setOutputDirectory(String o) {
  516. outputDir = o;
  517. }
  518. /** Issue an error; used for general tool errors not for grammar stuff
  519. * @param s The message
  520. */
  521. public void toolError(String s) {
  522. System.err.println("error: " + s);
  523. }
  524. /** Issue a warning
  525. * @param s the message
  526. */
  527. public void warning(String s) {
  528. System.err.println("warning: " + s);
  529. }
  530. /** Issue a warning with line number information
  531. * @param s The message
  532. * @param file The file that has the warning (or null)
  533. * @param line The grammar file line number on which the warning occured (or -1)
  534. * @param column The grammar file line number on which the warning occured (or -1)
  535. */
  536. public void warning(String s, String file, int line, int column) {
  537. System.err.println(FileLineFormatter.getFormatter().
  538. getFormatString(file, line, column) + "warning:" + s);
  539. }
  540. /** Issue a warning with line number information
  541. * @param s The lines of the message
  542. * @param file The file that has the warning
  543. * @param line The grammar file line number on which the warning occured
  544. */
  545. public void warning(String[] s, String file, int line, int column) {
  546. if (s == null || s.length == 0) {
  547. panic("bad multi-line message to Tool.warning");
  548. }
  549. System.err.println(FileLineFormatter.getFormatter().
  550. getFormatString(file, line, column) + "warning:" + s[0]);
  551. for (int i = 1; i < s.length; i++) {
  552. System.err.println(FileLineFormatter.getFormatter().
  553. getFormatString(file, line, column) + " " + s[i]);
  554. }
  555. }
  556. /**
  557. * Support C++ & C# namespaces (for now).
  558. * C++: Add a nested namespace name to the current namespace.
  559. * C# : Specify an enclosing namespace for the generated code.
  560. * DAW: David Wagner -- C# support by kunle odutola
  561. */
  562. public void setNameSpace(String name) {
  563. if (null == nameSpace)
  564. nameSpace = new NameSpace(StringUtils.stripFrontBack(name, "\"", "\""));
  565. }
  566. }