Home | History | Annotate | Download | only in tests
      1 import unittest
      2 import textwrap
      3 import antlr3
      4 import antlr3.tree
      5 import testbase
      6 import sys
      7 
      8 class 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 
   1516 if __name__ == '__main__':
   1517     unittest.main()
   1518