xref: /aosp_15_r20/external/antlr/runtime/Python3/tests/t053hetero.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 Robotimport sys
7*16467b97STreehugger Robot
8*16467b97STreehugger Robotclass T(testbase.ANTLRTest):
9*16467b97STreehugger Robot    def parserClass(self, base):
10*16467b97STreehugger Robot        class TParser(base):
11*16467b97STreehugger Robot            def __init__(self, *args, **kwargs):
12*16467b97STreehugger Robot                super().__init__(*args, **kwargs)
13*16467b97STreehugger Robot
14*16467b97STreehugger Robot                self._output = ""
15*16467b97STreehugger Robot
16*16467b97STreehugger Robot
17*16467b97STreehugger Robot            def capture(self, t):
18*16467b97STreehugger Robot                self._output += t
19*16467b97STreehugger Robot
20*16467b97STreehugger Robot
21*16467b97STreehugger Robot            def traceIn(self, ruleName, ruleIndex):
22*16467b97STreehugger Robot                self.traces.append('>'+ruleName)
23*16467b97STreehugger Robot
24*16467b97STreehugger Robot
25*16467b97STreehugger Robot            def traceOut(self, ruleName, ruleIndex):
26*16467b97STreehugger Robot                self.traces.append('<'+ruleName)
27*16467b97STreehugger Robot
28*16467b97STreehugger Robot
29*16467b97STreehugger Robot            def recover(self, input, re):
30*16467b97STreehugger Robot                # no error recovery yet, just crash!
31*16467b97STreehugger Robot                raise
32*16467b97STreehugger Robot
33*16467b97STreehugger Robot        return TParser
34*16467b97STreehugger Robot
35*16467b97STreehugger Robot
36*16467b97STreehugger Robot    def lexerClass(self, base):
37*16467b97STreehugger Robot        class TLexer(base):
38*16467b97STreehugger Robot            def __init__(self, *args, **kwargs):
39*16467b97STreehugger Robot                super().__init__(*args, **kwargs)
40*16467b97STreehugger Robot
41*16467b97STreehugger Robot                self._output = ""
42*16467b97STreehugger Robot
43*16467b97STreehugger Robot
44*16467b97STreehugger Robot            def capture(self, t):
45*16467b97STreehugger Robot                self._output += t
46*16467b97STreehugger Robot
47*16467b97STreehugger Robot
48*16467b97STreehugger Robot            def traceIn(self, ruleName, ruleIndex):
49*16467b97STreehugger Robot                self.traces.append('>'+ruleName)
50*16467b97STreehugger Robot
51*16467b97STreehugger Robot
52*16467b97STreehugger Robot            def traceOut(self, ruleName, ruleIndex):
53*16467b97STreehugger Robot                self.traces.append('<'+ruleName)
54*16467b97STreehugger Robot
55*16467b97STreehugger Robot
56*16467b97STreehugger Robot            def recover(self, input, re):
57*16467b97STreehugger Robot                # no error recovery yet, just crash!
58*16467b97STreehugger Robot                raise
59*16467b97STreehugger Robot
60*16467b97STreehugger Robot        return TLexer
61*16467b97STreehugger Robot
62*16467b97STreehugger Robot
63*16467b97STreehugger Robot    def execParser(self, grammar, grammarEntry, input):
64*16467b97STreehugger Robot        lexerCls, parserCls = self.compileInlineGrammar(grammar)
65*16467b97STreehugger Robot
66*16467b97STreehugger Robot        cStream = antlr3.StringStream(input)
67*16467b97STreehugger Robot        lexer = lexerCls(cStream)
68*16467b97STreehugger Robot        tStream = antlr3.CommonTokenStream(lexer)
69*16467b97STreehugger Robot        parser = parserCls(tStream)
70*16467b97STreehugger Robot        r = getattr(parser, grammarEntry)()
71*16467b97STreehugger Robot
72*16467b97STreehugger Robot        if r:
73*16467b97STreehugger Robot            return r.tree.toStringTree()
74*16467b97STreehugger Robot
75*16467b97STreehugger Robot        return ""
76*16467b97STreehugger Robot
77*16467b97STreehugger Robot
78*16467b97STreehugger Robot    def execTreeParser(self, grammar, grammarEntry, treeGrammar, treeEntry, input):
79*16467b97STreehugger Robot        lexerCls, parserCls = self.compileInlineGrammar(grammar)
80*16467b97STreehugger Robot        walkerCls = self.compileInlineGrammar(treeGrammar)
81*16467b97STreehugger Robot
82*16467b97STreehugger Robot        cStream = antlr3.StringStream(input)
83*16467b97STreehugger Robot        lexer = lexerCls(cStream)
84*16467b97STreehugger Robot        tStream = antlr3.CommonTokenStream(lexer)
85*16467b97STreehugger Robot        parser = parserCls(tStream)
86*16467b97STreehugger Robot        r = getattr(parser, grammarEntry)()
87*16467b97STreehugger Robot        nodes = antlr3.tree.CommonTreeNodeStream(r.tree)
88*16467b97STreehugger Robot        nodes.setTokenStream(tStream)
89*16467b97STreehugger Robot        walker = walkerCls(nodes)
90*16467b97STreehugger Robot        r = getattr(walker, treeEntry)()
91*16467b97STreehugger Robot
92*16467b97STreehugger Robot        if r:
93*16467b97STreehugger Robot            return r.tree.toStringTree()
94*16467b97STreehugger Robot
95*16467b97STreehugger Robot        return ""
96*16467b97STreehugger Robot
97*16467b97STreehugger Robot
98*16467b97STreehugger Robot    # PARSERS -- AUTO AST
99*16467b97STreehugger Robot
100*16467b97STreehugger Robot    def testToken(self):
101*16467b97STreehugger Robot        grammar = textwrap.dedent(
102*16467b97STreehugger Robot        r'''
103*16467b97STreehugger Robot        grammar T1;
104*16467b97STreehugger Robot        options {
105*16467b97STreehugger Robot            language=Python3;
106*16467b97STreehugger Robot            output=AST;
107*16467b97STreehugger Robot        }
108*16467b97STreehugger Robot        @header {
109*16467b97STreehugger Robot        class V(CommonTree):
110*16467b97STreehugger Robot            def toString(self):
111*16467b97STreehugger Robot                return self.token.text + "<V>"
112*16467b97STreehugger Robot            __str__ = toString
113*16467b97STreehugger Robot
114*16467b97STreehugger Robot        }
115*16467b97STreehugger Robot        a : ID<V> ;
116*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
117*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
118*16467b97STreehugger Robot        ''')
119*16467b97STreehugger Robot
120*16467b97STreehugger Robot        found = self.execParser(
121*16467b97STreehugger Robot            grammar, 'a',
122*16467b97STreehugger Robot            input="a"
123*16467b97STreehugger Robot            )
124*16467b97STreehugger Robot
125*16467b97STreehugger Robot        self.assertEqual("a<V>", found)
126*16467b97STreehugger Robot
127*16467b97STreehugger Robot
128*16467b97STreehugger Robot    def testTokenCommonTree(self):
129*16467b97STreehugger Robot        grammar = textwrap.dedent(
130*16467b97STreehugger Robot            r'''
131*16467b97STreehugger Robot            grammar T;
132*16467b97STreehugger Robot            options {
133*16467b97STreehugger Robot                language=Python3;
134*16467b97STreehugger Robot                output=AST;
135*16467b97STreehugger Robot            }
136*16467b97STreehugger Robot            a : ID<CommonTree> ;
137*16467b97STreehugger Robot            ID : 'a'..'z'+ ;
138*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
139*16467b97STreehugger Robot            ''')
140*16467b97STreehugger Robot
141*16467b97STreehugger Robot        found = self.execParser(
142*16467b97STreehugger Robot            grammar, 'a',
143*16467b97STreehugger Robot            input="a")
144*16467b97STreehugger Robot
145*16467b97STreehugger Robot        self.assertEqual("a", found)
146*16467b97STreehugger Robot
147*16467b97STreehugger Robot
148*16467b97STreehugger Robot    def testTokenWithQualifiedType(self):
149*16467b97STreehugger Robot        grammar = textwrap.dedent(
150*16467b97STreehugger Robot            r'''
151*16467b97STreehugger Robot            grammar T;
152*16467b97STreehugger Robot            options {
153*16467b97STreehugger Robot                language=Python3;
154*16467b97STreehugger Robot                output=AST;
155*16467b97STreehugger Robot            }
156*16467b97STreehugger Robot            @members {
157*16467b97STreehugger Robot            class V(CommonTree):
158*16467b97STreehugger Robot                def toString(self):
159*16467b97STreehugger Robot                    return self.token.text + "<V>"
160*16467b97STreehugger Robot                __str__ = toString
161*16467b97STreehugger Robot            }
162*16467b97STreehugger Robot            a : ID<TParser.V> ; // TParser.V is qualified name
163*16467b97STreehugger Robot            ID : 'a'..'z'+ ;
164*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
165*16467b97STreehugger Robot            ''')
166*16467b97STreehugger Robot
167*16467b97STreehugger Robot        found = self.execParser(
168*16467b97STreehugger Robot            grammar, 'a',
169*16467b97STreehugger Robot            input="a"
170*16467b97STreehugger Robot            )
171*16467b97STreehugger Robot
172*16467b97STreehugger Robot        self.assertEqual("a<V>", found)
173*16467b97STreehugger Robot
174*16467b97STreehugger Robot
175*16467b97STreehugger Robot    def testNamedType(self):
176*16467b97STreehugger Robot        grammar = textwrap.dedent(
177*16467b97STreehugger Robot            r"""
178*16467b97STreehugger Robot            grammar $T;
179*16467b97STreehugger Robot            options {
180*16467b97STreehugger Robot                language=Python3;
181*16467b97STreehugger Robot                output=AST;
182*16467b97STreehugger Robot            }
183*16467b97STreehugger Robot            @header {
184*16467b97STreehugger Robot            class V(CommonTree):
185*16467b97STreehugger Robot                def toString(self):
186*16467b97STreehugger Robot                    return self.token.text + "<V>"
187*16467b97STreehugger Robot                __str__ = toString
188*16467b97STreehugger Robot            }
189*16467b97STreehugger Robot            a : ID<node=V> ;
190*16467b97STreehugger Robot            ID : 'a'..'z'+ ;
191*16467b97STreehugger Robot            WS : (' '|'\\n') {$channel=HIDDEN;} ;
192*16467b97STreehugger Robot            """)
193*16467b97STreehugger Robot
194*16467b97STreehugger Robot        found = self.execParser(grammar, 'a', input="a")
195*16467b97STreehugger Robot        self.assertEqual("a<V>", found)
196*16467b97STreehugger Robot
197*16467b97STreehugger Robot
198*16467b97STreehugger Robot    def testTokenWithLabel(self):
199*16467b97STreehugger Robot        grammar = textwrap.dedent(
200*16467b97STreehugger Robot        r'''
201*16467b97STreehugger Robot        grammar T2;
202*16467b97STreehugger Robot        options {
203*16467b97STreehugger Robot            language=Python3;
204*16467b97STreehugger Robot            output=AST;
205*16467b97STreehugger Robot        }
206*16467b97STreehugger Robot        @header {
207*16467b97STreehugger Robot        class V(CommonTree):
208*16467b97STreehugger Robot            def toString(self):
209*16467b97STreehugger Robot                return self.token.text + "<V>"
210*16467b97STreehugger Robot            __str__ = toString
211*16467b97STreehugger Robot
212*16467b97STreehugger Robot        }
213*16467b97STreehugger Robot        a : x=ID<V> ;
214*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
215*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
216*16467b97STreehugger Robot        ''')
217*16467b97STreehugger Robot
218*16467b97STreehugger Robot        found = self.execParser(
219*16467b97STreehugger Robot            grammar, 'a',
220*16467b97STreehugger Robot            input="a"
221*16467b97STreehugger Robot            )
222*16467b97STreehugger Robot
223*16467b97STreehugger Robot        self.assertEqual("a<V>", found)
224*16467b97STreehugger Robot
225*16467b97STreehugger Robot
226*16467b97STreehugger Robot    def testTokenWithListLabel(self):
227*16467b97STreehugger Robot        grammar = textwrap.dedent(
228*16467b97STreehugger Robot        r'''
229*16467b97STreehugger Robot        grammar T3;
230*16467b97STreehugger Robot        options {
231*16467b97STreehugger Robot            language=Python3;
232*16467b97STreehugger Robot            output=AST;
233*16467b97STreehugger Robot        }
234*16467b97STreehugger Robot        @header {
235*16467b97STreehugger Robot        class V(CommonTree):
236*16467b97STreehugger Robot            def toString(self):
237*16467b97STreehugger Robot                return self.token.text + "<V>"
238*16467b97STreehugger Robot            __str__ = toString
239*16467b97STreehugger Robot
240*16467b97STreehugger Robot        }
241*16467b97STreehugger Robot        a : x+=ID<V> ;
242*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
243*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
244*16467b97STreehugger Robot        ''')
245*16467b97STreehugger Robot
246*16467b97STreehugger Robot        found = self.execParser(
247*16467b97STreehugger Robot            grammar, 'a',
248*16467b97STreehugger Robot            input="a"
249*16467b97STreehugger Robot            )
250*16467b97STreehugger Robot
251*16467b97STreehugger Robot        self.assertEqual("a<V>", found)
252*16467b97STreehugger Robot
253*16467b97STreehugger Robot
254*16467b97STreehugger Robot    def testTokenRoot(self):
255*16467b97STreehugger Robot        grammar = textwrap.dedent(
256*16467b97STreehugger Robot        r'''
257*16467b97STreehugger Robot        grammar T4;
258*16467b97STreehugger Robot        options {
259*16467b97STreehugger Robot            language=Python3;
260*16467b97STreehugger Robot            output=AST;
261*16467b97STreehugger Robot        }
262*16467b97STreehugger Robot        @header {
263*16467b97STreehugger Robot        class V(CommonTree):
264*16467b97STreehugger Robot            def toString(self):
265*16467b97STreehugger Robot                return self.token.text + "<V>"
266*16467b97STreehugger Robot            __str__ = toString
267*16467b97STreehugger Robot
268*16467b97STreehugger Robot        }
269*16467b97STreehugger Robot        a : ID<V>^ ;
270*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
271*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
272*16467b97STreehugger Robot        ''')
273*16467b97STreehugger Robot
274*16467b97STreehugger Robot        found = self.execParser(
275*16467b97STreehugger Robot            grammar, 'a',
276*16467b97STreehugger Robot            input="a"
277*16467b97STreehugger Robot            )
278*16467b97STreehugger Robot
279*16467b97STreehugger Robot        self.assertEqual("a<V>", found)
280*16467b97STreehugger Robot
281*16467b97STreehugger Robot
282*16467b97STreehugger Robot    def testTokenRootWithListLabel(self):
283*16467b97STreehugger Robot        grammar = textwrap.dedent(
284*16467b97STreehugger Robot        r'''
285*16467b97STreehugger Robot        grammar T5;
286*16467b97STreehugger Robot        options {
287*16467b97STreehugger Robot            language=Python3;
288*16467b97STreehugger Robot            output=AST;
289*16467b97STreehugger Robot        }
290*16467b97STreehugger Robot        @header {
291*16467b97STreehugger Robot        class V(CommonTree):
292*16467b97STreehugger Robot            def toString(self):
293*16467b97STreehugger Robot                return self.token.text + "<V>"
294*16467b97STreehugger Robot            __str__ = toString
295*16467b97STreehugger Robot
296*16467b97STreehugger Robot        }
297*16467b97STreehugger Robot        a : x+=ID<V>^ ;
298*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
299*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
300*16467b97STreehugger Robot        ''')
301*16467b97STreehugger Robot
302*16467b97STreehugger Robot        found = self.execParser(
303*16467b97STreehugger Robot            grammar, 'a',
304*16467b97STreehugger Robot            input="a"
305*16467b97STreehugger Robot            )
306*16467b97STreehugger Robot
307*16467b97STreehugger Robot        self.assertEqual("a<V>", found)
308*16467b97STreehugger Robot
309*16467b97STreehugger Robot
310*16467b97STreehugger Robot    def testString(self):
311*16467b97STreehugger Robot        grammar = textwrap.dedent(
312*16467b97STreehugger Robot        r'''
313*16467b97STreehugger Robot        grammar T6;
314*16467b97STreehugger Robot        options {
315*16467b97STreehugger Robot            language=Python3;
316*16467b97STreehugger Robot            output=AST;
317*16467b97STreehugger Robot        }
318*16467b97STreehugger Robot        @header {
319*16467b97STreehugger Robot        class V(CommonTree):
320*16467b97STreehugger Robot            def toString(self):
321*16467b97STreehugger Robot                return self.token.text + "<V>"
322*16467b97STreehugger Robot            __str__ = toString
323*16467b97STreehugger Robot
324*16467b97STreehugger Robot        }
325*16467b97STreehugger Robot        a : 'begin'<V> ;
326*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
327*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
328*16467b97STreehugger Robot        ''')
329*16467b97STreehugger Robot
330*16467b97STreehugger Robot        found = self.execParser(
331*16467b97STreehugger Robot            grammar, 'a',
332*16467b97STreehugger Robot            input="begin"
333*16467b97STreehugger Robot            )
334*16467b97STreehugger Robot
335*16467b97STreehugger Robot        self.assertEqual("begin<V>", found)
336*16467b97STreehugger Robot
337*16467b97STreehugger Robot
338*16467b97STreehugger Robot    def testStringRoot(self):
339*16467b97STreehugger Robot        grammar = textwrap.dedent(
340*16467b97STreehugger Robot        r'''
341*16467b97STreehugger Robot        grammar T7;
342*16467b97STreehugger Robot        options {
343*16467b97STreehugger Robot            language=Python3;
344*16467b97STreehugger Robot            output=AST;
345*16467b97STreehugger Robot        }
346*16467b97STreehugger Robot        @header {
347*16467b97STreehugger Robot        class V(CommonTree):
348*16467b97STreehugger Robot            def toString(self):
349*16467b97STreehugger Robot                return self.token.text + "<V>"
350*16467b97STreehugger Robot            __str__ = toString
351*16467b97STreehugger Robot
352*16467b97STreehugger Robot        }
353*16467b97STreehugger Robot        a : 'begin'<V>^ ;
354*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
355*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
356*16467b97STreehugger Robot        ''')
357*16467b97STreehugger Robot
358*16467b97STreehugger Robot        found = self.execParser(
359*16467b97STreehugger Robot            grammar, 'a',
360*16467b97STreehugger Robot            input="begin"
361*16467b97STreehugger Robot            )
362*16467b97STreehugger Robot
363*16467b97STreehugger Robot        self.assertEqual("begin<V>", found)
364*16467b97STreehugger Robot
365*16467b97STreehugger Robot
366*16467b97STreehugger Robot    # PARSERS -- REWRITE AST
367*16467b97STreehugger Robot
368*16467b97STreehugger Robot    def testRewriteToken(self):
369*16467b97STreehugger Robot        grammar = textwrap.dedent(
370*16467b97STreehugger Robot        r'''
371*16467b97STreehugger Robot        grammar T8;
372*16467b97STreehugger Robot        options {
373*16467b97STreehugger Robot            language=Python3;
374*16467b97STreehugger Robot            output=AST;
375*16467b97STreehugger Robot        }
376*16467b97STreehugger Robot        @header {
377*16467b97STreehugger Robot        class V(CommonTree):
378*16467b97STreehugger Robot            def toString(self):
379*16467b97STreehugger Robot                return self.token.text + "<V>"
380*16467b97STreehugger Robot            __str__ = toString
381*16467b97STreehugger Robot
382*16467b97STreehugger Robot        }
383*16467b97STreehugger Robot        a : ID -> ID<V> ;
384*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
385*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
386*16467b97STreehugger Robot        ''')
387*16467b97STreehugger Robot
388*16467b97STreehugger Robot        found = self.execParser(
389*16467b97STreehugger Robot            grammar, 'a',
390*16467b97STreehugger Robot            input="a"
391*16467b97STreehugger Robot            )
392*16467b97STreehugger Robot
393*16467b97STreehugger Robot        self.assertEqual("a<V>", found)
394*16467b97STreehugger Robot
395*16467b97STreehugger Robot
396*16467b97STreehugger Robot    def testRewriteTokenWithArgs(self):
397*16467b97STreehugger Robot        grammar = textwrap.dedent(
398*16467b97STreehugger Robot        r'''
399*16467b97STreehugger Robot        grammar T9;
400*16467b97STreehugger Robot        options {
401*16467b97STreehugger Robot            language=Python3;
402*16467b97STreehugger Robot            output=AST;
403*16467b97STreehugger Robot        }
404*16467b97STreehugger Robot        @header {
405*16467b97STreehugger Robot        class V(CommonTree):
406*16467b97STreehugger Robot            def __init__(self, *args):
407*16467b97STreehugger Robot                if len(args) == 4:
408*16467b97STreehugger Robot                    ttype = args[0]
409*16467b97STreehugger Robot                    x = args[1]
410*16467b97STreehugger Robot                    y = args[2]
411*16467b97STreehugger Robot                    z = args[3]
412*16467b97STreehugger Robot                    token = CommonToken(type=ttype, text="")
413*16467b97STreehugger Robot
414*16467b97STreehugger Robot                elif len(args) == 3:
415*16467b97STreehugger Robot                    ttype = args[0]
416*16467b97STreehugger Robot                    token = args[1]
417*16467b97STreehugger Robot                    x = args[2]
418*16467b97STreehugger Robot                    y, z = 0, 0
419*16467b97STreehugger Robot
420*16467b97STreehugger Robot                else:
421*16467b97STreehugger Robot                    raise TypeError("Invalid args {!r}".format(args))
422*16467b97STreehugger Robot
423*16467b97STreehugger Robot                super().__init__(token)
424*16467b97STreehugger Robot                self.x = x
425*16467b97STreehugger Robot                self.y = y
426*16467b97STreehugger Robot                self.z = z
427*16467b97STreehugger Robot
428*16467b97STreehugger Robot            def toString(self):
429*16467b97STreehugger Robot                txt = ""
430*16467b97STreehugger Robot                if self.token:
431*16467b97STreehugger Robot                    txt += self.token.text
432*16467b97STreehugger Robot                txt +="<V>;{0.x}{0.y}{0.z}".format(self)
433*16467b97STreehugger Robot                return txt
434*16467b97STreehugger Robot            __str__ = toString
435*16467b97STreehugger Robot
436*16467b97STreehugger Robot        }
437*16467b97STreehugger Robot        a : ID -> ID<V>[42,19,30] ID<V>[$ID,99];
438*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
439*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
440*16467b97STreehugger Robot        ''')
441*16467b97STreehugger Robot
442*16467b97STreehugger Robot        found = self.execParser(
443*16467b97STreehugger Robot            grammar, 'a',
444*16467b97STreehugger Robot            input="a"
445*16467b97STreehugger Robot            )
446*16467b97STreehugger Robot
447*16467b97STreehugger Robot        self.assertEqual("<V>;421930 a<V>;9900", found)
448*16467b97STreehugger Robot
449*16467b97STreehugger Robot
450*16467b97STreehugger Robot    def testRewriteTokenRoot(self):
451*16467b97STreehugger Robot        grammar = textwrap.dedent(
452*16467b97STreehugger Robot        r'''
453*16467b97STreehugger Robot        grammar T10;
454*16467b97STreehugger Robot        options {
455*16467b97STreehugger Robot            language=Python3;
456*16467b97STreehugger Robot            output=AST;
457*16467b97STreehugger Robot        }
458*16467b97STreehugger Robot        @header {
459*16467b97STreehugger Robot        class V(CommonTree):
460*16467b97STreehugger Robot            def toString(self):
461*16467b97STreehugger Robot                return self.token.text + "<V>"
462*16467b97STreehugger Robot            __str__ = toString
463*16467b97STreehugger Robot
464*16467b97STreehugger Robot        }
465*16467b97STreehugger Robot        a : ID INT -> ^(ID<V> INT) ;
466*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
467*16467b97STreehugger Robot        INT : '0'..'9'+ ;
468*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
469*16467b97STreehugger Robot        ''')
470*16467b97STreehugger Robot
471*16467b97STreehugger Robot        found = self.execParser(
472*16467b97STreehugger Robot            grammar, 'a',
473*16467b97STreehugger Robot            input="a 2"
474*16467b97STreehugger Robot            )
475*16467b97STreehugger Robot
476*16467b97STreehugger Robot        self.assertEqual("(a<V> 2)", found)
477*16467b97STreehugger Robot
478*16467b97STreehugger Robot
479*16467b97STreehugger Robot    def testRewriteString(self):
480*16467b97STreehugger Robot        grammar = textwrap.dedent(
481*16467b97STreehugger Robot        r'''
482*16467b97STreehugger Robot        grammar T11;
483*16467b97STreehugger Robot        options {
484*16467b97STreehugger Robot            language=Python3;
485*16467b97STreehugger Robot            output=AST;
486*16467b97STreehugger Robot        }
487*16467b97STreehugger Robot        @header {
488*16467b97STreehugger Robot        class V(CommonTree):
489*16467b97STreehugger Robot            def toString(self):
490*16467b97STreehugger Robot                return self.token.text + "<V>"
491*16467b97STreehugger Robot            __str__ = toString
492*16467b97STreehugger Robot
493*16467b97STreehugger Robot        }
494*16467b97STreehugger Robot        a : 'begin' -> 'begin'<V> ;
495*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
496*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
497*16467b97STreehugger Robot        ''')
498*16467b97STreehugger Robot
499*16467b97STreehugger Robot        found = self.execParser(
500*16467b97STreehugger Robot            grammar, 'a',
501*16467b97STreehugger Robot            input="begin"
502*16467b97STreehugger Robot            )
503*16467b97STreehugger Robot
504*16467b97STreehugger Robot        self.assertEqual("begin<V>", found)
505*16467b97STreehugger Robot
506*16467b97STreehugger Robot
507*16467b97STreehugger Robot    def testRewriteStringRoot(self):
508*16467b97STreehugger Robot        grammar = textwrap.dedent(
509*16467b97STreehugger Robot        r'''
510*16467b97STreehugger Robot        grammar T12;
511*16467b97STreehugger Robot        options {
512*16467b97STreehugger Robot            language=Python3;
513*16467b97STreehugger Robot            output=AST;
514*16467b97STreehugger Robot        }
515*16467b97STreehugger Robot        @header {
516*16467b97STreehugger Robot        class V(CommonTree):
517*16467b97STreehugger Robot            def toString(self):
518*16467b97STreehugger Robot                return self.token.text + "<V>"
519*16467b97STreehugger Robot            __str__ = toString
520*16467b97STreehugger Robot
521*16467b97STreehugger Robot        }
522*16467b97STreehugger Robot        a : 'begin' INT -> ^('begin'<V> INT) ;
523*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
524*16467b97STreehugger Robot        INT : '0'..'9'+ ;
525*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
526*16467b97STreehugger Robot        ''')
527*16467b97STreehugger Robot
528*16467b97STreehugger Robot        found = self.execParser(
529*16467b97STreehugger Robot            grammar, 'a',
530*16467b97STreehugger Robot            input="begin 2"
531*16467b97STreehugger Robot            )
532*16467b97STreehugger Robot
533*16467b97STreehugger Robot        self.assertEqual("(begin<V> 2)", found)
534*16467b97STreehugger Robot
535*16467b97STreehugger Robot    def testRewriteRuleResults(self):
536*16467b97STreehugger Robot        grammar = textwrap.dedent(
537*16467b97STreehugger Robot            r'''
538*16467b97STreehugger Robot            grammar T;
539*16467b97STreehugger Robot            options {
540*16467b97STreehugger Robot                language=Python3;
541*16467b97STreehugger Robot                output=AST;
542*16467b97STreehugger Robot            }
543*16467b97STreehugger Robot            tokens {LIST;}
544*16467b97STreehugger Robot            @header {
545*16467b97STreehugger Robot            class V(CommonTree):
546*16467b97STreehugger Robot                def toString(self):
547*16467b97STreehugger Robot                    return self.token.text + "<V>"
548*16467b97STreehugger Robot                __str__ = toString
549*16467b97STreehugger Robot
550*16467b97STreehugger Robot            class W(CommonTree):
551*16467b97STreehugger Robot                def __init__(self, tokenType, txt):
552*16467b97STreehugger Robot                    super().__init__(
553*16467b97STreehugger Robot                        CommonToken(type=tokenType, text=txt))
554*16467b97STreehugger Robot
555*16467b97STreehugger Robot                def toString(self):
556*16467b97STreehugger Robot                    return self.token.text + "<W>"
557*16467b97STreehugger Robot                __str__ = toString
558*16467b97STreehugger Robot
559*16467b97STreehugger Robot            }
560*16467b97STreehugger Robot            a : id (',' id)* -> ^(LIST<W>["LIST"] id+);
561*16467b97STreehugger Robot            id : ID -> ID<V>;
562*16467b97STreehugger Robot            ID : 'a'..'z'+ ;
563*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
564*16467b97STreehugger Robot            ''')
565*16467b97STreehugger Robot
566*16467b97STreehugger Robot        found = self.execParser(
567*16467b97STreehugger Robot            grammar, 'a',
568*16467b97STreehugger Robot            input="a,b,c")
569*16467b97STreehugger Robot
570*16467b97STreehugger Robot        self.assertEqual("(LIST<W> a<V> b<V> c<V>)", found)
571*16467b97STreehugger Robot
572*16467b97STreehugger Robot    def testCopySemanticsWithHetero(self):
573*16467b97STreehugger Robot        grammar = textwrap.dedent(
574*16467b97STreehugger Robot            r'''
575*16467b97STreehugger Robot            grammar T;
576*16467b97STreehugger Robot            options {
577*16467b97STreehugger Robot                language=Python3;
578*16467b97STreehugger Robot                output=AST;
579*16467b97STreehugger Robot            }
580*16467b97STreehugger Robot            @header {
581*16467b97STreehugger Robot            class V(CommonTree):
582*16467b97STreehugger Robot                def dupNode(self):
583*16467b97STreehugger Robot                    return V(self)
584*16467b97STreehugger Robot
585*16467b97STreehugger Robot                def toString(self):
586*16467b97STreehugger Robot                    return self.token.text + "<V>"
587*16467b97STreehugger Robot                __str__ = toString
588*16467b97STreehugger Robot
589*16467b97STreehugger Robot            }
590*16467b97STreehugger Robot            a : type ID (',' ID)* ';' -> ^(type ID)+;
591*16467b97STreehugger Robot            type : 'int'<V> ;
592*16467b97STreehugger Robot            ID : 'a'..'z'+ ;
593*16467b97STreehugger Robot            INT : '0'..'9'+;
594*16467b97STreehugger Robot            WS : (' '|'\\n') {$channel=HIDDEN;} ;
595*16467b97STreehugger Robot            ''')
596*16467b97STreehugger Robot
597*16467b97STreehugger Robot        found = self.execParser(
598*16467b97STreehugger Robot            grammar, 'a',
599*16467b97STreehugger Robot            input="int a, b, c;")
600*16467b97STreehugger Robot        self.assertEqual("(int<V> a) (int<V> b) (int<V> c)", found)
601*16467b97STreehugger Robot
602*16467b97STreehugger Robot    # TREE PARSERS -- REWRITE AST
603*16467b97STreehugger Robot
604*16467b97STreehugger Robot    def testTreeParserRewriteFlatList(self):
605*16467b97STreehugger Robot        grammar = textwrap.dedent(
606*16467b97STreehugger Robot        r'''
607*16467b97STreehugger Robot        grammar T13;
608*16467b97STreehugger Robot        options {
609*16467b97STreehugger Robot            language=Python3;
610*16467b97STreehugger Robot            output=AST;
611*16467b97STreehugger Robot        }
612*16467b97STreehugger Robot        a : ID INT;
613*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
614*16467b97STreehugger Robot        INT : '0'..'9'+;
615*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
616*16467b97STreehugger Robot        ''')
617*16467b97STreehugger Robot
618*16467b97STreehugger Robot        treeGrammar = textwrap.dedent(
619*16467b97STreehugger Robot        r'''
620*16467b97STreehugger Robot        tree grammar TP13;
621*16467b97STreehugger Robot        options {
622*16467b97STreehugger Robot            language=Python3;
623*16467b97STreehugger Robot            output=AST;
624*16467b97STreehugger Robot            ASTLabelType=CommonTree;
625*16467b97STreehugger Robot            tokenVocab=T13;
626*16467b97STreehugger Robot        }
627*16467b97STreehugger Robot        @header {
628*16467b97STreehugger Robot        class V(CommonTree):
629*16467b97STreehugger Robot            def toString(self):
630*16467b97STreehugger Robot                return self.token.text + "<V>"
631*16467b97STreehugger Robot            __str__ = toString
632*16467b97STreehugger Robot
633*16467b97STreehugger Robot        class W(CommonTree):
634*16467b97STreehugger Robot            def toString(self):
635*16467b97STreehugger Robot                return self.token.text + "<W>"
636*16467b97STreehugger Robot            __str__ = toString
637*16467b97STreehugger Robot
638*16467b97STreehugger Robot        }
639*16467b97STreehugger Robot        a : ID INT -> INT<V> ID<W>
640*16467b97STreehugger Robot          ;
641*16467b97STreehugger Robot        ''')
642*16467b97STreehugger Robot
643*16467b97STreehugger Robot        found = self.execTreeParser(
644*16467b97STreehugger Robot            grammar, 'a',
645*16467b97STreehugger Robot            treeGrammar, 'a',
646*16467b97STreehugger Robot            input="abc 34"
647*16467b97STreehugger Robot            )
648*16467b97STreehugger Robot
649*16467b97STreehugger Robot        self.assertEqual("34<V> abc<W>", found)
650*16467b97STreehugger Robot
651*16467b97STreehugger Robot
652*16467b97STreehugger Robot    def testTreeParserRewriteTree(self):
653*16467b97STreehugger Robot        grammar = textwrap.dedent(
654*16467b97STreehugger Robot        r'''
655*16467b97STreehugger Robot        grammar T14;
656*16467b97STreehugger Robot        options {
657*16467b97STreehugger Robot            language=Python3;
658*16467b97STreehugger Robot            output=AST;
659*16467b97STreehugger Robot        }
660*16467b97STreehugger Robot        a : ID INT;
661*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
662*16467b97STreehugger Robot        INT : '0'..'9'+;
663*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
664*16467b97STreehugger Robot        ''')
665*16467b97STreehugger Robot
666*16467b97STreehugger Robot        treeGrammar = textwrap.dedent(
667*16467b97STreehugger Robot        r'''
668*16467b97STreehugger Robot        tree grammar TP14;
669*16467b97STreehugger Robot        options {
670*16467b97STreehugger Robot            language=Python3;
671*16467b97STreehugger Robot            output=AST;
672*16467b97STreehugger Robot            ASTLabelType=CommonTree;
673*16467b97STreehugger Robot            tokenVocab=T14;
674*16467b97STreehugger Robot        }
675*16467b97STreehugger Robot        @header {
676*16467b97STreehugger Robot        class V(CommonTree):
677*16467b97STreehugger Robot            def toString(self):
678*16467b97STreehugger Robot                return self.token.text + "<V>"
679*16467b97STreehugger Robot            __str__ = toString
680*16467b97STreehugger Robot
681*16467b97STreehugger Robot        class W(CommonTree):
682*16467b97STreehugger Robot            def toString(self):
683*16467b97STreehugger Robot                return self.token.text + "<W>"
684*16467b97STreehugger Robot            __str__ = toString
685*16467b97STreehugger Robot
686*16467b97STreehugger Robot        }
687*16467b97STreehugger Robot        a : ID INT -> ^(INT<V> ID<W>)
688*16467b97STreehugger Robot          ;
689*16467b97STreehugger Robot        ''')
690*16467b97STreehugger Robot
691*16467b97STreehugger Robot        found = self.execTreeParser(
692*16467b97STreehugger Robot            grammar, 'a',
693*16467b97STreehugger Robot            treeGrammar, 'a',
694*16467b97STreehugger Robot            input="abc 34"
695*16467b97STreehugger Robot            )
696*16467b97STreehugger Robot
697*16467b97STreehugger Robot        self.assertEqual("(34<V> abc<W>)", found)
698*16467b97STreehugger Robot
699*16467b97STreehugger Robot
700*16467b97STreehugger Robot    def testTreeParserRewriteImaginary(self):
701*16467b97STreehugger Robot        grammar = textwrap.dedent(
702*16467b97STreehugger Robot        r'''
703*16467b97STreehugger Robot        grammar T15;
704*16467b97STreehugger Robot        options {
705*16467b97STreehugger Robot            language=Python3;
706*16467b97STreehugger Robot            output=AST;
707*16467b97STreehugger Robot        }
708*16467b97STreehugger Robot        a : ID ;
709*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
710*16467b97STreehugger Robot        INT : '0'..'9'+;
711*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
712*16467b97STreehugger Robot        ''')
713*16467b97STreehugger Robot
714*16467b97STreehugger Robot        treeGrammar = textwrap.dedent(
715*16467b97STreehugger Robot        r'''
716*16467b97STreehugger Robot        tree grammar TP15;
717*16467b97STreehugger Robot        options {
718*16467b97STreehugger Robot            language=Python3;
719*16467b97STreehugger Robot            output=AST;
720*16467b97STreehugger Robot            ASTLabelType=CommonTree;
721*16467b97STreehugger Robot            tokenVocab=T15;
722*16467b97STreehugger Robot        }
723*16467b97STreehugger Robot        tokens { ROOT; }
724*16467b97STreehugger Robot        @header {
725*16467b97STreehugger Robot        class V(CommonTree):
726*16467b97STreehugger Robot            def __init__(self, tokenType):
727*16467b97STreehugger Robot                super().__init__(CommonToken(tokenType))
728*16467b97STreehugger Robot
729*16467b97STreehugger Robot            def toString(self):
730*16467b97STreehugger Robot                return tokenNames[self.token.type] + "<V>"
731*16467b97STreehugger Robot            __str__ = toString
732*16467b97STreehugger Robot
733*16467b97STreehugger Robot
734*16467b97STreehugger Robot        }
735*16467b97STreehugger Robot        a : ID -> ROOT<V> ID
736*16467b97STreehugger Robot          ;
737*16467b97STreehugger Robot        ''')
738*16467b97STreehugger Robot
739*16467b97STreehugger Robot        found = self.execTreeParser(
740*16467b97STreehugger Robot            grammar, 'a',
741*16467b97STreehugger Robot            treeGrammar, 'a',
742*16467b97STreehugger Robot            input="abc"
743*16467b97STreehugger Robot            )
744*16467b97STreehugger Robot
745*16467b97STreehugger Robot        self.assertEqual("ROOT<V> abc", found)
746*16467b97STreehugger Robot
747*16467b97STreehugger Robot
748*16467b97STreehugger Robot    def testTreeParserRewriteImaginaryWithArgs(self):
749*16467b97STreehugger Robot        grammar = textwrap.dedent(
750*16467b97STreehugger Robot        r'''
751*16467b97STreehugger Robot        grammar T16;
752*16467b97STreehugger Robot        options {
753*16467b97STreehugger Robot            language=Python3;
754*16467b97STreehugger Robot            output=AST;
755*16467b97STreehugger Robot        }
756*16467b97STreehugger Robot        a : ID ;
757*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
758*16467b97STreehugger Robot        INT : '0'..'9'+;
759*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
760*16467b97STreehugger Robot        ''')
761*16467b97STreehugger Robot
762*16467b97STreehugger Robot        treeGrammar = textwrap.dedent(
763*16467b97STreehugger Robot        r'''
764*16467b97STreehugger Robot        tree grammar TP16;
765*16467b97STreehugger Robot        options {
766*16467b97STreehugger Robot            language=Python3;
767*16467b97STreehugger Robot            output=AST;
768*16467b97STreehugger Robot            ASTLabelType=CommonTree;
769*16467b97STreehugger Robot            tokenVocab=T16;
770*16467b97STreehugger Robot        }
771*16467b97STreehugger Robot        tokens { ROOT; }
772*16467b97STreehugger Robot        @header {
773*16467b97STreehugger Robot        class V(CommonTree):
774*16467b97STreehugger Robot            def __init__(self, tokenType, x):
775*16467b97STreehugger Robot                super().__init__(CommonToken(tokenType))
776*16467b97STreehugger Robot                self.x = x
777*16467b97STreehugger Robot
778*16467b97STreehugger Robot            def toString(self):
779*16467b97STreehugger Robot                return tokenNames[self.token.type] + "<V>;" + str(self.x)
780*16467b97STreehugger Robot            __str__ = toString
781*16467b97STreehugger Robot
782*16467b97STreehugger Robot        }
783*16467b97STreehugger Robot        a : ID -> ROOT<V>[42] ID
784*16467b97STreehugger Robot          ;
785*16467b97STreehugger Robot        ''')
786*16467b97STreehugger Robot
787*16467b97STreehugger Robot        found = self.execTreeParser(
788*16467b97STreehugger Robot            grammar, 'a',
789*16467b97STreehugger Robot            treeGrammar, 'a',
790*16467b97STreehugger Robot            input="abc"
791*16467b97STreehugger Robot            )
792*16467b97STreehugger Robot
793*16467b97STreehugger Robot        self.assertEqual("ROOT<V>;42 abc", found)
794*16467b97STreehugger Robot
795*16467b97STreehugger Robot
796*16467b97STreehugger Robot    def testTreeParserRewriteImaginaryRoot(self):
797*16467b97STreehugger Robot        grammar = textwrap.dedent(
798*16467b97STreehugger Robot        r'''
799*16467b97STreehugger Robot        grammar T17;
800*16467b97STreehugger Robot        options {
801*16467b97STreehugger Robot            language=Python3;
802*16467b97STreehugger Robot            output=AST;
803*16467b97STreehugger Robot        }
804*16467b97STreehugger Robot        a : ID ;
805*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
806*16467b97STreehugger Robot        INT : '0'..'9'+;
807*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
808*16467b97STreehugger Robot        ''')
809*16467b97STreehugger Robot
810*16467b97STreehugger Robot        treeGrammar = textwrap.dedent(
811*16467b97STreehugger Robot        r'''
812*16467b97STreehugger Robot        tree grammar TP17;
813*16467b97STreehugger Robot        options {
814*16467b97STreehugger Robot            language=Python3;
815*16467b97STreehugger Robot            output=AST;
816*16467b97STreehugger Robot            ASTLabelType=CommonTree;
817*16467b97STreehugger Robot            tokenVocab=T17;
818*16467b97STreehugger Robot        }
819*16467b97STreehugger Robot        tokens { ROOT; }
820*16467b97STreehugger Robot        @header {
821*16467b97STreehugger Robot        class V(CommonTree):
822*16467b97STreehugger Robot            def __init__(self, tokenType):
823*16467b97STreehugger Robot                super().__init__(CommonToken(tokenType))
824*16467b97STreehugger Robot
825*16467b97STreehugger Robot            def toString(self):
826*16467b97STreehugger Robot                return tokenNames[self.token.type] + "<V>"
827*16467b97STreehugger Robot            __str__ = toString
828*16467b97STreehugger Robot
829*16467b97STreehugger Robot        }
830*16467b97STreehugger Robot        a : ID -> ^(ROOT<V> ID)
831*16467b97STreehugger Robot          ;
832*16467b97STreehugger Robot        ''')
833*16467b97STreehugger Robot
834*16467b97STreehugger Robot        found = self.execTreeParser(
835*16467b97STreehugger Robot            grammar, 'a',
836*16467b97STreehugger Robot            treeGrammar, 'a',
837*16467b97STreehugger Robot            input="abc"
838*16467b97STreehugger Robot            )
839*16467b97STreehugger Robot
840*16467b97STreehugger Robot        self.assertEqual("(ROOT<V> abc)", found)
841*16467b97STreehugger Robot
842*16467b97STreehugger Robot
843*16467b97STreehugger Robot    def testTreeParserRewriteImaginaryFromReal(self):
844*16467b97STreehugger Robot        grammar = textwrap.dedent(
845*16467b97STreehugger Robot        r'''
846*16467b97STreehugger Robot        grammar T18;
847*16467b97STreehugger Robot        options {
848*16467b97STreehugger Robot            language=Python3;
849*16467b97STreehugger Robot            output=AST;
850*16467b97STreehugger Robot        }
851*16467b97STreehugger Robot        a : ID ;
852*16467b97STreehugger Robot        ID : 'a'..'z'+ ;
853*16467b97STreehugger Robot        INT : '0'..'9'+;
854*16467b97STreehugger Robot        WS : (' '|'\n') {$channel=HIDDEN;} ;
855*16467b97STreehugger Robot        ''')
856*16467b97STreehugger Robot
857*16467b97STreehugger Robot        treeGrammar = textwrap.dedent(
858*16467b97STreehugger Robot        r'''
859*16467b97STreehugger Robot        tree grammar TP18;
860*16467b97STreehugger Robot        options {
861*16467b97STreehugger Robot            language=Python3;
862*16467b97STreehugger Robot            output=AST;
863*16467b97STreehugger Robot            ASTLabelType=CommonTree;
864*16467b97STreehugger Robot            tokenVocab=T18;
865*16467b97STreehugger Robot        }
866*16467b97STreehugger Robot        tokens { ROOT; }
867*16467b97STreehugger Robot        @header {
868*16467b97STreehugger Robot        class V(CommonTree):
869*16467b97STreehugger Robot            def __init__(self, tokenType, tree=None):
870*16467b97STreehugger Robot                if tree is None:
871*16467b97STreehugger Robot                    super().__init__(CommonToken(tokenType))
872*16467b97STreehugger Robot                else:
873*16467b97STreehugger Robot                    super().__init__(tree)
874*16467b97STreehugger Robot                    self.token.type = tokenType
875*16467b97STreehugger Robot
876*16467b97STreehugger Robot            def toString(self):
877*16467b97STreehugger Robot                return tokenNames[self.token.type]+"<V>@"+str(self.token.line)
878*16467b97STreehugger Robot            __str__ = toString
879*16467b97STreehugger Robot
880*16467b97STreehugger Robot        }
881*16467b97STreehugger Robot        a : ID -> ROOT<V>[$ID]
882*16467b97STreehugger Robot          ;
883*16467b97STreehugger Robot        ''')
884*16467b97STreehugger Robot
885*16467b97STreehugger Robot        found = self.execTreeParser(
886*16467b97STreehugger Robot            grammar, 'a',
887*16467b97STreehugger Robot            treeGrammar, 'a',
888*16467b97STreehugger Robot            input="abc"
889*16467b97STreehugger Robot            )
890*16467b97STreehugger Robot
891*16467b97STreehugger Robot        self.assertEqual("ROOT<V>@1", found)
892*16467b97STreehugger Robot
893*16467b97STreehugger Robot
894*16467b97STreehugger Robot    def testTreeParserAutoHeteroAST(self):
895*16467b97STreehugger Robot        grammar = textwrap.dedent(
896*16467b97STreehugger Robot            r'''
897*16467b97STreehugger Robot            grammar T;
898*16467b97STreehugger Robot            options {
899*16467b97STreehugger Robot                language=Python3;
900*16467b97STreehugger Robot                output=AST;
901*16467b97STreehugger Robot            }
902*16467b97STreehugger Robot            a : ID ';' ;
903*16467b97STreehugger Robot            ID : 'a'..'z'+ ;
904*16467b97STreehugger Robot            INT : '0'..'9'+;
905*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
906*16467b97STreehugger Robot            ''')
907*16467b97STreehugger Robot
908*16467b97STreehugger Robot        treeGrammar = textwrap.dedent(
909*16467b97STreehugger Robot            r'''
910*16467b97STreehugger Robot            tree grammar TP;
911*16467b97STreehugger Robot            options {
912*16467b97STreehugger Robot                language=Python3;
913*16467b97STreehugger Robot                output=AST;
914*16467b97STreehugger Robot                ASTLabelType=CommonTree;
915*16467b97STreehugger Robot                tokenVocab=T;
916*16467b97STreehugger Robot            }
917*16467b97STreehugger Robot            tokens { ROOT; }
918*16467b97STreehugger Robot            @header {
919*16467b97STreehugger Robot            class V(CommonTree):
920*16467b97STreehugger Robot                def toString(self):
921*16467b97STreehugger Robot                    return CommonTree.toString(self) + "<V>"
922*16467b97STreehugger Robot                __str__ = toString
923*16467b97STreehugger Robot
924*16467b97STreehugger Robot            }
925*16467b97STreehugger Robot
926*16467b97STreehugger Robot            a : ID<V> ';'<V>;
927*16467b97STreehugger Robot            ''')
928*16467b97STreehugger Robot
929*16467b97STreehugger Robot        found = self.execTreeParser(
930*16467b97STreehugger Robot            grammar, 'a',
931*16467b97STreehugger Robot            treeGrammar, 'a',
932*16467b97STreehugger Robot            input="abc;"
933*16467b97STreehugger Robot            )
934*16467b97STreehugger Robot
935*16467b97STreehugger Robot        self.assertEqual("abc<V> ;<V>", found)
936*16467b97STreehugger Robot
937*16467b97STreehugger Robot
938*16467b97STreehugger Robotif __name__ == '__main__':
939*16467b97STreehugger Robot    unittest.main()
940