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