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