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