Tool.java
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:18k
源码类别:

编译器/解释器

开发平台:

Others

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