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 import org.antlr.Tool; 31 import org.antlr.codegen.CodeGenerator; 32 import org.antlr.grammar.v3.ANTLRParser; 33 import org.antlr.grammar.v3.ActionTranslator; 34 import org.antlr.runtime.CommonToken; 35 import org.stringtemplate.v4.ST; 36 import org.stringtemplate.v4.STGroup; 37 import org.antlr.tool.*; 38 import org.junit.Test; 39 40 import java.io.StringReader; 41 import java.util.ArrayList; 42 import java.util.List; 43 44 import static org.junit.Assert.*; 45 46 /** Check the $x, $x.y attributes. For checking the actual 47 * translation, assume the Java target. This is still a great test 48 * for the semantics of the $x.y stuff regardless of the target. 49 */ 50 public class TestAttributes extends BaseTest { 51 52 /** Public default constructor used by TestRig */ TestAttributes()53 public TestAttributes() { 54 } 55 testEscapedLessThanInAction()56 @Test public void testEscapedLessThanInAction() throws Exception { 57 Grammar g = new Grammar(); 58 Tool antlr = newTool(); 59 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 60 String action = "i<3; '<xmltag>'"; 61 ActionTranslator translator = new ActionTranslator(generator,"a", 62 new CommonToken(ANTLRParser.ACTION,action),0); 63 String expecting = action; 64 String rawTranslation = 65 translator.translate(); 66 STGroup templates = 67 new STGroup(); 68 ST actionST = new ST(templates, "<action>"); 69 actionST.add("action", rawTranslation); 70 String found = actionST.render(); 71 assertEquals(expecting, found); 72 } 73 testEscaped$InAction()74 @Test public void testEscaped$InAction() throws Exception { 75 String action = "int \\$n; \"\\$in string\\$\""; 76 String expecting = "int $n; \"$in string$\""; 77 Grammar g = new Grammar( 78 "parser grammar t;\n"+ 79 "@members {"+action+"}\n"+ 80 "a[User u, int i]\n" + 81 " : {"+action+"}\n" + 82 " ;"); 83 Tool antlr = newTool(); 84 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 85 g.setCodeGenerator(generator); 86 generator.genRecognizer(); // forces load of templates 87 ActionTranslator translator = 88 new ActionTranslator(generator, 89 "a", 90 new CommonToken(ANTLRParser.ACTION,action),0); 91 String found = translator.translate(); assertEquals(expecting, found); 92 } 93 testArguments()94 @Test public void testArguments() throws Exception { 95 String action = "$i; $i.x; $u; $u.x"; 96 String expecting = "i; i.x; u; u.x"; 97 98 ErrorQueue equeue = new ErrorQueue(); 99 ErrorManager.setErrorListener(equeue); 100 Grammar g = new Grammar( 101 "parser grammar t;\n"+ 102 "a[User u, int i]\n" + 103 " : {"+action+"}\n" + 104 " ;"); 105 Tool antlr = newTool(); 106 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 107 g.setCodeGenerator(generator); 108 generator.genRecognizer(); // forces load of templates 109 ActionTranslator translator = new ActionTranslator(generator,"a", 110 new CommonToken(ANTLRParser.ACTION,action),1); 111 String found = translator.translate(); assertEquals(expecting, found); 112 113 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 114 } 115 testComplicatedArgParsing()116 @Test public void testComplicatedArgParsing() throws Exception { 117 String action = "x, (*a).foo(21,33), 3.2+1, '\\n', "+ 118 "\"a,oo\\nick\", {bl, \"fdkj\"eck}"; 119 String expecting = "x, (*a).foo(21,33), 3.2+1, '\\n', \"a,oo\\nick\", {bl, \"fdkj\"eck}"; 120 121 ErrorQueue equeue = new ErrorQueue(); 122 ErrorManager.setErrorListener(equeue); 123 124 // now check in actual grammar. 125 Grammar g = new Grammar( 126 "parser grammar t;\n"+ 127 "a[User u, int i]\n" + 128 " : A a["+action+"] B\n" + 129 " ;"); 130 Tool antlr = newTool(); 131 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 132 g.setCodeGenerator(generator); 133 generator.genRecognizer(); // forces load of templates 134 ActionTranslator translator = new ActionTranslator(generator,"a", 135 new CommonToken(ANTLRParser.ACTION,action),1); 136 String rawTranslation = translator.translate(); 137 assertEquals(expecting, rawTranslation); 138 139 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 140 } 141 testBracketArgParsing()142 @Test public void testBracketArgParsing() throws Exception { 143 ErrorQueue equeue = new ErrorQueue(); 144 ErrorManager.setErrorListener(equeue); 145 146 // now check in actual grammar. 147 Grammar g = new Grammar( 148 "parser grammar t;\n"+ 149 "a[String[\\] ick, int i]\n" + 150 " : A \n"+ 151 " ;"); 152 Tool antlr = newTool(); 153 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 154 g.setCodeGenerator(generator); 155 generator.genRecognizer(); // forces load of templates 156 Rule r = g.getRule("a"); 157 AttributeScope parameters = r.parameterScope; 158 List<Attribute> attrs = parameters.getAttributes(); 159 assertEquals("attribute mismatch","String[] ick",attrs.get(0).decl.toString()); 160 assertEquals("parameter name mismatch","ick",attrs.get(0).name); 161 assertEquals("declarator mismatch", "String[]", attrs.get(0).type); 162 163 assertEquals("attribute mismatch","int i",attrs.get(1).decl.toString()); 164 assertEquals("parameter name mismatch","i",attrs.get(1).name); 165 assertEquals("declarator mismatch", "int", attrs.get(1).type); 166 167 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 168 } 169 testStringArgParsing()170 @Test public void testStringArgParsing() throws Exception { 171 String action = "34, '{', \"it's<\", '\"', \"\\\"\", 19"; 172 String expecting = "34, '{', \"it's<\", '\"', \"\\\"\", 19"; 173 174 ErrorQueue equeue = new ErrorQueue(); 175 ErrorManager.setErrorListener(equeue); 176 177 // now check in actual grammar. 178 Grammar g = new Grammar( 179 "parser grammar t;\n"+ 180 "a[User u, int i]\n" + 181 " : A a["+action+"] B\n" + 182 " ;"); 183 Tool antlr = newTool(); 184 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 185 g.setCodeGenerator(generator); 186 generator.genRecognizer(); // forces load of templates 187 ActionTranslator translator = new ActionTranslator(generator,"a", 188 new CommonToken(ANTLRParser.ACTION,action),1); 189 String rawTranslation = translator.translate(); 190 assertEquals(expecting, rawTranslation); 191 192 List<String> expectArgs = new ArrayList<String>() { 193 {add("34");} 194 {add("'{'");} 195 {add("\"it's<\"");} 196 {add("'\"'");} 197 {add("\"\\\"\"");} // that's "\"" 198 {add("19");} 199 }; 200 List<String> actualArgs = CodeGenerator.getListOfArgumentsFromAction(action, ','); 201 assertEquals("args mismatch", expectArgs, actualArgs); 202 203 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 204 } 205 testComplicatedSingleArgParsing()206 @Test public void testComplicatedSingleArgParsing() throws Exception { 207 String action = "(*a).foo(21,33,\",\")"; 208 String expecting = "(*a).foo(21,33,\",\")"; 209 210 ErrorQueue equeue = new ErrorQueue(); 211 ErrorManager.setErrorListener(equeue); 212 213 // now check in actual grammar. 214 Grammar g = new Grammar( 215 "parser grammar t;\n"+ 216 "a[User u, int i]\n" + 217 " : A a["+action+"] B\n" + 218 " ;"); 219 Tool antlr = newTool(); 220 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 221 g.setCodeGenerator(generator); 222 generator.genRecognizer(); // forces load of templates 223 ActionTranslator translator = new ActionTranslator(generator,"a", 224 new CommonToken(ANTLRParser.ACTION,action),1); 225 String rawTranslation = translator.translate(); 226 assertEquals(expecting, rawTranslation); 227 228 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 229 } 230 testArgWithLT()231 @Test public void testArgWithLT() throws Exception { 232 String action = "34<50"; 233 String expecting = "34<50"; 234 235 ErrorQueue equeue = new ErrorQueue(); 236 ErrorManager.setErrorListener(equeue); 237 238 // now check in actual grammar. 239 Grammar g = new Grammar( 240 "parser grammar t;\n"+ 241 "a[boolean b]\n" + 242 " : A a["+action+"] B\n" + 243 " ;"); 244 Tool antlr = newTool(); 245 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 246 g.setCodeGenerator(generator); 247 generator.genRecognizer(); // forces load of templates 248 ActionTranslator translator = new ActionTranslator(generator,"a", 249 new CommonToken(ANTLRParser.ACTION,action),1); 250 String rawTranslation = 251 translator.translate(); 252 assertEquals(expecting, rawTranslation); 253 254 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 255 } 256 testGenericsAsArgumentDefinition()257 @Test public void testGenericsAsArgumentDefinition() throws Exception { 258 String action = "$foo.get(\"ick\");"; 259 String expecting = "foo.get(\"ick\");"; 260 261 ErrorQueue equeue = new ErrorQueue(); 262 ErrorManager.setErrorListener(equeue); 263 String grammar = 264 "parser grammar T;\n"+ 265 "a[HashMap<String,String> foo]\n" + 266 " : {"+action+"}\n" + 267 " ;"; 268 Grammar g = new Grammar(grammar); 269 Rule ra = g.getRule("a"); 270 List<Attribute> attrs = ra.parameterScope.getAttributes(); 271 assertEquals("attribute mismatch","HashMap<String,String> foo",attrs.get(0).decl.toString()); 272 assertEquals("parameter name mismatch","foo",attrs.get(0).name); 273 assertEquals("declarator mismatch", "HashMap<String,String>", attrs.get(0).type); 274 275 Tool antlr = newTool(); 276 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 277 g.setCodeGenerator(generator); 278 generator.genRecognizer(); // forces load of templates 279 ActionTranslator translator = new ActionTranslator(generator,"a", 280 new CommonToken(ANTLRParser.ACTION,action),1); 281 String found = translator.translate(); assertEquals(expecting, found); 282 283 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 284 } 285 testGenericsAsArgumentDefinition2()286 @Test public void testGenericsAsArgumentDefinition2() throws Exception { 287 String action = "$foo.get(\"ick\"); x=3;"; 288 String expecting = "foo.get(\"ick\"); x=3;"; 289 290 ErrorQueue equeue = new ErrorQueue(); 291 ErrorManager.setErrorListener(equeue); 292 String grammar = 293 "parser grammar T;\n"+ 294 "a[HashMap<String,String> foo, int x, List<String> duh]\n" + 295 " : {"+action+"}\n" + 296 " ;"; 297 Grammar g = new Grammar(grammar); 298 Rule ra = g.getRule("a"); 299 List<Attribute> attrs = ra.parameterScope.getAttributes(); 300 301 assertEquals("attribute mismatch","HashMap<String,String> foo",attrs.get(0).decl.toString().trim()); 302 assertEquals("parameter name mismatch","foo",attrs.get(0).name); 303 assertEquals("declarator mismatch", "HashMap<String,String>", attrs.get(0).type); 304 305 assertEquals("attribute mismatch","int x",attrs.get(1).decl.toString().trim()); 306 assertEquals("parameter name mismatch","x",attrs.get(1).name); 307 assertEquals("declarator mismatch", "int", attrs.get(1).type); 308 309 assertEquals("attribute mismatch","List<String> duh",attrs.get(2).decl.toString().trim()); 310 assertEquals("parameter name mismatch","duh",attrs.get(2).name); 311 assertEquals("declarator mismatch", "List<String>", attrs.get(2).type); 312 313 Tool antlr = newTool(); 314 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 315 g.setCodeGenerator(generator); 316 generator.genRecognizer(); // forces load of templates 317 ActionTranslator translator = new ActionTranslator(generator,"a", 318 new CommonToken(ANTLRParser.ACTION,action),1); 319 String found = translator.translate(); assertEquals(expecting, found); 320 321 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 322 } 323 testGenericsAsReturnValue()324 @Test public void testGenericsAsReturnValue() throws Exception { 325 ErrorQueue equeue = new ErrorQueue(); 326 ErrorManager.setErrorListener(equeue); 327 String grammar = 328 "parser grammar T;\n"+ 329 "a returns [HashMap<String,String> foo] : ;\n"; 330 Grammar g = new Grammar(grammar); 331 Rule ra = g.getRule("a"); 332 List<Attribute> attrs = ra.returnScope.getAttributes(); 333 assertEquals("attribute mismatch","HashMap<String,String> foo",attrs.get(0).decl.toString()); 334 assertEquals("parameter name mismatch","foo",attrs.get(0).name); 335 assertEquals("declarator mismatch", "HashMap<String,String>", attrs.get(0).type); 336 337 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 338 } 339 testComplicatedArgParsingWithTranslation()340 @Test public void testComplicatedArgParsingWithTranslation() throws Exception { 341 String action = "x, $A.text+\"3242\", (*$A).foo(21,33), 3.2+1, '\\n', "+ 342 "\"a,oo\\nick\", {bl, \"fdkj\"eck}"; 343 String expecting = "x, (A1!=null?A1.getText():null)+\"3242\", (*A1).foo(21,33), 3.2+1, '\\n', \"a,oo\\nick\", {bl, \"fdkj\"eck}"; 344 345 ErrorQueue equeue = new ErrorQueue(); 346 ErrorManager.setErrorListener(equeue); 347 348 // now check in actual grammar. 349 Grammar g = new Grammar( 350 "parser grammar t;\n"+ 351 "a[User u, int i]\n" + 352 " : A a["+action+"] B\n" + 353 " ;"); 354 Tool antlr = newTool(); 355 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 356 g.setCodeGenerator(generator); 357 generator.genRecognizer(); // forces load of templates 358 ActionTranslator translator = new ActionTranslator(generator,"a", 359 new CommonToken(ANTLRParser.ACTION,action),1); 360 String found = translator.translate(); assertEquals(expecting, found); 361 362 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 363 } 364 365 /** $x.start refs are checked during translation not before so ANTLR misses 366 the fact that rule r has refs to predefined attributes if the ref is after 367 the def of the method or self-referential. Actually would be ok if I didn't 368 convert actions to strings; keep as templates. 369 June 9, 2006: made action translation leave templates not strings 370 */ testRefToReturnValueBeforeRefToPredefinedAttr()371 @Test public void testRefToReturnValueBeforeRefToPredefinedAttr() throws Exception { 372 String action = "$x.foo"; 373 String expecting = "(x!=null?((t.b_return)x).foo:0)"; 374 375 ErrorQueue equeue = new ErrorQueue(); 376 ErrorManager.setErrorListener(equeue); 377 Grammar g = new Grammar( 378 "parser grammar t;\n"+ 379 "a : x=b {"+action+"} ;\n" + 380 "b returns [int foo] : B {$b.start} ;\n"); 381 Tool antlr = newTool(); 382 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 383 g.setCodeGenerator(generator); 384 generator.genRecognizer(); // forces load of templates 385 ActionTranslator translator = new ActionTranslator(generator,"a", 386 new CommonToken(ANTLRParser.ACTION,action),1); 387 String found = translator.translate(); 388 assertEquals(expecting, found); 389 390 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 391 } 392 testRuleLabelBeforeRefToPredefinedAttr()393 @Test public void testRuleLabelBeforeRefToPredefinedAttr() throws Exception { 394 // As of Mar 2007, I'm removing unused labels. Unfortunately, 395 // the action is not seen until code gen. Can't see $x.text 396 // before stripping unused labels. We really need to translate 397 // actions first so code gen logic can use info. 398 String action = "$x.text"; 399 String expecting = "(x!=null?input.toString(x.start,x.stop):null)"; 400 401 ErrorQueue equeue = new ErrorQueue(); 402 ErrorManager.setErrorListener(equeue); 403 Grammar g = new Grammar( 404 "parser grammar t;\n"+ 405 "a : x=b {###"+action+"!!!} ;\n" + 406 "b : B ;\n"); 407 Tool antlr = newTool(); 408 409 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 410 g.setCodeGenerator(generator); 411 generator.genRecognizer(); // codegen phase sets some vars we need 412 ST codeST = generator.getRecognizerST(); 413 String code = codeST.render(); 414 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 415 assertEquals(expecting, found); 416 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 417 } 418 testInvalidArguments()419 @Test public void testInvalidArguments() throws Exception { 420 String action = "$x"; 421 String expecting = action; 422 423 ErrorQueue equeue = new ErrorQueue(); 424 ErrorManager.setErrorListener(equeue); 425 Grammar g = new Grammar( 426 "parser grammar t;\n"+ 427 "a[User u, int i]\n" + 428 " : {"+action+"}\n" + 429 " ;"); 430 Tool antlr = newTool(); 431 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 432 ActionTranslator translator = new ActionTranslator(generator, 433 "a", 434 new CommonToken(ANTLRParser.ACTION,action),1); 435 String found = translator.translate(); 436 assertEquals(expecting, found); 437 438 int expectedMsgID = ErrorManager.MSG_UNKNOWN_SIMPLE_ATTRIBUTE; 439 Object expectedArg = "x"; 440 GrammarSemanticsMessage expectedMessage = 441 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 442 checkError(equeue, expectedMessage); 443 } 444 testReturnValue()445 @Test public void testReturnValue() throws Exception { 446 String action = "$x.i"; 447 String expecting = "x"; 448 449 ErrorQueue equeue = new ErrorQueue(); 450 ErrorManager.setErrorListener(equeue); 451 Grammar g = new Grammar( 452 "grammar t;\n"+ 453 "a returns [int i]\n" + 454 " : 'a'\n" + 455 " ;\n" + 456 "b : x=a {"+action+"} ;\n"); 457 Tool antlr = newTool(); 458 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 459 g.setCodeGenerator(generator); 460 generator.genRecognizer(); // forces load of templates 461 ActionTranslator translator = 462 new ActionTranslator(generator, 463 "b", 464 new CommonToken(ANTLRParser.ACTION,action),1); 465 String found = translator.translate(); 466 assertEquals(expecting, found); 467 468 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 469 } 470 testActionNotMovedToSynPred()471 @Test public void testActionNotMovedToSynPred() throws Exception { 472 String action = "$b = true;"; 473 String expecting = "retval.b = true;"; 474 475 ErrorQueue equeue = new ErrorQueue(); 476 ErrorManager.setErrorListener(equeue); 477 Grammar g = new Grammar( 478 "grammar t;\n"+ 479 "options {output=AST;}\n" + // push b into retval struct 480 "a returns [boolean b]\n" + 481 "options {backtrack=true;}\n" + 482 " : 'a' {"+action+"}\n" + 483 " | 'a'\n" + 484 " ;\n"); 485 Tool antlr = newTool(); 486 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 487 g.setCodeGenerator(generator); 488 generator.genRecognizer(); // forces load of templates 489 ActionTranslator translator = 490 new ActionTranslator(generator, 491 "a", 492 new CommonToken(ANTLRParser.ACTION,action),1); 493 String found = translator.translate(); 494 assertEquals(expecting, found); 495 496 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 497 } 498 testReturnValueWithNumber()499 @Test public void testReturnValueWithNumber() throws Exception { 500 String action = "$x.i1"; 501 String expecting = "x"; 502 503 ErrorQueue equeue = new ErrorQueue(); 504 ErrorManager.setErrorListener(equeue); 505 Grammar g = new Grammar( 506 "grammar t;\n"+ 507 "a returns [int i1]\n" + 508 " : 'a'\n" + 509 " ;\n" + 510 "b : x=a {"+action+"} ;\n"); 511 Tool antlr = newTool(); 512 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 513 g.setCodeGenerator(generator); 514 generator.genRecognizer(); // forces load of templates 515 ActionTranslator translator = 516 new ActionTranslator(generator, 517 "b", 518 new CommonToken(ANTLRParser.ACTION,action),1); 519 String found = translator.translate(); 520 assertEquals(expecting, found); 521 522 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 523 } 524 testReturnValues()525 @Test public void testReturnValues() throws Exception { 526 String action = "$i; $i.x; $u; $u.x"; 527 String expecting = "retval.i; retval.i.x; retval.u; retval.u.x"; 528 529 ErrorQueue equeue = new ErrorQueue(); 530 ErrorManager.setErrorListener(equeue); 531 Grammar g = new Grammar( 532 "parser grammar t;\n"+ 533 "a returns [User u, int i]\n" + 534 " : {"+action+"}\n" + 535 " ;"); 536 Tool antlr = newTool(); 537 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 538 g.setCodeGenerator(generator); 539 generator.genRecognizer(); // forces load of templates 540 ActionTranslator translator = new ActionTranslator(generator,"a", 541 new CommonToken(ANTLRParser.ACTION,action),1); 542 String found = translator.translate(); 543 assertEquals(expecting, found); 544 545 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 546 } 547 548 /* regression test for ANTLR-46 */ testReturnWithMultipleRuleRefs()549 @Test public void testReturnWithMultipleRuleRefs() throws Exception { 550 String action1 = "$obj = $rule2.obj;"; 551 String action2 = "$obj = $rule3.obj;"; 552 String expecting1 = "obj = rule21;"; 553 String expecting2 = "obj = rule32;"; 554 555 ErrorQueue equeue = new ErrorQueue(); 556 ErrorManager.setErrorListener(equeue); 557 Grammar g = new Grammar( 558 "grammar t;\n" + 559 "rule1 returns [ Object obj ]\n" + 560 ": rule2 { "+action1+" }\n" + 561 "| rule3 { "+action2+" }\n" + 562 ";\n"+ 563 "rule2 returns [ Object obj ]\n"+ 564 ": foo='foo' { $obj = $foo.text; }\n"+ 565 ";\n"+ 566 "rule3 returns [ Object obj ]\n"+ 567 ": bar='bar' { $obj = $bar.text; }\n"+ 568 ";"); 569 Tool antlr = newTool(); 570 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 571 g.setCodeGenerator(generator); 572 generator.genRecognizer(); // forces load of templates 573 int i = 0; 574 String action = action1; 575 String expecting = expecting1; 576 do { 577 ActionTranslator translator = new ActionTranslator(generator,"rule1", 578 new CommonToken(ANTLRParser.ACTION,action),i+1); 579 String found = translator.translate(); 580 assertEquals(expecting, found); 581 action = action2; 582 expecting = expecting2; 583 } while (i++ < 1); 584 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 585 } 586 testInvalidReturnValues()587 @Test public void testInvalidReturnValues() throws Exception { 588 String action = "$x"; 589 String expecting = action; 590 591 ErrorQueue equeue = new ErrorQueue(); 592 ErrorManager.setErrorListener(equeue); 593 Grammar g = new Grammar( 594 "parser grammar t;\n"+ 595 "a returns [User u, int i]\n" + 596 " : {"+action+"}\n" + 597 " ;"); 598 Tool antlr = newTool(); 599 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 600 ActionTranslator translator = new ActionTranslator(generator,"a", 601 new CommonToken(ANTLRParser.ACTION,action),1); 602 String found = translator.translate(); 603 assertEquals(expecting, found); 604 605 int expectedMsgID = ErrorManager.MSG_UNKNOWN_SIMPLE_ATTRIBUTE; 606 Object expectedArg = "x"; 607 GrammarSemanticsMessage expectedMessage = 608 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 609 checkError(equeue, expectedMessage); 610 } 611 testTokenLabels()612 @Test public void testTokenLabels() throws Exception { 613 String action = "$id; $f; $id.text; $id.getText(); $id.dork " + 614 "$id.type; $id.line; $id.pos; " + 615 "$id.channel; $id.index;"; 616 String expecting = "id; f; (id!=null?id.getText():null); id.getText(); id.dork (id!=null?id.getType():0); (id!=null?id.getLine():0); (id!=null?id.getCharPositionInLine():0); (id!=null?id.getChannel():0); (id!=null?id.getTokenIndex():0);"; 617 618 ErrorQueue equeue = new ErrorQueue(); 619 ErrorManager.setErrorListener(equeue); 620 Grammar g = new Grammar( 621 "parser grammar t;\n"+ 622 "a : id=ID f=FLOAT {"+action+"}\n" + 623 " ;"); 624 Tool antlr = newTool(); 625 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 626 g.setCodeGenerator(generator); 627 generator.genRecognizer(); // forces load of templates 628 ActionTranslator translator = new ActionTranslator(generator,"a", 629 new CommonToken(ANTLRParser.ACTION,action),1); 630 String found = translator.translate(); 631 assertEquals(expecting, found); 632 633 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 634 } 635 testRuleLabels()636 @Test public void testRuleLabels() throws Exception { 637 String action = "$r.x; $r.start;\n $r.stop;\n $r.tree; $a.x; $a.stop;"; 638 String expecting = "(r!=null?((t.a_return)r).x:0); (r!=null?(r.start):null);" + newline + 639 "\t\t\t (r!=null?(r.stop):null);" + newline + 640 "\t\t\t (r!=null?((Object)r.getTree()):null); (r!=null?((t.a_return)r).x:0); (r!=null?(r.stop):null);"; 641 642 ErrorQueue equeue = new ErrorQueue(); 643 ErrorManager.setErrorListener(equeue); 644 Grammar g = new Grammar( 645 "parser grammar t;\n"+ 646 "a returns [int x]\n" + 647 " :\n" + 648 " ;\n"+ 649 "b : r=a {###"+action+"!!!}\n" + 650 " ;"); 651 Tool antlr = newTool(); 652 antlr.setOutputDirectory(null); // write to /dev/null 653 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 654 g.setCodeGenerator(generator); 655 generator.genRecognizer(); // codegen phase sets some vars we need 656 ST codeST = generator.getRecognizerST(); 657 String code = codeST.render(); 658 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 659 assertEquals(expecting, found); 660 661 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 662 } 663 testAmbiguRuleRef()664 @Test public void testAmbiguRuleRef() throws Exception { 665 ErrorQueue equeue = new ErrorQueue(); 666 ErrorManager.setErrorListener(equeue); 667 Grammar g = new Grammar( 668 "parser grammar t;\n"+ 669 "a : A a {$a.text} | B ;"); 670 Tool antlr = newTool(); 671 antlr.setOutputDirectory(null); // write to /dev/null 672 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 673 g.setCodeGenerator(generator); 674 generator.genRecognizer(); 675 676 // error(132): <string>:2:9: reference $a is ambiguous; rule a is enclosing rule and referenced in the production 677 assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size()); 678 } 679 testRuleLabelsWithSpecialToken()680 @Test public void testRuleLabelsWithSpecialToken() throws Exception { 681 String action = "$r.x; $r.start; $r.stop; $r.tree; $a.x; $a.stop;"; 682 String expecting = "(r!=null?((t.a_return)r).x:0); (r!=null?((MYTOKEN)r.start):null); (r!=null?((MYTOKEN)r.stop):null); (r!=null?((Object)r.getTree()):null); (r!=null?((t.a_return)r).x:0); (r!=null?((MYTOKEN)r.stop):null);"; 683 684 ErrorQueue equeue = new ErrorQueue(); 685 ErrorManager.setErrorListener(equeue); 686 Grammar g = new Grammar( 687 "parser grammar t;\n"+ 688 "options {TokenLabelType=MYTOKEN;}\n"+ 689 "a returns [int x]\n" + 690 " :\n" + 691 " ;\n"+ 692 "b : r=a {###"+action+"!!!}\n" + 693 " ;"); 694 Tool antlr = newTool(); 695 antlr.setOutputDirectory(null); // write to /dev/null 696 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 697 g.setCodeGenerator(generator); 698 generator.genRecognizer(); // codegen phase sets some vars we need 699 700 ST codeST = generator.getRecognizerST(); 701 String code = codeST.render(); 702 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 703 assertEquals(expecting, found); 704 705 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 706 } 707 testForwardRefRuleLabels()708 @Test public void testForwardRefRuleLabels() throws Exception { 709 String action = "$r.x; $r.start; $r.stop; $r.tree; $a.x; $a.tree;"; 710 String expecting = "(r!=null?((t.a_return)r).x:0); (r!=null?(r.start):null); (r!=null?(r.stop):null); (r!=null?((Object)r.getTree()):null); (r!=null?((t.a_return)r).x:0); (r!=null?((Object)r.getTree()):null);"; 711 712 ErrorQueue equeue = new ErrorQueue(); 713 ErrorManager.setErrorListener(equeue); 714 Grammar g = new Grammar( 715 "parser grammar t;\n"+ 716 "b : r=a {###"+action+"!!!}\n" + 717 " ;\n" + 718 "a returns [int x]\n" + 719 " : ;\n"); 720 Tool antlr = newTool(); 721 antlr.setOutputDirectory(null); // write to /dev/null 722 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 723 g.setCodeGenerator(generator); 724 generator.genRecognizer(); // codegen phase sets some vars we need 725 726 ST codeST = generator.getRecognizerST(); 727 String code = codeST.render(); 728 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 729 assertEquals(expecting, found); 730 731 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 732 } 733 testInvalidRuleLabelAccessesParameter()734 @Test public void testInvalidRuleLabelAccessesParameter() throws Exception { 735 String action = "$r.z"; 736 String expecting = action; 737 738 ErrorQueue equeue = new ErrorQueue(); 739 ErrorManager.setErrorListener(equeue); 740 Grammar g = new Grammar( 741 "parser grammar t;\n"+ 742 "a[int z] returns [int x]\n" + 743 " :\n" + 744 " ;\n"+ 745 "b : r=a[3] {"+action+"}\n" + 746 " ;"); 747 Tool antlr = newTool(); 748 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 749 ActionTranslator translator = new ActionTranslator(generator, "b", 750 new CommonToken(ANTLRParser.ACTION,action),1); 751 String found = translator.translate(); assertEquals(expecting, found); 752 753 int expectedMsgID = ErrorManager.MSG_INVALID_RULE_PARAMETER_REF; 754 Object expectedArg = "a"; 755 Object expectedArg2 = "z"; 756 GrammarSemanticsMessage expectedMessage = 757 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 758 checkError(equeue, expectedMessage); 759 } 760 testInvalidRuleLabelAccessesScopeAttribute()761 @Test public void testInvalidRuleLabelAccessesScopeAttribute() throws Exception { 762 String action = "$r.n"; 763 String expecting = action; 764 765 ErrorQueue equeue = new ErrorQueue(); 766 ErrorManager.setErrorListener(equeue); 767 Grammar g = new Grammar( 768 "parser grammar t;\n"+ 769 "a\n" + 770 "scope { int n; }\n" + 771 " :\n" + 772 " ;\n"+ 773 "b : r=a[3] {"+action+"}\n" + 774 " ;"); 775 Tool antlr = newTool(); 776 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 777 ActionTranslator translator = new ActionTranslator(generator, "b", 778 new CommonToken(ANTLRParser.ACTION,action),1); 779 String found = translator.translate(); 780 assertEquals(expecting, found); 781 782 int expectedMsgID = ErrorManager.MSG_INVALID_RULE_SCOPE_ATTRIBUTE_REF; 783 Object expectedArg = "a"; 784 Object expectedArg2 = "n"; 785 GrammarSemanticsMessage expectedMessage = 786 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 787 checkError(equeue, expectedMessage); 788 } 789 testInvalidRuleAttribute()790 @Test public void testInvalidRuleAttribute() throws Exception { 791 String action = "$r.blort"; 792 String expecting = action; 793 794 ErrorQueue equeue = new ErrorQueue(); 795 ErrorManager.setErrorListener(equeue); 796 Grammar g = new Grammar( 797 "parser grammar t;\n"+ 798 "a[int z] returns [int x]\n" + 799 " :\n" + 800 " ;\n"+ 801 "b : r=a[3] {"+action+"}\n" + 802 " ;"); 803 Tool antlr = newTool(); 804 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 805 ActionTranslator translator = new ActionTranslator(generator, "b", 806 new CommonToken(ANTLRParser.ACTION,action),1); 807 String found = translator.translate(); 808 assertEquals(expecting, found); 809 810 int expectedMsgID = ErrorManager.MSG_UNKNOWN_RULE_ATTRIBUTE; 811 Object expectedArg = "a"; 812 Object expectedArg2 = "blort"; 813 GrammarSemanticsMessage expectedMessage = 814 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 815 checkError(equeue, expectedMessage); 816 } 817 testMissingRuleAttribute()818 @Test public void testMissingRuleAttribute() throws Exception { 819 String action = "$r"; 820 String expecting = action; 821 822 ErrorQueue equeue = new ErrorQueue(); 823 ErrorManager.setErrorListener(equeue); 824 Grammar g = new Grammar( 825 "parser grammar t;\n"+ 826 "a[int z] returns [int x]\n" + 827 " :\n" + 828 " ;\n"+ 829 "b : r=a[3] {"+action+"}\n" + 830 " ;"); 831 Tool antlr = newTool(); 832 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 833 ActionTranslator translator = new ActionTranslator(generator, "b", 834 new CommonToken(ANTLRParser.ACTION,action),1); 835 String rawTranslation = 836 translator.translate(); 837 838 int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_SCOPE; 839 Object expectedArg = "r"; 840 Object expectedArg2 = null; 841 GrammarSemanticsMessage expectedMessage = 842 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 843 checkError(equeue, expectedMessage); 844 } 845 testMissingUnlabeledRuleAttribute()846 @Test public void testMissingUnlabeledRuleAttribute() throws Exception { 847 String action = "$a"; 848 String expecting = action; 849 850 ErrorQueue equeue = new ErrorQueue(); 851 ErrorManager.setErrorListener(equeue); 852 Grammar g = new Grammar( 853 "parser grammar t;\n"+ 854 "a returns [int x]:\n" + 855 " ;\n"+ 856 "b : a {"+action+"}\n" + 857 " ;"); 858 Tool antlr = newTool(); 859 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 860 ActionTranslator translator = new ActionTranslator(generator, "b", 861 new CommonToken(ANTLRParser.ACTION,action),1); 862 String rawTranslation = 863 translator.translate(); 864 865 int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_SCOPE; 866 Object expectedArg = "a"; 867 GrammarSemanticsMessage expectedMessage = 868 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 869 checkError(equeue, expectedMessage); 870 } 871 testNonDynamicAttributeOutsideRule()872 @Test public void testNonDynamicAttributeOutsideRule() throws Exception { 873 String action = "public void foo() { $x; }"; 874 String expecting = action; 875 876 ErrorQueue equeue = new ErrorQueue(); 877 ErrorManager.setErrorListener(equeue); 878 Grammar g = new Grammar( 879 "parser grammar t;\n"+ 880 "@members {'+action+'}\n" + 881 "a : ;\n"); 882 Tool antlr = newTool(); 883 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 884 ActionTranslator translator = new ActionTranslator(generator, 885 null, 886 new CommonToken(ANTLRParser.ACTION,action),0); 887 String found = translator.translate(); assertEquals(expecting, found); 888 889 int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_REF_NOT_IN_RULE; 890 Object expectedArg = "x"; 891 GrammarSemanticsMessage expectedMessage = 892 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 893 checkError(equeue, expectedMessage); 894 } 895 testNonDynamicAttributeOutsideRule2()896 @Test public void testNonDynamicAttributeOutsideRule2() throws Exception { 897 String action = "public void foo() { $x.y; }"; 898 String expecting = action; 899 900 ErrorQueue equeue = new ErrorQueue(); 901 ErrorManager.setErrorListener(equeue); 902 Grammar g = new Grammar( 903 "parser grammar t;\n"+ 904 "@members {'+action+'}\n" + 905 "a : ;\n"); 906 Tool antlr = newTool(); 907 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 908 ActionTranslator translator = new ActionTranslator(generator, 909 null, 910 new CommonToken(ANTLRParser.ACTION,action),0); 911 String found = translator.translate(); 912 assertEquals(expecting, found); 913 914 int expectedMsgID = ErrorManager.MSG_ATTRIBUTE_REF_NOT_IN_RULE; 915 Object expectedArg = "x"; 916 Object expectedArg2 = "y"; 917 GrammarSemanticsMessage expectedMessage = 918 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 919 checkError(equeue, expectedMessage); 920 } 921 922 // D Y N A M I C A L L Y S C O P E D A T T R I B U T E S 923 testBasicGlobalScope()924 @Test public void testBasicGlobalScope() throws Exception { 925 String action = "$Symbols::names.add($id.text);"; 926 String expecting = "Symbols_stack.peek().names.add((id!=null?id.getText():null));"; 927 928 ErrorQueue equeue = new ErrorQueue(); 929 ErrorManager.setErrorListener(equeue); 930 Grammar g = new Grammar( 931 "grammar t;\n"+ 932 "scope Symbols {\n" + 933 " int n;\n" + 934 " List names;\n" + 935 "}\n" + 936 "a scope Symbols; : (id=ID ';' {"+action+"} )+\n" + 937 " ;\n" + 938 "ID : 'a';\n"); 939 Tool antlr = newTool(); 940 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 941 g.setCodeGenerator(generator); 942 generator.genRecognizer(); // forces load of templates 943 ActionTranslator translator = new ActionTranslator(generator,"a", 944 new CommonToken(ANTLRParser.ACTION,action),1); 945 String found = translator.translate(); 946 assertEquals(expecting, found); 947 948 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 949 } 950 testUnknownGlobalScope()951 @Test public void testUnknownGlobalScope() throws Exception { 952 String action = "$Symbols::names.add($id.text);"; 953 954 ErrorQueue equeue = new ErrorQueue(); 955 ErrorManager.setErrorListener(equeue); 956 Grammar g = new Grammar( 957 "grammar t;\n"+ 958 "a scope Symbols; : (id=ID ';' {"+action+"} )+\n" + 959 " ;\n" + 960 "ID : 'a';\n"); 961 Tool antlr = newTool(); 962 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 963 g.setCodeGenerator(generator); 964 generator.genRecognizer(); // forces load of templates 965 ActionTranslator translator = new ActionTranslator(generator,"a", 966 new CommonToken(ANTLRParser.ACTION,action),1); 967 968 assertEquals("unexpected errors: "+equeue, 2, equeue.errors.size()); 969 970 int expectedMsgID = ErrorManager.MSG_UNKNOWN_DYNAMIC_SCOPE; 971 Object expectedArg = "Symbols"; 972 GrammarSemanticsMessage expectedMessage = 973 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 974 checkError(equeue, expectedMessage); 975 } 976 testIndexedGlobalScope()977 @Test public void testIndexedGlobalScope() throws Exception { 978 String action = "$Symbols[-1]::names.add($id.text);"; 979 String expecting = 980 "Symbols_stack.elementAt(Symbols_stack.size()-1-1).names.add((id!=null?id.getText():null));"; 981 982 ErrorQueue equeue = new ErrorQueue(); 983 ErrorManager.setErrorListener(equeue); 984 Grammar g = new Grammar( 985 "grammar t;\n"+ 986 "scope Symbols {\n" + 987 " int n;\n" + 988 " List names;\n" + 989 "}\n" + 990 "a scope Symbols; : (id=ID ';' {"+action+"} )+\n" + 991 " ;\n" + 992 "ID : 'a';\n"); 993 Tool antlr = newTool(); 994 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 995 g.setCodeGenerator(generator); 996 generator.genRecognizer(); // forces load of templates 997 ActionTranslator translator = new ActionTranslator(generator,"a", 998 new CommonToken(ANTLRParser.ACTION,action),1); 999 String found = translator.translate(); 1000 assertEquals(expecting, found); 1001 1002 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1003 } 1004 test0IndexedGlobalScope()1005 @Test public void test0IndexedGlobalScope() throws Exception { 1006 String action = "$Symbols[0]::names.add($id.text);"; 1007 String expecting = 1008 "Symbols_stack.elementAt(0).names.add((id!=null?id.getText():null));"; 1009 1010 ErrorQueue equeue = new ErrorQueue(); 1011 ErrorManager.setErrorListener(equeue); 1012 Grammar g = new Grammar( 1013 "grammar t;\n"+ 1014 "scope Symbols {\n" + 1015 " int n;\n" + 1016 " List names;\n" + 1017 "}\n" + 1018 "a scope Symbols; : (id=ID ';' {"+action+"} )+\n" + 1019 " ;\n" + 1020 "ID : 'a';\n"); 1021 Tool antlr = newTool(); 1022 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1023 g.setCodeGenerator(generator); 1024 generator.genRecognizer(); // forces load of templates 1025 ActionTranslator translator = new ActionTranslator(generator,"a", 1026 new CommonToken(ANTLRParser.ACTION,action),1); 1027 String found = translator.translate(); 1028 assertEquals(expecting, found); 1029 1030 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1031 } 1032 testAbsoluteIndexedGlobalScope()1033 @Test public void testAbsoluteIndexedGlobalScope() throws Exception { 1034 String action = "$Symbols[3]::names.add($id.text);"; 1035 String expecting = 1036 "Symbols_stack.elementAt(3).names.add((id!=null?id.getText():null));"; 1037 1038 ErrorQueue equeue = new ErrorQueue(); 1039 ErrorManager.setErrorListener(equeue); 1040 Grammar g = new Grammar( 1041 "grammar t;\n"+ 1042 "scope Symbols {\n" + 1043 " int n;\n" + 1044 " List names;\n" + 1045 "}\n" + 1046 "a scope Symbols; : (id=ID ';' {"+action+"} )+\n" + 1047 " ;\n" + 1048 "ID : 'a';\n"); 1049 Tool antlr = newTool(); 1050 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1051 g.setCodeGenerator(generator); 1052 generator.genRecognizer(); // forces load of templates 1053 ActionTranslator translator = new ActionTranslator(generator,"a", 1054 new CommonToken(ANTLRParser.ACTION,action),1); 1055 String found = translator.translate(); 1056 assertEquals(expecting, found); 1057 1058 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1059 } 1060 testScopeAndAttributeWithUnderscore()1061 @Test public void testScopeAndAttributeWithUnderscore() throws Exception { 1062 String action = "$foo_bar::a_b;"; 1063 String expecting = "foo_bar_stack.peek().a_b;"; 1064 1065 ErrorQueue equeue = new ErrorQueue(); 1066 ErrorManager.setErrorListener(equeue); 1067 Grammar g = new Grammar( 1068 "grammar t;\n"+ 1069 "scope foo_bar {\n" + 1070 " int a_b;\n" + 1071 "}\n" + 1072 "a scope foo_bar; : (ID {"+action+"} )+\n" + 1073 " ;\n" + 1074 "ID : 'a';\n"); 1075 Tool antlr = newTool(); 1076 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1077 g.setCodeGenerator(generator); 1078 generator.genRecognizer(); // forces load of templates 1079 ActionTranslator translator = new ActionTranslator(generator,"a", 1080 new CommonToken(ANTLRParser.ACTION,action),1); 1081 String found = translator.translate(); 1082 assertEquals(expecting, found); 1083 1084 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1085 } 1086 testSharedGlobalScope()1087 @Test public void testSharedGlobalScope() throws Exception { 1088 String action = "$Symbols::x;"; 1089 String expecting = "Symbols_stack.peek().x;"; 1090 1091 ErrorQueue equeue = new ErrorQueue(); 1092 ErrorManager.setErrorListener(equeue); 1093 Grammar g = new Grammar( 1094 "grammar t;\n"+ 1095 "scope Symbols {\n" + 1096 " String x;\n" + 1097 "}\n" + 1098 "a\n"+ 1099 "scope { int y; }\n"+ 1100 "scope Symbols;\n" + 1101 " : b {"+action+"}\n" + 1102 " ;\n" + 1103 "b : ID {$Symbols::x=$ID.text} ;\n" + 1104 "ID : 'a';\n"); 1105 Tool antlr = newTool(); 1106 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1107 g.setCodeGenerator(generator); 1108 generator.genRecognizer(); // forces load of templates 1109 ActionTranslator translator = new ActionTranslator(generator,"a", 1110 new CommonToken(ANTLRParser.ACTION,action),1); 1111 String found = translator.translate(); 1112 assertEquals(expecting, found); 1113 1114 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1115 } 1116 testGlobalScopeOutsideRule()1117 @Test public void testGlobalScopeOutsideRule() throws Exception { 1118 String action = "public void foo() {$Symbols::names.add('foo');}"; 1119 String expecting = "public void foo() {Symbols_stack.peek().names.add('foo');}"; 1120 1121 ErrorQueue equeue = new ErrorQueue(); 1122 ErrorManager.setErrorListener(equeue); 1123 Grammar g = new Grammar( 1124 "grammar t;\n"+ 1125 "scope Symbols {\n" + 1126 " int n;\n" + 1127 " List names;\n" + 1128 "}\n" + 1129 "@members {'+action+'}\n" + 1130 "a : \n" + 1131 " ;\n"); 1132 Tool antlr = newTool(); 1133 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1134 g.setCodeGenerator(generator); 1135 generator.genRecognizer(); // forces load of templates 1136 ActionTranslator translator = new ActionTranslator(generator,"a", 1137 new CommonToken(ANTLRParser.ACTION,action),1); 1138 String found = translator.translate(); 1139 assertEquals(expecting, found); 1140 1141 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1142 } 1143 testRuleScopeOutsideRule()1144 @Test public void testRuleScopeOutsideRule() throws Exception { 1145 String action = "public void foo() {$a::name;}"; 1146 String expecting = "public void foo() {a_stack.peek().name;}"; 1147 1148 ErrorQueue equeue = new ErrorQueue(); 1149 ErrorManager.setErrorListener(equeue); 1150 Grammar g = new Grammar( 1151 "grammar t;\n"+ 1152 "@members {"+action+"}\n" + 1153 "a\n" + 1154 "scope { String name; }\n" + 1155 " : {foo();}\n" + 1156 " ;\n"); 1157 Tool antlr = newTool(); 1158 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1159 g.setCodeGenerator(generator); 1160 generator.genRecognizer(); // forces load of templates 1161 ActionTranslator translator = new ActionTranslator(generator, 1162 null, 1163 new CommonToken(ANTLRParser.ACTION,action),0); 1164 String found = translator.translate(); assertEquals(expecting, found); 1165 1166 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1167 } 1168 testBasicRuleScope()1169 @Test public void testBasicRuleScope() throws Exception { 1170 String action = "$a::n;"; 1171 String expecting = "a_stack.peek().n;"; 1172 1173 ErrorQueue equeue = new ErrorQueue(); 1174 ErrorManager.setErrorListener(equeue); 1175 Grammar g = new Grammar( 1176 "grammar t;\n"+ 1177 "a\n" + 1178 "scope {\n" + 1179 " int n;\n" + 1180 "} : {"+action+"}\n" + 1181 " ;\n"); 1182 Tool antlr = newTool(); 1183 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1184 g.setCodeGenerator(generator); 1185 generator.genRecognizer(); // forces load of templates 1186 ActionTranslator translator = new ActionTranslator(generator,"a", 1187 new CommonToken(ANTLRParser.ACTION,action),1); 1188 String found = translator.translate(); 1189 assertEquals(expecting, found); 1190 1191 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1192 } 1193 testUnqualifiedRuleScopeAccessInsideRule()1194 @Test public void testUnqualifiedRuleScopeAccessInsideRule() throws Exception { 1195 String action = "$n;"; 1196 String expecting = action; 1197 1198 ErrorQueue equeue = new ErrorQueue(); 1199 ErrorManager.setErrorListener(equeue); 1200 Grammar g = new Grammar( 1201 "grammar t;\n"+ 1202 "a\n" + 1203 "scope {\n" + 1204 " int n;\n" + 1205 "} : {"+action+"}\n" + 1206 " ;\n"); 1207 Tool antlr = newTool(); 1208 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1209 g.setCodeGenerator(generator); 1210 generator.genRecognizer(); // forces load of templates 1211 1212 int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_ATTRIBUTE; 1213 Object expectedArg = "n"; 1214 Object expectedArg2 = null; 1215 GrammarSemanticsMessage expectedMessage = 1216 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, 1217 expectedArg2); 1218 checkError(equeue, expectedMessage); 1219 } 1220 testIsolatedDynamicRuleScopeRef()1221 @Test public void testIsolatedDynamicRuleScopeRef() throws Exception { 1222 String action = "$a;"; // refers to stack not top of stack 1223 String expecting = "a_stack;"; 1224 1225 ErrorQueue equeue = new ErrorQueue(); 1226 ErrorManager.setErrorListener(equeue); 1227 Grammar g = new Grammar( 1228 "grammar t;\n"+ 1229 "a\n" + 1230 "scope {\n" + 1231 " int n;\n" + 1232 "} : b ;\n" + 1233 "b : {"+action+"}\n" + 1234 " ;\n"); 1235 Tool antlr = newTool(); 1236 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1237 g.setCodeGenerator(generator); 1238 generator.genRecognizer(); // forces load of templates 1239 ActionTranslator translator = new ActionTranslator(generator, "b", 1240 new CommonToken(ANTLRParser.ACTION,action),1); 1241 String found = translator.translate(); 1242 assertEquals(expecting, found); 1243 1244 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1245 } 1246 testDynamicRuleScopeRefInSubrule()1247 @Test public void testDynamicRuleScopeRefInSubrule() throws Exception { 1248 String action = "$a::n;"; 1249 String expecting = "a_stack.peek().n;"; 1250 1251 ErrorQueue equeue = new ErrorQueue(); 1252 ErrorManager.setErrorListener(equeue); 1253 Grammar g = new Grammar( 1254 "grammar t;\n"+ 1255 "a\n" + 1256 "scope {\n" + 1257 " float n;\n" + 1258 "} : b ;\n" + 1259 "b : {"+action+"}\n" + 1260 " ;\n"); 1261 Tool antlr = newTool(); 1262 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1263 g.setCodeGenerator(generator); 1264 generator.genRecognizer(); // forces load of templates 1265 ActionTranslator translator = new ActionTranslator(generator, "b", 1266 new CommonToken(ANTLRParser.ACTION,action),1); 1267 String found = translator.translate(); 1268 assertEquals(expecting, found); 1269 1270 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1271 } 1272 testIsolatedGlobalScopeRef()1273 @Test public void testIsolatedGlobalScopeRef() throws Exception { 1274 String action = "$Symbols;"; 1275 String expecting = "Symbols_stack;"; 1276 1277 ErrorQueue equeue = new ErrorQueue(); 1278 ErrorManager.setErrorListener(equeue); 1279 Grammar g = new Grammar( 1280 "grammar t;\n"+ 1281 "scope Symbols {\n" + 1282 " String x;\n" + 1283 "}\n" + 1284 "a\n"+ 1285 "scope { int y; }\n"+ 1286 "scope Symbols;\n" + 1287 " : b {"+action+"}\n" + 1288 " ;\n" + 1289 "b : ID {$Symbols::x=$ID.text} ;\n" + 1290 "ID : 'a';\n"); 1291 Tool antlr = newTool(); 1292 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1293 g.setCodeGenerator(generator); 1294 generator.genRecognizer(); // forces load of templates 1295 ActionTranslator translator = new ActionTranslator(generator,"a", 1296 new CommonToken(ANTLRParser.ACTION,action),1); 1297 String found = translator.translate(); 1298 assertEquals(expecting, found); 1299 1300 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1301 } 1302 testRuleScopeFromAnotherRule()1303 @Test public void testRuleScopeFromAnotherRule() throws Exception { 1304 String action = "$a::n;"; // must be qualified 1305 String expecting = "a_stack.peek().n;"; 1306 1307 ErrorQueue equeue = new ErrorQueue(); 1308 ErrorManager.setErrorListener(equeue); 1309 Grammar g = new Grammar( 1310 "grammar t;\n"+ 1311 "a\n" + 1312 "scope {\n" + 1313 " boolean n;\n" + 1314 "} : b\n" + 1315 " ;\n" + 1316 "b : {"+action+"}\n" + 1317 " ;\n"); 1318 Tool antlr = newTool(); 1319 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1320 g.setCodeGenerator(generator); 1321 generator.genRecognizer(); // forces load of templates 1322 ActionTranslator translator = new ActionTranslator(generator, "b", 1323 new CommonToken(ANTLRParser.ACTION,action),1); 1324 String found = translator.translate(); 1325 assertEquals(expecting, found); 1326 1327 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1328 } 1329 testFullyQualifiedRefToCurrentRuleParameter()1330 @Test public void testFullyQualifiedRefToCurrentRuleParameter() throws Exception { 1331 String action = "$a.i;"; 1332 String expecting = "i;"; 1333 1334 ErrorQueue equeue = new ErrorQueue(); 1335 ErrorManager.setErrorListener(equeue); 1336 Grammar g = new Grammar( 1337 "grammar t;\n"+ 1338 "a[int i]: {"+action+"}\n" + 1339 " ;\n"); 1340 Tool antlr = newTool(); 1341 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1342 g.setCodeGenerator(generator); 1343 generator.genRecognizer(); // forces load of templates 1344 ActionTranslator translator = new ActionTranslator(generator,"a", 1345 new CommonToken(ANTLRParser.ACTION,action),1); 1346 String found = translator.translate(); assertEquals(expecting, found); 1347 1348 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1349 } 1350 testFullyQualifiedRefToCurrentRuleRetVal()1351 @Test public void testFullyQualifiedRefToCurrentRuleRetVal() throws Exception { 1352 String action = "$a.i;"; 1353 String expecting = "retval.i;"; 1354 1355 ErrorQueue equeue = new ErrorQueue(); 1356 ErrorManager.setErrorListener(equeue); 1357 Grammar g = new Grammar( 1358 "grammar t;\n"+ 1359 "a returns [int i, int j]: {"+action+"}\n" + 1360 " ;\n"); 1361 Tool antlr = newTool(); 1362 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1363 g.setCodeGenerator(generator); 1364 generator.genRecognizer(); // forces load of templates 1365 ActionTranslator translator = new ActionTranslator(generator,"a", 1366 new CommonToken(ANTLRParser.ACTION,action),1); 1367 String found = translator.translate(); 1368 assertEquals(expecting, found); 1369 1370 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1371 } 1372 testSetFullyQualifiedRefToCurrentRuleRetVal()1373 @Test public void testSetFullyQualifiedRefToCurrentRuleRetVal() throws Exception { 1374 String action = "$a.i = 1;"; 1375 String expecting = "retval.i = 1;"; 1376 1377 ErrorQueue equeue = new ErrorQueue(); 1378 ErrorManager.setErrorListener(equeue); 1379 Grammar g = new Grammar( 1380 "grammar t;\n"+ 1381 "a returns [int i, int j]: {"+action+"}\n" + 1382 " ;\n"); 1383 Tool antlr = newTool(); 1384 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1385 g.setCodeGenerator(generator); 1386 generator.genRecognizer(); // forces load of templates 1387 ActionTranslator translator = new ActionTranslator(generator,"a", 1388 new CommonToken(ANTLRParser.ACTION,action),1); 1389 String found = translator.translate(); 1390 assertEquals(expecting, found); 1391 1392 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1393 } 1394 testIsolatedRefToCurrentRule()1395 @Test public void testIsolatedRefToCurrentRule() throws Exception { 1396 String action = "$a;"; 1397 String expecting = ""; 1398 1399 ErrorQueue equeue = new ErrorQueue(); 1400 ErrorManager.setErrorListener(equeue); 1401 Grammar g = new Grammar( 1402 "grammar t;\n"+ 1403 "a : 'a' {"+action+"}\n" + 1404 " ;\n"); 1405 Tool antlr = newTool(); 1406 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1407 g.setCodeGenerator(generator); 1408 generator.genRecognizer(); // forces load of templates 1409 1410 int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_SCOPE; 1411 Object expectedArg = "a"; 1412 Object expectedArg2 = null; 1413 GrammarSemanticsMessage expectedMessage = 1414 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, 1415 expectedArg2); 1416 checkError(equeue, expectedMessage); 1417 } 1418 testIsolatedRefToRule()1419 @Test public void testIsolatedRefToRule() throws Exception { 1420 String action = "$x;"; 1421 1422 ErrorQueue equeue = new ErrorQueue(); 1423 ErrorManager.setErrorListener(equeue); 1424 Grammar g = new Grammar( 1425 "grammar t;\n"+ 1426 "a : x=b {"+action+"}\n" + 1427 " ;\n" + 1428 "b : 'b' ;\n"); 1429 Tool antlr = newTool(); 1430 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1431 g.setCodeGenerator(generator); 1432 generator.genRecognizer(); // forces load of templates 1433 1434 int expectedMsgID = ErrorManager.MSG_ISOLATED_RULE_SCOPE; 1435 Object expectedArg = "x"; 1436 GrammarSemanticsMessage expectedMessage = 1437 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 1438 checkError(equeue, expectedMessage); 1439 } 1440 1441 /* I think these have to be errors $a.x makes no sense. 1442 @Test public void testFullyQualifiedRefToLabelInCurrentRule() throws Exception { 1443 String action = "$a.x;"; 1444 String expecting = "x;"; 1445 1446 ErrorQueue equeue = new ErrorQueue(); 1447 ErrorManager.setErrorListener(equeue); 1448 Grammar g = new Grammar( 1449 "grammar t;\n"+ 1450 "a : x='a' {"+action+"}\n" + 1451 " ;\n"); 1452 Tool antlr = newTool(); 1453 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1454 g.setCodeGenerator(generator); 1455 generator.genRecognizer(); // forces load of templates 1456 ActionTranslator translator = new ActionTranslator(generator,"a", 1457 new CommonToken(ANTLRParser.ACTION,action),1); 1458 String rawTranslation = 1459 translator.translate(); 1460 STGroup templates = 1461 new STGroup(); 1462 ST actionST = new ST(templates, rawTranslation); 1463 String found = actionST.render(); 1464 assertEquals(expecting, found); 1465 1466 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1467 } 1468 1469 @Test public void testFullyQualifiedRefToListLabelInCurrentRule() throws Exception { 1470 String action = "$a.x;"; // must be qualified 1471 String expecting = "list_x;"; 1472 1473 ErrorQueue equeue = new ErrorQueue(); 1474 ErrorManager.setErrorListener(equeue); 1475 Grammar g = new Grammar( 1476 "grammar t;\n"+ 1477 "a : x+='a' {"+action+"}\n" + 1478 " ;\n"); 1479 Tool antlr = newTool(); 1480 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1481 g.setCodeGenerator(generator); 1482 generator.genRecognizer(); // forces load of templates 1483 ActionTranslator translator = new ActionTranslator(generator,"a", 1484 new CommonToken(ANTLRParser.ACTION,action),1); 1485 String found = translator.translate(); assertEquals(expecting, found); 1486 1487 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1488 } 1489 */ testFullyQualifiedRefToTemplateAttributeInCurrentRule()1490 @Test public void testFullyQualifiedRefToTemplateAttributeInCurrentRule() throws Exception { 1491 String action = "$a.st;"; // can be qualified 1492 String expecting = "retval.st;"; 1493 1494 ErrorQueue equeue = new ErrorQueue(); 1495 ErrorManager.setErrorListener(equeue); 1496 Grammar g = new Grammar( 1497 "parser grammar t;\n" + 1498 "options {output=template;}\n"+ 1499 "a : (A->{$A.text}) {"+action+"}\n" + 1500 " ;\n"); 1501 Tool antlr = newTool(); 1502 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1503 g.setCodeGenerator(generator); 1504 generator.genRecognizer(); // forces load of templates 1505 ActionTranslator translator = new ActionTranslator(generator,"a", 1506 new CommonToken(ANTLRParser.ACTION,action),1); 1507 String found = translator.translate(); 1508 assertEquals(expecting, found); 1509 1510 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1511 } 1512 testRuleRefWhenRuleHasScope()1513 @Test public void testRuleRefWhenRuleHasScope() throws Exception { 1514 String action = "$b.start;"; 1515 String expecting = "(b1!=null?(b1.start):null);"; 1516 1517 ErrorQueue equeue = new ErrorQueue(); 1518 ErrorManager.setErrorListener(equeue); 1519 Grammar g = new Grammar( 1520 "grammar t;\n" + 1521 "a : b {###"+action+"!!!} ;\n" + 1522 "b\n" + 1523 "scope {\n" + 1524 " int n;\n" + 1525 "} : 'b' \n" + 1526 " ;\n"); 1527 Tool antlr = newTool(); 1528 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1529 g.setCodeGenerator(generator); 1530 generator.genRecognizer(); // forces load of templates 1531 1532 ST codeST = generator.getRecognizerST(); 1533 String code = codeST.render(); 1534 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 1535 assertEquals(expecting, found); 1536 1537 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1538 } 1539 testDynamicScopeRefOkEvenThoughRuleRefExists()1540 @Test public void testDynamicScopeRefOkEvenThoughRuleRefExists() throws Exception { 1541 String action = "$b::n;"; 1542 String expecting = "b_stack.peek().n;"; 1543 1544 ErrorQueue equeue = new ErrorQueue(); 1545 ErrorManager.setErrorListener(equeue); 1546 Grammar g = new Grammar( 1547 "grammar t;\n" + 1548 "s : b ;\n"+ 1549 "b\n" + 1550 "scope {\n" + 1551 " int n;\n" + 1552 "} : '(' b ')' {"+action+"}\n" + // refers to current invocation's n 1553 " ;\n"); 1554 Tool antlr = newTool(); 1555 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1556 g.setCodeGenerator(generator); 1557 generator.genRecognizer(); // forces load of templates 1558 ActionTranslator translator = new ActionTranslator(generator, "b", 1559 new CommonToken(ANTLRParser.ACTION,action),1); 1560 String found = translator.translate(); assertEquals(expecting, found); 1561 1562 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1563 } 1564 testRefToTemplateAttributeForCurrentRule()1565 @Test public void testRefToTemplateAttributeForCurrentRule() throws Exception { 1566 String action = "$st=null;"; 1567 String expecting = "retval.st =null;"; 1568 1569 ErrorQueue equeue = new ErrorQueue(); 1570 ErrorManager.setErrorListener(equeue); 1571 Grammar g = new Grammar( 1572 "parser grammar t;\n" + 1573 "options {output=template;}\n"+ 1574 "a : {"+action+"}\n" + 1575 " ;\n"); 1576 Tool antlr = newTool(); 1577 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1578 g.setCodeGenerator(generator); 1579 generator.genRecognizer(); // forces load of templates 1580 ActionTranslator translator = new ActionTranslator(generator,"a", 1581 new CommonToken(ANTLRParser.ACTION,action),1); 1582 String found = translator.translate(); assertEquals(expecting, found); 1583 1584 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1585 } 1586 testRefToTextAttributeForCurrentRule()1587 @Test public void testRefToTextAttributeForCurrentRule() throws Exception { 1588 String action = "$text"; 1589 String expecting = "input.toString(retval.start,input.LT(-1))"; 1590 1591 ErrorQueue equeue = new ErrorQueue(); 1592 ErrorManager.setErrorListener(equeue); 1593 Grammar g = new Grammar( 1594 "parser grammar t;\n" + 1595 "options {output=template;}\n"+ 1596 "a : {###"+action+"!!!}\n" + 1597 " ;\n"); 1598 Tool antlr = newTool(); 1599 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1600 g.setCodeGenerator(generator); 1601 generator.genRecognizer(); // codegen phase sets some vars we need 1602 ST codeST = generator.getRecognizerST(); 1603 String code = codeST.render(); 1604 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 1605 assertEquals(expecting, found); 1606 1607 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1608 } 1609 testRefToStartAttributeForCurrentRule()1610 @Test public void testRefToStartAttributeForCurrentRule() throws Exception { 1611 String action = "$start;"; 1612 String expecting = "(retval.start);"; 1613 1614 ErrorQueue equeue = new ErrorQueue(); 1615 ErrorManager.setErrorListener(equeue); 1616 Grammar g = new Grammar( 1617 "parser grammar t;\n" + 1618 "a : {###"+action+"!!!}\n" + 1619 " ;\n"); 1620 Tool antlr = newTool(); 1621 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1622 g.setCodeGenerator(generator); 1623 generator.genRecognizer(); // forces load of templates 1624 ActionTranslator translator = new ActionTranslator(generator,"a", 1625 new CommonToken(ANTLRParser.ACTION,action),1); 1626 ST codeST = generator.getRecognizerST(); 1627 String code = codeST.render(); 1628 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 1629 assertEquals(expecting, found); 1630 1631 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1632 } 1633 testTokenLabelFromMultipleAlts()1634 @Test public void testTokenLabelFromMultipleAlts() throws Exception { 1635 String action = "$ID.text;"; // must be qualified 1636 String action2 = "$INT.text;"; // must be qualified 1637 String expecting = "(ID1!=null?ID1.getText():null);"; 1638 String expecting2 = "(INT2!=null?INT2.getText():null);"; 1639 1640 ErrorQueue equeue = new ErrorQueue(); 1641 ErrorManager.setErrorListener(equeue); 1642 Grammar g = new Grammar( 1643 "grammar t;\n"+ 1644 "a : ID {"+action+"}\n" + 1645 " | INT {"+action2+"}\n" + 1646 " ;\n" + 1647 "ID : 'a';\n" + 1648 "INT : '0';\n"); 1649 Tool antlr = newTool(); 1650 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1651 g.setCodeGenerator(generator); 1652 generator.genRecognizer(); // forces load of templates 1653 ActionTranslator translator = new ActionTranslator(generator,"a", 1654 new CommonToken(ANTLRParser.ACTION,action),1); 1655 String found = translator.translate(); assertEquals(expecting, found); 1656 1657 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1658 translator = new ActionTranslator(generator, 1659 "a", 1660 new CommonToken(ANTLRParser.ACTION,action2),2); 1661 found = translator.translate(); 1662 assertEquals(expecting2, found); 1663 1664 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1665 } 1666 testRuleLabelFromMultipleAlts()1667 @Test public void testRuleLabelFromMultipleAlts() throws Exception { 1668 String action = "$b.text;"; // must be qualified 1669 String action2 = "$c.text;"; // must be qualified 1670 String expecting = "(b1!=null?input.toString(b1.start,b1.stop):null);"; 1671 String expecting2 = "(c2!=null?input.toString(c2.start,c2.stop):null);"; 1672 1673 ErrorQueue equeue = new ErrorQueue(); 1674 ErrorManager.setErrorListener(equeue); 1675 Grammar g = new Grammar( 1676 "grammar t;\n"+ 1677 "a : b {###"+action+"!!!}\n" + 1678 " | c {^^^"+action2+"&&&}\n" + 1679 " ;\n" + 1680 "b : 'a';\n" + 1681 "c : '0';\n"); 1682 Tool antlr = newTool(); 1683 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1684 g.setCodeGenerator(generator); 1685 generator.genRecognizer(); // codegen phase sets some vars we need 1686 ST codeST = generator.getRecognizerST(); 1687 String code = codeST.render(); 1688 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 1689 assertEquals(expecting, found); 1690 found = code.substring(code.indexOf("^^^")+3,code.indexOf("&&&")); 1691 assertEquals(expecting2, found); 1692 1693 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1694 } 1695 testUnknownDynamicAttribute()1696 @Test public void testUnknownDynamicAttribute() throws Exception { 1697 String action = "$a::x"; 1698 String expecting = action; 1699 1700 ErrorQueue equeue = new ErrorQueue(); 1701 ErrorManager.setErrorListener(equeue); 1702 Grammar g = new Grammar( 1703 "grammar t;\n"+ 1704 "a\n" + 1705 "scope {\n" + 1706 " int n;\n" + 1707 "} : {"+action+"}\n" + 1708 " ;\n"); 1709 Tool antlr = newTool(); 1710 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1711 g.setCodeGenerator(generator); 1712 generator.genRecognizer(); // forces load of templates 1713 ActionTranslator translator = 1714 new ActionTranslator(generator, 1715 "a", 1716 new CommonToken(ANTLRParser.ACTION,action),1); 1717 String found = translator.translate(); assertEquals(expecting, found); 1718 1719 int expectedMsgID = ErrorManager.MSG_UNKNOWN_DYNAMIC_SCOPE_ATTRIBUTE; 1720 Object expectedArg = "a"; 1721 Object expectedArg2 = "x"; 1722 GrammarSemanticsMessage expectedMessage = 1723 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 1724 checkError(equeue, expectedMessage); 1725 } 1726 testUnknownGlobalDynamicAttribute()1727 @Test public void testUnknownGlobalDynamicAttribute() throws Exception { 1728 String action = "$Symbols::x"; 1729 String expecting = action; 1730 1731 ErrorQueue equeue = new ErrorQueue(); 1732 ErrorManager.setErrorListener(equeue); 1733 Grammar g = new Grammar( 1734 "grammar t;\n"+ 1735 "scope Symbols {\n" + 1736 " int n;\n" + 1737 "}\n" + 1738 "a : {'+action+'}\n" + 1739 " ;\n"); 1740 Tool antlr = newTool(); 1741 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1742 g.setCodeGenerator(generator); 1743 generator.genRecognizer(); // forces load of templates 1744 ActionTranslator translator = 1745 new ActionTranslator(generator, 1746 "a", 1747 new CommonToken(ANTLRParser.ACTION,action),1); 1748 String found = translator.translate(); assertEquals(expecting, found); 1749 1750 int expectedMsgID = ErrorManager.MSG_UNKNOWN_DYNAMIC_SCOPE_ATTRIBUTE; 1751 Object expectedArg = "Symbols"; 1752 Object expectedArg2 = "x"; 1753 GrammarSemanticsMessage expectedMessage = 1754 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 1755 checkError(equeue, expectedMessage); 1756 } 1757 testUnqualifiedRuleScopeAttribute()1758 @Test public void testUnqualifiedRuleScopeAttribute() throws Exception { 1759 String action = "$n;"; // must be qualified 1760 String expecting = "$n;"; 1761 1762 ErrorQueue equeue = new ErrorQueue(); 1763 ErrorManager.setErrorListener(equeue); 1764 Grammar g = new Grammar( 1765 "grammar t;\n"+ 1766 "a\n" + 1767 "scope {\n" + 1768 " int n;\n" + 1769 "} : b\n" + 1770 " ;\n" + 1771 "b : {'+action+'}\n" + 1772 " ;\n"); 1773 Tool antlr = newTool(); 1774 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1775 ActionTranslator translator = 1776 new ActionTranslator(generator, 1777 "b", 1778 new CommonToken(ANTLRParser.ACTION,action),1); 1779 String found = translator.translate(); assertEquals(expecting, found); 1780 1781 int expectedMsgID = ErrorManager.MSG_UNKNOWN_SIMPLE_ATTRIBUTE; 1782 Object expectedArg = "n"; 1783 Object expectedArg2 = null; 1784 GrammarSemanticsMessage expectedMessage = 1785 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 1786 checkError(equeue, expectedMessage); 1787 } 1788 testRuleAndTokenLabelTypeMismatch()1789 @Test public void testRuleAndTokenLabelTypeMismatch() throws Exception { 1790 ErrorQueue equeue = new ErrorQueue(); 1791 ErrorManager.setErrorListener(equeue); 1792 Grammar g = new Grammar( 1793 "grammar t;\n"+ 1794 "a : id='foo' id=b\n" + 1795 " ;\n" + 1796 "b : ;\n"); 1797 int expectedMsgID = ErrorManager.MSG_LABEL_TYPE_CONFLICT; 1798 Object expectedArg = "id"; 1799 Object expectedArg2 = "rule!=token"; 1800 GrammarSemanticsMessage expectedMessage = 1801 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 1802 checkError(equeue, expectedMessage); 1803 } 1804 testListAndTokenLabelTypeMismatch()1805 @Test public void testListAndTokenLabelTypeMismatch() throws Exception { 1806 ErrorQueue equeue = new ErrorQueue(); 1807 ErrorManager.setErrorListener(equeue); 1808 Grammar g = new Grammar( 1809 "grammar t;\n"+ 1810 "a : ids+='a' ids='b'\n" + 1811 " ;\n" + 1812 "b : ;\n"); 1813 int expectedMsgID = ErrorManager.MSG_LABEL_TYPE_CONFLICT; 1814 Object expectedArg = "ids"; 1815 Object expectedArg2 = "token!=token-list"; 1816 GrammarSemanticsMessage expectedMessage = 1817 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 1818 checkError(equeue, expectedMessage); 1819 } 1820 testListAndRuleLabelTypeMismatch()1821 @Test public void testListAndRuleLabelTypeMismatch() throws Exception { 1822 ErrorQueue equeue = new ErrorQueue(); 1823 ErrorManager.setErrorListener(equeue); 1824 Grammar g = new Grammar( 1825 "grammar t;\n" + 1826 "options {output=AST;}\n"+ 1827 "a : bs+=b bs=b\n" + 1828 " ;\n" + 1829 "b : 'b';\n"); 1830 int expectedMsgID = ErrorManager.MSG_LABEL_TYPE_CONFLICT; 1831 Object expectedArg = "bs"; 1832 Object expectedArg2 = "rule!=rule-list"; 1833 GrammarSemanticsMessage expectedMessage = 1834 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 1835 checkError(equeue, expectedMessage); 1836 } 1837 testArgReturnValueMismatch()1838 @Test public void testArgReturnValueMismatch() throws Exception { 1839 ErrorQueue equeue = new ErrorQueue(); 1840 ErrorManager.setErrorListener(equeue); 1841 Grammar g = new Grammar( 1842 "grammar t;\n"+ 1843 "a[int i] returns [int x, int i]\n" + 1844 " : \n" + 1845 " ;\n" + 1846 "b : ;\n"); 1847 int expectedMsgID = ErrorManager.MSG_ARG_RETVAL_CONFLICT; 1848 Object expectedArg = "i"; 1849 Object expectedArg2 = "a"; 1850 GrammarSemanticsMessage expectedMessage = 1851 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 1852 checkError(equeue, expectedMessage); 1853 } 1854 testSimplePlusEqualLabel()1855 @Test public void testSimplePlusEqualLabel() throws Exception { 1856 String action = "$ids.size();"; // must be qualified 1857 String expecting = "list_ids.size();"; 1858 1859 ErrorQueue equeue = new ErrorQueue(); 1860 ErrorManager.setErrorListener(equeue); 1861 Grammar g = new Grammar( 1862 "parser grammar t;\n"+ 1863 "a : ids+=ID ( COMMA ids+=ID {"+action+"})* ;\n"); 1864 Tool antlr = newTool(); 1865 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1866 g.setCodeGenerator(generator); 1867 generator.genRecognizer(); // forces load of templates 1868 ActionTranslator translator = 1869 new ActionTranslator(generator, 1870 "a", 1871 new CommonToken(ANTLRParser.ACTION,action),1); 1872 String found = translator.translate(); 1873 assertEquals(expecting, found); 1874 1875 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1876 } 1877 testPlusEqualStringLabel()1878 @Test public void testPlusEqualStringLabel() throws Exception { 1879 String action = "$ids.size();"; // must be qualified 1880 String expecting = "list_ids.size();"; 1881 1882 ErrorQueue equeue = new ErrorQueue(); 1883 ErrorManager.setErrorListener(equeue); 1884 Grammar g = new Grammar( 1885 "grammar t;\n"+ 1886 "a : ids+='if' ( ',' ids+=ID {"+action+"})* ;" + 1887 "ID : 'a';\n"); 1888 Tool antlr = newTool(); 1889 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1890 g.setCodeGenerator(generator); 1891 generator.genRecognizer(); // forces load of templates 1892 ActionTranslator translator = 1893 new ActionTranslator(generator, 1894 "a", 1895 new CommonToken(ANTLRParser.ACTION,action),1); 1896 String found = translator.translate(); 1897 assertEquals(expecting, found); 1898 1899 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1900 } 1901 testPlusEqualSetLabel()1902 @Test public void testPlusEqualSetLabel() throws Exception { 1903 String action = "$ids.size();"; // must be qualified 1904 String expecting = "list_ids.size();"; 1905 1906 ErrorQueue equeue = new ErrorQueue(); 1907 ErrorManager.setErrorListener(equeue); 1908 Grammar g = new Grammar( 1909 "grammar t;\n"+ 1910 "a : ids+=('a'|'b') ( ',' ids+=ID {"+action+"})* ;" + 1911 "ID : 'a';\n"); 1912 Tool antlr = newTool(); 1913 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1914 g.setCodeGenerator(generator); 1915 generator.genRecognizer(); // forces load of templates 1916 ActionTranslator translator = 1917 new ActionTranslator(generator, 1918 "a", 1919 new CommonToken(ANTLRParser.ACTION,action),1); 1920 String found = translator.translate(); 1921 assertEquals(expecting, found); 1922 1923 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1924 } 1925 testPlusEqualWildcardLabel()1926 @Test public void testPlusEqualWildcardLabel() throws Exception { 1927 String action = "$ids.size();"; // must be qualified 1928 String expecting = "list_ids.size();"; 1929 1930 ErrorQueue equeue = new ErrorQueue(); 1931 ErrorManager.setErrorListener(equeue); 1932 Grammar g = new Grammar( 1933 "grammar t;\n"+ 1934 "a : ids+=. ( ',' ids+=ID {"+action+"})* ;" + 1935 "ID : 'a';\n"); 1936 Tool antlr = newTool(); 1937 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1938 ActionTranslator translator = 1939 new ActionTranslator(generator, 1940 "a", 1941 new CommonToken(ANTLRParser.ACTION,action),1); 1942 g.setCodeGenerator(generator); 1943 generator.genRecognizer(); // forces load of templates 1944 String found = translator.translate(); 1945 assertEquals(expecting, found); 1946 1947 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1948 } 1949 testImplicitTokenLabel()1950 @Test public void testImplicitTokenLabel() throws Exception { 1951 String action = "$ID; $ID.text; $ID.getText()"; 1952 String expecting = "ID1; (ID1!=null?ID1.getText():null); ID1.getText()"; 1953 1954 ErrorQueue equeue = new ErrorQueue(); 1955 ErrorManager.setErrorListener(equeue); 1956 Grammar g = new Grammar( 1957 "grammar t;\n"+ 1958 "a : ID {"+action+"} ;" + 1959 "ID : 'a';\n"); 1960 Tool antlr = newTool(); 1961 antlr.setOutputDirectory(null); // write to /dev/null 1962 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1963 1964 ActionTranslator translator = 1965 new ActionTranslator(generator, 1966 "a", 1967 new CommonToken(ANTLRParser.ACTION,action),1); 1968 g.setCodeGenerator(generator); 1969 generator.genRecognizer(); // forces load of templates 1970 String found = translator.translate(); 1971 assertEquals(expecting, found); 1972 1973 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1974 } 1975 testImplicitRuleLabel()1976 @Test public void testImplicitRuleLabel() throws Exception { 1977 String action = "$r.start;"; 1978 String expecting = "(r1!=null?(r1.start):null);"; 1979 1980 ErrorQueue equeue = new ErrorQueue(); 1981 ErrorManager.setErrorListener(equeue); 1982 Grammar g = new Grammar( 1983 "grammar t;\n"+ 1984 "a : r {###"+action+"!!!} ;" + 1985 "r : 'a';\n"); 1986 Tool antlr = newTool(); 1987 antlr.setOutputDirectory(null); // write to /dev/null 1988 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 1989 g.setCodeGenerator(generator); 1990 generator.genRecognizer(); 1991 1992 ST codeST = generator.getRecognizerST(); 1993 String code = codeST.render(); 1994 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 1995 assertEquals(expecting, found); 1996 1997 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 1998 } 1999 testReuseExistingLabelWithImplicitRuleLabel()2000 @Test public void testReuseExistingLabelWithImplicitRuleLabel() throws Exception { 2001 String action = "$r.start;"; 2002 String expecting = "(x!=null?(x.start):null);"; 2003 2004 ErrorQueue equeue = new ErrorQueue(); 2005 ErrorManager.setErrorListener(equeue); 2006 Grammar g = new Grammar( 2007 "grammar t;\n"+ 2008 "a : x=r {###"+action+"!!!} ;" + 2009 "r : 'a';\n"); 2010 Tool antlr = newTool(); 2011 antlr.setOutputDirectory(null); // write to /dev/null 2012 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2013 g.setCodeGenerator(generator); 2014 generator.genRecognizer(); 2015 2016 ST codeST = generator.getRecognizerST(); 2017 String code = codeST.render(); 2018 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 2019 assertEquals(expecting, found); 2020 2021 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2022 } 2023 testReuseExistingListLabelWithImplicitRuleLabel()2024 @Test public void testReuseExistingListLabelWithImplicitRuleLabel() throws Exception { 2025 String action = "$r.start;"; 2026 String expecting = "(x!=null?(x.start):null);"; 2027 2028 ErrorQueue equeue = new ErrorQueue(); 2029 ErrorManager.setErrorListener(equeue); 2030 Grammar g = new Grammar( 2031 "grammar t;\n"+ 2032 "options {output=AST;}\n" + 2033 "a : x+=r {###"+action+"!!!} ;" + 2034 "r : 'a';\n"); 2035 Tool antlr = newTool(); 2036 antlr.setOutputDirectory(null); // write to /dev/null 2037 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2038 g.setCodeGenerator(generator); 2039 generator.genRecognizer(); 2040 2041 ST codeST = generator.getRecognizerST(); 2042 String code = codeST.render(); 2043 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 2044 assertEquals(expecting, found); 2045 2046 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2047 } 2048 testReuseExistingLabelWithImplicitTokenLabel()2049 @Test public void testReuseExistingLabelWithImplicitTokenLabel() throws Exception { 2050 String action = "$ID.text;"; 2051 String expecting = "(x!=null?x.getText():null);"; 2052 2053 ErrorQueue equeue = new ErrorQueue(); 2054 ErrorManager.setErrorListener(equeue); 2055 Grammar g = new Grammar( 2056 "grammar t;\n"+ 2057 "a : x=ID {"+action+"} ;" + 2058 "ID : 'a';\n"); 2059 Tool antlr = newTool(); 2060 antlr.setOutputDirectory(null); // write to /dev/null 2061 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2062 g.setCodeGenerator(generator); 2063 generator.genRecognizer(); 2064 2065 ActionTranslator translator = new ActionTranslator(generator,"a", 2066 new CommonToken(ANTLRParser.ACTION,action),1); 2067 String found = translator.translate(); 2068 assertEquals(expecting, found); 2069 2070 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2071 } 2072 testReuseExistingListLabelWithImplicitTokenLabel()2073 @Test public void testReuseExistingListLabelWithImplicitTokenLabel() throws Exception { 2074 String action = "$ID.text;"; 2075 String expecting = "(x!=null?x.getText():null);"; 2076 2077 ErrorQueue equeue = new ErrorQueue(); 2078 ErrorManager.setErrorListener(equeue); 2079 Grammar g = new Grammar( 2080 "grammar t;\n"+ 2081 "a : x+=ID {"+action+"} ;" + 2082 "ID : 'a';\n"); 2083 Tool antlr = newTool(); 2084 antlr.setOutputDirectory(null); // write to /dev/null 2085 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2086 g.setCodeGenerator(generator); 2087 generator.genRecognizer(); 2088 2089 ActionTranslator translator = new ActionTranslator(generator,"a", 2090 new CommonToken(ANTLRParser.ACTION,action),1); 2091 String found = translator.translate(); 2092 assertEquals(expecting, found); 2093 2094 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2095 } 2096 testRuleLabelWithoutOutputOption()2097 @Test public void testRuleLabelWithoutOutputOption() throws Exception { 2098 ErrorQueue equeue = new ErrorQueue(); 2099 ErrorManager.setErrorListener(equeue); 2100 Grammar g = new Grammar( 2101 "grammar T;\n"+ 2102 "s : x+=a ;" + 2103 "a : 'a';\n"+ 2104 "b : 'b';\n"+ 2105 "WS : ' '|'\n';\n"); 2106 Tool antlr = newTool(); 2107 antlr.setOutputDirectory(null); // write to /dev/null 2108 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2109 g.setCodeGenerator(generator); 2110 generator.genRecognizer(); 2111 2112 int expectedMsgID = ErrorManager.MSG_LIST_LABEL_INVALID_UNLESS_RETVAL_STRUCT; 2113 Object expectedArg = "x"; 2114 Object expectedArg2 = null; 2115 GrammarSemanticsMessage expectedMessage = 2116 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2117 checkError(equeue, expectedMessage); 2118 } 2119 testRuleLabelOnTwoDifferentRulesAST()2120 @Test public void testRuleLabelOnTwoDifferentRulesAST() throws Exception { 2121 String grammar = 2122 "grammar T;\n"+ 2123 "options {output=AST;}\n"+ 2124 "s : x+=a x+=b {System.out.println($x);} ;" + 2125 "a : 'a';\n"+ 2126 "b : 'b';\n"+ 2127 "WS : (' '|'\\n') {skip();};\n"; 2128 String expecting = "[a, b]\na b\n"; 2129 String found = execParser("T.g", grammar, "TParser", "TLexer", 2130 "s", "a b", false); 2131 assertEquals(expecting, found); 2132 } 2133 testRuleLabelOnTwoDifferentRulesTemplate()2134 @Test public void testRuleLabelOnTwoDifferentRulesTemplate() throws Exception { 2135 String grammar = 2136 "grammar T;\n"+ 2137 "options {output=template;}\n"+ 2138 "s : x+=a x+=b {System.out.println($x);} ;" + 2139 "a : 'a' -> {%{\"hi\"}} ;\n"+ 2140 "b : 'b' -> {%{\"mom\"}} ;\n"+ 2141 "WS : (' '|'\\n') {skip();};\n"; 2142 String expecting = "[hi, mom]\n"; 2143 String found = execParser("T.g", grammar, "TParser", "TLexer", 2144 "s", "a b", false); 2145 assertEquals(expecting, found); 2146 } 2147 testMissingArgs()2148 @Test public void testMissingArgs() throws Exception { 2149 ErrorQueue equeue = new ErrorQueue(); 2150 ErrorManager.setErrorListener(equeue); 2151 Grammar g = new Grammar( 2152 "grammar t;\n"+ 2153 "a : r ;" + 2154 "r[int i] : 'a';\n"); 2155 Tool antlr = newTool(); 2156 antlr.setOutputDirectory(null); // write to /dev/null 2157 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2158 g.setCodeGenerator(generator); 2159 generator.genRecognizer(); 2160 2161 int expectedMsgID = ErrorManager.MSG_MISSING_RULE_ARGS; 2162 Object expectedArg = "r"; 2163 Object expectedArg2 = null; 2164 GrammarSemanticsMessage expectedMessage = 2165 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2166 checkError(equeue, expectedMessage); 2167 } 2168 testArgsWhenNoneDefined()2169 @Test public void testArgsWhenNoneDefined() throws Exception { 2170 ErrorQueue equeue = new ErrorQueue(); 2171 ErrorManager.setErrorListener(equeue); 2172 Grammar g = new Grammar( 2173 "grammar t;\n"+ 2174 "a : r[32,34] ;" + 2175 "r : 'a';\n"); 2176 Tool antlr = newTool(); 2177 antlr.setOutputDirectory(null); // write to /dev/null 2178 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2179 g.setCodeGenerator(generator); 2180 generator.genRecognizer(); 2181 2182 int expectedMsgID = ErrorManager.MSG_RULE_HAS_NO_ARGS; 2183 Object expectedArg = "r"; 2184 Object expectedArg2 = null; 2185 GrammarSemanticsMessage expectedMessage = 2186 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2187 checkError(equeue, expectedMessage); 2188 } 2189 testReturnInitValue()2190 @Test public void testReturnInitValue() throws Exception { 2191 ErrorQueue equeue = new ErrorQueue(); 2192 ErrorManager.setErrorListener(equeue); 2193 Grammar g = new Grammar( 2194 "grammar t;\n"+ 2195 "a : r ;\n" + 2196 "r returns [int x=0] : 'a' {$x = 4;} ;\n"); 2197 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2198 2199 Rule r = g.getRule("r"); 2200 AttributeScope retScope = r.returnScope; 2201 List<Attribute> parameters = retScope.getAttributes(); 2202 assertNotNull("missing return action", parameters); 2203 assertEquals(1, parameters.size()); 2204 String found = parameters.get(0).toString(); 2205 String expecting = "int x=0"; 2206 assertEquals(expecting, found); 2207 } 2208 testMultipleReturnInitValue()2209 @Test public void testMultipleReturnInitValue() throws Exception { 2210 ErrorQueue equeue = new ErrorQueue(); 2211 ErrorManager.setErrorListener(equeue); 2212 Grammar g = new Grammar( 2213 "grammar t;\n"+ 2214 "a : r ;\n" + 2215 "r returns [int x=0, int y, String s=new String(\"foo\")] : 'a' {$x = 4;} ;\n"); 2216 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2217 2218 Rule r = g.getRule("r"); 2219 AttributeScope retScope = r.returnScope; 2220 List<Attribute> parameters = retScope.getAttributes(); 2221 assertNotNull("missing return action", parameters); 2222 assertEquals(3, parameters.size()); 2223 assertEquals("int x=0", parameters.get(0).toString()); 2224 assertEquals("int y", parameters.get(1).toString()); 2225 assertEquals("String s=new String(\"foo\")", parameters.get(2).toString()); 2226 } 2227 testCStyleReturnInitValue()2228 @Test public void testCStyleReturnInitValue() throws Exception { 2229 ErrorQueue equeue = new ErrorQueue(); 2230 ErrorManager.setErrorListener(equeue); 2231 Grammar g = new Grammar( 2232 "grammar t;\n"+ 2233 "a : r ;\n" + 2234 "r returns [int (*x)()=NULL] : 'a' ;\n"); 2235 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2236 2237 Rule r = g.getRule("r"); 2238 AttributeScope retScope = r.returnScope; 2239 List<Attribute> parameters = retScope.getAttributes(); 2240 assertNotNull("missing return action", parameters); 2241 assertEquals(1, parameters.size()); 2242 String found = parameters.get(0).toString(); 2243 String expecting = "int (*)() x=NULL"; 2244 assertEquals(expecting, found); 2245 } 2246 testArgsWithInitValues()2247 @Test public void testArgsWithInitValues() throws Exception { 2248 ErrorQueue equeue = new ErrorQueue(); 2249 ErrorManager.setErrorListener(equeue); 2250 Grammar g = new Grammar( 2251 "grammar t;\n"+ 2252 "a : r[32,34] ;" + 2253 "r[int x, int y=3] : 'a';\n"); 2254 Tool antlr = newTool(); 2255 antlr.setOutputDirectory(null); // write to /dev/null 2256 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2257 g.setCodeGenerator(generator); 2258 generator.genRecognizer(); 2259 2260 int expectedMsgID = ErrorManager.MSG_ARG_INIT_VALUES_ILLEGAL; 2261 Object expectedArg = "y"; 2262 Object expectedArg2 = null; 2263 GrammarSemanticsMessage expectedMessage = 2264 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2265 checkError(equeue, expectedMessage); 2266 } 2267 testArgsOnToken()2268 @Test public void testArgsOnToken() throws Exception { 2269 ErrorQueue equeue = new ErrorQueue(); 2270 ErrorManager.setErrorListener(equeue); 2271 Grammar g = new Grammar( 2272 "grammar t;\n"+ 2273 "a : ID[32,34] ;" + 2274 "ID : 'a';\n"); 2275 Tool antlr = newTool(); 2276 antlr.setOutputDirectory(null); // write to /dev/null 2277 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2278 g.setCodeGenerator(generator); 2279 generator.genRecognizer(); 2280 2281 int expectedMsgID = ErrorManager.MSG_ARGS_ON_TOKEN_REF; 2282 Object expectedArg = "ID"; 2283 Object expectedArg2 = null; 2284 GrammarSemanticsMessage expectedMessage = 2285 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2286 checkError(equeue, expectedMessage); 2287 } 2288 testArgsOnTokenInLexer()2289 @Test public void testArgsOnTokenInLexer() throws Exception { 2290 ErrorQueue equeue = new ErrorQueue(); 2291 ErrorManager.setErrorListener(equeue); 2292 Grammar g = new Grammar( 2293 "lexer grammar t;\n"+ 2294 "R : 'z' ID[32,34] ;" + 2295 "ID : 'a';\n"); 2296 Tool antlr = newTool(); 2297 antlr.setOutputDirectory(null); // write to /dev/null 2298 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2299 g.setCodeGenerator(generator); 2300 generator.genRecognizer(); 2301 2302 int expectedMsgID = ErrorManager.MSG_RULE_HAS_NO_ARGS; 2303 Object expectedArg = "ID"; 2304 Object expectedArg2 = null; 2305 GrammarSemanticsMessage expectedMessage = 2306 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2307 checkError(equeue, expectedMessage); 2308 } 2309 testLabelOnRuleRefInLexer()2310 @Test public void testLabelOnRuleRefInLexer() throws Exception { 2311 String action = "$i.text"; 2312 String expecting = "(i!=null?i.getText():null)"; 2313 ErrorQueue equeue = new ErrorQueue(); 2314 ErrorManager.setErrorListener(equeue); 2315 Grammar g = new Grammar( 2316 "lexer grammar t;\n"+ 2317 "R : 'z' i=ID {"+action+"};" + 2318 "fragment ID : 'a';\n"); 2319 Tool antlr = newTool(); 2320 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2321 g.setCodeGenerator(generator); 2322 generator.genRecognizer(); // forces load of templates 2323 ActionTranslator translator = 2324 new ActionTranslator(generator, 2325 "R", 2326 new CommonToken(ANTLRParser.ACTION,action),1); 2327 String found = translator.translate(); 2328 assertEquals(expecting, found); 2329 2330 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2331 } 2332 testRefToRuleRefInLexer()2333 @Test public void testRefToRuleRefInLexer() throws Exception { 2334 String action = "$ID.text"; 2335 String expecting = "(ID1!=null?ID1.getText():null)"; 2336 ErrorQueue equeue = new ErrorQueue(); 2337 ErrorManager.setErrorListener(equeue); 2338 Grammar g = new Grammar( 2339 "lexer grammar t;\n"+ 2340 "R : 'z' ID {"+action+"};" + 2341 "ID : 'a';\n"); 2342 Tool antlr = newTool(); 2343 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2344 g.setCodeGenerator(generator); 2345 generator.genRecognizer(); // forces load of templates 2346 ActionTranslator translator = 2347 new ActionTranslator(generator, 2348 "R", 2349 new CommonToken(ANTLRParser.ACTION,action),1); 2350 String found = translator.translate(); 2351 assertEquals(expecting, found); 2352 2353 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2354 } 2355 testRefToRuleRefInLexerNoAttribute()2356 @Test public void testRefToRuleRefInLexerNoAttribute() throws Exception { 2357 String action = "$ID"; 2358 String expecting = "ID1"; 2359 ErrorQueue equeue = new ErrorQueue(); 2360 ErrorManager.setErrorListener(equeue); 2361 Grammar g = new Grammar( 2362 "lexer grammar t;\n"+ 2363 "R : 'z' ID {"+action+"};" + 2364 "ID : 'a';\n"); 2365 Tool antlr = newTool(); 2366 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2367 g.setCodeGenerator(generator); 2368 generator.genRecognizer(); // forces load of templates 2369 ActionTranslator translator = 2370 new ActionTranslator(generator, 2371 "R", 2372 new CommonToken(ANTLRParser.ACTION,action),1); 2373 String found = translator.translate(); 2374 assertEquals(expecting, found); 2375 2376 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2377 } 2378 testCharLabelInLexer()2379 @Test public void testCharLabelInLexer() throws Exception { 2380 ErrorQueue equeue = new ErrorQueue(); 2381 ErrorManager.setErrorListener(equeue); 2382 Grammar g = new Grammar( 2383 "lexer grammar t;\n"+ 2384 "R : x='z' ;\n"); 2385 2386 Tool antlr = newTool(); 2387 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2388 g.setCodeGenerator(generator); 2389 generator.genRecognizer(); // forces load of templates 2390 2391 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2392 } 2393 testCharListLabelInLexer()2394 @Test public void testCharListLabelInLexer() throws Exception { 2395 ErrorQueue equeue = new ErrorQueue(); 2396 ErrorManager.setErrorListener(equeue); 2397 Grammar g = new Grammar( 2398 "lexer grammar t;\n"+ 2399 "R : x+='z' ;\n"); 2400 2401 Tool antlr = newTool(); 2402 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2403 g.setCodeGenerator(generator); 2404 generator.genRecognizer(); // forces load of templates 2405 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2406 } 2407 testWildcardCharLabelInLexer()2408 @Test public void testWildcardCharLabelInLexer() throws Exception { 2409 ErrorQueue equeue = new ErrorQueue(); 2410 ErrorManager.setErrorListener(equeue); 2411 Grammar g = new Grammar( 2412 "lexer grammar t;\n"+ 2413 "R : x=. ;\n"); 2414 2415 Tool antlr = newTool(); 2416 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2417 g.setCodeGenerator(generator); 2418 generator.genRecognizer(); // forces load of templates 2419 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2420 } 2421 testWildcardCharListLabelInLexer()2422 @Test public void testWildcardCharListLabelInLexer() throws Exception { 2423 ErrorQueue equeue = new ErrorQueue(); 2424 ErrorManager.setErrorListener(equeue); 2425 Grammar g = new Grammar( 2426 "lexer grammar t;\n"+ 2427 "R : x+=. ;\n"); 2428 2429 Tool antlr = newTool(); 2430 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2431 g.setCodeGenerator(generator); 2432 generator.genRecognizer(); // forces load of templates 2433 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2434 } 2435 testMissingArgsInLexer()2436 @Test public void testMissingArgsInLexer() throws Exception { 2437 ErrorQueue equeue = new ErrorQueue(); 2438 ErrorManager.setErrorListener(equeue); 2439 Grammar g = new Grammar( 2440 "lexer grammar t;\n"+ 2441 "A : R ;" + 2442 "R[int i] : 'a';\n"); 2443 Tool antlr = newTool(); 2444 antlr.setOutputDirectory(null); // write to /dev/null 2445 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2446 g.setCodeGenerator(generator); 2447 generator.genRecognizer(); 2448 2449 int expectedMsgID = ErrorManager.MSG_MISSING_RULE_ARGS; 2450 Object expectedArg = "R"; 2451 Object expectedArg2 = null; 2452 // getting a second error @1:12, probably from nextToken 2453 GrammarSemanticsMessage expectedMessage = 2454 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2455 checkError(equeue, expectedMessage); 2456 } 2457 testLexerRulePropertyRefs()2458 @Test public void testLexerRulePropertyRefs() throws Exception { 2459 String action = "$text $type $line $pos $channel $index $start $stop"; 2460 String expecting = "getText() _type state.tokenStartLine state.tokenStartCharPositionInLine _channel -1 state.tokenStartCharIndex (getCharIndex()-1)"; 2461 ErrorQueue equeue = new ErrorQueue(); 2462 ErrorManager.setErrorListener(equeue); 2463 Grammar g = new Grammar( 2464 "lexer grammar t;\n"+ 2465 "R : 'r' {"+action+"};\n"); 2466 Tool antlr = newTool(); 2467 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2468 g.setCodeGenerator(generator); 2469 generator.genRecognizer(); // forces load of templates 2470 ActionTranslator translator = 2471 new ActionTranslator(generator, 2472 "R", 2473 new CommonToken(ANTLRParser.ACTION,action),1); 2474 String found = translator.translate(); 2475 assertEquals(expecting, found); 2476 2477 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2478 } 2479 testLexerLabelRefs()2480 @Test public void testLexerLabelRefs() throws Exception { 2481 String action = "$a $b.text $c $d.text"; 2482 String expecting = "a (b!=null?b.getText():null) c (d!=null?d.getText():null)"; 2483 ErrorQueue equeue = new ErrorQueue(); 2484 ErrorManager.setErrorListener(equeue); 2485 Grammar g = new Grammar( 2486 "lexer grammar t;\n"+ 2487 "R : a='c' b='hi' c=. d=DUH {"+action+"};\n" + 2488 "DUH : 'd' ;\n"); 2489 Tool antlr = newTool(); 2490 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2491 g.setCodeGenerator(generator); 2492 generator.genRecognizer(); // forces load of templates 2493 ActionTranslator translator = 2494 new ActionTranslator(generator, 2495 "R", 2496 new CommonToken(ANTLRParser.ACTION,action),1); 2497 String found = translator.translate(); 2498 assertEquals(expecting, found); 2499 2500 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2501 } 2502 testSettingLexerRulePropertyRefs()2503 @Test public void testSettingLexerRulePropertyRefs() throws Exception { 2504 String action = "$text $type=1 $line=1 $pos=1 $channel=1 $index"; 2505 String expecting = "getText() _type=1 state.tokenStartLine=1 state.tokenStartCharPositionInLine=1 _channel=1 -1"; 2506 ErrorQueue equeue = new ErrorQueue(); 2507 ErrorManager.setErrorListener(equeue); 2508 Grammar g = new Grammar( 2509 "lexer grammar t;\n"+ 2510 "R : 'r' {"+action+"};\n"); 2511 Tool antlr = newTool(); 2512 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2513 g.setCodeGenerator(generator); 2514 generator.genRecognizer(); // forces load of templates 2515 ActionTranslator translator = 2516 new ActionTranslator(generator, 2517 "R", 2518 new CommonToken(ANTLRParser.ACTION,action),1); 2519 String found = translator.translate(); 2520 assertEquals(expecting, found); 2521 2522 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2523 } 2524 testArgsOnTokenInLexerRuleOfCombined()2525 @Test public void testArgsOnTokenInLexerRuleOfCombined() throws Exception { 2526 ErrorQueue equeue = new ErrorQueue(); 2527 ErrorManager.setErrorListener(equeue); 2528 Grammar g = new Grammar( 2529 "grammar t;\n"+ 2530 "a : R;\n" + 2531 "R : 'z' ID[32] ;\n" + 2532 "ID : 'a';\n"); 2533 2534 String lexerGrammarStr = g.getLexerGrammar(); 2535 StringReader sr = new StringReader(lexerGrammarStr); 2536 Grammar lexerGrammar = new Grammar(); 2537 lexerGrammar.setFileName("<internally-generated-lexer>"); 2538 lexerGrammar.importTokenVocabulary(g); 2539 lexerGrammar.parseAndBuildAST(sr); 2540 lexerGrammar.defineGrammarSymbols(); 2541 lexerGrammar.checkNameSpaceAndActions(); 2542 sr.close(); 2543 2544 Tool antlr = newTool(); 2545 antlr.setOutputDirectory(null); // write to /dev/null 2546 CodeGenerator generator = new CodeGenerator(antlr, lexerGrammar, "Java"); 2547 lexerGrammar.setCodeGenerator(generator); 2548 generator.genRecognizer(); 2549 2550 int expectedMsgID = ErrorManager.MSG_RULE_HAS_NO_ARGS; 2551 Object expectedArg = "ID"; 2552 Object expectedArg2 = null; 2553 GrammarSemanticsMessage expectedMessage = 2554 new GrammarSemanticsMessage(expectedMsgID, lexerGrammar, null, expectedArg, expectedArg2); 2555 checkError(equeue, expectedMessage); 2556 } 2557 testMissingArgsOnTokenInLexerRuleOfCombined()2558 @Test public void testMissingArgsOnTokenInLexerRuleOfCombined() throws Exception { 2559 ErrorQueue equeue = new ErrorQueue(); 2560 ErrorManager.setErrorListener(equeue); 2561 Grammar g = new Grammar( 2562 "grammar t;\n"+ 2563 "a : R;\n" + 2564 "R : 'z' ID ;\n" + 2565 "ID[int i] : 'a';\n"); 2566 2567 String lexerGrammarStr = g.getLexerGrammar(); 2568 StringReader sr = new StringReader(lexerGrammarStr); 2569 Grammar lexerGrammar = new Grammar(); 2570 lexerGrammar.setFileName("<internally-generated-lexer>"); 2571 lexerGrammar.importTokenVocabulary(g); 2572 lexerGrammar.parseAndBuildAST(sr); 2573 lexerGrammar.defineGrammarSymbols(); 2574 lexerGrammar.checkNameSpaceAndActions(); 2575 sr.close(); 2576 2577 Tool antlr = newTool(); 2578 antlr.setOutputDirectory(null); // write to /dev/null 2579 CodeGenerator generator = new CodeGenerator(antlr, lexerGrammar, "Java"); 2580 lexerGrammar.setCodeGenerator(generator); 2581 generator.genRecognizer(); 2582 2583 int expectedMsgID = ErrorManager.MSG_MISSING_RULE_ARGS; 2584 Object expectedArg = "ID"; 2585 Object expectedArg2 = null; 2586 GrammarSemanticsMessage expectedMessage = 2587 new GrammarSemanticsMessage(expectedMsgID, lexerGrammar, null, expectedArg, expectedArg2); 2588 checkError(equeue, expectedMessage); 2589 } 2590 2591 // T R E E S 2592 testTokenLabelTreeProperty()2593 @Test public void testTokenLabelTreeProperty() throws Exception { 2594 String action = "$id.tree;"; 2595 String expecting = "id_tree;"; 2596 2597 ErrorQueue equeue = new ErrorQueue(); 2598 ErrorManager.setErrorListener(equeue); 2599 Grammar g = new Grammar( 2600 "grammar t;\n"+ 2601 "a : id=ID {"+action+"} ;\n" + 2602 "ID : 'a';\n"); 2603 2604 Tool antlr = newTool(); 2605 antlr.setOutputDirectory(null); // write to /dev/null 2606 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2607 ActionTranslator translator = 2608 new ActionTranslator(generator, 2609 "a", 2610 new CommonToken(ANTLRParser.ACTION,action),1); 2611 g.setCodeGenerator(generator); 2612 generator.genRecognizer(); // forces load of templates 2613 String found = translator.translate(); 2614 assertEquals(expecting, found); 2615 2616 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2617 } 2618 testTokenRefTreeProperty()2619 @Test public void testTokenRefTreeProperty() throws Exception { 2620 String action = "$ID.tree;"; 2621 String expecting = "ID1_tree;"; 2622 2623 ErrorQueue equeue = new ErrorQueue(); 2624 ErrorManager.setErrorListener(equeue); 2625 Grammar g = new Grammar( 2626 "grammar t;\n"+ 2627 "a : ID {"+action+"} ;" + 2628 "ID : 'a';\n"); 2629 Tool antlr = newTool(); 2630 antlr.setOutputDirectory(null); // write to /dev/null 2631 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2632 g.setCodeGenerator(generator); 2633 generator.genRecognizer(); 2634 2635 ActionTranslator translator = new ActionTranslator(generator,"a", 2636 new CommonToken(ANTLRParser.ACTION,action),1); 2637 String found = translator.translate(); 2638 assertEquals(expecting, found); 2639 } 2640 testAmbiguousTokenRef()2641 @Test public void testAmbiguousTokenRef() throws Exception { 2642 String action = "$ID;"; 2643 String expecting = ""; 2644 2645 ErrorQueue equeue = new ErrorQueue(); 2646 ErrorManager.setErrorListener(equeue); 2647 Grammar g = new Grammar( 2648 "grammar t;\n"+ 2649 "a : ID ID {"+action+"};" + 2650 "ID : 'a';\n"); 2651 Tool antlr = newTool(); 2652 antlr.setOutputDirectory(null); // write to /dev/null 2653 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2654 g.setCodeGenerator(generator); 2655 generator.genRecognizer(); 2656 2657 int expectedMsgID = ErrorManager.MSG_NONUNIQUE_REF; 2658 Object expectedArg = "ID"; 2659 GrammarSemanticsMessage expectedMessage = 2660 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 2661 checkError(equeue, expectedMessage); 2662 } 2663 testAmbiguousTokenRefWithProp()2664 @Test public void testAmbiguousTokenRefWithProp() throws Exception { 2665 String action = "$ID.text;"; 2666 String expecting = ""; 2667 2668 ErrorQueue equeue = new ErrorQueue(); 2669 ErrorManager.setErrorListener(equeue); 2670 Grammar g = new Grammar( 2671 "grammar t;\n"+ 2672 "a : ID ID {"+action+"};" + 2673 "ID : 'a';\n"); 2674 Tool antlr = newTool(); 2675 antlr.setOutputDirectory(null); // write to /dev/null 2676 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2677 g.setCodeGenerator(generator); 2678 generator.genRecognizer(); 2679 2680 int expectedMsgID = ErrorManager.MSG_NONUNIQUE_REF; 2681 Object expectedArg = "ID"; 2682 GrammarSemanticsMessage expectedMessage = 2683 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg); 2684 checkError(equeue, expectedMessage); 2685 } 2686 testRuleRefWithDynamicScope()2687 @Test public void testRuleRefWithDynamicScope() throws Exception { 2688 String action = "$field::x = $field.st;"; 2689 String expecting = "field_stack.peek().x = retval.st;"; 2690 2691 ErrorQueue equeue = new ErrorQueue(); 2692 ErrorManager.setErrorListener(equeue); 2693 Grammar g = new Grammar( 2694 "grammar a;\n" + 2695 "field\n" + 2696 "scope { ST x; }\n" + 2697 " : 'y' {"+action+"}\n" + 2698 " ;\n"); 2699 Tool antlr = newTool(); 2700 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2701 g.setCodeGenerator(generator); 2702 generator.genRecognizer(); // forces load of templates 2703 ActionTranslator translator = new ActionTranslator(generator, 2704 "field", 2705 new CommonToken(ANTLRParser.ACTION,action),1); 2706 String found = translator.translate(); 2707 assertEquals(expecting, found); 2708 2709 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2710 } 2711 testAssignToOwnRulenameAttr()2712 @Test public void testAssignToOwnRulenameAttr() throws Exception { 2713 String action = "$rule.tree = null;"; 2714 String expecting = "retval.tree = null;"; 2715 ErrorQueue equeue = new ErrorQueue(); 2716 ErrorManager.setErrorListener(equeue); 2717 Grammar g = new Grammar( 2718 "grammar a;\n" + 2719 "rule\n" + 2720 " : 'y' {" + action +"}\n" + 2721 " ;"); 2722 Tool antlr = newTool(); 2723 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2724 g.setCodeGenerator(generator); 2725 generator.genRecognizer(); // forces load of templates 2726 ActionTranslator translator = new ActionTranslator(generator, 2727 "rule", 2728 new CommonToken(ANTLRParser.ACTION,action),1); 2729 String found = translator.translate(); 2730 assertEquals(expecting, found); 2731 2732 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2733 } 2734 testAssignToOwnParamAttr()2735 @Test public void testAssignToOwnParamAttr() throws Exception { 2736 String action = "$rule.i = 42; $i = 23;"; 2737 String expecting = "i = 42; i = 23;"; 2738 ErrorQueue equeue = new ErrorQueue(); 2739 ErrorManager.setErrorListener(equeue); 2740 Grammar g = new Grammar( 2741 "grammar a;\n" + 2742 "rule[int i]\n" + 2743 " : 'y' {" + action +"}\n" + 2744 " ;"); 2745 Tool antlr = newTool(); 2746 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2747 g.setCodeGenerator(generator); 2748 generator.genRecognizer(); // forces load of templates 2749 ActionTranslator translator = new ActionTranslator(generator, 2750 "rule", 2751 new CommonToken(ANTLRParser.ACTION,action),1); 2752 String found = translator.translate(); 2753 assertEquals(expecting, found); 2754 2755 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2756 } 2757 testIllegalAssignToOwnRulenameAttr()2758 @Test public void testIllegalAssignToOwnRulenameAttr() throws Exception { 2759 String action = "$rule.stop = 0;"; 2760 ErrorQueue equeue = new ErrorQueue(); 2761 ErrorManager.setErrorListener(equeue); 2762 Grammar g = new Grammar( 2763 "grammar a;\n" + 2764 "rule\n" + 2765 " : 'y' {" + action +"}\n" + 2766 " ;"); 2767 Tool antlr = newTool(); 2768 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2769 g.setCodeGenerator(generator); 2770 generator.genRecognizer(); // forces load of templates 2771 ActionTranslator translator = new ActionTranslator(generator, 2772 "rule", 2773 new CommonToken(ANTLRParser.ACTION,action),1); 2774 String rawTranslation = 2775 translator.translate(); 2776 2777 int expectedMsgID = ErrorManager.MSG_WRITE_TO_READONLY_ATTR; 2778 Object expectedArg = "rule"; 2779 Object expectedArg2 = "stop"; 2780 GrammarSemanticsMessage expectedMessage = 2781 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2782 checkError(equeue, expectedMessage); 2783 } 2784 testIllegalAssignToLocalAttr()2785 @Test public void testIllegalAssignToLocalAttr() throws Exception { 2786 String action = "$tree = null; $st = null; $start = 0; $stop = 0; $text = 0;"; 2787 String expecting = "retval.tree = null; retval.st = null; "; 2788 ErrorQueue equeue = new ErrorQueue(); 2789 ErrorManager.setErrorListener(equeue); 2790 Grammar g = new Grammar( 2791 "grammar a;\n" + 2792 "rule\n" + 2793 " : 'y' {" + action +"}\n" + 2794 " ;"); 2795 Tool antlr = newTool(); 2796 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2797 g.setCodeGenerator(generator); 2798 generator.genRecognizer(); // forces load of templates 2799 ActionTranslator translator = new ActionTranslator(generator, 2800 "rule", 2801 new CommonToken(ANTLRParser.ACTION,action),1); 2802 String rawTranslation = 2803 translator.translate(); 2804 2805 int expectedMsgID = ErrorManager.MSG_WRITE_TO_READONLY_ATTR; 2806 ArrayList<Message> expectedErrors = new ArrayList<Message>(3); 2807 GrammarSemanticsMessage expectedMessage = 2808 new GrammarSemanticsMessage(expectedMsgID, g, null, "start", ""); 2809 expectedErrors.add(expectedMessage); 2810 GrammarSemanticsMessage expectedMessage2 = 2811 new GrammarSemanticsMessage(expectedMsgID, g, null, "stop", ""); 2812 expectedErrors.add(expectedMessage2); 2813 GrammarSemanticsMessage expectedMessage3 = 2814 new GrammarSemanticsMessage(expectedMsgID, g, null, "text", ""); 2815 expectedErrors.add(expectedMessage3); 2816 checkErrors(equeue, expectedErrors); 2817 2818 STGroup templates = 2819 new STGroup(); 2820 ST actionST = new ST(templates, rawTranslation); 2821 String found = actionST.render(); 2822 assertEquals(expecting, found); 2823 } 2824 testIllegalAssignRuleRefAttr()2825 @Test public void testIllegalAssignRuleRefAttr() throws Exception { 2826 String action = "$other.tree = null;"; 2827 ErrorQueue equeue = new ErrorQueue(); 2828 ErrorManager.setErrorListener(equeue); 2829 Grammar g = new Grammar( 2830 "grammar a;\n" + 2831 "options { output = AST;}" + 2832 "otherrule\n" + 2833 " : 'y' ;" + 2834 "rule\n" + 2835 " : other=otherrule {" + action +"}\n" + 2836 " ;"); 2837 Tool antlr = newTool(); 2838 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2839 g.setCodeGenerator(generator); 2840 generator.genRecognizer(); // forces load of templates 2841 ActionTranslator translator = new ActionTranslator(generator, 2842 "rule", 2843 new CommonToken(ANTLRParser.ACTION,action),1); 2844 String rawTranslation = 2845 translator.translate(); 2846 2847 int expectedMsgID = ErrorManager.MSG_WRITE_TO_READONLY_ATTR; 2848 Object expectedArg = "other"; 2849 Object expectedArg2 = "tree"; 2850 GrammarSemanticsMessage expectedMessage = 2851 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2852 checkError(equeue, expectedMessage); 2853 } 2854 testIllegalAssignTokenRefAttr()2855 @Test public void testIllegalAssignTokenRefAttr() throws Exception { 2856 String action = "$ID.text = \"test\";"; 2857 ErrorQueue equeue = new ErrorQueue(); 2858 ErrorManager.setErrorListener(equeue); 2859 Grammar g = new Grammar( 2860 "grammar a;\n" + 2861 "ID\n" + 2862 " : 'y' ;" + 2863 "rule\n" + 2864 " : ID {" + action +"}\n" + 2865 " ;"); 2866 Tool antlr = newTool(); 2867 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2868 g.setCodeGenerator(generator); 2869 generator.genRecognizer(); // forces load of templates 2870 ActionTranslator translator = new ActionTranslator(generator, 2871 "rule", 2872 new CommonToken(ANTLRParser.ACTION,action),1); 2873 String rawTranslation = 2874 translator.translate(); 2875 2876 int expectedMsgID = ErrorManager.MSG_WRITE_TO_READONLY_ATTR; 2877 Object expectedArg = "ID"; 2878 Object expectedArg2 = "text"; 2879 GrammarSemanticsMessage expectedMessage = 2880 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 2881 checkError(equeue, expectedMessage); 2882 } 2883 testAssignToTreeNodeAttribute()2884 @Test public void testAssignToTreeNodeAttribute() throws Exception { 2885 String action = "$tree.scope = localScope;"; 2886 String expecting = "retval.tree.scope = localScope;"; 2887 ErrorQueue equeue = new ErrorQueue(); 2888 ErrorManager.setErrorListener(equeue); 2889 Grammar g = new Grammar( 2890 "grammar a;\n" + 2891 "options { output=AST; }" + 2892 "rule\n" + 2893 "@init {\n" + 2894 " Scope localScope=null;\n" + 2895 "}\n" + 2896 "@after {\n" + 2897 " ###$tree.scope = localScope;!!!\n" + 2898 "}\n" + 2899 " : 'a' -> ^('a')\n" + 2900 ";"); 2901 Tool antlr = newTool(); 2902 2903 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2904 g.setCodeGenerator(generator); 2905 generator.genRecognizer(); // codegen phase sets some vars we need 2906 ST codeST = generator.getRecognizerST(); 2907 String code = codeST.render(); 2908 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 2909 assertEquals(expecting, found); 2910 2911 } 2912 testDoNotTranslateAttributeCompare()2913 @Test public void testDoNotTranslateAttributeCompare() throws Exception { 2914 String action = "$a.line == $b.line"; 2915 String expecting = "(a!=null?a.getLine():0) == (b!=null?b.getLine():0)"; 2916 ErrorQueue equeue = new ErrorQueue(); 2917 ErrorManager.setErrorListener(equeue); 2918 Grammar g = new Grammar( 2919 "lexer grammar a;\n" + 2920 "RULE:\n" + 2921 " a=ID b=ID {" + action + "}" + 2922 " ;\n" + 2923 "ID : 'id';" 2924 ); 2925 Tool antlr = newTool(); 2926 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2927 g.setCodeGenerator(generator); 2928 generator.genRecognizer(); 2929 ActionTranslator translator = new ActionTranslator(generator, 2930 "RULE", 2931 new CommonToken(ANTLRParser.ACTION,action),1); 2932 String found = translator.translate(); 2933 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2934 assertEquals(expecting, found); 2935 } 2936 testDoNotTranslateScopeAttributeCompare()2937 @Test public void testDoNotTranslateScopeAttributeCompare() throws Exception { 2938 String action = "if ($rule::foo == \"foo\" || 1) { System.out.println(\"ouch\"); }"; 2939 String expecting = "if (rule_stack.peek().foo == \"foo\" || 1) { System.out.println(\"ouch\"); }"; 2940 ErrorQueue equeue = new ErrorQueue(); 2941 ErrorManager.setErrorListener(equeue); 2942 Grammar g = new Grammar( 2943 "grammar a;\n" + 2944 "rule\n" + 2945 "scope {\n" + 2946 " String foo;" + 2947 "} :\n" + 2948 " twoIDs" + 2949 " ;\n" + 2950 "twoIDs:\n" + 2951 " ID ID {" + action + "}\n" + 2952 " ;\n" + 2953 "ID : 'id';" 2954 ); 2955 Tool antlr = newTool(); 2956 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 2957 g.setCodeGenerator(generator); 2958 generator.genRecognizer(); 2959 ActionTranslator translator = new ActionTranslator(generator, 2960 "twoIDs", 2961 new CommonToken(ANTLRParser.ACTION,action),1); 2962 String rawTranslation = 2963 translator.translate(); 2964 // check that we didn't use scopeSetAttributeRef int translation! 2965 boolean foundScopeSetAttributeRef = false; 2966 for (int i = 0; i < translator.chunks.size(); i++) { 2967 Object chunk = translator.chunks.get(i); 2968 if (chunk instanceof ST) { 2969 if (((ST)chunk).getName().equals("/scopeSetAttributeRef")) { 2970 foundScopeSetAttributeRef = true; 2971 } 2972 } 2973 } 2974 assertFalse("action translator used scopeSetAttributeRef template in comparison!", foundScopeSetAttributeRef); 2975 STGroup templates = 2976 new STGroup(); 2977 ST actionST = new ST(templates, rawTranslation); 2978 String found = actionST.render(); 2979 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 2980 assertEquals(expecting, found); 2981 } 2982 testTreeRuleStopAttributeIsInvalid()2983 @Test public void testTreeRuleStopAttributeIsInvalid() throws Exception { 2984 String action = "$r.x; $r.start; $r.stop"; 2985 String expecting = "(r!=null?((t.a_return)r).x:0); (r!=null?((CommonTree)r.start):null); $r.stop"; 2986 2987 ErrorQueue equeue = new ErrorQueue(); 2988 ErrorManager.setErrorListener(equeue); 2989 Grammar g = new Grammar( 2990 "tree grammar t;\n" + 2991 "options {ASTLabelType=CommonTree;}\n"+ 2992 "a returns [int x]\n" + 2993 " :\n" + 2994 " ;\n"+ 2995 "b : r=a {###"+action+"!!!}\n" + 2996 " ;"); 2997 System.out.println(g.toString()); 2998 Tool antlr = newTool(); 2999 antlr.setOutputDirectory(null); // write to /dev/null 3000 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 3001 g.setCodeGenerator(generator); 3002 generator.genRecognizer(); // codegen phase sets some vars we need 3003 ST codeST = generator.getRecognizerST(); 3004 String code = codeST.render(); 3005 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 3006 assertEquals(expecting, found); 3007 3008 int expectedMsgID = ErrorManager.MSG_UNKNOWN_RULE_ATTRIBUTE; 3009 Object expectedArg = "a"; 3010 Object expectedArg2 = "stop"; 3011 GrammarSemanticsMessage expectedMessage = 3012 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2); 3013 System.out.println("equeue:"+equeue); 3014 checkError(equeue, expectedMessage); 3015 } 3016 testRefToTextAttributeForCurrentTreeRule()3017 @Test public void testRefToTextAttributeForCurrentTreeRule() throws Exception { 3018 String action = "$text"; 3019 String expecting = "input.getTokenStream().toString(" + 3020 "input.getTreeAdaptor().getTokenStartIndex(retval.start)," + 3021 "input.getTreeAdaptor().getTokenStopIndex(retval.start))"; 3022 3023 ErrorQueue equeue = new ErrorQueue(); 3024 ErrorManager.setErrorListener(equeue); 3025 Grammar g = new Grammar( 3026 "tree grammar t;\n" + 3027 "options {ASTLabelType=CommonTree;}\n" + 3028 "a : {###"+action+"!!!}\n" + 3029 " ;\n"); 3030 3031 Tool antlr = newTool(); 3032 antlr.setOutputDirectory(null); // write to /dev/null 3033 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 3034 g.setCodeGenerator(generator); 3035 generator.genRecognizer(); // codegen phase sets some vars we need 3036 ST codeST = generator.getRecognizerST(); 3037 String code = codeST.render(); 3038 String found = code.substring(code.indexOf("###")+3,code.indexOf("!!!")); 3039 assertEquals(expecting, found); 3040 3041 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 3042 } 3043 testTypeOfGuardedAttributeRefIsCorrect()3044 @Test public void testTypeOfGuardedAttributeRefIsCorrect() throws Exception { 3045 String action = "int x = $b::n;"; 3046 String expecting = "int x = b_stack.peek().n;"; 3047 3048 ErrorQueue equeue = new ErrorQueue(); 3049 ErrorManager.setErrorListener(equeue); 3050 Grammar g = new Grammar( 3051 "grammar t;\n" + 3052 "s : b ;\n"+ 3053 "b\n" + 3054 "scope {\n" + 3055 " int n;\n" + 3056 "} : '(' b ')' {"+action+"}\n" + // refers to current invocation's n 3057 " ;\n"); 3058 Tool antlr = newTool(); 3059 CodeGenerator generator = new CodeGenerator(antlr, g, "Java"); 3060 g.setCodeGenerator(generator); 3061 generator.genRecognizer(); // forces load of templates 3062 ActionTranslator translator = new ActionTranslator(generator, "b", 3063 new CommonToken(ANTLRParser.ACTION,action),1); 3064 String found = translator.translate(); 3065 assertEquals(expecting, found); 3066 3067 assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size()); 3068 } 3069 3070 // S U P P O R T 3071 checkError(ErrorQueue equeue, GrammarSemanticsMessage expectedMessage)3072 protected void checkError(ErrorQueue equeue, 3073 GrammarSemanticsMessage expectedMessage) 3074 throws Exception 3075 { 3076 /* 3077 System.out.println(equeue.infos); 3078 System.out.println(equeue.warnings); 3079 System.out.println(equeue.errors); 3080 */ 3081 Message foundMsg = null; 3082 for (int i = 0; i < equeue.errors.size(); i++) { 3083 Message m = equeue.errors.get(i); 3084 if (m.msgID==expectedMessage.msgID ) { 3085 foundMsg = m; 3086 } 3087 } 3088 assertTrue("no error; "+expectedMessage.msgID+" expected", equeue.errors.size() > 0); 3089 assertNotNull("couldn't find expected error: "+expectedMessage.msgID+" in "+equeue, foundMsg); 3090 assertTrue("error is not a GrammarSemanticsMessage", 3091 foundMsg instanceof GrammarSemanticsMessage); 3092 assertEquals(expectedMessage.arg, foundMsg.arg); 3093 assertEquals(expectedMessage.arg2, foundMsg.arg2); 3094 } 3095 3096 /** Allow checking for multiple errors in one test */ checkErrors(ErrorQueue equeue, ArrayList<Message> expectedMessages)3097 protected void checkErrors(ErrorQueue equeue, 3098 ArrayList<Message> expectedMessages) 3099 throws Exception 3100 { 3101 ArrayList<Boolean> messageExpected = new ArrayList<Boolean>(equeue.errors.size()); 3102 for (int i = 0; i < equeue.errors.size(); i++) { 3103 Message m = equeue.errors.get(i); 3104 boolean foundMsg = false; 3105 for (int j = 0; j < expectedMessages.size(); j++) { 3106 Message em = expectedMessages.get(j); 3107 if (m.msgID==em.msgID && m.arg.equals(em.arg) && m.arg2.equals(em.arg2)) { 3108 foundMsg = true; 3109 } 3110 } 3111 if (foundMsg) { 3112 messageExpected.add(i, Boolean.TRUE); 3113 } else 3114 messageExpected.add(i, Boolean.FALSE); 3115 } 3116 for (int i = 0; i < equeue.errors.size(); i++) { 3117 assertTrue("unexpected error:" + equeue.errors.get(i), messageExpected.get(i)); 3118 } 3119 } 3120 } 3121