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.junit.Ignore; 31 import org.junit.Test; 32 33 public class TestAutoAST extends BaseTest { 34 protected boolean debug = false; 35 testTokenList()36 @Test public void testTokenList() throws Exception { 37 String grammar = 38 "grammar foo;\n" + 39 "options {output=AST;}\n" + 40 "a : ID INT ;\n" + 41 "ID : 'a'..'z'+ ;\n" + 42 "INT : '0'..'9'+;\n" + 43 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 44 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 45 "a", "abc 34", debug); 46 assertEquals("abc 34\n", found); 47 } 48 testTokenListInSingleAltBlock()49 @Test public void testTokenListInSingleAltBlock() throws Exception { 50 String grammar = 51 "grammar foo;\n" + 52 "options {output=AST;}\n" + 53 "a : (ID INT) ;\n" + 54 "ID : 'a'..'z'+ ;\n" + 55 "INT : '0'..'9'+;\n" + 56 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 57 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 58 "a", "abc 34", debug); 59 assertEquals("abc 34\n", found); 60 } 61 testSimpleRootAtOuterLevel()62 @Test public void testSimpleRootAtOuterLevel() throws Exception { 63 String grammar = 64 "grammar foo;\n" + 65 "options {output=AST;}\n" + 66 "a : ID^ INT ;\n" + 67 "ID : 'a'..'z'+ ;\n" + 68 "INT : '0'..'9'+;\n" + 69 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 70 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 71 "a", "abc 34", debug); 72 assertEquals("(abc 34)\n", found); 73 } 74 testSimpleRootAtOuterLevelReverse()75 @Test public void testSimpleRootAtOuterLevelReverse() throws Exception { 76 String grammar = 77 "grammar T;\n" + 78 "options {output=AST;}\n" + 79 "a : INT ID^ ;\n" + 80 "ID : 'a'..'z'+ ;\n" + 81 "INT : '0'..'9'+;\n" + 82 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 83 String found = execParser("T.g", grammar, "TParser", "TLexer", 84 "a", "34 abc", debug); 85 assertEquals("(abc 34)\n", found); 86 } 87 testBang()88 @Test public void testBang() throws Exception { 89 String grammar = 90 "grammar T;\n" + 91 "options {output=AST;}\n" + 92 "a : ID INT! ID! INT ;\n" + 93 "ID : 'a'..'z'+ ;\n" + 94 "INT : '0'..'9'+;\n" + 95 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 96 String found = execParser("T.g", grammar, "TParser", "TLexer", 97 "a", "abc 34 dag 4532", debug); 98 assertEquals("abc 4532\n", found); 99 } 100 testOptionalThenRoot()101 @Test public void testOptionalThenRoot() throws Exception { 102 String grammar = 103 "grammar T;\n" + 104 "options {output=AST;}\n" + 105 "a : ( ID INT )? ID^ ;\n" + 106 "ID : 'a'..'z'+ ;\n" + 107 "INT : '0'..'9'+;\n" + 108 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 109 String found = execParser("T.g", grammar, "TParser", "TLexer", 110 "a", "a 1 b", debug); 111 assertEquals("(b a 1)\n", found); 112 } 113 testLabeledStringRoot()114 @Test public void testLabeledStringRoot() throws Exception { 115 String grammar = 116 "grammar T;\n" + 117 "options {output=AST;}\n" + 118 "a : v='void'^ ID ';' ;\n" + 119 "ID : 'a'..'z'+ ;\n" + 120 "INT : '0'..'9'+;\n" + 121 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 122 String found = execParser("T.g", grammar, "TParser", "TLexer", 123 "a", "void foo;", debug); 124 assertEquals("(void foo ;)\n", found); 125 } 126 testWildcard()127 @Test public void testWildcard() throws Exception { 128 String grammar = 129 "grammar T;\n" + 130 "options {output=AST;}\n" + 131 "a : v='void'^ . ';' ;\n" + 132 "ID : 'a'..'z'+ ;\n" + 133 "INT : '0'..'9'+;\n" + 134 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 135 String found = execParser("T.g", grammar, "TParser", "TLexer", 136 "a", "void foo;", debug); 137 assertEquals("(void foo ;)\n", found); 138 } 139 testWildcardRoot()140 @Test public void testWildcardRoot() throws Exception { 141 String grammar = 142 "grammar T;\n" + 143 "options {output=AST;}\n" + 144 "a : v='void' .^ ';' ;\n" + 145 "ID : 'a'..'z'+ ;\n" + 146 "INT : '0'..'9'+;\n" + 147 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 148 String found = execParser("T.g", grammar, "TParser", "TLexer", 149 "a", "void foo;", debug); 150 assertEquals("(foo void ;)\n", found); 151 } 152 testWildcardRootWithLabel()153 @Test public void testWildcardRootWithLabel() throws Exception { 154 String grammar = 155 "grammar T;\n" + 156 "options {output=AST;}\n" + 157 "a : v='void' x=.^ ';' ;\n" + 158 "ID : 'a'..'z'+ ;\n" + 159 "INT : '0'..'9'+;\n" + 160 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 161 String found = execParser("T.g", grammar, "TParser", "TLexer", 162 "a", "void foo;", debug); 163 assertEquals("(foo void ;)\n", found); 164 } 165 testWildcardRootWithListLabel()166 @Test public void testWildcardRootWithListLabel() throws Exception { 167 String grammar = 168 "grammar T;\n" + 169 "options {output=AST;}\n" + 170 "a : v='void' x=.^ ';' ;\n" + 171 "ID : 'a'..'z'+ ;\n" + 172 "INT : '0'..'9'+;\n" + 173 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 174 String found = execParser("T.g", grammar, "TParser", "TLexer", 175 "a", "void foo;", debug); 176 assertEquals("(foo void ;)\n", found); 177 } 178 testWildcardBangWithListLabel()179 @Test public void testWildcardBangWithListLabel() throws Exception { 180 String grammar = 181 "grammar T;\n" + 182 "options {output=AST;}\n" + 183 "a : v='void' x=.! ';' ;\n" + 184 "ID : 'a'..'z'+ ;\n" + 185 "INT : '0'..'9'+;\n" + 186 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 187 String found = execParser("T.g", grammar, "TParser", "TLexer", 188 "a", "void foo;", debug); 189 assertEquals("void ;\n", found); 190 } 191 testRootRoot()192 @Test public void testRootRoot() throws Exception { 193 String grammar = 194 "grammar T;\n" + 195 "options {output=AST;}\n" + 196 "a : ID^ INT^ ID ;\n" + 197 "ID : 'a'..'z'+ ;\n" + 198 "INT : '0'..'9'+;\n" + 199 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 200 String found = execParser("T.g", grammar, "TParser", "TLexer", 201 "a", "a 34 c", debug); 202 assertEquals("(34 a c)\n", found); 203 } 204 testRootRoot2()205 @Test public void testRootRoot2() throws Exception { 206 String grammar = 207 "grammar T;\n" + 208 "options {output=AST;}\n" + 209 "a : ID INT^ ID^ ;\n" + 210 "ID : 'a'..'z'+ ;\n" + 211 "INT : '0'..'9'+;\n" + 212 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 213 String found = execParser("T.g", grammar, "TParser", "TLexer", 214 "a", "a 34 c", debug); 215 assertEquals("(c (34 a))\n", found); 216 } 217 testRootThenRootInLoop()218 @Test public void testRootThenRootInLoop() throws Exception { 219 String grammar = 220 "grammar T;\n" + 221 "options {output=AST;}\n" + 222 "a : ID^ (INT '*'^ ID)+ ;\n" + 223 "ID : 'a'..'z'+ ;\n" + 224 "INT : '0'..'9'+;\n" + 225 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 226 String found = execParser("T.g", grammar, "TParser", "TLexer", 227 "a", "a 34 * b 9 * c", debug); 228 assertEquals("(* (* (a 34) b 9) c)\n", found); 229 } 230 testNestedSubrule()231 @Test public void testNestedSubrule() throws Exception { 232 String grammar = 233 "grammar T;\n" + 234 "options {output=AST;}\n" + 235 "a : 'void' (({;}ID|INT) ID | 'null' ) ';' ;\n" + 236 "ID : 'a'..'z'+ ;\n" + 237 "INT : '0'..'9'+;\n" + 238 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 239 String found = execParser("T.g", grammar, "TParser", "TLexer", 240 "a", "void a b;", debug); 241 assertEquals("void a b ;\n", found); 242 } 243 testInvokeRule()244 @Test public void testInvokeRule() throws Exception { 245 String grammar = 246 "grammar T;\n" + 247 "options {output=AST;}\n" + 248 "a : type ID ;\n" + 249 "type : {;}'int' | 'float' ;\n" + 250 "ID : 'a'..'z'+ ;\n" + 251 "INT : '0'..'9'+;\n" + 252 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 253 String found = execParser("T.g", grammar, "TParser", "TLexer", 254 "a", "int a", debug); 255 assertEquals("int a\n", found); 256 } 257 testInvokeRuleAsRoot()258 @Test public void testInvokeRuleAsRoot() throws Exception { 259 String grammar = 260 "grammar T;\n" + 261 "options {output=AST;}\n" + 262 "a : type^ ID ;\n" + 263 "type : {;}'int' | 'float' ;\n" + 264 "ID : 'a'..'z'+ ;\n" + 265 "INT : '0'..'9'+;\n" + 266 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 267 String found = execParser("T.g", grammar, "TParser", "TLexer", 268 "a", "int a", debug); 269 assertEquals("(int a)\n", found); 270 } 271 testInvokeRuleAsRootWithLabel()272 @Test public void testInvokeRuleAsRootWithLabel() throws Exception { 273 String grammar = 274 "grammar T;\n" + 275 "options {output=AST;}\n" + 276 "a : x=type^ ID ;\n" + 277 "type : {;}'int' | 'float' ;\n" + 278 "ID : 'a'..'z'+ ;\n" + 279 "INT : '0'..'9'+;\n" + 280 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 281 String found = execParser("T.g", grammar, "TParser", "TLexer", 282 "a", "int a", debug); 283 assertEquals("(int a)\n", found); 284 } 285 testInvokeRuleAsRootWithListLabel()286 @Test public void testInvokeRuleAsRootWithListLabel() throws Exception { 287 String grammar = 288 "grammar T;\n" + 289 "options {output=AST;}\n" + 290 "a : x+=type^ ID ;\n" + 291 "type : {;}'int' | 'float' ;\n" + 292 "ID : 'a'..'z'+ ;\n" + 293 "INT : '0'..'9'+;\n" + 294 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 295 String found = execParser("T.g", grammar, "TParser", "TLexer", 296 "a", "int a", debug); 297 assertEquals("(int a)\n", found); 298 } 299 testRuleRootInLoop()300 @Test public void testRuleRootInLoop() throws Exception { 301 String grammar = 302 "grammar T;\n" + 303 "options {output=AST;}\n" + 304 "a : ID ('+'^ ID)* ;\n" + 305 "ID : 'a'..'z'+ ;\n" + 306 "INT : '0'..'9'+;\n" + 307 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 308 String found = execParser("T.g", grammar, "TParser", "TLexer", 309 "a", "a+b+c+d", debug); 310 assertEquals("(+ (+ (+ a b) c) d)\n", found); 311 } 312 testRuleInvocationRuleRootInLoop()313 @Test public void testRuleInvocationRuleRootInLoop() throws Exception { 314 String grammar = 315 "grammar T;\n" + 316 "options {output=AST;}\n" + 317 "a : ID (op^ ID)* ;\n" + 318 "op : {;}'+' | '-' ;\n" + 319 "ID : 'a'..'z'+ ;\n" + 320 "INT : '0'..'9'+;\n" + 321 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 322 String found = execParser("T.g", grammar, "TParser", "TLexer", 323 "a", "a+b+c-d", debug); 324 assertEquals("(- (+ (+ a b) c) d)\n", found); 325 } 326 testTailRecursion()327 @Test public void testTailRecursion() throws Exception { 328 String grammar = 329 "grammar T;\n" + 330 "options {output=AST;}\n" + 331 "s : a ;\n" + 332 "a : atom ('exp'^ a)? ;\n" + 333 "atom : INT ;\n" + 334 "ID : 'a'..'z'+ ;\n" + 335 "INT : '0'..'9'+;\n" + 336 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 337 String found = execParser("T.g", grammar, "TParser", "TLexer", 338 "s", "3 exp 4 exp 5", debug); 339 assertEquals("(exp 3 (exp 4 5))\n", found); 340 } 341 testSet()342 @Test public void testSet() throws Exception { 343 String grammar = 344 "grammar T;\n" + 345 "options {output=AST;}\n" + 346 "a : ID|INT ;\n" + 347 "ID : 'a'..'z'+ ;\n" + 348 "INT : '0'..'9'+;\n" + 349 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 350 String found = execParser("T.g", grammar, "TParser", "TLexer", 351 "a", "abc", debug); 352 assertEquals("abc\n", found); 353 } 354 testSetRoot()355 @Test public void testSetRoot() throws Exception { 356 String grammar = 357 "grammar T;\n" + 358 "options {output=AST;}\n" + 359 "a : ('+' | '-')^ ID ;\n" + 360 "ID : 'a'..'z'+ ;\n" + 361 "INT : '0'..'9'+;\n" + 362 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 363 String found = execParser("T.g", grammar, "TParser", "TLexer", 364 "a", "+abc", debug); 365 assertEquals("(+ abc)\n", found); 366 } 367 368 @Ignore 369 // TODO: FAILS until I rebuild the antlr.g in v3 370 // testSetRootWithLabel()371 public void testSetRootWithLabel() throws Exception { 372 373 String grammar = 374 "grammar T;\n" + 375 "options {output=AST;}\n" + 376 "a : x=('+' | '-')^ ID ;\n" + 377 "ID : 'a'..'z'+ ;\n" + 378 "INT : '0'..'9'+;\n" + 379 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 380 String found = execParser("T.g", grammar, "TParser", "TLexer", 381 "a", "+abc", debug); 382 assertEquals("(+ abc)\n", found); 383 } 384 testSetAsRuleRootInLoop()385 @Test public void testSetAsRuleRootInLoop() throws Exception { 386 String grammar = 387 "grammar T;\n" + 388 "options {output=AST;}\n" + 389 "a : ID (('+'|'-')^ ID)* ;\n" + 390 "ID : 'a'..'z'+ ;\n" + 391 "INT : '0'..'9'+;\n" + 392 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 393 String found = execParser("T.g", grammar, "TParser", "TLexer", 394 "a", "a+b-c", debug); 395 assertEquals("(- (+ a b) c)\n", found); 396 } 397 testNotSet()398 @Test public void testNotSet() throws Exception { 399 String grammar = 400 "grammar T;\n" + 401 "options {output=AST;}\n" + 402 "a : ~ID '+' INT ;\n" + 403 "ID : 'a'..'z'+ ;\n" + 404 "INT : '0'..'9'+;\n" + 405 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 406 String found = execParser("T.g", grammar, "TParser", "TLexer", 407 "a", "34+2", debug); 408 assertEquals("34 + 2\n", found); 409 } 410 testNotSetWithLabel()411 @Test public void testNotSetWithLabel() throws Exception { 412 String grammar = 413 "grammar T;\n" + 414 "options {output=AST;}\n" + 415 "a : x=~ID '+' INT ;\n" + 416 "ID : 'a'..'z'+ ;\n" + 417 "INT : '0'..'9'+;\n" + 418 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 419 String found = execParser("T.g", grammar, "TParser", "TLexer", 420 "a", "34+2", debug); 421 assertEquals("34 + 2\n", found); 422 } 423 testNotSetWithListLabel()424 @Test public void testNotSetWithListLabel() throws Exception { 425 String grammar = 426 "grammar T;\n" + 427 "options {output=AST;}\n" + 428 "a : x=~ID '+' INT ;\n" + 429 "ID : 'a'..'z'+ ;\n" + 430 "INT : '0'..'9'+;\n" + 431 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 432 String found = execParser("T.g", grammar, "TParser", "TLexer", 433 "a", "34+2", debug); 434 assertEquals("34 + 2\n", found); 435 } 436 testNotSetRoot()437 @Test public void testNotSetRoot() throws Exception { 438 String grammar = 439 "grammar T;\n" + 440 "options {output=AST;}\n" + 441 "a : ~'+'^ INT ;\n" + 442 "ID : 'a'..'z'+ ;\n" + 443 "INT : '0'..'9'+;\n" + 444 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 445 String found = execParser("T.g", grammar, "TParser", "TLexer", 446 "a", "34 55", debug); 447 assertEquals("(34 55)\n", found); 448 } 449 testNotSetRootWithLabel()450 @Test public void testNotSetRootWithLabel() throws Exception { 451 String grammar = 452 "grammar T;\n" + 453 "options {output=AST;}\n" + 454 "a : ~'+'^ INT ;\n" + 455 "ID : 'a'..'z'+ ;\n" + 456 "INT : '0'..'9'+;\n" + 457 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 458 String found = execParser("T.g", grammar, "TParser", "TLexer", 459 "a", "34 55", debug); 460 assertEquals("(34 55)\n", found); 461 } 462 testNotSetRootWithListLabel()463 @Test public void testNotSetRootWithListLabel() throws Exception { 464 String grammar = 465 "grammar T;\n" + 466 "options {output=AST;}\n" + 467 "a : ~'+'^ INT ;\n" + 468 "ID : 'a'..'z'+ ;\n" + 469 "INT : '0'..'9'+;\n" + 470 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 471 String found = execParser("T.g", grammar, "TParser", "TLexer", 472 "a", "34 55", debug); 473 assertEquals("(34 55)\n", found); 474 } 475 testNotSetRuleRootInLoop()476 @Test public void testNotSetRuleRootInLoop() throws Exception { 477 String grammar = 478 "grammar T;\n" + 479 "options {output=AST;}\n" + 480 "a : INT (~INT^ INT)* ;\n" + 481 "blort : '+' ;\n" + 482 "ID : 'a'..'z'+ ;\n" + 483 "INT : '0'..'9'+;\n" + 484 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 485 String found = execParser("T.g", grammar, "TParser", "TLexer", 486 "a", "3+4+5", debug); 487 assertEquals("(+ (+ 3 4) 5)\n", found); 488 } 489 testTokenLabelReuse()490 @Test public void testTokenLabelReuse() throws Exception { 491 // check for compilation problem due to multiple defines 492 String grammar = 493 "grammar T;\n" + 494 "options {output=AST;}\n" + 495 "a : id=ID id=ID {System.out.print(\"2nd id=\"+$id.text+';');} ;\n" + 496 "ID : 'a'..'z'+ ;\n" + 497 "INT : '0'..'9'+;\n" + 498 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 499 String found = execParser("T.g", grammar, "TParser", "TLexer", 500 "a", "a b", debug); 501 assertEquals("2nd id=b;a b\n", found); 502 } 503 testTokenLabelReuse2()504 @Test public void testTokenLabelReuse2() throws Exception { 505 // check for compilation problem due to multiple defines 506 String grammar = 507 "grammar T;\n" + 508 "options {output=AST;}\n" + 509 "a : id=ID id=ID^ {System.out.print(\"2nd id=\"+$id.text+';');} ;\n" + 510 "ID : 'a'..'z'+ ;\n" + 511 "INT : '0'..'9'+;\n" + 512 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 513 String found = execParser("T.g", grammar, "TParser", "TLexer", 514 "a", "a b", debug); 515 assertEquals("2nd id=b;(b a)\n", found); 516 } 517 testTokenListLabelReuse()518 @Test public void testTokenListLabelReuse() throws Exception { 519 // check for compilation problem due to multiple defines 520 // make sure ids has both ID tokens 521 String grammar = 522 "grammar T;\n" + 523 "options {output=AST;}\n" + 524 "a : ids+=ID ids+=ID {System.out.print(\"id list=\"+$ids+';');} ;\n" + 525 "ID : 'a'..'z'+ ;\n" + 526 "INT : '0'..'9'+;\n" + 527 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 528 String found = execParser("T.g", grammar, "TParser", "TLexer", 529 "a", "a b", debug); 530 String expecting = "id list=[[@0,0:0='a',<4>,1:0], [@2,2:2='b',<4>,1:2]];a b\n"; 531 assertEquals(expecting, found); 532 } 533 testTokenListLabelReuse2()534 @Test public void testTokenListLabelReuse2() throws Exception { 535 // check for compilation problem due to multiple defines 536 // make sure ids has both ID tokens 537 String grammar = 538 "grammar T;\n" + 539 "options {output=AST;}\n" + 540 "a : ids+=ID^ ids+=ID {System.out.print(\"id list=\"+$ids+';');} ;\n" + 541 "ID : 'a'..'z'+ ;\n" + 542 "INT : '0'..'9'+;\n" + 543 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 544 String found = execParser("T.g", grammar, "TParser", "TLexer", 545 "a", "a b", debug); 546 String expecting = "id list=[[@0,0:0='a',<4>,1:0], [@2,2:2='b',<4>,1:2]];(a b)\n"; 547 assertEquals(expecting, found); 548 } 549 testTokenListLabelRuleRoot()550 @Test public void testTokenListLabelRuleRoot() throws Exception { 551 String grammar = 552 "grammar T;\n" + 553 "options {output=AST;}\n" + 554 "a : id+=ID^ ;\n" + 555 "ID : 'a'..'z'+ ;\n" + 556 "INT : '0'..'9'+;\n" + 557 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 558 String found = execParser("T.g", grammar, "TParser", "TLexer", 559 "a", "a", debug); 560 assertEquals("a\n", found); 561 } 562 testTokenListLabelBang()563 @Test public void testTokenListLabelBang() throws Exception { 564 String grammar = 565 "grammar T;\n" + 566 "options {output=AST;}\n" + 567 "a : id+=ID! ;\n" + 568 "ID : 'a'..'z'+ ;\n" + 569 "INT : '0'..'9'+;\n" + 570 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 571 String found = execParser("T.g", grammar, "TParser", "TLexer", 572 "a", "a", debug); 573 assertEquals("", found); 574 } 575 testRuleListLabel()576 @Test public void testRuleListLabel() throws Exception { 577 String grammar = 578 "grammar T;\n" + 579 "options {output=AST;}\n" + 580 "a : x+=b x+=b {" + 581 "Tree t=(Tree)$x.get(1);" + 582 "System.out.print(\"2nd x=\"+t.toStringTree()+';');} ;\n" + 583 "b : ID;\n" + 584 "ID : 'a'..'z'+ ;\n" + 585 "INT : '0'..'9'+;\n" + 586 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 587 String found = execParser("T.g", grammar, "TParser", "TLexer", 588 "a", "a b", debug); 589 assertEquals("2nd x=b;a b\n", found); 590 } 591 testRuleListLabelRuleRoot()592 @Test public void testRuleListLabelRuleRoot() throws Exception { 593 String grammar = 594 "grammar T;\n" + 595 "options {output=AST;}\n" + 596 "a : ( x+=b^ )+ {" + 597 "System.out.print(\"x=\"+((CommonTree)$x.get(1)).toStringTree()+';');} ;\n" + 598 "b : ID;\n" + 599 "ID : 'a'..'z'+ ;\n" + 600 "INT : '0'..'9'+;\n" + 601 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 602 String found = execParser("T.g", grammar, "TParser", "TLexer", 603 "a", "a b", debug); 604 assertEquals("x=(b a);(b a)\n", found); 605 } 606 testRuleListLabelBang()607 @Test public void testRuleListLabelBang() throws Exception { 608 String grammar = 609 "grammar T;\n" + 610 "options {output=AST;}\n" + 611 "a : x+=b! x+=b {" + 612 "System.out.print(\"1st x=\"+((CommonTree)$x.get(0)).toStringTree()+';');} ;\n" + 613 "b : ID;\n" + 614 "ID : 'a'..'z'+ ;\n" + 615 "INT : '0'..'9'+;\n" + 616 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 617 String found = execParser("T.g", grammar, "TParser", "TLexer", 618 "a", "a b", debug); 619 assertEquals("1st x=a;b\n", found); 620 } 621 testComplicatedMelange()622 @Test public void testComplicatedMelange() throws Exception { 623 // check for compilation problem 624 String grammar = 625 "grammar T;\n" + 626 "options {output=AST;}\n" + 627 "a : A b=B b=B c+=C c+=C D {String s = $D.text;} ;\n" + 628 "A : 'a' ;\n" + 629 "B : 'b' ;\n" + 630 "C : 'c' ;\n" + 631 "D : 'd' ;\n" + 632 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 633 String found = execParser("T.g", grammar, "TParser", "TLexer", 634 "a", "a b b c c d", debug); 635 assertEquals("a b b c c d\n", found); 636 } 637 testReturnValueWithAST()638 @Test public void testReturnValueWithAST() throws Exception { 639 String grammar = 640 "grammar foo;\n" + 641 "options {output=AST;}\n" + 642 "a : ID b {System.out.println($b.i);} ;\n" + 643 "b returns [int i] : INT {$i=Integer.parseInt($INT.text);} ;\n" + 644 "ID : 'a'..'z'+ ;\n" + 645 "INT : '0'..'9'+;\n" + 646 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 647 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 648 "a", "abc 34", debug); 649 assertEquals("34\nabc 34\n", found); 650 } 651 testSetLoop()652 @Test public void testSetLoop() throws Exception { 653 String grammar = 654 "grammar T;\n" + 655 "options { output=AST; }\n" + 656 "r : (INT|ID)+ ; \n" + 657 "ID : 'a'..'z' + ;\n" + 658 "INT : '0'..'9' +;\n" + 659 "WS: (' ' | '\\n' | '\\t')+ {$channel = HIDDEN;};\n"; 660 String found = execParser("T.g", grammar, "TParser", "TLexer", 661 "r", "abc 34 d", debug); 662 assertEquals("abc 34 d\n", found); 663 } 664 testExtraTokenInSimpleDecl()665 @Test public void testExtraTokenInSimpleDecl() throws Exception { 666 String grammar = 667 "grammar foo;\n" + 668 "options {output=AST;}\n" + 669 "decl : type^ ID '='! INT ';'! ;\n" + 670 "type : 'int' | 'float' ;\n" + 671 "ID : 'a'..'z'+ ;\n" + 672 "INT : '0'..'9'+;\n" + 673 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 674 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 675 "decl", "int 34 x=1;", debug); 676 assertEquals("line 1:4 extraneous input '34' expecting ID\n", this.stderrDuringParse); 677 assertEquals("(int x 1)\n", found); // tree gets correct x and 1 tokens 678 } 679 testMissingIDInSimpleDecl()680 @Test public void testMissingIDInSimpleDecl() throws Exception { 681 String grammar = 682 "grammar foo;\n" + 683 "options {output=AST;}\n" + 684 "tokens {EXPR;}\n" + 685 "decl : type^ ID '='! INT ';'! ;\n" + 686 "type : 'int' | 'float' ;\n" + 687 "ID : 'a'..'z'+ ;\n" + 688 "INT : '0'..'9'+;\n" + 689 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 690 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 691 "decl", "int =1;", debug); 692 assertEquals("line 1:4 missing ID at '='\n", this.stderrDuringParse); 693 assertEquals("(int <missing ID> 1)\n", found); // tree gets invented ID token 694 } 695 testMissingSetInSimpleDecl()696 @Test public void testMissingSetInSimpleDecl() throws Exception { 697 String grammar = 698 "grammar foo;\n" + 699 "options {output=AST;}\n" + 700 "tokens {EXPR;}\n" + 701 "decl : type^ ID '='! INT ';'! ;\n" + 702 "type : 'int' | 'float' ;\n" + 703 "ID : 'a'..'z'+ ;\n" + 704 "INT : '0'..'9'+;\n" + 705 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 706 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 707 "decl", "x=1;", debug); 708 assertEquals("line 1:0 mismatched input 'x' expecting set null\n", this.stderrDuringParse); 709 assertEquals("(<error: x> x 1)\n", found); // tree gets invented ID token 710 } 711 testMissingTokenGivesErrorNode()712 @Test public void testMissingTokenGivesErrorNode() throws Exception { 713 String grammar = 714 "grammar foo;\n" + 715 "options {output=AST;}\n" + 716 "a : ID INT ;\n" + // follow is EOF 717 "ID : 'a'..'z'+ ;\n" + 718 "INT : '0'..'9'+;\n" + 719 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 720 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 721 "a", "abc", debug); 722 assertEquals("line 1:3 missing INT at '<EOF>'\n", this.stderrDuringParse); 723 assertEquals("abc <missing INT>\n", found); 724 } 725 testMissingTokenGivesErrorNodeInInvokedRule()726 @Test public void testMissingTokenGivesErrorNodeInInvokedRule() throws Exception { 727 String grammar = 728 "grammar foo;\n" + 729 "options {output=AST;}\n" + 730 "a : b ;\n" + 731 "b : ID INT ;\n" + // follow should see EOF 732 "ID : 'a'..'z'+ ;\n" + 733 "INT : '0'..'9'+;\n" + 734 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 735 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 736 "a", "abc", debug); 737 assertEquals("line 1:3 mismatched input '<EOF>' expecting INT\n", this.stderrDuringParse); 738 assertEquals("<mismatched token: [@1,3:3='<EOF>',<-1>,1:3], resync=abc>\n", found); 739 } 740 testExtraTokenGivesErrorNode()741 @Test public void testExtraTokenGivesErrorNode() throws Exception { 742 String grammar = 743 "grammar foo;\n" + 744 "options {output=AST;}\n" + 745 "a : b c ;\n" + 746 "b : ID ;\n" + 747 "c : INT ;\n" + 748 "ID : 'a'..'z'+ ;\n" + 749 "INT : '0'..'9'+;\n" + 750 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 751 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 752 "a", "abc ick 34", debug); 753 assertEquals("line 1:4 extraneous input 'ick' expecting INT\n", this.stderrDuringParse); 754 assertEquals("abc 34\n", found); 755 } 756 testMissingFirstTokenGivesErrorNode()757 @Test public void testMissingFirstTokenGivesErrorNode() throws Exception { 758 String grammar = 759 "grammar foo;\n" + 760 "options {output=AST;}\n" + 761 "a : ID INT ;\n" + 762 "ID : 'a'..'z'+ ;\n" + 763 "INT : '0'..'9'+;\n" + 764 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 765 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 766 "a", "34", debug); 767 assertEquals("line 1:0 missing ID at '34'\n", this.stderrDuringParse); 768 assertEquals("<missing ID> 34\n", found); 769 } 770 testMissingFirstTokenGivesErrorNode2()771 @Test public void testMissingFirstTokenGivesErrorNode2() throws Exception { 772 String grammar = 773 "grammar foo;\n" + 774 "options {output=AST;}\n" + 775 "a : b c ;\n" + 776 "b : ID ;\n" + 777 "c : INT ;\n" + 778 "ID : 'a'..'z'+ ;\n" + 779 "INT : '0'..'9'+;\n" + 780 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 781 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 782 "a", "34", debug); 783 // finds an error at the first token, 34, and re-syncs. 784 // re-synchronizing does not consume a token because 34 follows 785 // ref to rule b (start of c). It then matches 34 in c. 786 assertEquals("line 1:0 missing ID at '34'\n", this.stderrDuringParse); 787 assertEquals("<missing ID> 34\n", found); 788 } 789 testNoViableAltGivesErrorNode()790 @Test public void testNoViableAltGivesErrorNode() throws Exception { 791 String grammar = 792 "grammar foo;\n" + 793 "options {output=AST;}\n" + 794 "a : b | c ;\n" + 795 "b : ID ;\n" + 796 "c : INT ;\n" + 797 "ID : 'a'..'z'+ ;\n" + 798 "S : '*' ;\n" + 799 "INT : '0'..'9'+;\n" + 800 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 801 String found = execParser("foo.g", grammar, "fooParser", "fooLexer", 802 "a", "*", debug); 803 assertEquals("line 1:0 no viable alternative at input '*'\n", this.stderrDuringParse); 804 assertEquals("<unexpected: [@0,0:0='*',<6>,1:0], resync=*>\n", found); 805 } 806 807 808 // S U P P O R T 809 _test()810 public void _test() throws Exception { 811 String grammar = 812 "grammar T;\n" + 813 "options {output=AST;}\n" + 814 "a : ;\n" + 815 "ID : 'a'..'z'+ ;\n" + 816 "INT : '0'..'9'+;\n" + 817 "WS : (' '|'\\n') {$channel=HIDDEN;} ;\n"; 818 String found = execParser("T.g", grammar, "TParser", "TLexer", "a", "abc 34", debug); 819 assertEquals("\n", found); 820 } 821 822 } 823