xref: /aosp_15_r20/external/antlr/runtime/Python/tests/t055templates.py (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robotimport unittest
2*16467b97STreehugger Robotimport textwrap
3*16467b97STreehugger Robotimport antlr3
4*16467b97STreehugger Robotimport antlr3.tree
5*16467b97STreehugger Robotimport stringtemplate3
6*16467b97STreehugger Robotimport testbase
7*16467b97STreehugger Robotimport sys
8*16467b97STreehugger Robotimport os
9*16467b97STreehugger Robotfrom StringIO import StringIO
10*16467b97STreehugger Robot
11*16467b97STreehugger Robotclass T(testbase.ANTLRTest):
12*16467b97STreehugger Robot    def execParser(self, grammar, grammarEntry, input, group=None):
13*16467b97STreehugger Robot        lexerCls, parserCls = self.compileInlineGrammar(grammar)
14*16467b97STreehugger Robot
15*16467b97STreehugger Robot        cStream = antlr3.StringStream(input)
16*16467b97STreehugger Robot        lexer = lexerCls(cStream)
17*16467b97STreehugger Robot        tStream = antlr3.CommonTokenStream(lexer)
18*16467b97STreehugger Robot        parser = parserCls(tStream)
19*16467b97STreehugger Robot        if group is not None:
20*16467b97STreehugger Robot            parser.templateLib = group
21*16467b97STreehugger Robot        result = getattr(parser, grammarEntry)()
22*16467b97STreehugger Robot        if result.st is not None:
23*16467b97STreehugger Robot            return result.st.toString()
24*16467b97STreehugger Robot        return None
25*16467b97STreehugger Robot
26*16467b97STreehugger Robot
27*16467b97STreehugger Robot    def testInlineTemplate(self):
28*16467b97STreehugger Robot        grammar = textwrap.dedent(
29*16467b97STreehugger Robot            r'''grammar T;
30*16467b97STreehugger Robot            options {
31*16467b97STreehugger Robot              language=Python;
32*16467b97STreehugger Robot              output=template;
33*16467b97STreehugger Robot            }
34*16467b97STreehugger Robot            a : ID INT
35*16467b97STreehugger Robot              -> template(id={$ID.text}, int={$INT.text})
36*16467b97STreehugger Robot                 "id=<id>, int=<int>"
37*16467b97STreehugger Robot            ;
38*16467b97STreehugger Robot
39*16467b97STreehugger Robot            ID : 'a'..'z'+;
40*16467b97STreehugger Robot            INT : '0'..'9'+;
41*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
42*16467b97STreehugger Robot            '''
43*16467b97STreehugger Robot            )
44*16467b97STreehugger Robot
45*16467b97STreehugger Robot        found = self.execParser(
46*16467b97STreehugger Robot            grammar, 'a',
47*16467b97STreehugger Robot            "abc 34"
48*16467b97STreehugger Robot            )
49*16467b97STreehugger Robot
50*16467b97STreehugger Robot        self.failUnlessEqual("id=abc, int=34", found)
51*16467b97STreehugger Robot
52*16467b97STreehugger Robot
53*16467b97STreehugger Robot    def testExternalTemplate(self):
54*16467b97STreehugger Robot        templates = textwrap.dedent(
55*16467b97STreehugger Robot            '''\
56*16467b97STreehugger Robot            group T;
57*16467b97STreehugger Robot            expr(args, op) ::= <<
58*16467b97STreehugger Robot            [<args; separator={<op>}>]
59*16467b97STreehugger Robot            >>
60*16467b97STreehugger Robot            '''
61*16467b97STreehugger Robot            )
62*16467b97STreehugger Robot
63*16467b97STreehugger Robot        group = stringtemplate3.StringTemplateGroup(
64*16467b97STreehugger Robot            file=StringIO(templates),
65*16467b97STreehugger Robot            lexer='angle-bracket'
66*16467b97STreehugger Robot            )
67*16467b97STreehugger Robot
68*16467b97STreehugger Robot        grammar = textwrap.dedent(
69*16467b97STreehugger Robot            r'''grammar T2;
70*16467b97STreehugger Robot            options {
71*16467b97STreehugger Robot              language=Python;
72*16467b97STreehugger Robot              output=template;
73*16467b97STreehugger Robot            }
74*16467b97STreehugger Robot            a : r+=arg OP r+=arg
75*16467b97STreehugger Robot              -> expr(op={$OP.text}, args={$r})
76*16467b97STreehugger Robot            ;
77*16467b97STreehugger Robot            arg: ID -> template(t={$ID.text}) "<t>";
78*16467b97STreehugger Robot
79*16467b97STreehugger Robot            ID : 'a'..'z'+;
80*16467b97STreehugger Robot            OP: '+';
81*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
82*16467b97STreehugger Robot            '''
83*16467b97STreehugger Robot            )
84*16467b97STreehugger Robot
85*16467b97STreehugger Robot        found = self.execParser(
86*16467b97STreehugger Robot            grammar, 'a',
87*16467b97STreehugger Robot            "a + b",
88*16467b97STreehugger Robot            group
89*16467b97STreehugger Robot            )
90*16467b97STreehugger Robot
91*16467b97STreehugger Robot        self.failUnlessEqual("[a+b]", found)
92*16467b97STreehugger Robot
93*16467b97STreehugger Robot
94*16467b97STreehugger Robot    def testEmptyTemplate(self):
95*16467b97STreehugger Robot        grammar = textwrap.dedent(
96*16467b97STreehugger Robot            r'''grammar T;
97*16467b97STreehugger Robot            options {
98*16467b97STreehugger Robot              language=Python;
99*16467b97STreehugger Robot              output=template;
100*16467b97STreehugger Robot            }
101*16467b97STreehugger Robot            a : ID INT
102*16467b97STreehugger Robot              ->
103*16467b97STreehugger Robot            ;
104*16467b97STreehugger Robot
105*16467b97STreehugger Robot            ID : 'a'..'z'+;
106*16467b97STreehugger Robot            INT : '0'..'9'+;
107*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
108*16467b97STreehugger Robot            '''
109*16467b97STreehugger Robot            )
110*16467b97STreehugger Robot
111*16467b97STreehugger Robot        found = self.execParser(
112*16467b97STreehugger Robot            grammar, 'a',
113*16467b97STreehugger Robot            "abc 34"
114*16467b97STreehugger Robot            )
115*16467b97STreehugger Robot
116*16467b97STreehugger Robot        self.failUnless(found is None)
117*16467b97STreehugger Robot
118*16467b97STreehugger Robot
119*16467b97STreehugger Robot    def testList(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=template;
125*16467b97STreehugger Robot            }
126*16467b97STreehugger Robot            a: (r+=b)* EOF
127*16467b97STreehugger Robot              -> template(r={$r})
128*16467b97STreehugger Robot                 "<r; separator=\",\">"
129*16467b97STreehugger Robot            ;
130*16467b97STreehugger Robot
131*16467b97STreehugger Robot            b: ID
132*16467b97STreehugger Robot              -> template(t={$ID.text}) "<t>"
133*16467b97STreehugger Robot            ;
134*16467b97STreehugger Robot
135*16467b97STreehugger Robot            ID : 'a'..'z'+;
136*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
137*16467b97STreehugger Robot            '''
138*16467b97STreehugger Robot            )
139*16467b97STreehugger Robot
140*16467b97STreehugger Robot        found = self.execParser(
141*16467b97STreehugger Robot            grammar, 'a',
142*16467b97STreehugger Robot            "abc def ghi"
143*16467b97STreehugger Robot            )
144*16467b97STreehugger Robot
145*16467b97STreehugger Robot        self.failUnlessEqual("abc,def,ghi", found)
146*16467b97STreehugger Robot
147*16467b97STreehugger Robot
148*16467b97STreehugger Robot    def testAction(self):
149*16467b97STreehugger Robot        grammar = textwrap.dedent(
150*16467b97STreehugger Robot            r'''grammar T;
151*16467b97STreehugger Robot            options {
152*16467b97STreehugger Robot              language=Python;
153*16467b97STreehugger Robot              output=template;
154*16467b97STreehugger Robot            }
155*16467b97STreehugger Robot            a: ID
156*16467b97STreehugger Robot              -> { stringtemplate3.StringTemplate("hello") }
157*16467b97STreehugger Robot            ;
158*16467b97STreehugger Robot
159*16467b97STreehugger Robot            ID : 'a'..'z'+;
160*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
161*16467b97STreehugger Robot            '''
162*16467b97STreehugger Robot            )
163*16467b97STreehugger Robot
164*16467b97STreehugger Robot        found = self.execParser(
165*16467b97STreehugger Robot            grammar, 'a',
166*16467b97STreehugger Robot            "abc"
167*16467b97STreehugger Robot            )
168*16467b97STreehugger Robot
169*16467b97STreehugger Robot        self.failUnlessEqual("hello", found)
170*16467b97STreehugger Robot
171*16467b97STreehugger Robot
172*16467b97STreehugger Robot    def testTemplateExpressionInAction(self):
173*16467b97STreehugger Robot        grammar = textwrap.dedent(
174*16467b97STreehugger Robot            r'''grammar T;
175*16467b97STreehugger Robot            options {
176*16467b97STreehugger Robot              language=Python;
177*16467b97STreehugger Robot              output=template;
178*16467b97STreehugger Robot            }
179*16467b97STreehugger Robot            a: ID
180*16467b97STreehugger Robot              { $st = %{"hello"} }
181*16467b97STreehugger Robot            ;
182*16467b97STreehugger Robot
183*16467b97STreehugger Robot            ID : 'a'..'z'+;
184*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
185*16467b97STreehugger Robot            '''
186*16467b97STreehugger Robot            )
187*16467b97STreehugger Robot
188*16467b97STreehugger Robot        found = self.execParser(
189*16467b97STreehugger Robot            grammar, 'a',
190*16467b97STreehugger Robot            "abc"
191*16467b97STreehugger Robot            )
192*16467b97STreehugger Robot
193*16467b97STreehugger Robot        self.failUnlessEqual("hello", found)
194*16467b97STreehugger Robot
195*16467b97STreehugger Robot
196*16467b97STreehugger Robot    def testTemplateExpressionInAction2(self):
197*16467b97STreehugger Robot        grammar = textwrap.dedent(
198*16467b97STreehugger Robot            r'''grammar T;
199*16467b97STreehugger Robot            options {
200*16467b97STreehugger Robot              language=Python;
201*16467b97STreehugger Robot              output=template;
202*16467b97STreehugger Robot            }
203*16467b97STreehugger Robot            a: ID
204*16467b97STreehugger Robot              {
205*16467b97STreehugger Robot                res = %{"hello <foo>"}
206*16467b97STreehugger Robot                %res.foo = "world";
207*16467b97STreehugger Robot              }
208*16467b97STreehugger Robot              -> { res }
209*16467b97STreehugger Robot            ;
210*16467b97STreehugger Robot
211*16467b97STreehugger Robot            ID : 'a'..'z'+;
212*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
213*16467b97STreehugger Robot            '''
214*16467b97STreehugger Robot            )
215*16467b97STreehugger Robot
216*16467b97STreehugger Robot        found = self.execParser(
217*16467b97STreehugger Robot            grammar, 'a',
218*16467b97STreehugger Robot            "abc"
219*16467b97STreehugger Robot            )
220*16467b97STreehugger Robot
221*16467b97STreehugger Robot        self.failUnlessEqual("hello world", found)
222*16467b97STreehugger Robot
223*16467b97STreehugger Robot
224*16467b97STreehugger Robot    def testIndirectTemplateConstructor(self):
225*16467b97STreehugger Robot        templates = textwrap.dedent(
226*16467b97STreehugger Robot            '''\
227*16467b97STreehugger Robot            group T;
228*16467b97STreehugger Robot            expr(args, op) ::= <<
229*16467b97STreehugger Robot            [<args; separator={<op>}>]
230*16467b97STreehugger Robot            >>
231*16467b97STreehugger Robot            '''
232*16467b97STreehugger Robot            )
233*16467b97STreehugger Robot
234*16467b97STreehugger Robot        group = stringtemplate3.StringTemplateGroup(
235*16467b97STreehugger Robot            file=StringIO(templates),
236*16467b97STreehugger Robot            lexer='angle-bracket'
237*16467b97STreehugger Robot            )
238*16467b97STreehugger Robot
239*16467b97STreehugger Robot        grammar = textwrap.dedent(
240*16467b97STreehugger Robot            r'''grammar T;
241*16467b97STreehugger Robot            options {
242*16467b97STreehugger Robot              language=Python;
243*16467b97STreehugger Robot              output=template;
244*16467b97STreehugger Robot            }
245*16467b97STreehugger Robot            a: ID
246*16467b97STreehugger Robot              {
247*16467b97STreehugger Robot                $st = %({"expr"})(args={[1, 2, 3]}, op={"+"})
248*16467b97STreehugger Robot              }
249*16467b97STreehugger Robot            ;
250*16467b97STreehugger Robot
251*16467b97STreehugger Robot            ID : 'a'..'z'+;
252*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
253*16467b97STreehugger Robot            '''
254*16467b97STreehugger Robot            )
255*16467b97STreehugger Robot
256*16467b97STreehugger Robot        found = self.execParser(
257*16467b97STreehugger Robot            grammar, 'a',
258*16467b97STreehugger Robot            "abc",
259*16467b97STreehugger Robot            group
260*16467b97STreehugger Robot            )
261*16467b97STreehugger Robot
262*16467b97STreehugger Robot        self.failUnlessEqual("[1+2+3]", found)
263*16467b97STreehugger Robot
264*16467b97STreehugger Robot
265*16467b97STreehugger Robot    def testPredicates(self):
266*16467b97STreehugger Robot        grammar = textwrap.dedent(
267*16467b97STreehugger Robot            r'''grammar T3;
268*16467b97STreehugger Robot            options {
269*16467b97STreehugger Robot              language=Python;
270*16467b97STreehugger Robot              output=template;
271*16467b97STreehugger Robot            }
272*16467b97STreehugger Robot            a : ID INT
273*16467b97STreehugger Robot              -> {$ID.text=='a'}? template(int={$INT.text})
274*16467b97STreehugger Robot                                  "A: <int>"
275*16467b97STreehugger Robot              -> {$ID.text=='b'}? template(int={$INT.text})
276*16467b97STreehugger Robot                                  "B: <int>"
277*16467b97STreehugger Robot              ->                  template(int={$INT.text})
278*16467b97STreehugger Robot                                  "C: <int>"
279*16467b97STreehugger Robot            ;
280*16467b97STreehugger Robot
281*16467b97STreehugger Robot            ID : 'a'..'z'+;
282*16467b97STreehugger Robot            INT : '0'..'9'+;
283*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
284*16467b97STreehugger Robot            '''
285*16467b97STreehugger Robot            )
286*16467b97STreehugger Robot
287*16467b97STreehugger Robot        found = self.execParser(
288*16467b97STreehugger Robot            grammar, 'a',
289*16467b97STreehugger Robot            "b 34"
290*16467b97STreehugger Robot            )
291*16467b97STreehugger Robot
292*16467b97STreehugger Robot        self.failUnlessEqual("B: 34", found)
293*16467b97STreehugger Robot
294*16467b97STreehugger Robot
295*16467b97STreehugger Robot    def testBacktrackingMode(self):
296*16467b97STreehugger Robot        grammar = textwrap.dedent(
297*16467b97STreehugger Robot            r'''grammar T4;
298*16467b97STreehugger Robot            options {
299*16467b97STreehugger Robot              language=Python;
300*16467b97STreehugger Robot              output=template;
301*16467b97STreehugger Robot              backtrack=true;
302*16467b97STreehugger Robot            }
303*16467b97STreehugger Robot            a : (ID INT)=> ID INT
304*16467b97STreehugger Robot              -> template(id={$ID.text}, int={$INT.text})
305*16467b97STreehugger Robot                 "id=<id>, int=<int>"
306*16467b97STreehugger Robot            ;
307*16467b97STreehugger Robot
308*16467b97STreehugger Robot            ID : 'a'..'z'+;
309*16467b97STreehugger Robot            INT : '0'..'9'+;
310*16467b97STreehugger Robot            WS : (' '|'\n') {$channel=HIDDEN;} ;
311*16467b97STreehugger Robot            '''
312*16467b97STreehugger Robot            )
313*16467b97STreehugger Robot
314*16467b97STreehugger Robot        found = self.execParser(
315*16467b97STreehugger Robot            grammar, 'a',
316*16467b97STreehugger Robot            "abc 34"
317*16467b97STreehugger Robot            )
318*16467b97STreehugger Robot
319*16467b97STreehugger Robot        self.failUnlessEqual("id=abc, int=34", found)
320*16467b97STreehugger Robot
321*16467b97STreehugger Robot
322*16467b97STreehugger Robot    def testRewrite(self):
323*16467b97STreehugger Robot        grammar = textwrap.dedent(
324*16467b97STreehugger Robot            r'''grammar T5;
325*16467b97STreehugger Robot            options {
326*16467b97STreehugger Robot              language=Python;
327*16467b97STreehugger Robot              output=template;
328*16467b97STreehugger Robot              rewrite=true;
329*16467b97STreehugger Robot            }
330*16467b97STreehugger Robot
331*16467b97STreehugger Robot            prog: stat+;
332*16467b97STreehugger Robot
333*16467b97STreehugger Robot            stat
334*16467b97STreehugger Robot                : 'if' '(' expr ')' stat
335*16467b97STreehugger Robot                | 'return' return_expr ';'
336*16467b97STreehugger Robot                | '{' stat* '}'
337*16467b97STreehugger Robot                | ID '=' expr ';'
338*16467b97STreehugger Robot                ;
339*16467b97STreehugger Robot
340*16467b97STreehugger Robot            return_expr
341*16467b97STreehugger Robot                : expr
342*16467b97STreehugger Robot                  -> template(t={$text}) <<boom(<t>)>>
343*16467b97STreehugger Robot                ;
344*16467b97STreehugger Robot
345*16467b97STreehugger Robot            expr
346*16467b97STreehugger Robot                : ID
347*16467b97STreehugger Robot                | INT
348*16467b97STreehugger Robot                ;
349*16467b97STreehugger Robot
350*16467b97STreehugger Robot            ID:  'a'..'z'+;
351*16467b97STreehugger Robot            INT: '0'..'9'+;
352*16467b97STreehugger Robot            WS: (' '|'\n')+ {$channel=HIDDEN;} ;
353*16467b97STreehugger Robot            COMMENT: '/*' (options {greedy=false;} : .)* '*/' {$channel = HIDDEN;} ;
354*16467b97STreehugger Robot            '''
355*16467b97STreehugger Robot            )
356*16467b97STreehugger Robot
357*16467b97STreehugger Robot        input = textwrap.dedent(
358*16467b97STreehugger Robot            '''\
359*16467b97STreehugger Robot            if ( foo ) {
360*16467b97STreehugger Robot              b = /* bla */ 2;
361*16467b97STreehugger Robot              return 1 /* foo */;
362*16467b97STreehugger Robot            }
363*16467b97STreehugger Robot
364*16467b97STreehugger Robot            /* gnurz */
365*16467b97STreehugger Robot            return 12;
366*16467b97STreehugger Robot            '''
367*16467b97STreehugger Robot            )
368*16467b97STreehugger Robot
369*16467b97STreehugger Robot        lexerCls, parserCls = self.compileInlineGrammar(grammar)
370*16467b97STreehugger Robot
371*16467b97STreehugger Robot        cStream = antlr3.StringStream(input)
372*16467b97STreehugger Robot        lexer = lexerCls(cStream)
373*16467b97STreehugger Robot        tStream = antlr3.TokenRewriteStream(lexer)
374*16467b97STreehugger Robot        parser = parserCls(tStream)
375*16467b97STreehugger Robot        result = parser.prog()
376*16467b97STreehugger Robot
377*16467b97STreehugger Robot        found = tStream.toString()
378*16467b97STreehugger Robot
379*16467b97STreehugger Robot        expected = textwrap.dedent(
380*16467b97STreehugger Robot            '''\
381*16467b97STreehugger Robot            if ( foo ) {
382*16467b97STreehugger Robot              b = /* bla */ 2;
383*16467b97STreehugger Robot              return boom(1) /* foo */;
384*16467b97STreehugger Robot            }
385*16467b97STreehugger Robot
386*16467b97STreehugger Robot            /* gnurz */
387*16467b97STreehugger Robot            return boom(12);
388*16467b97STreehugger Robot            '''
389*16467b97STreehugger Robot            )
390*16467b97STreehugger Robot
391*16467b97STreehugger Robot        self.failUnlessEqual(expected, found)
392*16467b97STreehugger Robot
393*16467b97STreehugger Robot
394*16467b97STreehugger Robot    def testTreeRewrite(self):
395*16467b97STreehugger Robot        grammar = textwrap.dedent(
396*16467b97STreehugger Robot            r'''grammar T6;
397*16467b97STreehugger Robot            options {
398*16467b97STreehugger Robot              language=Python;
399*16467b97STreehugger Robot              output=AST;
400*16467b97STreehugger Robot            }
401*16467b97STreehugger Robot
402*16467b97STreehugger Robot            tokens {
403*16467b97STreehugger Robot              BLOCK;
404*16467b97STreehugger Robot              ASSIGN;
405*16467b97STreehugger Robot            }
406*16467b97STreehugger Robot
407*16467b97STreehugger Robot            prog: stat+;
408*16467b97STreehugger Robot
409*16467b97STreehugger Robot            stat
410*16467b97STreehugger Robot                : IF '(' e=expr ')' s=stat
411*16467b97STreehugger Robot                  -> ^(IF $e $s)
412*16467b97STreehugger Robot                | RETURN expr ';'
413*16467b97STreehugger Robot                  -> ^(RETURN expr)
414*16467b97STreehugger Robot                | '{' stat* '}'
415*16467b97STreehugger Robot                  -> ^(BLOCK stat*)
416*16467b97STreehugger Robot                | ID '=' expr ';'
417*16467b97STreehugger Robot                  -> ^(ASSIGN ID expr)
418*16467b97STreehugger Robot                ;
419*16467b97STreehugger Robot
420*16467b97STreehugger Robot            expr
421*16467b97STreehugger Robot                : ID
422*16467b97STreehugger Robot                | INT
423*16467b97STreehugger Robot                ;
424*16467b97STreehugger Robot
425*16467b97STreehugger Robot            IF: 'if';
426*16467b97STreehugger Robot            RETURN: 'return';
427*16467b97STreehugger Robot            ID:  'a'..'z'+;
428*16467b97STreehugger Robot            INT: '0'..'9'+;
429*16467b97STreehugger Robot            WS: (' '|'\n')+ {$channel=HIDDEN;} ;
430*16467b97STreehugger Robot            COMMENT: '/*' (options {greedy=false;} : .)* '*/' {$channel = HIDDEN;} ;
431*16467b97STreehugger Robot            '''
432*16467b97STreehugger Robot            )
433*16467b97STreehugger Robot
434*16467b97STreehugger Robot        treeGrammar = textwrap.dedent(
435*16467b97STreehugger Robot            r'''tree grammar T6Walker;
436*16467b97STreehugger Robot            options {
437*16467b97STreehugger Robot              language=Python;
438*16467b97STreehugger Robot              tokenVocab=T6;
439*16467b97STreehugger Robot              ASTLabelType=CommonTree;
440*16467b97STreehugger Robot              output=template;
441*16467b97STreehugger Robot              rewrite=true;
442*16467b97STreehugger Robot            }
443*16467b97STreehugger Robot
444*16467b97STreehugger Robot            prog: stat+;
445*16467b97STreehugger Robot
446*16467b97STreehugger Robot            stat
447*16467b97STreehugger Robot                : ^(IF expr stat)
448*16467b97STreehugger Robot                | ^(RETURN return_expr)
449*16467b97STreehugger Robot                | ^(BLOCK stat*)
450*16467b97STreehugger Robot                | ^(ASSIGN ID expr)
451*16467b97STreehugger Robot                ;
452*16467b97STreehugger Robot
453*16467b97STreehugger Robot            return_expr
454*16467b97STreehugger Robot                : expr
455*16467b97STreehugger Robot                  -> template(t={$text}) <<boom(<t>)>>
456*16467b97STreehugger Robot                ;
457*16467b97STreehugger Robot
458*16467b97STreehugger Robot            expr
459*16467b97STreehugger Robot                : ID
460*16467b97STreehugger Robot                | INT
461*16467b97STreehugger Robot                ;
462*16467b97STreehugger Robot            '''
463*16467b97STreehugger Robot            )
464*16467b97STreehugger Robot
465*16467b97STreehugger Robot        input = textwrap.dedent(
466*16467b97STreehugger Robot            '''\
467*16467b97STreehugger Robot            if ( foo ) {
468*16467b97STreehugger Robot              b = /* bla */ 2;
469*16467b97STreehugger Robot              return 1 /* foo */;
470*16467b97STreehugger Robot            }
471*16467b97STreehugger Robot
472*16467b97STreehugger Robot            /* gnurz */
473*16467b97STreehugger Robot            return 12;
474*16467b97STreehugger Robot            '''
475*16467b97STreehugger Robot            )
476*16467b97STreehugger Robot
477*16467b97STreehugger Robot        lexerCls, parserCls = self.compileInlineGrammar(grammar)
478*16467b97STreehugger Robot        walkerCls = self.compileInlineGrammar(treeGrammar)
479*16467b97STreehugger Robot
480*16467b97STreehugger Robot        cStream = antlr3.StringStream(input)
481*16467b97STreehugger Robot        lexer = lexerCls(cStream)
482*16467b97STreehugger Robot        tStream = antlr3.TokenRewriteStream(lexer)
483*16467b97STreehugger Robot        parser = parserCls(tStream)
484*16467b97STreehugger Robot        tree = parser.prog().tree
485*16467b97STreehugger Robot        nodes = antlr3.tree.CommonTreeNodeStream(tree)
486*16467b97STreehugger Robot        nodes.setTokenStream(tStream)
487*16467b97STreehugger Robot        walker = walkerCls(nodes)
488*16467b97STreehugger Robot        walker.prog()
489*16467b97STreehugger Robot
490*16467b97STreehugger Robot        found = tStream.toString()
491*16467b97STreehugger Robot
492*16467b97STreehugger Robot        expected = textwrap.dedent(
493*16467b97STreehugger Robot            '''\
494*16467b97STreehugger Robot            if ( foo ) {
495*16467b97STreehugger Robot              b = /* bla */ 2;
496*16467b97STreehugger Robot              return boom(1) /* foo */;
497*16467b97STreehugger Robot            }
498*16467b97STreehugger Robot
499*16467b97STreehugger Robot            /* gnurz */
500*16467b97STreehugger Robot            return boom(12);
501*16467b97STreehugger Robot            '''
502*16467b97STreehugger Robot            )
503*16467b97STreehugger Robot
504*16467b97STreehugger Robot        self.failUnlessEqual(expected, found)
505*16467b97STreehugger Robot
506*16467b97STreehugger Robot
507*16467b97STreehugger Robotif __name__ == '__main__':
508*16467b97STreehugger Robot    unittest.main()
509