Home | History | Annotate | Download | only in tests
      1 import unittest
      2 import textwrap
      3 import antlr3
      4 import antlr3.tree
      5 import testbase
      6 
      7 class T(testbase.ANTLRTest):
      8     def walkerClass(self, base):
      9         class TWalker(base):
     10             def __init__(self, *args, **kwargs):
     11                 base.__init__(self, *args, **kwargs)
     12 
     13                 self._output = ""
     14 
     15 
     16             def capture(self, t):
     17                 self._output += t
     18 
     19 
     20             def traceIn(self, ruleName, ruleIndex):
     21                 self.traces.append('>'+ruleName)
     22 
     23 
     24             def traceOut(self, ruleName, ruleIndex):
     25                 self.traces.append('<'+ruleName)
     26 
     27 
     28             def recover(self, input, re):
     29                 # no error recovery yet, just crash!
     30                 raise
     31             
     32         return TWalker
     33     
     34 
     35     def execTreeParser(self, grammar, grammarEntry, treeGrammar, treeEntry, input):
     36         lexerCls, parserCls = self.compileInlineGrammar(grammar)
     37         walkerCls = self.compileInlineGrammar(treeGrammar)
     38 
     39         cStream = antlr3.StringStream(input)
     40         lexer = lexerCls(cStream)
     41         tStream = antlr3.CommonTokenStream(lexer)
     42         parser = parserCls(tStream)
     43         r = getattr(parser, grammarEntry)()
     44         nodes = antlr3.tree.CommonTreeNodeStream(r.tree)
     45         nodes.setTokenStream(tStream)
     46         walker = walkerCls(nodes)
     47         getattr(walker, treeEntry)()
     48 
     49         return walker._output
     50     
     51 
     52     def testFlatList(self):
     53         grammar = textwrap.dedent(
     54         r'''grammar T;
     55         options {
     56             language=Python;
     57             output=AST;
     58         }
     59         a : ID INT;
     60         ID : 'a'..'z'+ ;
     61         INT : '0'..'9'+;
     62         WS : (' '|'\n') {$channel=HIDDEN;} ;
     63         ''')
     64         
     65         treeGrammar = textwrap.dedent(
     66         r'''tree grammar TP;
     67         options {
     68             language=Python;
     69             ASTLabelType=CommonTree;
     70         }
     71         a : ID INT
     72             {self.capture("\%s, \%s" \% ($ID, $INT))}
     73           ;
     74         ''')
     75 
     76         found = self.execTreeParser(
     77             grammar, 'a',
     78             treeGrammar, 'a',
     79             "abc 34"
     80             )
     81 
     82         self.failUnlessEqual("abc, 34", found)
     83         
     84 
     85 
     86     def testSimpleTree(self):
     87         grammar = textwrap.dedent(
     88             r'''grammar T;
     89             options {
     90                 language=Python;
     91                 output=AST;
     92             }
     93             a : ID INT -> ^(ID INT);
     94             ID : 'a'..'z'+ ;
     95             INT : '0'..'9'+;
     96             WS : (' '|'\\n') {$channel=HIDDEN;} ;
     97             ''')
     98 
     99         treeGrammar = textwrap.dedent(
    100             r'''tree grammar TP;
    101             options {
    102                 language=Python;
    103                 ASTLabelType=CommonTree;
    104             }
    105             a : ^(ID INT)
    106                 {self.capture(str($ID)+", "+str($INT))}
    107               ;
    108             ''')
    109 
    110         found = self.execTreeParser(
    111             grammar, 'a',
    112             treeGrammar, 'a',
    113             "abc 34"
    114             )
    115             
    116         self.failUnlessEqual("abc, 34", found)
    117 
    118 
    119     def testFlatVsTreeDecision(self):
    120         grammar = textwrap.dedent(
    121             r'''grammar T;
    122             options {
    123                 language=Python;
    124                 output=AST;
    125             }
    126             a : b c ;
    127             b : ID INT -> ^(ID INT);
    128             c : ID INT;
    129             ID : 'a'..'z'+ ;
    130             INT : '0'..'9'+;
    131             WS : (' '|'\\n') {$channel=HIDDEN;} ;
    132             ''')
    133         
    134         treeGrammar = textwrap.dedent(
    135             r'''tree grammar TP;
    136             options {
    137                 language=Python;
    138                 ASTLabelType=CommonTree;
    139             }
    140             a : b b ;
    141             b : ID INT    {self.capture(str($ID)+" "+str($INT)+'\n')}
    142               | ^(ID INT) {self.capture("^("+str($ID)+" "+str($INT)+')');}
    143               ;
    144             ''')
    145         
    146         found = self.execTreeParser(
    147             grammar, 'a',
    148             treeGrammar, 'a',
    149             "a 1 b 2"
    150             )
    151         self.failUnlessEqual("^(a 1)b 2\n", found)
    152 
    153 
    154     def testFlatVsTreeDecision2(self):
    155         grammar = textwrap.dedent(
    156             r"""grammar T;
    157             options {
    158                 language=Python;
    159                 output=AST;
    160             }
    161             a : b c ;
    162             b : ID INT+ -> ^(ID INT+);
    163             c : ID INT+;
    164             ID : 'a'..'z'+ ;
    165             INT : '0'..'9'+;
    166             WS : (' '|'\n') {$channel=HIDDEN;} ;
    167             """)
    168 
    169         treeGrammar = textwrap.dedent(
    170             r'''tree grammar TP;
    171             options {
    172                 language=Python;
    173                 ASTLabelType=CommonTree;
    174             }
    175             a : b b ;
    176             b : ID INT+    {self.capture(str($ID)+" "+str($INT)+"\n")}
    177               | ^(x=ID (y=INT)+) {self.capture("^("+str($x)+' '+str($y)+')')}
    178               ;
    179             ''')
    180 
    181         found = self.execTreeParser(
    182             grammar, 'a',
    183             treeGrammar, 'a',
    184             "a 1 2 3 b 4 5"
    185             )
    186         self.failUnlessEqual("^(a 3)b 5\n", found)
    187 
    188 
    189     def testCyclicDFALookahead(self):
    190         grammar = textwrap.dedent(
    191             r'''grammar T;
    192             options {
    193                 language=Python;
    194                 output=AST;
    195             }
    196             a : ID INT+ PERIOD;
    197             ID : 'a'..'z'+ ;
    198             INT : '0'..'9'+;
    199             SEMI : ';' ;
    200             PERIOD : '.' ;
    201             WS : (' '|'\n') {$channel=HIDDEN;} ;
    202             ''')
    203 
    204         treeGrammar = textwrap.dedent(
    205             r'''tree grammar TP;
    206             options {
    207                 language=Python;
    208                 ASTLabelType=CommonTree;
    209             }
    210             a : ID INT+ PERIOD {self.capture("alt 1")}
    211               | ID INT+ SEMI   {self.capture("alt 2")}
    212               ;
    213             ''')
    214 
    215         found = self.execTreeParser(
    216             grammar, 'a',
    217             treeGrammar, 'a',
    218             "a 1 2 3."
    219             )
    220         self.failUnlessEqual("alt 1", found)
    221 
    222 
    223 ##     def testTemplateOutput(self):
    224 ## 		String grammar =
    225 ## 			"grammar T;\n" +
    226 ## 			"options {output=AST;}\n" +
    227 ## 			"a : ID INT;\n" +
    228 ## 			"ID : 'a'..'z'+ ;\n" +
    229 ## 			"INT : '0'..'9'+;\n" +
    230 ## 			"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
    231 
    232 ## 		String treeGrammar =
    233 ## 			"tree grammar TP;\n" +
    234 ## 			"options {output=template; ASTLabelType=CommonTree;}\n" +
    235 ## 			"s : a {System.out.println($a.st);};\n" +
    236 ## 			"a : ID INT -> {new StringTemplate($INT.text)}\n" +
    237 ## 			"  ;\n";
    238 
    239 ## 		String found = execTreeParser("T.g", grammar, "TParser", "TP.g",
    240 ## 				    treeGrammar, "TP", "TLexer", "a", "s", "abc 34");
    241 ## 		assertEquals("34\n", found);
    242 ## 	}
    243 
    244 
    245     def testNullableChildList(self):
    246         grammar = textwrap.dedent(
    247             r'''grammar T;
    248             options {
    249                 language=Python;
    250                 output=AST;
    251             }
    252             a : ID INT? -> ^(ID INT?);
    253             ID : 'a'..'z'+ ;
    254             INT : '0'..'9'+;
    255             WS : (' '|'\\n') {$channel=HIDDEN;} ;
    256             ''')
    257         
    258         treeGrammar = textwrap.dedent(
    259             r'''tree grammar TP;
    260             options {
    261                 language=Python;
    262                 ASTLabelType=CommonTree;
    263             }
    264             a : ^(ID INT?)
    265                 {self.capture(str($ID))}
    266               ;
    267             ''')
    268 
    269         found = self.execTreeParser(
    270             grammar, 'a',
    271             treeGrammar, 'a',
    272             "abc"
    273             )
    274         self.failUnlessEqual("abc", found)
    275 
    276 
    277     def testNullableChildList2(self):
    278         grammar = textwrap.dedent(
    279             r'''grammar T;
    280             options {
    281                 language=Python;
    282                 output=AST;
    283             }
    284             a : ID INT? SEMI -> ^(ID INT?) SEMI ;
    285             ID : 'a'..'z'+ ;
    286             INT : '0'..'9'+;
    287             SEMI : ';' ;
    288             WS : (' '|'\n') {$channel=HIDDEN;} ;
    289             ''')
    290 
    291         treeGrammar = textwrap.dedent(
    292             r'''tree grammar TP;
    293             options {
    294                 language=Python;
    295                 ASTLabelType=CommonTree;
    296             }
    297             a : ^(ID INT?) SEMI
    298                 {self.capture(str($ID))}
    299               ;
    300             ''')
    301         
    302         found = self.execTreeParser(
    303             grammar, 'a',
    304             treeGrammar, 'a',
    305             "abc;"
    306             )
    307         self.failUnlessEqual("abc", found)
    308 
    309 
    310     def testNullableChildList3(self):
    311         grammar = textwrap.dedent(
    312             r'''grammar T;
    313             options {
    314                 language=Python;
    315                 output=AST;
    316             }
    317             a : x=ID INT? (y=ID)? SEMI -> ^($x INT? $y?) SEMI ;
    318             ID : 'a'..'z'+ ;
    319             INT : '0'..'9'+;
    320             SEMI : ';' ;
    321             WS : (' '|'\\n') {$channel=HIDDEN;} ;
    322             ''')
    323 
    324         treeGrammar = textwrap.dedent(
    325             r'''tree grammar TP;
    326             options {
    327                 language=Python;
    328                 ASTLabelType=CommonTree;
    329             }
    330             a : ^(ID INT? b) SEMI
    331                 {self.capture(str($ID)+", "+str($b.text))}
    332               ;
    333             b : ID? ;
    334             ''')
    335         
    336         found = self.execTreeParser(
    337             grammar, 'a',
    338             treeGrammar, 'a',
    339             "abc def;"
    340             )
    341         self.failUnlessEqual("abc, def", found)
    342 
    343 
    344     def testActionsAfterRoot(self):
    345         grammar = textwrap.dedent(
    346             r'''grammar T;
    347             options {
    348                 language=Python;
    349                 output=AST;
    350             }
    351             a : x=ID INT? SEMI -> ^($x INT?) ;
    352             ID : 'a'..'z'+ ;
    353             INT : '0'..'9'+;
    354             SEMI : ';' ;
    355             WS : (' '|'\n') {$channel=HIDDEN;} ;
    356             ''')
    357 
    358         treeGrammar = textwrap.dedent(
    359             r'''tree grammar TP;
    360             options {
    361                 language=Python;
    362                 ASTLabelType=CommonTree;
    363             }
    364             a @init {x=0} : ^(ID {x=1} {x=2} INT?)
    365                 {self.capture(str($ID)+", "+str(x))}
    366               ;
    367             ''')
    368 
    369         found = self.execTreeParser(
    370             grammar, 'a',
    371             treeGrammar, 'a',
    372             "abc;"
    373             )
    374         self.failUnless("abc, 2\n", found)
    375 
    376 
    377     def testWildcardLookahead(self):
    378         grammar = textwrap.dedent(
    379             r'''
    380             grammar T;
    381             options {language=Python; output=AST;}
    382             a : ID '+'^ INT;
    383             ID : 'a'..'z'+ ;
    384             INT : '0'..'9'+;
    385             SEMI : ';' ;
    386             PERIOD : '.' ;
    387             WS : (' '|'\n') {$channel=HIDDEN;} ;
    388             ''')
    389 
    390         treeGrammar = textwrap.dedent(
    391             r'''
    392             tree grammar TP; 
    393             options {language=Python; tokenVocab=T; ASTLabelType=CommonTree;}
    394             a : ^('+' . INT) { self.capture("alt 1") }
    395               ;
    396             ''')
    397 
    398         found = self.execTreeParser(
    399             grammar, 'a',
    400             treeGrammar, 'a',
    401             "a + 2")
    402         self.assertEquals("alt 1", found)
    403 
    404 
    405     def testWildcardLookahead2(self):
    406         grammar = textwrap.dedent(
    407             r'''
    408             grammar T;
    409             options {language=Python; output=AST;}
    410             a : ID '+'^ INT;
    411             ID : 'a'..'z'+ ;
    412             INT : '0'..'9'+;
    413             SEMI : ';' ;
    414             PERIOD : '.' ;
    415             WS : (' '|'\n') {$channel=HIDDEN;} ;
    416             ''')
    417 
    418         treeGrammar = textwrap.dedent(
    419             r'''
    420             tree grammar TP;
    421             options {language=Python; tokenVocab=T; ASTLabelType=CommonTree;}
    422             a : ^('+' . INT) { self.capture("alt 1") }
    423               | ^('+' . .)   { self.capture("alt 2") }
    424               ;
    425             ''')
    426 
    427         # AMBIG upon '+' DOWN INT UP etc.. but so what.
    428 
    429         found = self.execTreeParser(
    430             grammar, 'a',
    431             treeGrammar, 'a',
    432             "a + 2")
    433         self.assertEquals("alt 1", found)
    434 
    435 
    436     def testWildcardLookahead3(self):
    437         grammar = textwrap.dedent(
    438             r'''
    439             grammar T;
    440             options {language=Python; output=AST;}
    441             a : ID '+'^ INT;
    442             ID : 'a'..'z'+ ;
    443             INT : '0'..'9'+;
    444             SEMI : ';' ;
    445             PERIOD : '.' ;
    446             WS : (' '|'\n') {$channel=HIDDEN;} ;
    447             ''')
    448 
    449         treeGrammar = textwrap.dedent(
    450             r'''
    451             tree grammar TP;
    452             options {language=Python; tokenVocab=T; ASTLabelType=CommonTree;}
    453             a : ^('+' ID INT) { self.capture("alt 1") }
    454               | ^('+' . .)   { self.capture("alt 2") }
    455               ;
    456             ''')
    457 
    458         # AMBIG upon '+' DOWN INT UP etc.. but so what.
    459 
    460         found = self.execTreeParser(
    461             grammar, 'a',
    462             treeGrammar, 'a',
    463             "a + 2")
    464         self.assertEquals("alt 1", found)
    465 
    466 
    467     def testWildcardPlusLookahead(self):
    468         grammar = textwrap.dedent(
    469             r'''
    470             grammar T;
    471             options {language=Python; output=AST;}
    472             a : ID '+'^ INT;
    473             ID : 'a'..'z'+ ;
    474             INT : '0'..'9'+;
    475             SEMI : ';' ;
    476             PERIOD : '.' ;
    477             WS : (' '|'\n') {$channel=HIDDEN;} ;
    478             ''')
    479 
    480         treeGrammar = textwrap.dedent(
    481             r'''
    482             tree grammar TP;
    483             options {language=Python; tokenVocab=T; ASTLabelType=CommonTree;}
    484             a : ^('+' INT INT ) { self.capture("alt 1") }
    485               | ^('+' .+)   { self.capture("alt 2") }
    486               ;
    487             ''')
    488 
    489         # AMBIG upon '+' DOWN INT UP etc.. but so what.
    490 
    491         found = self.execTreeParser(
    492             grammar, 'a',
    493             treeGrammar, 'a',
    494             "a + 2")
    495         self.assertEquals("alt 2", found)
    496 
    497 
    498 if __name__ == '__main__':
    499     unittest.main()
    500