1 /* 2 * [The "BSD license"] 3 * Copyright (c) 2010 Terence Parr 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 package org.antlr.test; 29 30 31 import org.antlr.Tool; 32 import org.antlr.analysis.Label; 33 import org.antlr.runtime.CommonTokenStream; 34 import org.antlr.runtime.Token; 35 import org.antlr.runtime.TokenSource; 36 import org.stringtemplate.v4.ST; 37 import org.stringtemplate.v4.STGroup; 38 import org.antlr.tool.ANTLRErrorListener; 39 import org.antlr.tool.ErrorManager; 40 import org.antlr.tool.GrammarSemanticsMessage; 41 import org.antlr.tool.Message; 42 import org.junit.After; 43 import org.junit.Assert; 44 import org.junit.Before; 45 46 import javax.tools.*; 47 import java.io.*; 48 import java.util.*; 49 50 51 public abstract class BaseTest { 52 public static final String newline = System.getProperty("line.separator"); 53 54 public static final String jikes = null;//"/usr/bin/jikes"; 55 public static final String pathSep = System.getProperty("path.separator"); 56 57 /** 58 * When runnning from Maven, the junit tests are run via the surefire plugin. It sets the 59 * classpath for the test environment into the following property. We need to pick this up 60 * for the junit tests that are going to generate and try to run code. 61 */ 62 public static final String SUREFIRE_CLASSPATH = System.getProperty("surefire.test.class.path", ""); 63 64 /** 65 * Build up the full classpath we need, including the surefire path (if present) 66 */ 67 public static final String CLASSPATH = System.getProperty("java.class.path") + (SUREFIRE_CLASSPATH.equals("") ? "" : pathSep + SUREFIRE_CLASSPATH); 68 69 public String tmpdir = null; 70 71 /** reset during setUp and set to true if we find a problem */ 72 protected boolean lastTestFailed = false; 73 74 /** If error during parser execution, store stderr here; can't return 75 * stdout and stderr. This doesn't trap errors from running antlr. 76 */ 77 protected String stderrDuringParse; 78 79 @Before setUp()80 public void setUp() throws Exception { 81 lastTestFailed = false; // hope for the best, but set to true in asserts that fail 82 // new output dir for each test 83 tmpdir = new File(System.getProperty("java.io.tmpdir"), 84 "antlr-"+getClass().getName()+"-"+ 85 System.currentTimeMillis()).getAbsolutePath(); 86 ErrorManager.resetErrorState(); 87 STGroup.defaultGroup = new STGroup(); 88 } 89 90 @After tearDown()91 public void tearDown() throws Exception { 92 // remove tmpdir if no error. 93 if ( !lastTestFailed ) eraseTempDir(); 94 95 } 96 newTool(String[] args)97 protected Tool newTool(String[] args) { 98 Tool tool = new Tool(args); 99 tool.setOutputDirectory(tmpdir); 100 return tool; 101 } 102 newTool()103 protected Tool newTool() { 104 Tool tool = new Tool(); 105 tool.setOutputDirectory(tmpdir); 106 return tool; 107 } 108 compile(String fileName)109 protected boolean compile(String fileName) { 110 String classpathOption = "-classpath"; 111 112 String[] args = new String[] { 113 "javac", "-d", tmpdir, 114 classpathOption, tmpdir+pathSep+CLASSPATH, 115 tmpdir+"/"+fileName 116 }; 117 String cmdLine = "javac" +" -d "+tmpdir+" "+classpathOption+" "+tmpdir+pathSep+CLASSPATH+" "+fileName; 118 //System.out.println("compile: "+cmdLine); 119 120 121 File f = new File(tmpdir, fileName); 122 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 123 124 StandardJavaFileManager fileManager = 125 compiler.getStandardFileManager(null, null, null); 126 127 Iterable<? extends JavaFileObject> compilationUnits = 128 fileManager.getJavaFileObjectsFromFiles(Arrays.asList(f)); 129 130 Iterable<String> compileOptions = 131 Arrays.asList(new String[]{"-d", tmpdir, "-cp", tmpdir+pathSep+CLASSPATH} ); 132 133 JavaCompiler.CompilationTask task = 134 compiler.getTask(null, fileManager, null, compileOptions, null, 135 compilationUnits); 136 boolean ok = task.call(); 137 138 try { 139 fileManager.close(); 140 } 141 catch (IOException ioe) { 142 ioe.printStackTrace(System.err); 143 } 144 return ok; 145 } 146 147 /** Return true if all is ok, no errors */ antlr(String fileName, String grammarFileName, String grammarStr, boolean debug)148 protected boolean antlr(String fileName, String grammarFileName, String grammarStr, boolean debug) { 149 boolean allIsWell = true; 150 mkdir(tmpdir); 151 writeFile(tmpdir, fileName, grammarStr); 152 try { 153 final List options = new ArrayList(); 154 if ( debug ) { 155 options.add("-debug"); 156 } 157 options.add("-o"); 158 options.add(tmpdir); 159 options.add("-lib"); 160 options.add(tmpdir); 161 options.add(new File(tmpdir,grammarFileName).toString()); 162 final String[] optionsA = new String[options.size()]; 163 options.toArray(optionsA); 164 /* 165 final ErrorQueue equeue = new ErrorQueue(); 166 ErrorManager.setErrorListener(equeue); 167 */ 168 Tool antlr = newTool(optionsA); 169 antlr.process(); 170 ANTLRErrorListener listener = ErrorManager.getErrorListener(); 171 if ( listener instanceof ErrorQueue ) { 172 ErrorQueue equeue = (ErrorQueue)listener; 173 if ( equeue.errors.size()>0 ) { 174 allIsWell = false; 175 System.err.println("antlr reports errors from "+options); 176 for (int i = 0; i < equeue.errors.size(); i++) { 177 Message msg = (Message) equeue.errors.get(i); 178 System.err.println(msg); 179 } 180 System.out.println("!!!\ngrammar:"); 181 System.out.println(grammarStr); 182 System.out.println("###"); 183 } 184 } 185 } 186 catch (Exception e) { 187 allIsWell = false; 188 System.err.println("problems building grammar: "+e); 189 e.printStackTrace(System.err); 190 } 191 return allIsWell; 192 } 193 execLexer(String grammarFileName, String grammarStr, String lexerName, String input, boolean debug)194 protected String execLexer(String grammarFileName, 195 String grammarStr, 196 String lexerName, 197 String input, 198 boolean debug) 199 { 200 rawGenerateAndBuildRecognizer(grammarFileName, 201 grammarStr, 202 null, 203 lexerName, 204 debug); 205 writeFile(tmpdir, "input", input); 206 return rawExecRecognizer(null, 207 null, 208 lexerName, 209 null, 210 null, 211 false, 212 false, 213 false, 214 debug); 215 } 216 execParser(String grammarFileName, String grammarStr, String parserName, String lexerName, String startRuleName, String input, boolean debug)217 protected String execParser(String grammarFileName, 218 String grammarStr, 219 String parserName, 220 String lexerName, 221 String startRuleName, 222 String input, boolean debug) 223 { 224 rawGenerateAndBuildRecognizer(grammarFileName, 225 grammarStr, 226 parserName, 227 lexerName, 228 debug); 229 writeFile(tmpdir, "input", input); 230 boolean parserBuildsTrees = 231 grammarStr.indexOf("output=AST")>=0 || 232 grammarStr.indexOf("output = AST")>=0; 233 boolean parserBuildsTemplate = 234 grammarStr.indexOf("output=template")>=0 || 235 grammarStr.indexOf("output = template")>=0; 236 return rawExecRecognizer(parserName, 237 null, 238 lexerName, 239 startRuleName, 240 null, 241 parserBuildsTrees, 242 parserBuildsTemplate, 243 false, 244 debug); 245 } 246 execTreeParser(String parserGrammarFileName, String parserGrammarStr, String parserName, String treeParserGrammarFileName, String treeParserGrammarStr, String treeParserName, String lexerName, String parserStartRuleName, String treeParserStartRuleName, String input)247 protected String execTreeParser(String parserGrammarFileName, 248 String parserGrammarStr, 249 String parserName, 250 String treeParserGrammarFileName, 251 String treeParserGrammarStr, 252 String treeParserName, 253 String lexerName, 254 String parserStartRuleName, 255 String treeParserStartRuleName, 256 String input) 257 { 258 return execTreeParser(parserGrammarFileName, 259 parserGrammarStr, 260 parserName, 261 treeParserGrammarFileName, 262 treeParserGrammarStr, 263 treeParserName, 264 lexerName, 265 parserStartRuleName, 266 treeParserStartRuleName, 267 input, 268 false); 269 } 270 execTreeParser(String parserGrammarFileName, String parserGrammarStr, String parserName, String treeParserGrammarFileName, String treeParserGrammarStr, String treeParserName, String lexerName, String parserStartRuleName, String treeParserStartRuleName, String input, boolean debug)271 protected String execTreeParser(String parserGrammarFileName, 272 String parserGrammarStr, 273 String parserName, 274 String treeParserGrammarFileName, 275 String treeParserGrammarStr, 276 String treeParserName, 277 String lexerName, 278 String parserStartRuleName, 279 String treeParserStartRuleName, 280 String input, 281 boolean debug) 282 { 283 // build the parser 284 rawGenerateAndBuildRecognizer(parserGrammarFileName, 285 parserGrammarStr, 286 parserName, 287 lexerName, 288 debug); 289 290 // build the tree parser 291 rawGenerateAndBuildRecognizer(treeParserGrammarFileName, 292 treeParserGrammarStr, 293 treeParserName, 294 lexerName, 295 debug); 296 297 writeFile(tmpdir, "input", input); 298 299 boolean parserBuildsTrees = 300 parserGrammarStr.indexOf("output=AST")>=0 || 301 parserGrammarStr.indexOf("output = AST")>=0; 302 boolean treeParserBuildsTrees = 303 treeParserGrammarStr.indexOf("output=AST")>=0 || 304 treeParserGrammarStr.indexOf("output = AST")>=0; 305 boolean parserBuildsTemplate = 306 parserGrammarStr.indexOf("output=template")>=0 || 307 parserGrammarStr.indexOf("output = template")>=0; 308 309 return rawExecRecognizer(parserName, 310 treeParserName, 311 lexerName, 312 parserStartRuleName, 313 treeParserStartRuleName, 314 parserBuildsTrees, 315 parserBuildsTemplate, 316 treeParserBuildsTrees, 317 debug); 318 } 319 320 /** Return true if all is well */ rawGenerateAndBuildRecognizer(String grammarFileName, String grammarStr, String parserName, String lexerName, boolean debug)321 protected boolean rawGenerateAndBuildRecognizer(String grammarFileName, 322 String grammarStr, 323 String parserName, 324 String lexerName, 325 boolean debug) 326 { 327 //System.out.println(grammarStr); 328 boolean allIsWell = 329 antlr(grammarFileName, grammarFileName, grammarStr, debug); 330 if ( lexerName!=null ) { 331 boolean ok; 332 if ( parserName!=null ) { 333 ok = compile(parserName+".java"); 334 if ( !ok ) { allIsWell = false; } 335 } 336 ok = compile(lexerName+".java"); 337 if ( !ok ) { allIsWell = false; } 338 } 339 else { 340 boolean ok = compile(parserName+".java"); 341 if ( !ok ) { allIsWell = false; } 342 } 343 return allIsWell; 344 } 345 rawExecRecognizer(String parserName, String treeParserName, String lexerName, String parserStartRuleName, String treeParserStartRuleName, boolean parserBuildsTrees, boolean parserBuildsTemplate, boolean treeParserBuildsTrees, boolean debug)346 protected String rawExecRecognizer(String parserName, 347 String treeParserName, 348 String lexerName, 349 String parserStartRuleName, 350 String treeParserStartRuleName, 351 boolean parserBuildsTrees, 352 boolean parserBuildsTemplate, 353 boolean treeParserBuildsTrees, 354 boolean debug) 355 { 356 this.stderrDuringParse = null; 357 writeRecognizerAndCompile(parserName, treeParserName, lexerName, parserStartRuleName, treeParserStartRuleName, parserBuildsTrees, parserBuildsTemplate, treeParserBuildsTrees, debug); 358 359 return execRecognizer(); 360 } 361 execRecognizer()362 public String execRecognizer() { 363 try { 364 String inputFile = new File(tmpdir, "input").getAbsolutePath(); 365 String[] args = new String[] { 366 "java", "-classpath", tmpdir+pathSep+CLASSPATH, 367 "Test", inputFile 368 }; 369 //String cmdLine = "java -classpath "+CLASSPATH+pathSep+tmpdir+" Test " + new File(tmpdir, "input").getAbsolutePath(); 370 //System.out.println("execParser: "+cmdLine); 371 Process process = 372 Runtime.getRuntime().exec(args, null, new File(tmpdir)); 373 StreamVacuum stdoutVacuum = new StreamVacuum(process.getInputStream(), inputFile); 374 StreamVacuum stderrVacuum = new StreamVacuum(process.getErrorStream(), inputFile); 375 stdoutVacuum.start(); 376 stderrVacuum.start(); 377 process.waitFor(); 378 stdoutVacuum.join(); 379 stderrVacuum.join(); 380 String output = null; 381 output = stdoutVacuum.toString(); 382 if ( stderrVacuum.toString().length()>0 ) { 383 this.stderrDuringParse = stderrVacuum.toString(); 384 System.err.println("exec stderrVacuum: "+ stderrVacuum); 385 } 386 return output; 387 } 388 catch (Exception e) { 389 System.err.println("can't exec recognizer"); 390 e.printStackTrace(System.err); 391 } 392 return null; 393 } 394 writeRecognizerAndCompile(String parserName, String treeParserName, String lexerName, String parserStartRuleName, String treeParserStartRuleName, boolean parserBuildsTrees, boolean parserBuildsTemplate, boolean treeParserBuildsTrees, boolean debug)395 public void writeRecognizerAndCompile(String parserName, String treeParserName, String lexerName, String parserStartRuleName, String treeParserStartRuleName, boolean parserBuildsTrees, boolean parserBuildsTemplate, boolean treeParserBuildsTrees, boolean debug) { 396 if ( treeParserBuildsTrees && parserBuildsTrees ) { 397 writeTreeAndTreeTestFile(parserName, 398 treeParserName, 399 lexerName, 400 parserStartRuleName, 401 treeParserStartRuleName, 402 debug); 403 } 404 else if ( parserBuildsTrees ) { 405 writeTreeTestFile(parserName, 406 treeParserName, 407 lexerName, 408 parserStartRuleName, 409 treeParserStartRuleName, 410 debug); 411 } 412 else if ( parserBuildsTemplate ) { 413 writeTemplateTestFile(parserName, 414 lexerName, 415 parserStartRuleName, 416 debug); 417 } 418 else if ( parserName==null ) { 419 writeLexerTestFile(lexerName, debug); 420 } 421 else { 422 writeTestFile(parserName, 423 lexerName, 424 parserStartRuleName, 425 debug); 426 } 427 428 compile("Test.java"); 429 } 430 checkGrammarSemanticsError(ErrorQueue equeue, GrammarSemanticsMessage expectedMessage)431 protected void checkGrammarSemanticsError(ErrorQueue equeue, 432 GrammarSemanticsMessage expectedMessage) 433 throws Exception 434 { 435 /* 436 System.out.println(equeue.infos); 437 System.out.println(equeue.warnings); 438 System.out.println(equeue.errors); 439 assertTrue("number of errors mismatch", n, equeue.errors.size()); 440 */ 441 Message foundMsg = null; 442 for (int i = 0; i < equeue.errors.size(); i++) { 443 Message m = (Message)equeue.errors.get(i); 444 if (m.msgID==expectedMessage.msgID ) { 445 foundMsg = m; 446 } 447 } 448 assertNotNull("no error; "+expectedMessage.msgID+" expected", foundMsg); 449 assertTrue("error is not a GrammarSemanticsMessage", 450 foundMsg instanceof GrammarSemanticsMessage); 451 assertEquals(expectedMessage.arg, foundMsg.arg); 452 if ( equeue.size()!=1 ) { 453 System.err.println(equeue); 454 } 455 } 456 checkGrammarSemanticsWarning(ErrorQueue equeue, GrammarSemanticsMessage expectedMessage)457 protected void checkGrammarSemanticsWarning(ErrorQueue equeue, 458 GrammarSemanticsMessage expectedMessage) 459 throws Exception 460 { 461 Message foundMsg = null; 462 for (int i = 0; i < equeue.warnings.size(); i++) { 463 Message m = (Message)equeue.warnings.get(i); 464 if (m.msgID==expectedMessage.msgID ) { 465 foundMsg = m; 466 } 467 } 468 assertNotNull("no error; "+expectedMessage.msgID+" expected", foundMsg); 469 assertTrue("error is not a GrammarSemanticsMessage", 470 foundMsg instanceof GrammarSemanticsMessage); 471 assertEquals(expectedMessage.arg, foundMsg.arg); 472 } 473 checkError(ErrorQueue equeue, Message expectedMessage)474 protected void checkError(ErrorQueue equeue, 475 Message expectedMessage) 476 throws Exception 477 { 478 //System.out.println("errors="+equeue); 479 Message foundMsg = null; 480 for (int i = 0; i < equeue.errors.size(); i++) { 481 Message m = (Message)equeue.errors.get(i); 482 if (m.msgID==expectedMessage.msgID ) { 483 foundMsg = m; 484 } 485 } 486 assertTrue("no error; "+expectedMessage.msgID+" expected", equeue.errors.size()>0); 487 assertTrue("too many errors; "+equeue.errors, equeue.errors.size()<=1); 488 assertNotNull("couldn't find expected error: "+expectedMessage.msgID, foundMsg); 489 /* 490 assertTrue("error is not a GrammarSemanticsMessage", 491 foundMsg instanceof GrammarSemanticsMessage); 492 */ 493 assertEquals(expectedMessage.arg, foundMsg.arg); 494 assertEquals(expectedMessage.arg2, foundMsg.arg2); 495 ErrorManager.resetErrorState(); // wack errors for next test 496 } 497 498 public static class StreamVacuum implements Runnable { 499 StringBuffer buf = new StringBuffer(); 500 BufferedReader in; 501 Thread sucker; 502 String inputFile; StreamVacuum(InputStream in, String inputFile)503 public StreamVacuum(InputStream in, String inputFile) { 504 this.in = new BufferedReader( new InputStreamReader(in) ); 505 this.inputFile = inputFile; 506 } start()507 public void start() { 508 sucker = new Thread(this); 509 sucker.start(); 510 } run()511 public void run() { 512 try { 513 String line = in.readLine(); 514 while (line!=null) { 515 if (line.startsWith(inputFile)) 516 line = line.substring(inputFile.length()+1); 517 buf.append(line); 518 buf.append('\n'); 519 line = in.readLine(); 520 } 521 } 522 catch (IOException ioe) { 523 System.err.println("can't read output from process"); 524 } 525 } 526 /** wait for the thread to finish */ join()527 public void join() throws InterruptedException { 528 sucker.join(); 529 } toString()530 public String toString() { 531 return buf.toString(); 532 } 533 } 534 535 public static class FilteringTokenStream extends CommonTokenStream { FilteringTokenStream(TokenSource src)536 public FilteringTokenStream(TokenSource src) { super(src); } 537 Set<Integer> hide = new HashSet<Integer>(); sync(int i)538 protected void sync(int i) { 539 super.sync(i); 540 if ( hide.contains(get(i).getType()) ) get(i).setChannel(Token.HIDDEN_CHANNEL); 541 } setTokenTypeChannel(int ttype, int channel)542 public void setTokenTypeChannel(int ttype, int channel) { 543 hide.add(ttype); 544 } 545 } 546 writeFile(String dir, String fileName, String content)547 protected void writeFile(String dir, String fileName, String content) { 548 try { 549 File f = new File(dir, fileName); 550 FileWriter w = new FileWriter(f); 551 BufferedWriter bw = new BufferedWriter(w); 552 bw.write(content); 553 bw.close(); 554 w.close(); 555 } 556 catch (IOException ioe) { 557 System.err.println("can't write file"); 558 ioe.printStackTrace(System.err); 559 } 560 } 561 mkdir(String dir)562 protected void mkdir(String dir) { 563 File f = new File(dir); 564 f.mkdirs(); 565 } 566 writeTestFile(String parserName, String lexerName, String parserStartRuleName, boolean debug)567 protected void writeTestFile(String parserName, 568 String lexerName, 569 String parserStartRuleName, 570 boolean debug) 571 { 572 ST outputFileST = new ST( 573 "import org.antlr.runtime.*;\n" + 574 "import org.antlr.runtime.tree.*;\n" + 575 "import org.antlr.runtime.debug.*;\n" + 576 "\n" + 577 "class Profiler2 extends Profiler {\n" + 578 " public void terminate() { ; }\n" + 579 "}\n"+ 580 "public class Test {\n" + 581 " public static void main(String[] args) throws Exception {\n" + 582 " CharStream input = new ANTLRFileStream(args[0]);\n" + 583 " <lexerName> lex = new <lexerName>(input);\n" + 584 " CommonTokenStream tokens = new CommonTokenStream(lex);\n" + 585 " <createParser>\n"+ 586 " parser.<parserStartRuleName>();\n" + 587 " }\n" + 588 "}" 589 ); 590 ST createParserST = 591 new ST( 592 " Profiler2 profiler = new Profiler2();\n"+ 593 " <parserName> parser = new <parserName>(tokens,profiler);\n" + 594 " profiler.setParser(parser);\n"); 595 if ( !debug ) { 596 createParserST = 597 new ST( 598 " <parserName> parser = new <parserName>(tokens);\n"); 599 } 600 outputFileST.add("createParser", createParserST); 601 outputFileST.add("parserName", parserName); 602 outputFileST.add("lexerName", lexerName); 603 outputFileST.add("parserStartRuleName", parserStartRuleName); 604 writeFile(tmpdir, "Test.java", outputFileST.render()); 605 } 606 writeLexerTestFile(String lexerName, boolean debug)607 protected void writeLexerTestFile(String lexerName, boolean debug) { 608 ST outputFileST = new ST( 609 "import org.antlr.runtime.*;\n" + 610 "import org.antlr.runtime.tree.*;\n" + 611 "import org.antlr.runtime.debug.*;\n" + 612 "\n" + 613 "class Profiler2 extends Profiler {\n" + 614 " public void terminate() { ; }\n" + 615 "}\n"+ 616 "public class Test {\n" + 617 " public static void main(String[] args) throws Exception {\n" + 618 " CharStream input = new ANTLRFileStream(args[0]);\n" + 619 " <lexerName> lex = new <lexerName>(input);\n" + 620 " CommonTokenStream tokens = new CommonTokenStream(lex);\n" + 621 " System.out.println(tokens);\n" + 622 " }\n" + 623 "}" 624 ); 625 outputFileST.add("lexerName", lexerName); 626 writeFile(tmpdir, "Test.java", outputFileST.render()); 627 } 628 writeTreeTestFile(String parserName, String treeParserName, String lexerName, String parserStartRuleName, String treeParserStartRuleName, boolean debug)629 protected void writeTreeTestFile(String parserName, 630 String treeParserName, 631 String lexerName, 632 String parserStartRuleName, 633 String treeParserStartRuleName, 634 boolean debug) 635 { 636 ST outputFileST = new ST( 637 "import org.antlr.runtime.*;\n" + 638 "import org.antlr.runtime.tree.*;\n" + 639 "import org.antlr.runtime.debug.*;\n" + 640 "\n" + 641 "class Profiler2 extends Profiler {\n" + 642 " public void terminate() { ; }\n" + 643 "}\n"+ 644 "public class Test {\n" + 645 " public static void main(String[] args) throws Exception {\n" + 646 " CharStream input = new ANTLRFileStream(args[0]);\n" + 647 " <lexerName> lex = new <lexerName>(input);\n" + 648 " TokenRewriteStream tokens = new TokenRewriteStream(lex);\n" + 649 " <createParser>\n"+ 650 " <parserName>.<parserStartRuleName>_return r = parser.<parserStartRuleName>();\n" + 651 " <if(!treeParserStartRuleName)>\n" + 652 " if ( r.tree!=null ) {\n" + 653 " System.out.println(((Tree)r.tree).toStringTree());\n" + 654 " ((CommonTree)r.tree).sanityCheckParentAndChildIndexes();\n" + 655 " }\n" + 656 " <else>\n" + 657 " CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree);\n" + 658 " nodes.setTokenStream(tokens);\n" + 659 " <treeParserName> walker = new <treeParserName>(nodes);\n" + 660 " walker.<treeParserStartRuleName>();\n" + 661 " <endif>\n" + 662 " }\n" + 663 "}" 664 ); 665 ST createParserST = 666 new ST( 667 " Profiler2 profiler = new Profiler2();\n"+ 668 " <parserName> parser = new <parserName>(tokens,profiler);\n" + 669 " profiler.setParser(parser);\n"); 670 if ( !debug ) { 671 createParserST = 672 new ST( 673 " <parserName> parser = new <parserName>(tokens);\n"); 674 } 675 outputFileST.add("createParser", createParserST); 676 outputFileST.add("parserName", parserName); 677 outputFileST.add("treeParserName", treeParserName); 678 outputFileST.add("lexerName", lexerName); 679 outputFileST.add("parserStartRuleName", parserStartRuleName); 680 outputFileST.add("treeParserStartRuleName", treeParserStartRuleName); 681 writeFile(tmpdir, "Test.java", outputFileST.render()); 682 } 683 684 /** Parser creates trees and so does the tree parser */ writeTreeAndTreeTestFile(String parserName, String treeParserName, String lexerName, String parserStartRuleName, String treeParserStartRuleName, boolean debug)685 protected void writeTreeAndTreeTestFile(String parserName, 686 String treeParserName, 687 String lexerName, 688 String parserStartRuleName, 689 String treeParserStartRuleName, 690 boolean debug) 691 { 692 ST outputFileST = new ST( 693 "import org.antlr.runtime.*;\n" + 694 "import org.antlr.runtime.tree.*;\n" + 695 "import org.antlr.runtime.debug.*;\n" + 696 "\n" + 697 "class Profiler2 extends Profiler {\n" + 698 " public void terminate() { ; }\n" + 699 "}\n"+ 700 "public class Test {\n" + 701 " public static void main(String[] args) throws Exception {\n" + 702 " CharStream input = new ANTLRFileStream(args[0]);\n" + 703 " <lexerName> lex = new <lexerName>(input);\n" + 704 " TokenRewriteStream tokens = new TokenRewriteStream(lex);\n" + 705 " <createParser>\n"+ 706 " <parserName>.<parserStartRuleName>_return r = parser.<parserStartRuleName>();\n" + 707 " ((CommonTree)r.tree).sanityCheckParentAndChildIndexes();\n" + 708 " CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree);\n" + 709 " nodes.setTokenStream(tokens);\n" + 710 " <treeParserName> walker = new <treeParserName>(nodes);\n" + 711 " <treeParserName>.<treeParserStartRuleName>_return r2 = walker.<treeParserStartRuleName>();\n" + 712 " CommonTree rt = ((CommonTree)r2.tree);\n" + 713 " if ( rt!=null ) System.out.println(((CommonTree)r2.tree).toStringTree());\n" + 714 " }\n" + 715 "}" 716 ); 717 ST createParserST = 718 new ST( 719 " Profiler2 profiler = new Profiler2();\n"+ 720 " <parserName> parser = new <parserName>(tokens,profiler);\n" + 721 " profiler.setParser(parser);\n"); 722 if ( !debug ) { 723 createParserST = 724 new ST( 725 " <parserName> parser = new <parserName>(tokens);\n"); 726 } 727 outputFileST.add("createParser", createParserST); 728 outputFileST.add("parserName", parserName); 729 outputFileST.add("treeParserName", treeParserName); 730 outputFileST.add("lexerName", lexerName); 731 outputFileST.add("parserStartRuleName", parserStartRuleName); 732 outputFileST.add("treeParserStartRuleName", treeParserStartRuleName); 733 writeFile(tmpdir, "Test.java", outputFileST.render()); 734 } 735 writeTemplateTestFile(String parserName, String lexerName, String parserStartRuleName, boolean debug)736 protected void writeTemplateTestFile(String parserName, 737 String lexerName, 738 String parserStartRuleName, 739 boolean debug) 740 { 741 ST outputFileST = new ST( 742 "import org.antlr.runtime.*;\n" + 743 "import org.antlr.stringtemplate.*;\n" + 744 "import org.antlr.stringtemplate.language.*;\n" + 745 "import org.antlr.runtime.debug.*;\n" + 746 "import java.io.*;\n" + 747 "\n" + 748 "class Profiler2 extends Profiler {\n" + 749 " public void terminate() { ; }\n" + 750 "}\n"+ 751 "public class Test {\n" + 752 " static String templates = \"group T; foo(x,y) ::= \\\"\\<x> \\<y>\\\"\";\n" + 753 " static StringTemplateGroup group ="+ 754 " new StringTemplateGroup(new StringReader(templates)," + 755 " AngleBracketTemplateLexer.class);"+ 756 " public static void main(String[] args) throws Exception {\n" + 757 " CharStream input = new ANTLRFileStream(args[0]);\n" + 758 " <lexerName> lex = new <lexerName>(input);\n" + 759 " CommonTokenStream tokens = new CommonTokenStream(lex);\n" + 760 " <createParser>\n"+ 761 " parser.setTemplateLib(group);\n"+ 762 " <parserName>.<parserStartRuleName>_return r = parser.<parserStartRuleName>();\n" + 763 " if ( r.st!=null )\n" + 764 " System.out.print(r.st.toString());\n" + 765 " else\n" + 766 " System.out.print(\"\");\n" + 767 " }\n" + 768 "}" 769 ); 770 ST createParserST = 771 new ST( 772 " Profiler2 profiler = new Profiler2();\n"+ 773 " <parserName> parser = new <parserName>(tokens,profiler);\n" + 774 " profiler.setParser(parser);\n"); 775 if ( !debug ) { 776 createParserST = 777 new ST( 778 " <parserName> parser = new <parserName>(tokens);\n"); 779 } 780 outputFileST.add("createParser", createParserST); 781 outputFileST.add("parserName", parserName); 782 outputFileST.add("lexerName", lexerName); 783 outputFileST.add("parserStartRuleName", parserStartRuleName); 784 writeFile(tmpdir, "Test.java", outputFileST.render()); 785 } 786 eraseFiles(final String filesEndingWith)787 protected void eraseFiles(final String filesEndingWith) { 788 File tmpdirF = new File(tmpdir); 789 String[] files = tmpdirF.list(); 790 for(int i = 0; files!=null && i < files.length; i++) { 791 if ( files[i].endsWith(filesEndingWith) ) { 792 new File(tmpdir+"/"+files[i]).delete(); 793 } 794 } 795 } 796 eraseFiles()797 protected void eraseFiles() { 798 File tmpdirF = new File(tmpdir); 799 String[] files = tmpdirF.list(); 800 for(int i = 0; files!=null && i < files.length; i++) { 801 new File(tmpdir+"/"+files[i]).delete(); 802 } 803 } 804 eraseTempDir()805 protected void eraseTempDir() { 806 File tmpdirF = new File(tmpdir); 807 if ( tmpdirF.exists() ) { 808 eraseFiles(); 809 tmpdirF.delete(); 810 } 811 } 812 getFirstLineOfException()813 public String getFirstLineOfException() { 814 if ( this.stderrDuringParse ==null ) { 815 return null; 816 } 817 String[] lines = this.stderrDuringParse.split("\n"); 818 String prefix="Exception in thread \"main\" "; 819 return lines[0].substring(prefix.length(),lines[0].length()); 820 } 821 realElements(List elements)822 public List realElements(List elements) { 823 List n = new ArrayList(); 824 for (int i = Label.NUM_FAUX_LABELS+Label.MIN_TOKEN_TYPE - 1; i < elements.size(); i++) { 825 Object o = (Object) elements.get(i); 826 if ( o!=null ) { 827 n.add(o); 828 } 829 } 830 return n; 831 } 832 realElements(Map<String, Integer> elements)833 public List<String> realElements(Map<String, Integer> elements) { 834 List n = new ArrayList(); 835 Iterator iterator = elements.keySet().iterator(); 836 while (iterator.hasNext()) { 837 String tokenID = (String) iterator.next(); 838 if ( elements.get(tokenID) >= Label.MIN_TOKEN_TYPE ) { 839 n.add(tokenID+"="+elements.get(tokenID)); 840 } 841 } 842 Collections.sort(n); 843 return n; 844 } 845 sortLinesInString(String s)846 public String sortLinesInString(String s) { 847 String lines[] = s.split("\n"); 848 Arrays.sort(lines); 849 List<String> linesL = Arrays.asList(lines); 850 StringBuffer buf = new StringBuffer(); 851 for (String l : linesL) { 852 buf.append(l); 853 buf.append('\n'); 854 } 855 return buf.toString(); 856 } 857 858 /** 859 * When looking at a result set that consists of a Map/HashTable 860 * we cannot rely on the output order, as the hashing algorithm or other aspects 861 * of the implementation may be different on differnt JDKs or platforms. Hence 862 * we take the Map, convert the keys to a List, sort them and Stringify the Map, which is a 863 * bit of a hack, but guarantees that we get the same order on all systems. We assume that 864 * the keys are strings. 865 * 866 * @param m The Map that contains keys we wish to return in sorted order 867 * @return A string that represents all the keys in sorted order. 868 */ sortMapToString(Map m)869 public String sortMapToString(Map m) { 870 871 System.out.println("Map toString looks like: " + m.toString()); 872 // Pass in crap, and get nothing back 873 // 874 if (m == null) { 875 return null; 876 } 877 878 // Sort the keys in the Map 879 // 880 TreeMap nset = new TreeMap(m); 881 882 System.out.println("Tree map looks like: " + nset.toString()); 883 return nset.toString(); 884 } 885 886 // override to track errors 887 assertEquals(String msg, Object a, Object b)888 public void assertEquals(String msg, Object a, Object b) { try {Assert.assertEquals(msg,a,b);} catch (Error e) {lastTestFailed=true; throw e;} } assertEquals(Object a, Object b)889 public void assertEquals(Object a, Object b) { try {Assert.assertEquals(a,b);} catch (Error e) {lastTestFailed=true; throw e;} } assertEquals(String msg, long a, long b)890 public void assertEquals(String msg, long a, long b) { try {Assert.assertEquals(msg,a,b);} catch (Error e) {lastTestFailed=true; throw e;} } assertEquals(long a, long b)891 public void assertEquals(long a, long b) { try {Assert.assertEquals(a,b);} catch (Error e) {lastTestFailed=true; throw e;} } 892 assertTrue(String msg, boolean b)893 public void assertTrue(String msg, boolean b) { try {Assert.assertTrue(msg,b);} catch (Error e) {lastTestFailed=true; throw e;} } assertTrue(boolean b)894 public void assertTrue(boolean b) { try {Assert.assertTrue(b);} catch (Error e) {lastTestFailed=true; throw e;} } 895 assertFalse(String msg, boolean b)896 public void assertFalse(String msg, boolean b) { try {Assert.assertFalse(msg,b);} catch (Error e) {lastTestFailed=true; throw e;} } assertFalse(boolean b)897 public void assertFalse(boolean b) { try {Assert.assertFalse(b);} catch (Error e) {lastTestFailed=true; throw e;} } 898 assertNotNull(String msg, Object p)899 public void assertNotNull(String msg, Object p) { try {Assert.assertNotNull(msg, p);} catch (Error e) {lastTestFailed=true; throw e;} } assertNotNull(Object p)900 public void assertNotNull(Object p) { try {Assert.assertNotNull(p);} catch (Error e) {lastTestFailed=true; throw e;} } 901 assertNull(String msg, Object p)902 public void assertNull(String msg, Object p) { try {Assert.assertNull(msg, p);} catch (Error e) {lastTestFailed=true; throw e;} } assertNull(Object p)903 public void assertNull(Object p) { try {Assert.assertNull(p);} catch (Error e) {lastTestFailed=true; throw e;} } 904 } 905