xref: /aosp_15_r20/external/antlr/runtime/Python/tests/t060leftrecursion.py (revision 16467b971bd3e2009fad32dd79016f2c7e421deb)
1*16467b97STreehugger Robotimport unittest
2*16467b97STreehugger Robotimport re
3*16467b97STreehugger Robotimport textwrap
4*16467b97STreehugger Robotimport antlr3
5*16467b97STreehugger Robotimport testbase
6*16467b97STreehugger Robot
7*16467b97STreehugger Robot
8*16467b97STreehugger Robot# Left-recursion resolution is not yet enabled in the tool.
9*16467b97STreehugger Robot
10*16467b97STreehugger Robot# class TestLeftRecursion(testbase.ANTLRTest):
11*16467b97STreehugger Robot#     def parserClass(self, base):
12*16467b97STreehugger Robot#         class TParser(base):
13*16467b97STreehugger Robot#             def __init__(self, *args, **kwargs):
14*16467b97STreehugger Robot#                 base.__init__(self, *args, **kwargs)
15*16467b97STreehugger Robot
16*16467b97STreehugger Robot#                 self._output = ""
17*16467b97STreehugger Robot
18*16467b97STreehugger Robot
19*16467b97STreehugger Robot#             def capture(self, t):
20*16467b97STreehugger Robot#                 self._output += str(t)
21*16467b97STreehugger Robot
22*16467b97STreehugger Robot
23*16467b97STreehugger Robot#             def recover(self, input, re):
24*16467b97STreehugger Robot#                 # no error recovery yet, just crash!
25*16467b97STreehugger Robot#                 raise
26*16467b97STreehugger Robot
27*16467b97STreehugger Robot#         return TParser
28*16467b97STreehugger Robot
29*16467b97STreehugger Robot
30*16467b97STreehugger Robot#     def execParser(self, grammar, grammarEntry, input):
31*16467b97STreehugger Robot#         lexerCls, parserCls = self.compileInlineGrammar(grammar)
32*16467b97STreehugger Robot
33*16467b97STreehugger Robot#         cStream = antlr3.StringStream(input)
34*16467b97STreehugger Robot#         lexer = lexerCls(cStream)
35*16467b97STreehugger Robot#         tStream = antlr3.CommonTokenStream(lexer)
36*16467b97STreehugger Robot#         parser = parserCls(tStream)
37*16467b97STreehugger Robot#         getattr(parser, grammarEntry)()
38*16467b97STreehugger Robot#         return parser._output
39*16467b97STreehugger Robot
40*16467b97STreehugger Robot
41*16467b97STreehugger Robot#     def runTests(self, grammar, tests, grammarEntry):
42*16467b97STreehugger Robot#         lexerCls, parserCls = self.compileInlineGrammar(grammar)
43*16467b97STreehugger Robot
44*16467b97STreehugger Robot#         build_ast = re.search(r'output\s*=\s*AST', grammar)
45*16467b97STreehugger Robot
46*16467b97STreehugger Robot#         for input, expecting in tests:
47*16467b97STreehugger Robot#             cStream = antlr3.StringStream(input)
48*16467b97STreehugger Robot#             lexer = lexerCls(cStream)
49*16467b97STreehugger Robot#             tStream = antlr3.CommonTokenStream(lexer)
50*16467b97STreehugger Robot#             parser = parserCls(tStream)
51*16467b97STreehugger Robot#             r = getattr(parser, grammarEntry)()
52*16467b97STreehugger Robot#             found = parser._output
53*16467b97STreehugger Robot#             if build_ast:
54*16467b97STreehugger Robot#               found += r.tree.toStringTree()
55*16467b97STreehugger Robot
56*16467b97STreehugger Robot#             self.assertEquals(
57*16467b97STreehugger Robot#                 expecting, found,
58*16467b97STreehugger Robot#                 "%r != %r (for input %r)" % (expecting, found, input))
59*16467b97STreehugger Robot
60*16467b97STreehugger Robot
61*16467b97STreehugger Robot#     def testSimple(self):
62*16467b97STreehugger Robot#         grammar = textwrap.dedent(
63*16467b97STreehugger Robot#             r"""
64*16467b97STreehugger Robot#             grammar T;
65*16467b97STreehugger Robot#             options {
66*16467b97STreehugger Robot#                 language=Python;
67*16467b97STreehugger Robot#             }
68*16467b97STreehugger Robot#             s : a { self.capture($a.text) } ;
69*16467b97STreehugger Robot#             a : a ID
70*16467b97STreehugger Robot#               | ID
71*16467b97STreehugger Robot#               ;
72*16467b97STreehugger Robot#             ID : 'a'..'z'+ ;
73*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
74*16467b97STreehugger Robot#             """)
75*16467b97STreehugger Robot
76*16467b97STreehugger Robot#         found = self.execParser(grammar, 's', 'a b c')
77*16467b97STreehugger Robot#         expecting = "abc"
78*16467b97STreehugger Robot#         self.assertEquals(expecting, found)
79*16467b97STreehugger Robot
80*16467b97STreehugger Robot
81*16467b97STreehugger Robot#     def testSemPred(self):
82*16467b97STreehugger Robot#         grammar = textwrap.dedent(
83*16467b97STreehugger Robot#             r"""
84*16467b97STreehugger Robot#             grammar T;
85*16467b97STreehugger Robot#             options {
86*16467b97STreehugger Robot#                 language=Python;
87*16467b97STreehugger Robot#             }
88*16467b97STreehugger Robot#             s : a { self.capture($a.text) } ;
89*16467b97STreehugger Robot#             a : a {True}? ID
90*16467b97STreehugger Robot#               | ID
91*16467b97STreehugger Robot#               ;
92*16467b97STreehugger Robot#             ID : 'a'..'z'+ ;
93*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
94*16467b97STreehugger Robot#             """)
95*16467b97STreehugger Robot
96*16467b97STreehugger Robot#         found = self.execParser(grammar, "s", "a b c")
97*16467b97STreehugger Robot#         expecting = "abc"
98*16467b97STreehugger Robot#         self.assertEquals(expecting, found)
99*16467b97STreehugger Robot
100*16467b97STreehugger Robot#     def testTernaryExpr(self):
101*16467b97STreehugger Robot#         grammar = textwrap.dedent(
102*16467b97STreehugger Robot#             r"""
103*16467b97STreehugger Robot#             grammar T;
104*16467b97STreehugger Robot#             options {
105*16467b97STreehugger Robot#                 language=Python;
106*16467b97STreehugger Robot#                 output=AST;
107*16467b97STreehugger Robot#             }
108*16467b97STreehugger Robot#             e : e '*'^ e
109*16467b97STreehugger Robot#               | e '+'^ e
110*16467b97STreehugger Robot#               | e '?'<assoc=right>^ e ':'! e
111*16467b97STreehugger Robot#               | e '='<assoc=right>^ e
112*16467b97STreehugger Robot#               | ID
113*16467b97STreehugger Robot#               ;
114*16467b97STreehugger Robot#             ID : 'a'..'z'+ ;
115*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
116*16467b97STreehugger Robot#             """)
117*16467b97STreehugger Robot
118*16467b97STreehugger Robot#         tests = [
119*16467b97STreehugger Robot#             ("a", "a"),
120*16467b97STreehugger Robot#             ("a+b", "(+ a b)"),
121*16467b97STreehugger Robot#             ("a*b", "(* a b)"),
122*16467b97STreehugger Robot#             ("a?b:c", "(? a b c)"),
123*16467b97STreehugger Robot#             ("a=b=c", "(= a (= b c))"),
124*16467b97STreehugger Robot#             ("a?b+c:d", "(? a (+ b c) d)"),
125*16467b97STreehugger Robot#             ("a?b=c:d", "(? a (= b c) d)"),
126*16467b97STreehugger Robot#             ("a? b?c:d : e", "(? a (? b c d) e)"),
127*16467b97STreehugger Robot#             ("a?b: c?d:e", "(? a b (? c d e))"),
128*16467b97STreehugger Robot#             ]
129*16467b97STreehugger Robot#         self.runTests(grammar, tests, "e")
130*16467b97STreehugger Robot
131*16467b97STreehugger Robot
132*16467b97STreehugger Robot#     def testDeclarationsUsingASTOperators(self):
133*16467b97STreehugger Robot#         grammar = textwrap.dedent(
134*16467b97STreehugger Robot#             r"""
135*16467b97STreehugger Robot#             grammar T;
136*16467b97STreehugger Robot#             options {
137*16467b97STreehugger Robot#                 language=Python;
138*16467b97STreehugger Robot#                 output=AST;
139*16467b97STreehugger Robot#             }
140*16467b97STreehugger Robot#             declarator
141*16467b97STreehugger Robot#                     : declarator '['^ e ']'!
142*16467b97STreehugger Robot#                     | declarator '['^ ']'!
143*16467b97STreehugger Robot#                     | declarator '('^ ')'!
144*16467b97STreehugger Robot#                     | '*'^ declarator // binds less tight than suffixes
145*16467b97STreehugger Robot#                     | '('! declarator ')'!
146*16467b97STreehugger Robot#                     | ID
147*16467b97STreehugger Robot#                     ;
148*16467b97STreehugger Robot#             e : INT ;
149*16467b97STreehugger Robot#             ID : 'a'..'z'+ ;
150*16467b97STreehugger Robot#             INT : '0'..'9'+ ;
151*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
152*16467b97STreehugger Robot#             """)
153*16467b97STreehugger Robot
154*16467b97STreehugger Robot#         tests = [
155*16467b97STreehugger Robot#             ("a", "a"),
156*16467b97STreehugger Robot#             ("*a", "(* a)"),
157*16467b97STreehugger Robot#             ("**a", "(* (* a))"),
158*16467b97STreehugger Robot#             ("a[3]", "([ a 3)"),
159*16467b97STreehugger Robot#             ("b[]", "([ b)"),
160*16467b97STreehugger Robot#             ("(a)", "a"),
161*16467b97STreehugger Robot#             ("a[]()", "(( ([ a))"),
162*16467b97STreehugger Robot#             ("a[][]", "([ ([ a))"),
163*16467b97STreehugger Robot#             ("*a[]", "(* ([ a))"),
164*16467b97STreehugger Robot#             ("(*a)[]", "([ (* a))"),
165*16467b97STreehugger Robot#             ]
166*16467b97STreehugger Robot#         self.runTests(grammar, tests, "declarator")
167*16467b97STreehugger Robot
168*16467b97STreehugger Robot
169*16467b97STreehugger Robot#     def testDeclarationsUsingRewriteOperators(self):
170*16467b97STreehugger Robot#         grammar = textwrap.dedent(
171*16467b97STreehugger Robot#             r"""
172*16467b97STreehugger Robot#             grammar T;
173*16467b97STreehugger Robot#             options {
174*16467b97STreehugger Robot#                 language=Python;
175*16467b97STreehugger Robot#                 output=AST;
176*16467b97STreehugger Robot#             }
177*16467b97STreehugger Robot#             declarator
178*16467b97STreehugger Robot#                     : declarator '[' e ']' -> ^('[' declarator e)
179*16467b97STreehugger Robot#                     | declarator '[' ']' -> ^('[' declarator)
180*16467b97STreehugger Robot#                     | declarator '(' ')' -> ^('(' declarator)
181*16467b97STreehugger Robot#                     | '*' declarator -> ^('*' declarator)  // binds less tight than suffixes
182*16467b97STreehugger Robot#                     | '(' declarator ')' -> declarator
183*16467b97STreehugger Robot#                     | ID -> ID
184*16467b97STreehugger Robot#                     ;
185*16467b97STreehugger Robot#             e : INT ;
186*16467b97STreehugger Robot#             ID : 'a'..'z'+ ;
187*16467b97STreehugger Robot#             INT : '0'..'9'+ ;
188*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
189*16467b97STreehugger Robot#             """)
190*16467b97STreehugger Robot
191*16467b97STreehugger Robot#         tests = [
192*16467b97STreehugger Robot#             ("a", "a"),
193*16467b97STreehugger Robot#             ("*a", "(* a)"),
194*16467b97STreehugger Robot#             ("**a", "(* (* a))"),
195*16467b97STreehugger Robot#             ("a[3]", "([ a 3)"),
196*16467b97STreehugger Robot#             ("b[]", "([ b)"),
197*16467b97STreehugger Robot#             ("(a)", "a"),
198*16467b97STreehugger Robot#             ("a[]()", "(( ([ a))"),
199*16467b97STreehugger Robot#             ("a[][]", "([ ([ a))"),
200*16467b97STreehugger Robot#             ("*a[]", "(* ([ a))"),
201*16467b97STreehugger Robot#             ("(*a)[]", "([ (* a))"),
202*16467b97STreehugger Robot#             ]
203*16467b97STreehugger Robot#         self.runTests(grammar, tests, "declarator")
204*16467b97STreehugger Robot
205*16467b97STreehugger Robot
206*16467b97STreehugger Robot#     def testExpressionsUsingASTOperators(self):
207*16467b97STreehugger Robot#         grammar = textwrap.dedent(
208*16467b97STreehugger Robot#             r"""
209*16467b97STreehugger Robot#             grammar T;
210*16467b97STreehugger Robot#             options {
211*16467b97STreehugger Robot#                 language=Python;
212*16467b97STreehugger Robot#                 output=AST;
213*16467b97STreehugger Robot#             }
214*16467b97STreehugger Robot#             e : e '.'^ ID
215*16467b97STreehugger Robot#               | e '.'^ 'this'
216*16467b97STreehugger Robot#               | '-'^ e
217*16467b97STreehugger Robot#               | e '*'^ e
218*16467b97STreehugger Robot#               | e ('+'^|'-'^) e
219*16467b97STreehugger Robot#               | INT
220*16467b97STreehugger Robot#               | ID
221*16467b97STreehugger Robot#               ;
222*16467b97STreehugger Robot#             ID : 'a'..'z'+ ;
223*16467b97STreehugger Robot#             INT : '0'..'9'+ ;
224*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
225*16467b97STreehugger Robot#             """)
226*16467b97STreehugger Robot
227*16467b97STreehugger Robot#         tests = [
228*16467b97STreehugger Robot#             ("a", "a"),
229*16467b97STreehugger Robot#             ("1", "1"),
230*16467b97STreehugger Robot#             ("a+1", "(+ a 1)"),
231*16467b97STreehugger Robot#             ("a*1", "(* a 1)"),
232*16467b97STreehugger Robot#             ("a.b", "(. a b)"),
233*16467b97STreehugger Robot#             ("a.this", "(. a this)"),
234*16467b97STreehugger Robot#             ("a-b+c", "(+ (- a b) c)"),
235*16467b97STreehugger Robot#             ("a+b*c", "(+ a (* b c))"),
236*16467b97STreehugger Robot#             ("a.b+1", "(+ (. a b) 1)"),
237*16467b97STreehugger Robot#             ("-a", "(- a)"),
238*16467b97STreehugger Robot#             ("-a+b", "(+ (- a) b)"),
239*16467b97STreehugger Robot#             ("-a.b", "(- (. a b))"),
240*16467b97STreehugger Robot#             ]
241*16467b97STreehugger Robot#         self.runTests(grammar, tests, "e")
242*16467b97STreehugger Robot
243*16467b97STreehugger Robot
244*16467b97STreehugger Robot#     @testbase.broken(
245*16467b97STreehugger Robot#         "Grammar compilation returns errors", testbase.GrammarCompileError)
246*16467b97STreehugger Robot#     def testExpressionsUsingRewriteOperators(self):
247*16467b97STreehugger Robot#         grammar = textwrap.dedent(
248*16467b97STreehugger Robot#             r"""
249*16467b97STreehugger Robot#             grammar T;
250*16467b97STreehugger Robot#             options {
251*16467b97STreehugger Robot#                 language=Python;
252*16467b97STreehugger Robot#                 output=AST;
253*16467b97STreehugger Robot#             }
254*16467b97STreehugger Robot#             e : e '.' ID                   -> ^('.' e ID)
255*16467b97STreehugger Robot#               | e '.' 'this'               -> ^('.' e 'this')
256*16467b97STreehugger Robot#               | '-' e                      -> ^('-' e)
257*16467b97STreehugger Robot#               | e '*' b=e                  -> ^('*' e $b)
258*16467b97STreehugger Robot#               | e (op='+'|op='-') b=e      -> ^($op e $b)
259*16467b97STreehugger Robot#               | INT                        -> INT
260*16467b97STreehugger Robot#               | ID                         -> ID
261*16467b97STreehugger Robot#               ;
262*16467b97STreehugger Robot#             ID : 'a'..'z'+ ;
263*16467b97STreehugger Robot#             INT : '0'..'9'+ ;
264*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
265*16467b97STreehugger Robot#             """)
266*16467b97STreehugger Robot
267*16467b97STreehugger Robot#         tests = [
268*16467b97STreehugger Robot#             ("a", "a"),
269*16467b97STreehugger Robot#             ("1", "1"),
270*16467b97STreehugger Robot#             ("a+1", "(+ a 1)"),
271*16467b97STreehugger Robot#             ("a*1", "(* a 1)"),
272*16467b97STreehugger Robot#             ("a.b", "(. a b)"),
273*16467b97STreehugger Robot#             ("a.this", "(. a this)"),
274*16467b97STreehugger Robot#             ("a+b*c", "(+ a (* b c))"),
275*16467b97STreehugger Robot#             ("a.b+1", "(+ (. a b) 1)"),
276*16467b97STreehugger Robot#             ("-a", "(- a)"),
277*16467b97STreehugger Robot#             ("-a+b", "(+ (- a) b)"),
278*16467b97STreehugger Robot#             ("-a.b", "(- (. a b))"),
279*16467b97STreehugger Robot#             ]
280*16467b97STreehugger Robot#         self.runTests(grammar, tests, "e")
281*16467b97STreehugger Robot
282*16467b97STreehugger Robot
283*16467b97STreehugger Robot#     def testExpressionAssociativity(self):
284*16467b97STreehugger Robot#         grammar = textwrap.dedent(
285*16467b97STreehugger Robot#             r"""
286*16467b97STreehugger Robot#             grammar T;
287*16467b97STreehugger Robot#             options {
288*16467b97STreehugger Robot#                 language=Python;
289*16467b97STreehugger Robot#                 output=AST;
290*16467b97STreehugger Robot#             }
291*16467b97STreehugger Robot#             e
292*16467b97STreehugger Robot#               : e '.'^ ID
293*16467b97STreehugger Robot#               | '-'^ e
294*16467b97STreehugger Robot#               | e '^'<assoc=right>^ e
295*16467b97STreehugger Robot#               | e '*'^ e
296*16467b97STreehugger Robot#               | e ('+'^|'-'^) e
297*16467b97STreehugger Robot#               | e ('='<assoc=right>^ |'+='<assoc=right>^) e
298*16467b97STreehugger Robot#               | INT
299*16467b97STreehugger Robot#               | ID
300*16467b97STreehugger Robot#               ;
301*16467b97STreehugger Robot#             ID : 'a'..'z'+ ;
302*16467b97STreehugger Robot#             INT : '0'..'9'+ ;
303*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
304*16467b97STreehugger Robot#             """)
305*16467b97STreehugger Robot
306*16467b97STreehugger Robot#         tests = [
307*16467b97STreehugger Robot#             ("a", "a"),
308*16467b97STreehugger Robot#             ("1", "1"),
309*16467b97STreehugger Robot#             ("a+1", "(+ a 1)"),
310*16467b97STreehugger Robot#             ("a*1", "(* a 1)"),
311*16467b97STreehugger Robot#             ("a.b", "(. a b)"),
312*16467b97STreehugger Robot#             ("a-b+c", "(+ (- a b) c)"),
313*16467b97STreehugger Robot#             ("a+b*c", "(+ a (* b c))"),
314*16467b97STreehugger Robot#             ("a.b+1", "(+ (. a b) 1)"),
315*16467b97STreehugger Robot#             ("-a", "(- a)"),
316*16467b97STreehugger Robot#             ("-a+b", "(+ (- a) b)"),
317*16467b97STreehugger Robot#             ("-a.b", "(- (. a b))"),
318*16467b97STreehugger Robot#             ("a^b^c", "(^ a (^ b c))"),
319*16467b97STreehugger Robot#             ("a=b=c", "(= a (= b c))"),
320*16467b97STreehugger Robot#             ("a=b=c+d.e", "(= a (= b (+ c (. d e))))"),
321*16467b97STreehugger Robot#             ]
322*16467b97STreehugger Robot#         self.runTests(grammar, tests, "e")
323*16467b97STreehugger Robot
324*16467b97STreehugger Robot
325*16467b97STreehugger Robot#     def testJavaExpressions(self):
326*16467b97STreehugger Robot#       grammar = textwrap.dedent(
327*16467b97STreehugger Robot#             r"""
328*16467b97STreehugger Robot#             grammar T;
329*16467b97STreehugger Robot#             options {
330*16467b97STreehugger Robot#                 language=Python;
331*16467b97STreehugger Robot#                 output=AST;
332*16467b97STreehugger Robot#             }
333*16467b97STreehugger Robot#             expressionList
334*16467b97STreehugger Robot#                 :   e (','! e)*
335*16467b97STreehugger Robot#                 ;
336*16467b97STreehugger Robot#             e   :   '('! e ')'!
337*16467b97STreehugger Robot#                 |   'this'
338*16467b97STreehugger Robot#                 |   'super'
339*16467b97STreehugger Robot#                 |   INT
340*16467b97STreehugger Robot#                 |   ID
341*16467b97STreehugger Robot#                 |   type '.'^ 'class'
342*16467b97STreehugger Robot#                 |   e '.'^ ID
343*16467b97STreehugger Robot#                 |   e '.'^ 'this'
344*16467b97STreehugger Robot#                 |   e '.'^ 'super' '('^ expressionList? ')'!
345*16467b97STreehugger Robot#                 |   e '.'^ 'new'^ ID '('! expressionList? ')'!
346*16467b97STreehugger Robot#                 |       'new'^ type ( '(' expressionList? ')'! | (options {k=1;}:'[' e ']'!)+) // ugly; simplified
347*16467b97STreehugger Robot#                 |   e '['^ e ']'!
348*16467b97STreehugger Robot#                 |   '('^ type ')'! e
349*16467b97STreehugger Robot#                 |   e ('++'^ | '--'^)
350*16467b97STreehugger Robot#                 |   e '('^ expressionList? ')'!
351*16467b97STreehugger Robot#                 |   ('+'^|'-'^|'++'^|'--'^) e
352*16467b97STreehugger Robot#                 |   ('~'^|'!'^) e
353*16467b97STreehugger Robot#                 |   e ('*'^|'/'^|'%'^) e
354*16467b97STreehugger Robot#                 |   e ('+'^|'-'^) e
355*16467b97STreehugger Robot#                 |   e ('<'^ '<' | '>'^ '>' '>' | '>'^ '>') e
356*16467b97STreehugger Robot#                 |   e ('<='^ | '>='^ | '>'^ | '<'^) e
357*16467b97STreehugger Robot#                 |   e 'instanceof'^ e
358*16467b97STreehugger Robot#                 |   e ('=='^ | '!='^) e
359*16467b97STreehugger Robot#                 |   e '&'^ e
360*16467b97STreehugger Robot#                 |   e '^'<assoc=right>^ e
361*16467b97STreehugger Robot#                 |   e '|'^ e
362*16467b97STreehugger Robot#                 |   e '&&'^ e
363*16467b97STreehugger Robot#                 |   e '||'^ e
364*16467b97STreehugger Robot#                 |   e '?' e ':' e
365*16467b97STreehugger Robot#                 |   e ('='<assoc=right>^
366*16467b97STreehugger Robot#                       |'+='<assoc=right>^
367*16467b97STreehugger Robot#                       |'-='<assoc=right>^
368*16467b97STreehugger Robot#                       |'*='<assoc=right>^
369*16467b97STreehugger Robot#                       |'/='<assoc=right>^
370*16467b97STreehugger Robot#                       |'&='<assoc=right>^
371*16467b97STreehugger Robot#                       |'|='<assoc=right>^
372*16467b97STreehugger Robot#                       |'^='<assoc=right>^
373*16467b97STreehugger Robot#                       |'>>='<assoc=right>^
374*16467b97STreehugger Robot#                       |'>>>='<assoc=right>^
375*16467b97STreehugger Robot#                       |'<<='<assoc=right>^
376*16467b97STreehugger Robot#                       |'%='<assoc=right>^) e
377*16467b97STreehugger Robot#                 ;
378*16467b97STreehugger Robot#             type: ID
379*16467b97STreehugger Robot#                 | ID '['^ ']'!
380*16467b97STreehugger Robot#                 | 'int'
381*16467b97STreehugger Robot#                 | 'int' '['^ ']'!
382*16467b97STreehugger Robot#                 ;
383*16467b97STreehugger Robot#             ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
384*16467b97STreehugger Robot#             INT : '0'..'9'+ ;
385*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
386*16467b97STreehugger Robot#             """)
387*16467b97STreehugger Robot
388*16467b97STreehugger Robot#       tests = [
389*16467b97STreehugger Robot#           ("a", "a"),
390*16467b97STreehugger Robot#           ("1", "1"),
391*16467b97STreehugger Robot#           ("a+1", "(+ a 1)"),
392*16467b97STreehugger Robot#           ("a*1", "(* a 1)"),
393*16467b97STreehugger Robot#           ("a.b", "(. a b)"),
394*16467b97STreehugger Robot#           ("a-b+c", "(+ (- a b) c)"),
395*16467b97STreehugger Robot#           ("a+b*c", "(+ a (* b c))"),
396*16467b97STreehugger Robot#           ("a.b+1", "(+ (. a b) 1)"),
397*16467b97STreehugger Robot#           ("-a", "(- a)"),
398*16467b97STreehugger Robot#           ("-a+b", "(+ (- a) b)"),
399*16467b97STreehugger Robot#           ("-a.b", "(- (. a b))"),
400*16467b97STreehugger Robot#           ("a^b^c", "(^ a (^ b c))"),
401*16467b97STreehugger Robot#           ("a=b=c", "(= a (= b c))"),
402*16467b97STreehugger Robot#           ("a=b=c+d.e", "(= a (= b (+ c (. d e))))"),
403*16467b97STreehugger Robot#           ("a|b&c", "(| a (& b c))"),
404*16467b97STreehugger Robot#           ("(a|b)&c", "(& (| a b) c)"),
405*16467b97STreehugger Robot#           ("a > b", "(> a b)"),
406*16467b97STreehugger Robot#           ("a >> b", "(> a b)"),  # text is from one token
407*16467b97STreehugger Robot#           ("a < b", "(< a b)"),
408*16467b97STreehugger Robot#           ("(T)x", "(( T x)"),
409*16467b97STreehugger Robot#           ("new A().b", "(. (new A () b)"),
410*16467b97STreehugger Robot#           ("(T)t.f()", "(( (( T (. t f)))"),
411*16467b97STreehugger Robot#           ("a.f(x)==T.c", "(== (( (. a f) x) (. T c))"),
412*16467b97STreehugger Robot#           ("a.f().g(x,1)", "(( (. (( (. a f)) g) x 1)"),
413*16467b97STreehugger Robot#           ("new T[((n-1) * x) + 1]", "(new T [ (+ (* (- n 1) x) 1))"),
414*16467b97STreehugger Robot#           ]
415*16467b97STreehugger Robot#       self.runTests(grammar, tests, "e")
416*16467b97STreehugger Robot
417*16467b97STreehugger Robot
418*16467b97STreehugger Robot#     def testReturnValueAndActions(self):
419*16467b97STreehugger Robot#         grammar = textwrap.dedent(
420*16467b97STreehugger Robot#             r"""
421*16467b97STreehugger Robot#             grammar T;
422*16467b97STreehugger Robot#             options {
423*16467b97STreehugger Robot#                 language=Python;
424*16467b97STreehugger Robot#             }
425*16467b97STreehugger Robot#             s : e { self.capture($e.v) } ;
426*16467b97STreehugger Robot#             e returns [v, ignored]
427*16467b97STreehugger Robot#               : e '*' b=e {$v *= $b.v;}
428*16467b97STreehugger Robot#               | e '+' b=e {$v += $b.v;}
429*16467b97STreehugger Robot#               | INT {$v = int($INT.text);}
430*16467b97STreehugger Robot#               ;
431*16467b97STreehugger Robot#             INT : '0'..'9'+ ;
432*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
433*16467b97STreehugger Robot#             """)
434*16467b97STreehugger Robot
435*16467b97STreehugger Robot#         tests = [
436*16467b97STreehugger Robot#             ("4", "4"),
437*16467b97STreehugger Robot#             ("1+2", "3")
438*16467b97STreehugger Robot#             ]
439*16467b97STreehugger Robot#         self.runTests(grammar, tests, "s")
440*16467b97STreehugger Robot
441*16467b97STreehugger Robot
442*16467b97STreehugger Robot#     def testReturnValueAndActionsAndASTs(self):
443*16467b97STreehugger Robot#         grammar = textwrap.dedent(
444*16467b97STreehugger Robot#             r"""
445*16467b97STreehugger Robot#             grammar T;
446*16467b97STreehugger Robot#             options {
447*16467b97STreehugger Robot#                 language=Python;
448*16467b97STreehugger Robot#                 output=AST;
449*16467b97STreehugger Robot#             }
450*16467b97STreehugger Robot#             s : e { self.capture("v=\%s, " \% $e.v) } ;
451*16467b97STreehugger Robot#             e returns [v, ignored]
452*16467b97STreehugger Robot#               : e '*'^ b=e {$v *= $b.v;}
453*16467b97STreehugger Robot#               | e '+'^ b=e {$v += $b.v;}
454*16467b97STreehugger Robot#               | INT {$v = int($INT.text);}
455*16467b97STreehugger Robot#               ;
456*16467b97STreehugger Robot#             INT : '0'..'9'+ ;
457*16467b97STreehugger Robot#             WS : (' '|'\n') {self.skip()} ;
458*16467b97STreehugger Robot#             """)
459*16467b97STreehugger Robot
460*16467b97STreehugger Robot#         tests = [
461*16467b97STreehugger Robot#             ("4", "v=4, 4"),
462*16467b97STreehugger Robot#             ("1+2", "v=3, (+ 1 2)"),
463*16467b97STreehugger Robot#             ]
464*16467b97STreehugger Robot#         self.runTests(grammar, tests, "s")
465*16467b97STreehugger Robot
466*16467b97STreehugger Robot
467*16467b97STreehugger Robotif __name__ == '__main__':
468*16467b97STreehugger Robot    unittest.main()
469