1import unittest
2import textwrap
3import antlr3
4import antlr3.tree
5import testbase
6import sys
7
8class T(testbase.ANTLRTest):
9    def setUp(self):
10        self.oldPath = sys.path[:]
11        sys.path.insert(0, self.baseDir)
12
13
14    def tearDown(self):
15        sys.path = self.oldPath
16
17
18    def parserClass(self, base):
19        class TParser(base):
20            def __init__(self, *args, **kwargs):
21                super().__init__(*args, **kwargs)
22
23                self._output = ""
24
25
26            def capture(self, t):
27                self._output += t
28
29
30            def traceIn(self, ruleName, ruleIndex):
31                self.traces.append('>'+ruleName)
32
33
34            def traceOut(self, ruleName, ruleIndex):
35                self.traces.append('<'+ruleName)
36
37
38            def recover(self, input, re):
39                # no error recovery yet, just crash!
40                raise
41
42        return TParser
43
44
45    def lexerClass(self, base):
46        class TLexer(base):
47            def __init__(self, *args, **kwargs):
48                super().__init__(*args, **kwargs)
49
50                self._output = ""
51
52
53            def capture(self, t):
54                self._output += t
55
56
57            def traceIn(self, ruleName, ruleIndex):
58                self.traces.append('>'+ruleName)
59
60
61            def traceOut(self, ruleName, ruleIndex):
62                self.traces.append('<'+ruleName)
63
64
65            def recover(self, input):
66                # no error recovery yet, just crash!
67                raise
68
69        return TLexer
70
71
72    def execParser(self, grammar, grammarEntry, slaves, input):
73        for slave in slaves:
74            parserName = self.writeInlineGrammar(slave)[0]
75            # slave parsers are imported as normal python modules
76            # to force reloading current version, purge module from sys.modules
77            if parserName + 'Parser' in sys.modules:
78                del sys.modules[parserName + 'Parser']
79
80        lexerCls, parserCls = self.compileInlineGrammar(grammar)
81
82        cStream = antlr3.StringStream(input)
83        lexer = lexerCls(cStream)
84        tStream = antlr3.CommonTokenStream(lexer)
85        parser = parserCls(tStream)
86        getattr(parser, grammarEntry)()
87
88        return parser._output
89
90
91    def execLexer(self, grammar, slaves, input):
92        for slave in slaves:
93            parserName = self.writeInlineGrammar(slave)[0]
94            # slave parsers are imported as normal python modules
95            # to force reloading current version, purge module from sys.modules
96            if parserName + 'Parser' in sys.modules:
97                del sys.modules[parserName + 'Parser']
98
99        lexerCls = self.compileInlineGrammar(grammar)
100
101        cStream = antlr3.StringStream(input)
102        lexer = lexerCls(cStream)
103
104        while True:
105            token = lexer.nextToken()
106            if token is None or token.type == antlr3.EOF:
107                break
108
109            lexer._output += token.text
110
111        return lexer._output
112
113
114    def testDelegatorInvokesDelegateRule(self):
115        slave = textwrap.dedent(
116        r'''
117        parser grammar S1;
118        options {
119            language=Python3;
120        }
121        @members {
122            def capture(self, t):
123                self.gM1.capture(t)
124
125        }
126
127        a : B { self.capture("S.a") } ;
128        ''')
129
130        master = textwrap.dedent(
131        r'''
132        grammar M1;
133        options {
134            language=Python3;
135        }
136        import S1;
137        s : a ;
138        B : 'b' ; // defines B from inherited token space
139        WS : (' '|'\n') {self.skip()} ;
140        ''')
141
142        found = self.execParser(
143            master, 's',
144            slaves=[slave],
145            input="b"
146            )
147
148        self.assertEqual("S.a", found)
149
150
151    def testDelegatorInvokesDelegateRuleWithArgs(self):
152        slave = textwrap.dedent(
153        r'''
154        parser grammar S2;
155        options {
156            language=Python3;
157        }
158        @members {
159            def capture(self, t):
160                self.gM2.capture(t)
161        }
162        a[x] returns [y] : B {self.capture("S.a"); $y="1000";} ;
163        ''')
164
165        master = textwrap.dedent(
166        r'''
167        grammar M2;
168        options {
169            language=Python3;
170        }
171        import S2;
172        s : label=a[3] {self.capture($label.y);} ;
173        B : 'b' ; // defines B from inherited token space
174        WS : (' '|'\n') {self.skip()} ;
175        ''')
176
177        found = self.execParser(
178            master, 's',
179            slaves=[slave],
180            input="b"
181            )
182
183        self.assertEqual("S.a1000", found)
184
185
186    def testDelegatorAccessesDelegateMembers(self):
187        slave = textwrap.dedent(
188        r'''
189        parser grammar S3;
190        options {
191            language=Python3;
192        }
193        @members {
194            def capture(self, t):
195                self.gM3.capture(t)
196
197            def foo(self):
198                self.capture("foo")
199        }
200        a : B ;
201        ''')
202
203        master = textwrap.dedent(
204        r'''
205        grammar M3;        // uses no rules from the import
206        options {
207            language=Python3;
208        }
209        import S3;
210        s : 'b' {self.gS3.foo();} ; // gS is import pointer
211        WS : (' '|'\n') {self.skip()} ;
212        ''')
213
214        found = self.execParser(
215            master, 's',
216            slaves=[slave],
217            input="b"
218            )
219
220        self.assertEqual("foo", found)
221
222
223    def testDelegatorInvokesFirstVersionOfDelegateRule(self):
224        slave = textwrap.dedent(
225        r'''
226        parser grammar S4;
227        options {
228            language=Python3;
229        }
230        @members {
231            def capture(self, t):
232                self.gM4.capture(t)
233        }
234        a : b {self.capture("S.a");} ;
235        b : B ;
236        ''')
237
238        slave2 = textwrap.dedent(
239        r'''
240        parser grammar T4;
241        options {
242            language=Python3;
243        }
244        @members {
245            def capture(self, t):
246                self.gM4.capture(t)
247        }
248        a : B {self.capture("T.a");} ; // hidden by S.a
249        ''')
250
251        master = textwrap.dedent(
252        r'''
253        grammar M4;
254        options {
255            language=Python3;
256        }
257        import S4,T4;
258        s : a ;
259        B : 'b' ;
260        WS : (' '|'\n') {self.skip()} ;
261        ''')
262
263        found = self.execParser(
264            master, 's',
265            slaves=[slave, slave2],
266            input="b"
267            )
268
269        self.assertEqual("S.a", found)
270
271
272    def testDelegatesSeeSameTokenType(self):
273        slave = textwrap.dedent(
274        r'''
275        parser grammar S5; // A, B, C token type order
276        options {
277            language=Python3;
278        }
279        tokens { A; B; C; }
280        @members {
281            def capture(self, t):
282                self.gM5.capture(t)
283        }
284        x : A {self.capture("S.x ");} ;
285        ''')
286
287        slave2 = textwrap.dedent(
288        r'''
289        parser grammar T5;
290        options {
291            language=Python3;
292        }
293        tokens { C; B; A; } /// reverse order
294        @members {
295            def capture(self, t):
296                self.gM5.capture(t)
297        }
298        y : A {self.capture("T.y");} ;
299        ''')
300
301        master = textwrap.dedent(
302        r'''
303        grammar M5;
304        options {
305            language=Python3;
306        }
307        import S5,T5;
308        s : x y ; // matches AA, which should be "aa"
309        B : 'b' ; // another order: B, A, C
310        A : 'a' ;
311        C : 'c' ;
312        WS : (' '|'\n') {self.skip()} ;
313        ''')
314
315        found = self.execParser(
316            master, 's',
317            slaves=[slave, slave2],
318            input="aa"
319            )
320
321        self.assertEqual("S.x T.y", found)
322
323
324    def testDelegatorRuleOverridesDelegate(self):
325        slave = textwrap.dedent(
326        r'''
327        parser grammar S6;
328        options {
329            language=Python3;
330        }
331        @members {
332            def capture(self, t):
333                self.gM6.capture(t)
334        }
335        a : b {self.capture("S.a");} ;
336        b : B ;
337        ''')
338
339        master = textwrap.dedent(
340        r'''
341        grammar M6;
342        options {
343            language=Python3;
344        }
345        import S6;
346        b : 'b'|'c' ;
347        WS : (' '|'\n') {self.skip()} ;
348        ''')
349
350        found = self.execParser(
351            master, 'a',
352            slaves=[slave],
353            input="c"
354            )
355
356        self.assertEqual("S.a", found)
357
358
359    # LEXER INHERITANCE
360
361    def testLexerDelegatorInvokesDelegateRule(self):
362        slave = textwrap.dedent(
363        r'''
364        lexer grammar S7;
365        options {
366            language=Python3;
367        }
368        @members {
369            def capture(self, t):
370                self.gM7.capture(t)
371        }
372        A : 'a' {self.capture("S.A ");} ;
373        C : 'c' ;
374        ''')
375
376        master = textwrap.dedent(
377        r'''
378        lexer grammar M7;
379        options {
380            language=Python3;
381        }
382        import S7;
383        B : 'b' ;
384        WS : (' '|'\n') {self.skip()} ;
385        ''')
386
387        found = self.execLexer(
388            master,
389            slaves=[slave],
390            input="abc"
391            )
392
393        self.assertEqual("S.A abc", found)
394
395
396    def testLexerDelegatorRuleOverridesDelegate(self):
397        slave = textwrap.dedent(
398        r'''
399        lexer grammar S8;
400        options {
401            language=Python3;
402        }
403        @members {
404            def capture(self, t):
405                self.gM8.capture(t)
406        }
407        A : 'a' {self.capture("S.A")} ;
408        ''')
409
410        master = textwrap.dedent(
411        r'''
412        lexer grammar M8;
413        options {
414            language=Python3;
415        }
416        import S8;
417        A : 'a' {self.capture("M.A ");} ;
418        WS : (' '|'\n') {self.skip()} ;
419        ''')
420
421        found = self.execLexer(
422            master,
423            slaves=[slave],
424            input="a"
425            )
426
427        self.assertEqual("M.A a", found)
428
429
430if __name__ == '__main__':
431    unittest.main()
432