1import unittest 2import textwrap 3import antlr3 4import antlr3.tree 5import testbase 6import sys 7 8class TestRewriteAST(testbase.ANTLRTest): 9 def parserClass(self, base): 10 class TParser(base): 11 def __init__(self, *args, **kwargs): 12 base.__init__(self, *args, **kwargs) 13 14 self._errors = [] 15 self._output = "" 16 17 18 def capture(self, t): 19 self._output += t 20 21 22 def traceIn(self, ruleName, ruleIndex): 23 self.traces.append('>'+ruleName) 24 25 26 def traceOut(self, ruleName, ruleIndex): 27 self.traces.append('<'+ruleName) 28 29 30 def emitErrorMessage(self, msg): 31 self._errors.append(msg) 32 33 34 return TParser 35 36 37 def lexerClass(self, base): 38 class TLexer(base): 39 def __init__(self, *args, **kwargs): 40 base.__init__(self, *args, **kwargs) 41 42 self._output = "" 43 44 45 def capture(self, t): 46 self._output += t 47 48 49 def traceIn(self, ruleName, ruleIndex): 50 self.traces.append('>'+ruleName) 51 52 53 def traceOut(self, ruleName, ruleIndex): 54 self.traces.append('<'+ruleName) 55 56 57 def recover(self, input, re): 58 # no error recovery yet, just crash! 59 raise 60 61 return TLexer 62 63 64 def execParser(self, grammar, grammarEntry, input, expectErrors=False): 65 lexerCls, parserCls = self.compileInlineGrammar(grammar) 66 67 cStream = antlr3.StringStream(input) 68 lexer = lexerCls(cStream) 69 tStream = antlr3.CommonTokenStream(lexer) 70 parser = parserCls(tStream) 71 r = getattr(parser, grammarEntry)() 72 73 if not expectErrors: 74 self.assertEquals(len(parser._errors), 0, parser._errors) 75 76 result = "" 77 78 if r is not None: 79 if hasattr(r, 'result'): 80 result += r.result 81 82 if r.tree is not None: 83 result += r.tree.toStringTree() 84 85 if not expectErrors: 86 return result 87 88 else: 89 return result, parser._errors 90 91 92 def execTreeParser(self, grammar, grammarEntry, treeGrammar, treeEntry, input): 93 lexerCls, parserCls = self.compileInlineGrammar(grammar) 94 walkerCls = self.compileInlineGrammar(treeGrammar) 95 96 cStream = antlr3.StringStream(input) 97 lexer = lexerCls(cStream) 98 tStream = antlr3.CommonTokenStream(lexer) 99 parser = parserCls(tStream) 100 r = getattr(parser, grammarEntry)() 101 nodes = antlr3.tree.CommonTreeNodeStream(r.tree) 102 nodes.setTokenStream(tStream) 103 walker = walkerCls(nodes) 104 r = getattr(walker, treeEntry)() 105 106 if r is not None: 107 return r.tree.toStringTree() 108 109 return "" 110 111 112 def testDelete(self): 113 grammar = textwrap.dedent( 114 r''' 115 grammar T; 116 options {language=Python;output=AST;} 117 a : ID INT -> ; 118 ID : 'a'..'z'+ ; 119 INT : '0'..'9'+; 120 WS : (' '|'\n') {$channel=HIDDEN;} ; 121 ''') 122 123 found = self.execParser(grammar, "a", "abc 34") 124 self.assertEquals("", found) 125 126 127 def testSingleToken(self): 128 grammar = textwrap.dedent( 129 r''' 130 grammar T; 131 options {language=Python;output=AST;} 132 a : ID -> ID; 133 ID : 'a'..'z'+ ; 134 INT : '0'..'9'+; 135 WS : (' '|'\n') {$channel=HIDDEN;} ; 136 ''') 137 138 found = self.execParser(grammar, "a", "abc") 139 self.assertEquals("abc", found) 140 141 142 def testSingleTokenToNewNode(self): 143 grammar = textwrap.dedent( 144 r''' 145 grammar T; 146 options {language=Python;output=AST;} 147 a : ID -> ID["x"]; 148 ID : 'a'..'z'+ ; 149 INT : '0'..'9'+; 150 WS : (' '|'\n') {$channel=HIDDEN;} ; 151 ''') 152 153 found = self.execParser(grammar, "a", "abc") 154 self.assertEquals("x", found) 155 156 157 def testSingleTokenToNewNodeRoot(self): 158 grammar = textwrap.dedent( 159 r''' 160 grammar T; 161 options {language=Python;output=AST;} 162 a : ID -> ^(ID["x"] INT); 163 ID : 'a'..'z'+ ; 164 INT : '0'..'9'+; 165 WS : (' '|'\n') {$channel=HIDDEN;} ; 166 ''') 167 168 found = self.execParser(grammar, "a", "abc") 169 self.assertEquals("(x INT)", found) 170 171 172 def testSingleTokenToNewNode2(self): 173 # Allow creation of new nodes w/o args. 174 grammar = textwrap.dedent( 175 r''' 176 grammar TT; 177 options {language=Python;output=AST;} 178 a : ID -> ID[ ]; 179 ID : 'a'..'z'+ ; 180 INT : '0'..'9'+; 181 WS : (' '|'\n') {$channel=HIDDEN;} ; 182 ''') 183 184 found = self.execParser(grammar, "a", "abc") 185 self.assertEquals("ID", found) 186 187 188 def testSingleCharLiteral(self): 189 grammar = textwrap.dedent( 190 r''' 191 grammar T; 192 options {language=Python;output=AST;} 193 a : 'c' -> 'c'; 194 ID : 'a'..'z'+ ; 195 INT : '0'..'9'+; 196 WS : (' '|'\n') {$channel=HIDDEN;} ; 197 ''') 198 199 found = self.execParser(grammar, "a", "c") 200 self.assertEquals("c", found) 201 202 203 def testSingleStringLiteral(self): 204 grammar = textwrap.dedent( 205 r''' 206 grammar T; 207 options {language=Python;output=AST;} 208 a : 'ick' -> 'ick'; 209 ID : 'a'..'z'+ ; 210 INT : '0'..'9'+; 211 WS : (' '|'\n') {$channel=HIDDEN;} ; 212 ''') 213 214 found = self.execParser(grammar, "a", "ick") 215 self.assertEquals("ick", found) 216 217 218 def testSingleRule(self): 219 grammar = textwrap.dedent( 220 r''' 221 grammar T; 222 options {language=Python;output=AST;} 223 a : b -> b; 224 b : ID ; 225 ID : 'a'..'z'+ ; 226 INT : '0'..'9'+; 227 WS : (' '|'\n') {$channel=HIDDEN;} ; 228 ''') 229 230 found = self.execParser(grammar, "a", "abc") 231 self.assertEquals("abc", found) 232 233 234 def testReorderTokens(self): 235 grammar = textwrap.dedent( 236 r''' 237 grammar T; 238 options {language=Python;output=AST;} 239 a : ID INT -> INT ID; 240 ID : 'a'..'z'+ ; 241 INT : '0'..'9'+; 242 WS : (' '|'\n') {$channel=HIDDEN;} ; 243 ''') 244 245 found = self.execParser(grammar, "a", "abc 34") 246 self.assertEquals("34 abc", found) 247 248 249 def testReorderTokenAndRule(self): 250 grammar = textwrap.dedent( 251 r''' 252 grammar T; 253 options {language=Python;output=AST;} 254 a : b INT -> INT b; 255 b : ID ; 256 ID : 'a'..'z'+ ; 257 INT : '0'..'9'+; 258 WS : (' '|'\n') {$channel=HIDDEN;} ; 259 ''') 260 261 found = self.execParser(grammar, "a", "abc 34") 262 self.assertEquals("34 abc", found) 263 264 265 def testTokenTree(self): 266 grammar = textwrap.dedent( 267 r''' 268 grammar T; 269 options {language=Python;output=AST;} 270 a : ID INT -> ^(INT ID); 271 ID : 'a'..'z'+ ; 272 INT : '0'..'9'+; 273 WS : (' '|'\n') {$channel=HIDDEN;} ; 274 ''') 275 276 found = self.execParser(grammar, "a", "abc 34") 277 self.assertEquals("(34 abc)", found) 278 279 280 def testTokenTreeAfterOtherStuff(self): 281 grammar = textwrap.dedent( 282 r''' 283 grammar T; 284 options {language=Python;output=AST;} 285 a : 'void' ID INT -> 'void' ^(INT ID); 286 ID : 'a'..'z'+ ; 287 INT : '0'..'9'+; 288 WS : (' '|'\n') {$channel=HIDDEN;} ; 289 ''') 290 291 found = self.execParser(grammar, "a", "void abc 34") 292 self.assertEquals("void (34 abc)", found) 293 294 295 def testNestedTokenTreeWithOuterLoop(self): 296 # verify that ID and INT both iterate over outer index variable 297 grammar = textwrap.dedent( 298 r''' 299 grammar T; 300 options {language=Python;output=AST;} 301 tokens {DUH;} 302 a : ID INT ID INT -> ^( DUH ID ^( DUH INT) )+ ; 303 ID : 'a'..'z'+ ; 304 INT : '0'..'9'+; 305 WS : (' '|'\n') {$channel=HIDDEN;} ; 306 ''') 307 308 found = self.execParser(grammar, "a", "a 1 b 2") 309 self.assertEquals("(DUH a (DUH 1)) (DUH b (DUH 2))", found) 310 311 312 def testOptionalSingleToken(self): 313 grammar = textwrap.dedent( 314 r''' 315 grammar T; 316 options {language=Python;output=AST;} 317 a : ID -> ID? ; 318 ID : 'a'..'z'+ ; 319 INT : '0'..'9'+; 320 WS : (' '|'\n') {$channel=HIDDEN;} ; 321 ''') 322 323 found = self.execParser(grammar, "a", "abc") 324 self.assertEquals("abc", found) 325 326 327 def testClosureSingleToken(self): 328 grammar = textwrap.dedent( 329 r''' 330 grammar T; 331 options {language=Python;output=AST;} 332 a : ID ID -> ID* ; 333 ID : 'a'..'z'+ ; 334 INT : '0'..'9'+; 335 WS : (' '|'\n') {$channel=HIDDEN;} ; 336 ''') 337 338 found = self.execParser(grammar, "a", "a b") 339 self.assertEquals("a b", found) 340 341 342 def testPositiveClosureSingleToken(self): 343 grammar = textwrap.dedent( 344 r''' 345 grammar T; 346 options {language=Python;output=AST;} 347 a : ID ID -> ID+ ; 348 ID : 'a'..'z'+ ; 349 INT : '0'..'9'+; 350 WS : (' '|'\n') {$channel=HIDDEN;} ; 351 ''') 352 353 found = self.execParser(grammar, "a", "a b") 354 self.assertEquals("a b", found) 355 356 357 def testOptionalSingleRule(self): 358 grammar = textwrap.dedent( 359 r''' 360 grammar T; 361 options {language=Python;output=AST;} 362 a : b -> b?; 363 b : ID ; 364 ID : 'a'..'z'+ ; 365 INT : '0'..'9'+; 366 WS : (' '|'\n') {$channel=HIDDEN;} ; 367 ''') 368 369 found = self.execParser(grammar, "a", "abc") 370 self.assertEquals("abc", found) 371 372 373 def testClosureSingleRule(self): 374 grammar = textwrap.dedent( 375 r''' 376 grammar T; 377 options {language=Python;output=AST;} 378 a : b b -> b*; 379 b : ID ; 380 ID : 'a'..'z'+ ; 381 INT : '0'..'9'+; 382 WS : (' '|'\n') {$channel=HIDDEN;} ; 383 ''') 384 385 found = self.execParser(grammar, "a", "a b") 386 self.assertEquals("a b", found) 387 388 389 def testClosureOfLabel(self): 390 grammar = textwrap.dedent( 391 r''' 392 grammar T; 393 options {language=Python;output=AST;} 394 a : x+=b x+=b -> $x*; 395 b : ID ; 396 ID : 'a'..'z'+ ; 397 INT : '0'..'9'+; 398 WS : (' '|'\n') {$channel=HIDDEN;} ; 399 ''') 400 401 found = self.execParser(grammar, "a", "a b") 402 self.assertEquals("a b", found) 403 404 405 def testOptionalLabelNoListLabel(self): 406 grammar = textwrap.dedent( 407 r''' 408 grammar T; 409 options {language=Python;output=AST;} 410 a : (x=ID)? -> $x?; 411 ID : 'a'..'z'+ ; 412 INT : '0'..'9'+; 413 WS : (' '|'\n') {$channel=HIDDEN;} ; 414 ''') 415 416 found = self.execParser(grammar, "a", "a") 417 self.assertEquals("a", found) 418 419 420 def testPositiveClosureSingleRule(self): 421 grammar = textwrap.dedent( 422 r''' 423 grammar T; 424 options {language=Python;output=AST;} 425 a : b b -> b+; 426 b : ID ; 427 ID : 'a'..'z'+ ; 428 INT : '0'..'9'+; 429 WS : (' '|'\n') {$channel=HIDDEN;} ; 430 ''') 431 432 found = self.execParser(grammar, "a", "a b") 433 self.assertEquals("a b", found) 434 435 436 def testSinglePredicateT(self): 437 grammar = textwrap.dedent( 438 r''' 439 grammar T; 440 options {language=Python;output=AST;} 441 a : ID -> {True}? ID -> ; 442 ID : 'a'..'z'+ ; 443 INT : '0'..'9'+; 444 WS : (' '|'\n') {$channel=HIDDEN;} ; 445 ''') 446 447 found = self.execParser(grammar, "a", "abc") 448 self.assertEquals("abc", found) 449 450 451 def testSinglePredicateF(self): 452 grammar = textwrap.dedent( 453 r''' 454 grammar T; 455 options {language=Python;output=AST;} 456 a : ID -> {False}? ID -> ; 457 ID : 'a'..'z'+ ; 458 INT : '0'..'9'+; 459 WS : (' '|'\n') {$channel=HIDDEN;} ; 460 ''') 461 462 found = self.execParser(grammar, "a", "abc") 463 self.assertEquals("", found) 464 465 466 def testMultiplePredicate(self): 467 grammar = textwrap.dedent( 468 r''' 469 grammar T; 470 options {language=Python;output=AST;} 471 a : ID INT -> {False}? ID 472 -> {True}? INT 473 -> 474 ; 475 ID : 'a'..'z'+ ; 476 INT : '0'..'9'+; 477 WS : (' '|'\n') {$channel=HIDDEN;} ; 478 ''') 479 480 found = self.execParser(grammar, "a", "a 2") 481 self.assertEquals("2", found) 482 483 484 def testMultiplePredicateTrees(self): 485 grammar = textwrap.dedent( 486 r''' 487 grammar T; 488 options {language=Python;output=AST;} 489 a : ID INT -> {False}? ^(ID INT) 490 -> {True}? ^(INT ID) 491 -> ID 492 ; 493 ID : 'a'..'z'+ ; 494 INT : '0'..'9'+; 495 WS : (' '|'\n') {$channel=HIDDEN;} ; 496 ''') 497 498 found = self.execParser(grammar, "a", "a 2") 499 self.assertEquals("(2 a)", found) 500 501 502 def testSimpleTree(self): 503 grammar = textwrap.dedent( 504 r''' 505 grammar T; 506 options {language=Python;output=AST;} 507 a : op INT -> ^(op INT); 508 op : '+'|'-' ; 509 ID : 'a'..'z'+ ; 510 INT : '0'..'9'+; 511 WS : (' '|'\n') {$channel=HIDDEN;} ; 512 ''') 513 514 found = self.execParser(grammar, "a", "-34") 515 self.assertEquals("(- 34)", found) 516 517 518 def testSimpleTree2(self): 519 grammar = textwrap.dedent( 520 r''' 521 grammar T; 522 options {language=Python;output=AST;} 523 a : op INT -> ^(INT op); 524 op : '+'|'-' ; 525 ID : 'a'..'z'+ ; 526 INT : '0'..'9'+; 527 WS : (' '|'\n') {$channel=HIDDEN;} ; 528 ''') 529 530 found = self.execParser(grammar, "a", "+ 34") 531 self.assertEquals("(34 +)", found) 532 533 534 535 def testNestedTrees(self): 536 grammar = textwrap.dedent( 537 r''' 538 grammar T; 539 options {language=Python;output=AST;} 540 a : 'var' (ID ':' type ';')+ -> ^('var' ^(':' ID type)+) ; 541 type : 'int' | 'float' ; 542 ID : 'a'..'z'+ ; 543 INT : '0'..'9'+; 544 WS : (' '|'\n') {$channel=HIDDEN;} ; 545 ''') 546 547 found = self.execParser(grammar, "a", "var a:int; b:float;") 548 self.assertEquals("(var (: a int) (: b float))", found) 549 550 551 def testImaginaryTokenCopy(self): 552 grammar = textwrap.dedent( 553 r''' 554 grammar T; 555 options {language=Python;output=AST;} 556 tokens {VAR;} 557 a : ID (',' ID)*-> ^(VAR ID)+ ; 558 type : 'int' | 'float' ; 559 ID : 'a'..'z'+ ; 560 INT : '0'..'9'+; 561 WS : (' '|'\n') {$channel=HIDDEN;} ; 562 ''') 563 564 found = self.execParser(grammar, "a", "a,b,c") 565 self.assertEquals("(VAR a) (VAR b) (VAR c)", found) 566 567 568 def testTokenUnreferencedOnLeftButDefined(self): 569 grammar = textwrap.dedent( 570 r''' 571 grammar T; 572 options {language=Python;output=AST;} 573 tokens {VAR;} 574 a : b -> ID ; 575 b : ID ; 576 ID : 'a'..'z'+ ; 577 INT : '0'..'9'+; 578 WS : (' '|'\n') {$channel=HIDDEN;} ; 579 ''') 580 581 found = self.execParser(grammar, "a", "a") 582 self.assertEquals("ID", found) 583 584 585 def testImaginaryTokenCopySetText(self): 586 grammar = textwrap.dedent( 587 r''' 588 grammar T; 589 options {language=Python;output=AST;} 590 tokens {VAR;} 591 a : ID (',' ID)*-> ^(VAR["var"] ID)+ ; 592 type : 'int' | 'float' ; 593 ID : 'a'..'z'+ ; 594 INT : '0'..'9'+; 595 WS : (' '|'\n') {$channel=HIDDEN;} ; 596 ''') 597 598 found = self.execParser(grammar, "a", "a,b,c") 599 self.assertEquals("(var a) (var b) (var c)", found) 600 601 602 def testImaginaryTokenNoCopyFromToken(self): 603 grammar = textwrap.dedent( 604 r''' 605 grammar T; 606 options {language=Python;output=AST;} 607 tokens {BLOCK;} 608 a : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ; 609 type : 'int' | 'float' ; 610 ID : 'a'..'z'+ ; 611 INT : '0'..'9'+; 612 WS : (' '|'\n') {$channel=HIDDEN;} ; 613 ''') 614 615 found = self.execParser(grammar, "a", "{a b c}") 616 self.assertEquals("({ a b c)", found) 617 618 619 def testImaginaryTokenNoCopyFromTokenSetText(self): 620 grammar = textwrap.dedent( 621 r''' 622 grammar T; 623 options {language=Python;output=AST;} 624 tokens {BLOCK;} 625 a : lc='{' ID+ '}' -> ^(BLOCK[$lc,"block"] ID+) ; 626 type : 'int' | 'float' ; 627 ID : 'a'..'z'+ ; 628 INT : '0'..'9'+; 629 WS : (' '|'\n') {$channel=HIDDEN;} ; 630 ''') 631 632 found = self.execParser(grammar, "a", "{a b c}") 633 self.assertEquals("(block a b c)", found) 634 635 636 def testMixedRewriteAndAutoAST(self): 637 grammar = textwrap.dedent( 638 r''' 639 grammar T; 640 options {language=Python;output=AST;} 641 tokens {BLOCK;} 642 a : b b^ ; // 2nd b matches only an INT; can make it root 643 b : ID INT -> INT ID 644 | INT 645 ; 646 ID : 'a'..'z'+ ; 647 INT : '0'..'9'+; 648 WS : (' '|'\n') {$channel=HIDDEN;} ; 649 ''') 650 651 found = self.execParser(grammar, "a", "a 1 2") 652 self.assertEquals("(2 1 a)", found) 653 654 655 def testSubruleWithRewrite(self): 656 grammar = textwrap.dedent( 657 r''' 658 grammar T; 659 options {language=Python;output=AST;} 660 tokens {BLOCK;} 661 a : b b ; 662 b : (ID INT -> INT ID | INT INT -> INT+ ) 663 ; 664 ID : 'a'..'z'+ ; 665 INT : '0'..'9'+; 666 WS : (' '|'\n') {$channel=HIDDEN;} ; 667 ''') 668 669 found = self.execParser(grammar, "a", "a 1 2 3") 670 self.assertEquals("1 a 2 3", found) 671 672 673 def testSubruleWithRewrite2(self): 674 grammar = textwrap.dedent( 675 r''' 676 grammar T; 677 options {language=Python;output=AST;} 678 tokens {TYPE;} 679 a : b b ; 680 b : 'int' 681 ( ID -> ^(TYPE 'int' ID) 682 | ID '=' INT -> ^(TYPE 'int' ID INT) 683 ) 684 ';' 685 ; 686 ID : 'a'..'z'+ ; 687 INT : '0'..'9'+; 688 WS : (' '|'\n') {$channel=HIDDEN;} ; 689 ''') 690 691 found = self.execParser(grammar, "a", "int a; int b=3;") 692 self.assertEquals("(TYPE int a) (TYPE int b 3)", found) 693 694 695 def testNestedRewriteShutsOffAutoAST(self): 696 grammar = textwrap.dedent( 697 r''' 698 grammar T; 699 options {language=Python;output=AST;} 700 tokens {BLOCK;} 701 a : b b ; 702 b : ID ( ID (last=ID -> $last)+ ) ';' // get last ID 703 | INT // should still get auto AST construction 704 ; 705 ID : 'a'..'z'+ ; 706 INT : '0'..'9'+; 707 WS : (' '|'\n') {$channel=HIDDEN;} ; 708 ''') 709 710 found = self.execParser(grammar, "a", "a b c d; 42") 711 self.assertEquals("d 42", found) 712 713 714 def testRewriteActions(self): 715 grammar = textwrap.dedent( 716 r''' 717 grammar T; 718 options {language=Python;output=AST;} 719 a : atom -> ^({self.adaptor.create(INT,"9")} atom) ; 720 atom : INT ; 721 ID : 'a'..'z'+ ; 722 INT : '0'..'9'+; 723 WS : (' '|'\n') {$channel=HIDDEN;} ; 724 ''') 725 726 found = self.execParser(grammar, "a", "3") 727 self.assertEquals("(9 3)", found) 728 729 730 def testRewriteActions2(self): 731 grammar = textwrap.dedent( 732 r''' 733 grammar T; 734 options {language=Python;output=AST;} 735 a : atom -> {self.adaptor.create(INT,"9")} atom ; 736 atom : INT ; 737 ID : 'a'..'z'+ ; 738 INT : '0'..'9'+; 739 WS : (' '|'\n') {$channel=HIDDEN;} ; 740 ''') 741 742 found = self.execParser(grammar, "a", "3") 743 self.assertEquals("9 3", found) 744 745 746 def testRefToOldValue(self): 747 grammar = textwrap.dedent( 748 r''' 749 grammar T; 750 options {language=Python;output=AST;} 751 tokens {BLOCK;} 752 a : (atom -> atom) (op='+' r=atom -> ^($op $a $r) )* ; 753 atom : INT ; 754 ID : 'a'..'z'+ ; 755 INT : '0'..'9'+; 756 WS : (' '|'\n') {$channel=HIDDEN;} ; 757 ''') 758 759 found = self.execParser(grammar, "a", "3+4+5") 760 self.assertEquals("(+ (+ 3 4) 5)", found) 761 762 763 def testCopySemanticsForRules(self): 764 grammar = textwrap.dedent( 765 r''' 766 grammar T; 767 options {language=Python;output=AST;} 768 tokens {BLOCK;} 769 a : atom -> ^(atom atom) ; // NOT CYCLE! (dup atom) 770 atom : INT ; 771 ID : 'a'..'z'+ ; 772 INT : '0'..'9'+; 773 WS : (' '|'\n') {$channel=HIDDEN;} ; 774 ''') 775 776 found = self.execParser(grammar, "a", "3") 777 self.assertEquals("(3 3)", found) 778 779 780 def testCopySemanticsForRules2(self): 781 # copy type as a root for each invocation of (...)+ in rewrite 782 grammar = textwrap.dedent( 783 r''' 784 grammar T; 785 options {language=Python;output=AST;} 786 a : type ID (',' ID)* ';' -> ^(type ID)+ ; 787 type : 'int' ; 788 ID : 'a'..'z'+ ; 789 WS : (' '|'\n') {$channel=HIDDEN;} ; 790 ''') 791 792 found = self.execParser(grammar, "a", "int a,b,c;") 793 self.assertEquals("(int a) (int b) (int c)", found) 794 795 796 def testCopySemanticsForRules3(self): 797 # copy type *and* modifier even though it's optional 798 # for each invocation of (...)+ in rewrite 799 grammar = textwrap.dedent( 800 r''' 801 grammar T; 802 options {language=Python;output=AST;} 803 a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ; 804 type : 'int' ; 805 modifier : 'public' ; 806 ID : 'a'..'z'+ ; 807 WS : (' '|'\n') {$channel=HIDDEN;} ; 808 ''') 809 810 found = self.execParser(grammar, "a", "public int a,b,c;") 811 self.assertEquals("(int public a) (int public b) (int public c)", found) 812 813 814 def testCopySemanticsForRules3Double(self): 815 # copy type *and* modifier even though it's optional 816 # for each invocation of (...)+ in rewrite 817 grammar = textwrap.dedent( 818 r''' 819 grammar T; 820 options {language=Python;output=AST;} 821 a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ^(type modifier? ID)+ ; 822 type : 'int' ; 823 modifier : 'public' ; 824 ID : 'a'..'z'+ ; 825 WS : (' '|'\n') {$channel=HIDDEN;} ; 826 ''') 827 828 found = self.execParser(grammar, "a", "public int a,b,c;") 829 self.assertEquals("(int public a) (int public b) (int public c) (int public a) (int public b) (int public c)", found) 830 831 832 def testCopySemanticsForRules4(self): 833 # copy type *and* modifier even though it's optional 834 # for each invocation of (...)+ in rewrite 835 grammar = textwrap.dedent( 836 r''' 837 grammar T; 838 options {language=Python;output=AST;} 839 tokens {MOD;} 840 a : modifier? type ID (',' ID)* ';' -> ^(type ^(MOD modifier)? ID)+ ; 841 type : 'int' ; 842 modifier : 'public' ; 843 ID : 'a'..'z'+ ; 844 WS : (' '|'\n') {$channel=HIDDEN;} ; 845 ''') 846 847 found = self.execParser(grammar, "a", "public int a,b,c;") 848 self.assertEquals("(int (MOD public) a) (int (MOD public) b) (int (MOD public) c)", found) 849 850 851 def testCopySemanticsLists(self): 852 grammar = textwrap.dedent( 853 r''' 854 grammar T; 855 options {language=Python;output=AST;} 856 tokens {MOD;} 857 a : ID (',' ID)* ';' -> ID+ ID+ ; 858 ID : 'a'..'z'+ ; 859 WS : (' '|'\n') {$channel=HIDDEN;} ; 860 ''') 861 862 found = self.execParser(grammar, "a", "a,b,c;") 863 self.assertEquals("a b c a b c", found) 864 865 866 def testCopyRuleLabel(self): 867 grammar = textwrap.dedent( 868 r''' 869 grammar T; 870 options {language=Python;output=AST;} 871 tokens {BLOCK;} 872 a : x=b -> $x $x; 873 b : ID ; 874 ID : 'a'..'z'+ ; 875 WS : (' '|'\n') {$channel=HIDDEN;} ; 876 ''') 877 878 found = self.execParser(grammar, "a", "a") 879 self.assertEquals("a a", found) 880 881 882 def testCopyRuleLabel2(self): 883 grammar = textwrap.dedent( 884 r''' 885 grammar T; 886 options {language=Python;output=AST;} 887 tokens {BLOCK;} 888 a : x=b -> ^($x $x); 889 b : ID ; 890 ID : 'a'..'z'+ ; 891 WS : (' '|'\n') {$channel=HIDDEN;} ; 892 ''') 893 894 found = self.execParser(grammar, "a", "a") 895 self.assertEquals("(a a)", found) 896 897 898 def testQueueingOfTokens(self): 899 grammar = textwrap.dedent( 900 r''' 901 grammar T; 902 options {language=Python;output=AST;} 903 a : 'int' ID (',' ID)* ';' -> ^('int' ID+) ; 904 op : '+'|'-' ; 905 ID : 'a'..'z'+ ; 906 INT : '0'..'9'+; 907 WS : (' '|'\n') {$channel=HIDDEN;} ; 908 ''') 909 910 found = self.execParser(grammar, "a", "int a,b,c;") 911 self.assertEquals("(int a b c)", found) 912 913 914 def testCopyOfTokens(self): 915 grammar = textwrap.dedent( 916 r''' 917 grammar T; 918 options {language=Python;output=AST;} 919 a : 'int' ID ';' -> 'int' ID 'int' ID ; 920 op : '+'|'-' ; 921 ID : 'a'..'z'+ ; 922 INT : '0'..'9'+; 923 WS : (' '|'\n') {$channel=HIDDEN;} ; 924 ''') 925 926 found = self.execParser(grammar, "a", "int a;") 927 self.assertEquals("int a int a", found) 928 929 930 def testTokenCopyInLoop(self): 931 grammar = textwrap.dedent( 932 r''' 933 grammar T; 934 options {language=Python;output=AST;} 935 a : 'int' ID (',' ID)* ';' -> ^('int' ID)+ ; 936 op : '+'|'-' ; 937 ID : 'a'..'z'+ ; 938 INT : '0'..'9'+; 939 WS : (' '|'\n') {$channel=HIDDEN;} ; 940 ''') 941 942 found = self.execParser(grammar, "a", "int a,b,c;") 943 self.assertEquals("(int a) (int b) (int c)", found) 944 945 946 def testTokenCopyInLoopAgainstTwoOthers(self): 947 # must smear 'int' copies across as root of multiple trees 948 grammar = textwrap.dedent( 949 r''' 950 grammar T; 951 options {language=Python;output=AST;} 952 a : 'int' ID ':' INT (',' ID ':' INT)* ';' -> ^('int' ID INT)+ ; 953 op : '+'|'-' ; 954 ID : 'a'..'z'+ ; 955 INT : '0'..'9'+; 956 WS : (' '|'\n') {$channel=HIDDEN;} ; 957 ''') 958 959 found = self.execParser(grammar, "a", "int a:1,b:2,c:3;") 960 self.assertEquals("(int a 1) (int b 2) (int c 3)", found) 961 962 963 def testListRefdOneAtATime(self): 964 grammar = textwrap.dedent( 965 r''' 966 grammar T; 967 options {language=Python;output=AST;} 968 a : ID+ -> ID ID ID ; // works if 3 input IDs 969 op : '+'|'-' ; 970 ID : 'a'..'z'+ ; 971 INT : '0'..'9'+; 972 WS : (' '|'\n') {$channel=HIDDEN;} ; 973 ''') 974 975 found = self.execParser(grammar, "a", "a b c") 976 self.assertEquals("a b c", found) 977 978 979 def testSplitListWithLabels(self): 980 grammar = textwrap.dedent( 981 r''' 982 grammar T; 983 options {language=Python;output=AST;} 984 tokens {VAR;} 985 a : first=ID others+=ID* -> $first VAR $others+ ; 986 op : '+'|'-' ; 987 ID : 'a'..'z'+ ; 988 INT : '0'..'9'+; 989 WS : (' '|'\n') {$channel=HIDDEN;} ; 990 ''') 991 992 found = self.execParser(grammar, "a", "a b c") 993 self.assertEquals("a VAR b c", found) 994 995 996 def testComplicatedMelange(self): 997 grammar = textwrap.dedent( 998 r''' 999 grammar T; 1000 options {language=Python;output=AST;} 1001 tokens {BLOCK;} 1002 a : A A b=B B b=B c+=C C c+=C D {s=$D.text} -> A+ B+ C+ D ; 1003 type : 'int' | 'float' ; 1004 A : 'a' ; 1005 B : 'b' ; 1006 C : 'c' ; 1007 D : 'd' ; 1008 WS : (' '|'\n') {$channel=HIDDEN;} ; 1009 ''') 1010 1011 found = self.execParser(grammar, "a", "a a b b b c c c d") 1012 self.assertEquals("a a b b b c c c d", found) 1013 1014 1015 def testRuleLabel(self): 1016 grammar = textwrap.dedent( 1017 r''' 1018 grammar T; 1019 options {language=Python;output=AST;} 1020 tokens {BLOCK;} 1021 a : x=b -> $x; 1022 b : ID ; 1023 ID : 'a'..'z'+ ; 1024 WS : (' '|'\n') {$channel=HIDDEN;} ; 1025 ''') 1026 1027 found = self.execParser(grammar, "a", "a") 1028 self.assertEquals("a", found) 1029 1030 1031 def testAmbiguousRule(self): 1032 grammar = textwrap.dedent( 1033 r''' 1034 grammar T; 1035 options {language=Python;output=AST;} 1036 a : ID a -> a | INT ; 1037 ID : 'a'..'z'+ ; 1038 INT: '0'..'9'+ ; 1039 WS : (' '|'\n') {$channel=HIDDEN;} ; 1040 ''') 1041 1042 found = self.execParser(grammar, 1043 "a", "abc 34") 1044 self.assertEquals("34", found) 1045 1046 1047 def testRuleListLabel(self): 1048 grammar = textwrap.dedent( 1049 r''' 1050 grammar T; 1051 options {language=Python;output=AST;} 1052 tokens {BLOCK;} 1053 a : x+=b x+=b -> $x+; 1054 b : ID ; 1055 ID : 'a'..'z'+ ; 1056 WS : (' '|'\n') {$channel=HIDDEN;} ; 1057 ''') 1058 1059 found = self.execParser(grammar, "a", "a b") 1060 self.assertEquals("a b", found) 1061 1062 1063 def testRuleListLabel2(self): 1064 grammar = textwrap.dedent( 1065 r''' 1066 grammar T; 1067 options {language=Python;output=AST;} 1068 tokens {BLOCK;} 1069 a : x+=b x+=b -> $x $x*; 1070 b : ID ; 1071 ID : 'a'..'z'+ ; 1072 WS : (' '|'\n') {$channel=HIDDEN;} ; 1073 ''') 1074 1075 found = self.execParser(grammar, "a", "a b") 1076 self.assertEquals("a b", found) 1077 1078 1079 def testOptional(self): 1080 grammar = textwrap.dedent( 1081 r''' 1082 grammar T; 1083 options {language=Python;output=AST;} 1084 tokens {BLOCK;} 1085 a : x=b (y=b)? -> $x $y?; 1086 b : ID ; 1087 ID : 'a'..'z'+ ; 1088 WS : (' '|'\n') {$channel=HIDDEN;} ; 1089 ''') 1090 1091 found = self.execParser(grammar, "a", "a") 1092 self.assertEquals("a", found) 1093 1094 1095 def testOptional2(self): 1096 grammar = textwrap.dedent( 1097 r''' 1098 grammar T; 1099 options {language=Python;output=AST;} 1100 tokens {BLOCK;} 1101 a : x=ID (y=b)? -> $x $y?; 1102 b : ID ; 1103 ID : 'a'..'z'+ ; 1104 WS : (' '|'\n') {$channel=HIDDEN;} ; 1105 ''') 1106 1107 found = self.execParser(grammar, "a", "a b") 1108 self.assertEquals("a b", found) 1109 1110 1111 def testOptional3(self): 1112 grammar = textwrap.dedent( 1113 r''' 1114 grammar T; 1115 options {language=Python;output=AST;} 1116 tokens {BLOCK;} 1117 a : x=ID (y=b)? -> ($x $y)?; 1118 b : ID ; 1119 ID : 'a'..'z'+ ; 1120 WS : (' '|'\n') {$channel=HIDDEN;} ; 1121 ''') 1122 1123 found = self.execParser(grammar, "a", "a b") 1124 self.assertEquals("a b", found) 1125 1126 1127 def testOptional4(self): 1128 grammar = textwrap.dedent( 1129 r''' 1130 grammar T; 1131 options {language=Python;output=AST;} 1132 tokens {BLOCK;} 1133 a : x+=ID (y=b)? -> ($x $y)?; 1134 b : ID ; 1135 ID : 'a'..'z'+ ; 1136 WS : (' '|'\n') {$channel=HIDDEN;} ; 1137 ''') 1138 1139 found = self.execParser(grammar, "a", "a b") 1140 self.assertEquals("a b", found) 1141 1142 1143 def testOptional5(self): 1144 grammar = textwrap.dedent( 1145 r''' 1146 grammar T; 1147 options {language=Python;output=AST;} 1148 tokens {BLOCK;} 1149 a : ID -> ID? ; // match an ID to optional ID 1150 b : ID ; 1151 ID : 'a'..'z'+ ; 1152 WS : (' '|'\n') {$channel=HIDDEN;} ; 1153 ''') 1154 1155 found = self.execParser(grammar, "a", "a") 1156 self.assertEquals("a", found) 1157 1158 1159 def testArbitraryExprType(self): 1160 grammar = textwrap.dedent( 1161 r''' 1162 grammar T; 1163 options {language=Python;output=AST;} 1164 tokens {BLOCK;} 1165 a : x+=b x+=b -> {CommonTree(None)}; 1166 b : ID ; 1167 ID : 'a'..'z'+ ; 1168 WS : (' '|'\n') {$channel=HIDDEN;} ; 1169 ''') 1170 1171 found = self.execParser(grammar, "a", "a b") 1172 self.assertEquals("", found) 1173 1174 1175 def testSet(self): 1176 grammar = textwrap.dedent( 1177 r''' 1178 grammar T; 1179 options {language=Python;output=AST;} 1180 a: (INT|ID)+ -> INT+ ID+ ; 1181 INT: '0'..'9'+; 1182 ID : 'a'..'z'+; 1183 WS : (' '|'\n') {$channel=HIDDEN;} ; 1184 ''') 1185 1186 found = self.execParser(grammar, "a", "2 a 34 de") 1187 self.assertEquals("2 34 a de", found) 1188 1189 1190 def testSet2(self): 1191 grammar = textwrap.dedent( 1192 r''' 1193 grammar T; 1194 options {language=Python;output=AST;} 1195 a: (INT|ID) -> INT? ID? ; 1196 INT: '0'..'9'+; 1197 ID : 'a'..'z'+; 1198 WS : (' '|'\n') {$channel=HIDDEN;} ; 1199 ''') 1200 1201 found = self.execParser(grammar, "a", "2") 1202 self.assertEquals("2", found) 1203 1204 1205 @testbase.broken("http://www.antlr.org:8888/browse/ANTLR-162", 1206 antlr3.tree.RewriteEmptyStreamException) 1207 def testSetWithLabel(self): 1208 grammar = textwrap.dedent( 1209 r''' 1210 grammar T; 1211 options {language=Python;output=AST;} 1212 a : x=(INT|ID) -> $x ; 1213 INT: '0'..'9'+; 1214 ID : 'a'..'z'+; 1215 WS : (' '|'\n') {$channel=HIDDEN;} ; 1216 ''') 1217 1218 found = self.execParser(grammar, "a", "2") 1219 self.assertEquals("2", found) 1220 1221 1222 def testRewriteAction(self): 1223 grammar = textwrap.dedent( 1224 r''' 1225 grammar T; 1226 options {language=Python;output=AST;} 1227 tokens { FLOAT; } 1228 r 1229 : INT -> {CommonTree(CommonToken(type=FLOAT, text=$INT.text+".0"))} 1230 ; 1231 INT : '0'..'9'+; 1232 WS: (' ' | '\n' | '\t')+ {$channel = HIDDEN;}; 1233 ''') 1234 1235 found = self.execParser(grammar, "r", "25") 1236 self.assertEquals("25.0", found) 1237 1238 1239 def testOptionalSubruleWithoutRealElements(self): 1240 # copy type *and* modifier even though it's optional 1241 # for each invocation of (...)+ in rewrite 1242 grammar = textwrap.dedent( 1243 r""" 1244 grammar T; 1245 options {language=Python;output=AST;} 1246 tokens {PARMS;} 1247 1248 modulo 1249 : 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms+)?) 1250 ; 1251 parms : '#'|ID; 1252 ID : ('a'..'z' | 'A'..'Z')+; 1253 WS : (' '|'\n') {$channel=HIDDEN;} ; 1254 """) 1255 1256 found = self.execParser(grammar, "modulo", "modulo abc (x y #)") 1257 self.assertEquals("(modulo abc (PARMS x y #))", found) 1258 1259 1260 ## C A R D I N A L I T Y I S S U E S 1261 1262 def testCardinality(self): 1263 grammar = textwrap.dedent( 1264 r''' 1265 grammar T; 1266 options {language=Python;output=AST;} 1267 tokens {BLOCK;} 1268 a : ID ID INT INT INT -> (ID INT)+; 1269 ID : 'a'..'z'+ ; 1270 INT : '0'..'9'+; 1271 WS : (' '|'\n') {$channel=HIDDEN;} ; 1272 ''') 1273 1274 try: 1275 self.execParser(grammar, "a", "a b 3 4 5") 1276 self.fail() 1277 except antlr3.tree.RewriteCardinalityException: 1278 pass 1279 1280 1281 def testCardinality2(self): 1282 grammar = textwrap.dedent( 1283 r''' 1284 grammar T; 1285 options {language=Python;output=AST;} 1286 a : ID+ -> ID ID ID ; // only 2 input IDs 1287 op : '+'|'-' ; 1288 ID : 'a'..'z'+ ; 1289 INT : '0'..'9'+; 1290 WS : (' '|'\n') {$channel=HIDDEN;} ; 1291 ''') 1292 1293 try: 1294 self.execParser(grammar, "a", "a b") 1295 self.fail() 1296 except antlr3.tree.RewriteCardinalityException: 1297 pass 1298 1299 1300 def testCardinality3(self): 1301 grammar = textwrap.dedent( 1302 r''' 1303 grammar T; 1304 options {language=Python;output=AST;} 1305 a : ID? INT -> ID INT ; 1306 op : '+'|'-' ; 1307 ID : 'a'..'z'+ ; 1308 INT : '0'..'9'+; 1309 WS : (' '|'\n') {$channel=HIDDEN;} ; 1310 ''') 1311 1312 try: 1313 self.execParser(grammar, "a", "3") 1314 self.fail() 1315 except antlr3.tree.RewriteEmptyStreamException: 1316 pass 1317 1318 1319 def testLoopCardinality(self): 1320 grammar = textwrap.dedent( 1321 r''' 1322 grammar T; 1323 options {language=Python;output=AST;} 1324 a : ID? INT -> ID+ INT ; 1325 op : '+'|'-' ; 1326 ID : 'a'..'z'+ ; 1327 INT : '0'..'9'+; 1328 WS : (' '|'\n') {$channel=HIDDEN;} ; 1329 ''') 1330 1331 try: 1332 self.execParser(grammar, "a", "3") 1333 self.fail() 1334 except antlr3.tree.RewriteEarlyExitException: 1335 pass 1336 1337 1338 def testWildcard(self): 1339 grammar = textwrap.dedent( 1340 r''' 1341 grammar T; 1342 options {language=Python;output=AST;} 1343 a : ID c=. -> $c; 1344 ID : 'a'..'z'+ ; 1345 INT : '0'..'9'+; 1346 WS : (' '|'\n') {$channel=HIDDEN;} ; 1347 ''') 1348 1349 found = self.execParser(grammar, "a", "abc 34") 1350 self.assertEquals("34", found) 1351 1352 1353 # E R R O R S 1354 1355 def testExtraTokenInSimpleDecl(self): 1356 grammar = textwrap.dedent( 1357 r''' 1358 grammar foo; 1359 options {language=Python;output=AST;} 1360 tokens {EXPR;} 1361 decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1362 type : 'int' | 'float' ; 1363 ID : 'a'..'z'+ ; 1364 INT : '0'..'9'+; 1365 WS : (' '|'\n') {$channel=HIDDEN;} ; 1366 ''') 1367 1368 found, errors = self.execParser(grammar, "decl", "int 34 x=1;", 1369 expectErrors=True) 1370 self.assertEquals(["line 1:4 extraneous input u'34' expecting ID"], 1371 errors) 1372 self.assertEquals("(EXPR int x 1)", found) # tree gets correct x and 1 tokens 1373 1374 1375 #@testbase.broken("FIXME", AssertionError) 1376 def testMissingIDInSimpleDecl(self): 1377 grammar = textwrap.dedent( 1378 r''' 1379 grammar foo; 1380 options {language=Python;output=AST;} 1381 tokens {EXPR;} 1382 decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1383 type : 'int' | 'float' ; 1384 ID : 'a'..'z'+ ; 1385 INT : '0'..'9'+; 1386 WS : (' '|'\n') {$channel=HIDDEN;} ; 1387 ''') 1388 1389 found, errors = self.execParser(grammar, "decl", "int =1;", 1390 expectErrors=True) 1391 self.assertEquals(["line 1:4 missing ID at u'='"], errors) 1392 self.assertEquals("(EXPR int <missing ID> 1)", found) # tree gets invented ID token 1393 1394 1395 def testMissingSetInSimpleDecl(self): 1396 grammar = textwrap.dedent( 1397 r''' 1398 grammar foo; 1399 options {language=Python;output=AST;} 1400 tokens {EXPR;} 1401 decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1402 type : 'int' | 'float' ; 1403 ID : 'a'..'z'+ ; 1404 INT : '0'..'9'+; 1405 WS : (' '|'\n') {$channel=HIDDEN;} ; 1406 ''') 1407 1408 found, errors = self.execParser(grammar, "decl", "x=1;", 1409 expectErrors=True) 1410 self.assertEquals(["line 1:0 mismatched input u'x' expecting set None"], 1411 errors); 1412 self.assertEquals("(EXPR <error: x> x 1)", found) # tree gets invented ID token 1413 1414 1415 def testMissingTokenGivesErrorNode(self): 1416 grammar = textwrap.dedent( 1417 r''' 1418 grammar foo; 1419 options {language=Python;output=AST;} 1420 a : ID INT -> ID INT ; 1421 ID : 'a'..'z'+ ; 1422 INT : '0'..'9'+; 1423 WS : (' '|'\n') {$channel=HIDDEN;} ; 1424 ''') 1425 1426 found, errors = self.execParser(grammar, "a", "abc", 1427 expectErrors=True) 1428 self.assertEquals(["line 1:3 missing INT at '<EOF>'"], errors) 1429 # doesn't do in-line recovery for sets (yet?) 1430 self.assertEquals("abc <missing INT>", found) 1431 1432 1433 def testExtraTokenGivesErrorNode(self): 1434 grammar = textwrap.dedent( 1435 r''' 1436 grammar foo; 1437 options {language=Python;output=AST;} 1438 a : b c -> b c; 1439 b : ID -> ID ; 1440 c : INT -> INT ; 1441 ID : 'a'..'z'+ ; 1442 INT : '0'..'9'+; 1443 WS : (' '|'\n') {$channel=HIDDEN;} ; 1444 ''') 1445 1446 found, errors = self.execParser(grammar, "a", "abc ick 34", 1447 expectErrors=True) 1448 self.assertEquals(["line 1:4 extraneous input u'ick' expecting INT"], 1449 errors) 1450 self.assertEquals("abc 34", found) 1451 1452 1453 #@testbase.broken("FIXME", AssertionError) 1454 def testMissingFirstTokenGivesErrorNode(self): 1455 grammar = textwrap.dedent( 1456 r''' 1457 grammar foo; 1458 options {language=Python;output=AST;} 1459 a : ID INT -> ID INT ; 1460 ID : 'a'..'z'+ ; 1461 INT : '0'..'9'+; 1462 WS : (' '|'\n') {$channel=HIDDEN;} ; 1463 ''') 1464 1465 found, errors = self.execParser(grammar, "a", "34", expectErrors=True) 1466 self.assertEquals(["line 1:0 missing ID at u'34'"], errors) 1467 self.assertEquals("<missing ID> 34", found) 1468 1469 1470 #@testbase.broken("FIXME", AssertionError) 1471 def testMissingFirstTokenGivesErrorNode2(self): 1472 grammar = textwrap.dedent( 1473 r''' 1474 grammar foo; 1475 options {language=Python;output=AST;} 1476 a : b c -> b c; 1477 b : ID -> ID ; 1478 c : INT -> INT ; 1479 ID : 'a'..'z'+ ; 1480 INT : '0'..'9'+; 1481 WS : (' '|'\n') {$channel=HIDDEN;} ; 1482 ''') 1483 1484 found, errors = self.execParser(grammar, "a", "34", expectErrors=True) 1485 # finds an error at the first token, 34, and re-syncs. 1486 # re-synchronizing does not consume a token because 34 follows 1487 # ref to rule b (start of c). It then matches 34 in c. 1488 self.assertEquals(["line 1:0 missing ID at u'34'"], errors) 1489 self.assertEquals("<missing ID> 34", found) 1490 1491 1492 def testNoViableAltGivesErrorNode(self): 1493 grammar = textwrap.dedent( 1494 r''' 1495 grammar foo; 1496 options {language=Python;output=AST;} 1497 a : b -> b | c -> c; 1498 b : ID -> ID ; 1499 c : INT -> INT ; 1500 ID : 'a'..'z'+ ; 1501 S : '*' ; 1502 INT : '0'..'9'+; 1503 WS : (' '|'\n') {$channel=HIDDEN;} ; 1504 ''') 1505 1506 found, errors = self.execParser(grammar, "a", "*", expectErrors=True) 1507 # finds an error at the first token, 34, and re-syncs. 1508 # re-synchronizing does not consume a token because 34 follows 1509 # ref to rule b (start of c). It then matches 34 in c. 1510 self.assertEquals(["line 1:0 no viable alternative at input u'*'"], 1511 errors); 1512 self.assertEquals("<unexpected: [@0,0:0=u'*',<6>,1:0], resync=*>", 1513 found) 1514 1515 1516if __name__ == '__main__': 1517 unittest.main() 1518