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