xref: /aosp_15_r20/external/antlr/runtime/Python/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                base.__init__(self, *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                base.__init__(self, *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            try:
78*16467b97STreehugger Robot                del sys.modules[parserName+'Parser']
79*16467b97STreehugger Robot            except KeyError:
80*16467b97STreehugger Robot                pass
81*16467b97STreehugger Robot
82*16467b97STreehugger Robot        lexerCls, parserCls = self.compileInlineGrammar(grammar)
83*16467b97STreehugger Robot
84*16467b97STreehugger Robot        cStream = antlr3.StringStream(input)
85*16467b97STreehugger Robot        lexer = lexerCls(cStream)
86*16467b97STreehugger Robot        tStream = antlr3.CommonTokenStream(lexer)
87*16467b97STreehugger Robot        parser = parserCls(tStream)
88*16467b97STreehugger Robot        getattr(parser, grammarEntry)()
89*16467b97STreehugger Robot
90*16467b97STreehugger Robot        return parser._output
91*16467b97STreehugger Robot
92*16467b97STreehugger Robot
93*16467b97STreehugger Robot    def execLexer(self, grammar, slaves, input):
94*16467b97STreehugger Robot        for slave in slaves:
95*16467b97STreehugger Robot            parserName = self.writeInlineGrammar(slave)[0]
96*16467b97STreehugger Robot            # slave parsers are imported as normal python modules
97*16467b97STreehugger Robot            # to force reloading current version, purge module from sys.modules
98*16467b97STreehugger Robot            try:
99*16467b97STreehugger Robot                del sys.modules[parserName+'Parser']
100*16467b97STreehugger Robot            except KeyError:
101*16467b97STreehugger Robot                pass
102*16467b97STreehugger Robot
103*16467b97STreehugger Robot        lexerCls = self.compileInlineGrammar(grammar)
104*16467b97STreehugger Robot
105*16467b97STreehugger Robot        cStream = antlr3.StringStream(input)
106*16467b97STreehugger Robot        lexer = lexerCls(cStream)
107*16467b97STreehugger Robot
108*16467b97STreehugger Robot        while True:
109*16467b97STreehugger Robot            token = lexer.nextToken()
110*16467b97STreehugger Robot            if token is None or token.type == antlr3.EOF:
111*16467b97STreehugger Robot                break
112*16467b97STreehugger Robot
113*16467b97STreehugger Robot            lexer._output += token.text
114*16467b97STreehugger Robot
115*16467b97STreehugger Robot        return lexer._output
116*16467b97STreehugger Robot
117*16467b97STreehugger Robot
118*16467b97STreehugger Robot    # @Test public void testWildcardStillWorks() throws Exception {
119*16467b97STreehugger Robot    #     ErrorQueue equeue = new ErrorQueue();
120*16467b97STreehugger Robot    #     ErrorManager.setErrorListener(equeue);
121*16467b97STreehugger Robot    #     String grammar =
122*16467b97STreehugger Robot    #     "parser grammar S;\n" +
123*16467b97STreehugger Robot    #     "a : B . C ;\n"; // not qualified ID
124*16467b97STreehugger Robot    #     Grammar g = new Grammar(grammar);
125*16467b97STreehugger Robot    #     assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
126*16467b97STreehugger Robot    #     }
127*16467b97STreehugger Robot
128*16467b97STreehugger Robot
129*16467b97STreehugger Robot    def testDelegatorInvokesDelegateRule(self):
130*16467b97STreehugger Robot        slave = textwrap.dedent(
131*16467b97STreehugger Robot        r'''
132*16467b97STreehugger Robot        parser grammar S1;
133*16467b97STreehugger Robot        options {
134*16467b97STreehugger Robot            language=Python;
135*16467b97STreehugger Robot        }
136*16467b97STreehugger Robot        @members {
137*16467b97STreehugger Robot            def capture(self, t):
138*16467b97STreehugger Robot                self.gM1.capture(t)
139*16467b97STreehugger Robot
140*16467b97STreehugger Robot        }
141*16467b97STreehugger Robot
142*16467b97STreehugger Robot        a : B { self.capture("S.a") } ;
143*16467b97STreehugger Robot        ''')
144*16467b97STreehugger Robot
145*16467b97STreehugger Robot        master = textwrap.dedent(
146*16467b97STreehugger Robot        r'''
147*16467b97STreehugger Robot        grammar M1;
148*16467b97STreehugger Robot        options {
149*16467b97STreehugger Robot            language=Python;
150*16467b97STreehugger Robot        }
151*16467b97STreehugger Robot        import S1;
152*16467b97STreehugger Robot        s : a ;
153*16467b97STreehugger Robot        B : 'b' ; // defines B from inherited token space
154*16467b97STreehugger Robot        WS : (' '|'\n') {self.skip()} ;
155*16467b97STreehugger Robot        ''')
156*16467b97STreehugger Robot
157*16467b97STreehugger Robot        found = self.execParser(
158*16467b97STreehugger Robot            master, 's',
159*16467b97STreehugger Robot            slaves=[slave],
160*16467b97STreehugger Robot            input="b"
161*16467b97STreehugger Robot            )
162*16467b97STreehugger Robot
163*16467b97STreehugger Robot        self.failUnlessEqual("S.a", found)
164*16467b97STreehugger Robot
165*16467b97STreehugger Robot
166*16467b97STreehugger Robot        # @Test public void testDelegatorInvokesDelegateRuleWithReturnStruct() throws Exception {
167*16467b97STreehugger Robot        #     // must generate something like:
168*16467b97STreehugger Robot        #          // public int a(int x) throws RecognitionException { return gS.a(x); }
169*16467b97STreehugger Robot        #        // in M.
170*16467b97STreehugger Robot        #        String slave =
171*16467b97STreehugger Robot        #        "parser grammar S;\n" +
172*16467b97STreehugger Robot        #        "a : B {System.out.print(\"S.a\");} ;\n";
173*16467b97STreehugger Robot        #        mkdir(tmpdir);
174*16467b97STreehugger Robot        #        writeFile(tmpdir, "S.g", slave);
175*16467b97STreehugger Robot        #        String master =
176*16467b97STreehugger Robot        #        "grammar M;\n" +
177*16467b97STreehugger Robot        #        "import S;\n" +
178*16467b97STreehugger Robot        #        "s : a {System.out.println($a.text);} ;\n" +
179*16467b97STreehugger Robot        #        "B : 'b' ;" + // defines B from inherited token space
180*16467b97STreehugger Robot        #        "WS : (' '|'\\n') {skip();} ;\n" ;
181*16467b97STreehugger Robot        #        String found = execParser("M.g", master, "MParser", "MLexer",
182*16467b97STreehugger Robot        #                                    "s", "b", debug);
183*16467b97STreehugger Robot        #        assertEquals("S.ab\n", found);
184*16467b97STreehugger Robot        #        }
185*16467b97STreehugger Robot
186*16467b97STreehugger Robot
187*16467b97STreehugger Robot    def testDelegatorInvokesDelegateRuleWithArgs(self):
188*16467b97STreehugger Robot        slave = textwrap.dedent(
189*16467b97STreehugger Robot        r'''
190*16467b97STreehugger Robot        parser grammar S2;
191*16467b97STreehugger Robot        options {
192*16467b97STreehugger Robot            language=Python;
193*16467b97STreehugger Robot        }
194*16467b97STreehugger Robot        @members {
195*16467b97STreehugger Robot            def capture(self, t):
196*16467b97STreehugger Robot                self.gM2.capture(t)
197*16467b97STreehugger Robot        }
198*16467b97STreehugger Robot        a[x] returns [y] : B {self.capture("S.a"); $y="1000";} ;
199*16467b97STreehugger Robot        ''')
200*16467b97STreehugger Robot
201*16467b97STreehugger Robot        master = textwrap.dedent(
202*16467b97STreehugger Robot        r'''
203*16467b97STreehugger Robot        grammar M2;
204*16467b97STreehugger Robot        options {
205*16467b97STreehugger Robot            language=Python;
206*16467b97STreehugger Robot        }
207*16467b97STreehugger Robot        import S2;
208*16467b97STreehugger Robot        s : label=a[3] {self.capture($label.y);} ;
209*16467b97STreehugger Robot        B : 'b' ; // defines B from inherited token space
210*16467b97STreehugger Robot        WS : (' '|'\n') {self.skip()} ;
211*16467b97STreehugger Robot        ''')
212*16467b97STreehugger Robot
213*16467b97STreehugger Robot        found = self.execParser(
214*16467b97STreehugger Robot            master, 's',
215*16467b97STreehugger Robot            slaves=[slave],
216*16467b97STreehugger Robot            input="b"
217*16467b97STreehugger Robot            )
218*16467b97STreehugger Robot
219*16467b97STreehugger Robot        self.failUnlessEqual("S.a1000", found)
220*16467b97STreehugger Robot
221*16467b97STreehugger Robot
222*16467b97STreehugger Robot    def testDelegatorAccessesDelegateMembers(self):
223*16467b97STreehugger Robot        slave = textwrap.dedent(
224*16467b97STreehugger Robot        r'''
225*16467b97STreehugger Robot        parser grammar S3;
226*16467b97STreehugger Robot        options {
227*16467b97STreehugger Robot            language=Python;
228*16467b97STreehugger Robot        }
229*16467b97STreehugger Robot        @members {
230*16467b97STreehugger Robot            def capture(self, t):
231*16467b97STreehugger Robot                self.gM3.capture(t)
232*16467b97STreehugger Robot
233*16467b97STreehugger Robot            def foo(self):
234*16467b97STreehugger Robot                self.capture("foo")
235*16467b97STreehugger Robot        }
236*16467b97STreehugger Robot        a : B ;
237*16467b97STreehugger Robot        ''')
238*16467b97STreehugger Robot
239*16467b97STreehugger Robot        master = textwrap.dedent(
240*16467b97STreehugger Robot        r'''
241*16467b97STreehugger Robot        grammar M3;        // uses no rules from the import
242*16467b97STreehugger Robot        options {
243*16467b97STreehugger Robot            language=Python;
244*16467b97STreehugger Robot        }
245*16467b97STreehugger Robot        import S3;
246*16467b97STreehugger Robot        s : 'b' {self.gS3.foo();} ; // gS is import pointer
247*16467b97STreehugger Robot        WS : (' '|'\n') {self.skip()} ;
248*16467b97STreehugger Robot        ''')
249*16467b97STreehugger Robot
250*16467b97STreehugger Robot        found = self.execParser(
251*16467b97STreehugger Robot            master, 's',
252*16467b97STreehugger Robot            slaves=[slave],
253*16467b97STreehugger Robot            input="b"
254*16467b97STreehugger Robot            )
255*16467b97STreehugger Robot
256*16467b97STreehugger Robot        self.failUnlessEqual("foo", found)
257*16467b97STreehugger Robot
258*16467b97STreehugger Robot
259*16467b97STreehugger Robot    def testDelegatorInvokesFirstVersionOfDelegateRule(self):
260*16467b97STreehugger Robot        slave = textwrap.dedent(
261*16467b97STreehugger Robot        r'''
262*16467b97STreehugger Robot        parser grammar S4;
263*16467b97STreehugger Robot        options {
264*16467b97STreehugger Robot            language=Python;
265*16467b97STreehugger Robot        }
266*16467b97STreehugger Robot        @members {
267*16467b97STreehugger Robot            def capture(self, t):
268*16467b97STreehugger Robot                self.gM4.capture(t)
269*16467b97STreehugger Robot        }
270*16467b97STreehugger Robot        a : b {self.capture("S.a");} ;
271*16467b97STreehugger Robot        b : B ;
272*16467b97STreehugger Robot        ''')
273*16467b97STreehugger Robot
274*16467b97STreehugger Robot        slave2 = textwrap.dedent(
275*16467b97STreehugger Robot        r'''
276*16467b97STreehugger Robot        parser grammar T4;
277*16467b97STreehugger Robot        options {
278*16467b97STreehugger Robot            language=Python;
279*16467b97STreehugger Robot        }
280*16467b97STreehugger Robot        @members {
281*16467b97STreehugger Robot            def capture(self, t):
282*16467b97STreehugger Robot                self.gM4.capture(t)
283*16467b97STreehugger Robot        }
284*16467b97STreehugger Robot        a : B {self.capture("T.a");} ; // hidden by S.a
285*16467b97STreehugger Robot        ''')
286*16467b97STreehugger Robot
287*16467b97STreehugger Robot        master = textwrap.dedent(
288*16467b97STreehugger Robot        r'''
289*16467b97STreehugger Robot        grammar M4;
290*16467b97STreehugger Robot        options {
291*16467b97STreehugger Robot            language=Python;
292*16467b97STreehugger Robot        }
293*16467b97STreehugger Robot        import S4,T4;
294*16467b97STreehugger Robot        s : a ;
295*16467b97STreehugger Robot        B : 'b' ;
296*16467b97STreehugger Robot        WS : (' '|'\n') {self.skip()} ;
297*16467b97STreehugger Robot        ''')
298*16467b97STreehugger Robot
299*16467b97STreehugger Robot        found = self.execParser(
300*16467b97STreehugger Robot            master, 's',
301*16467b97STreehugger Robot            slaves=[slave, slave2],
302*16467b97STreehugger Robot            input="b"
303*16467b97STreehugger Robot            )
304*16467b97STreehugger Robot
305*16467b97STreehugger Robot        self.failUnlessEqual("S.a", found)
306*16467b97STreehugger Robot
307*16467b97STreehugger Robot
308*16467b97STreehugger Robot    def testDelegatesSeeSameTokenType(self):
309*16467b97STreehugger Robot        slave = textwrap.dedent(
310*16467b97STreehugger Robot        r'''
311*16467b97STreehugger Robot        parser grammar S5; // A, B, C token type order
312*16467b97STreehugger Robot        options {
313*16467b97STreehugger Robot            language=Python;
314*16467b97STreehugger Robot        }
315*16467b97STreehugger Robot        tokens { A; B; C; }
316*16467b97STreehugger Robot        @members {
317*16467b97STreehugger Robot            def capture(self, t):
318*16467b97STreehugger Robot                self.gM5.capture(t)
319*16467b97STreehugger Robot        }
320*16467b97STreehugger Robot        x : A {self.capture("S.x ");} ;
321*16467b97STreehugger Robot        ''')
322*16467b97STreehugger Robot
323*16467b97STreehugger Robot        slave2 = textwrap.dedent(
324*16467b97STreehugger Robot        r'''
325*16467b97STreehugger Robot        parser grammar T5;
326*16467b97STreehugger Robot        options {
327*16467b97STreehugger Robot            language=Python;
328*16467b97STreehugger Robot        }
329*16467b97STreehugger Robot        tokens { C; B; A; } /// reverse order
330*16467b97STreehugger Robot        @members {
331*16467b97STreehugger Robot            def capture(self, t):
332*16467b97STreehugger Robot                self.gM5.capture(t)
333*16467b97STreehugger Robot        }
334*16467b97STreehugger Robot        y : A {self.capture("T.y");} ;
335*16467b97STreehugger Robot        ''')
336*16467b97STreehugger Robot
337*16467b97STreehugger Robot        master = textwrap.dedent(
338*16467b97STreehugger Robot        r'''
339*16467b97STreehugger Robot        grammar M5;
340*16467b97STreehugger Robot        options {
341*16467b97STreehugger Robot            language=Python;
342*16467b97STreehugger Robot        }
343*16467b97STreehugger Robot        import S5,T5;
344*16467b97STreehugger Robot        s : x y ; // matches AA, which should be "aa"
345*16467b97STreehugger Robot        B : 'b' ; // another order: B, A, C
346*16467b97STreehugger Robot        A : 'a' ;
347*16467b97STreehugger Robot        C : 'c' ;
348*16467b97STreehugger Robot        WS : (' '|'\n') {self.skip()} ;
349*16467b97STreehugger Robot        ''')
350*16467b97STreehugger Robot
351*16467b97STreehugger Robot        found = self.execParser(
352*16467b97STreehugger Robot            master, 's',
353*16467b97STreehugger Robot            slaves=[slave, slave2],
354*16467b97STreehugger Robot            input="aa"
355*16467b97STreehugger Robot            )
356*16467b97STreehugger Robot
357*16467b97STreehugger Robot        self.failUnlessEqual("S.x T.y", found)
358*16467b97STreehugger Robot
359*16467b97STreehugger Robot
360*16467b97STreehugger Robot        # @Test public void testDelegatesSeeSameTokenType2() throws Exception {
361*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
362*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
363*16467b97STreehugger Robot        #         String slave =
364*16467b97STreehugger Robot        #                 "parser grammar S;\n" + // A, B, C token type order
365*16467b97STreehugger Robot        #                 "tokens { A; B; C; }\n" +
366*16467b97STreehugger Robot        #                 "x : A {System.out.println(\"S.x\");} ;\n";
367*16467b97STreehugger Robot        #         mkdir(tmpdir);
368*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
369*16467b97STreehugger Robot        #         String slave2 =
370*16467b97STreehugger Robot        #                 "parser grammar T;\n" +
371*16467b97STreehugger Robot        #                 "tokens { C; B; A; }\n" + // reverse order
372*16467b97STreehugger Robot        #                 "y : A {System.out.println(\"T.y\");} ;\n";
373*16467b97STreehugger Robot        #         mkdir(tmpdir);
374*16467b97STreehugger Robot        #         writeFile(tmpdir, "T.g", slave2);
375*16467b97STreehugger Robot
376*16467b97STreehugger Robot        #         String master =
377*16467b97STreehugger Robot        #                 "grammar M;\n" +
378*16467b97STreehugger Robot        #                 "import S,T;\n" +
379*16467b97STreehugger Robot        #                 "s : x y ;\n" + // matches AA, which should be "aa"
380*16467b97STreehugger Robot        #                 "B : 'b' ;\n" + // another order: B, A, C
381*16467b97STreehugger Robot        #                 "A : 'a' ;\n" +
382*16467b97STreehugger Robot        #                 "C : 'c' ;\n" +
383*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
384*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
385*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
386*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
387*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
388*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
389*16467b97STreehugger Robot        #         g.parseAndBuildAST();
390*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
391*16467b97STreehugger Robot
392*16467b97STreehugger Robot        #         String expectedTokenIDToTypeMap = "[A=4, B=5, C=6, WS=7]";
393*16467b97STreehugger Robot        #         String expectedStringLiteralToTypeMap = "{}";
394*16467b97STreehugger Robot        #         String expectedTypeToTokenList = "[A, B, C, WS]";
395*16467b97STreehugger Robot
396*16467b97STreehugger Robot        #         assertEquals(expectedTokenIDToTypeMap,
397*16467b97STreehugger Robot        #                                  realElements(g.composite.tokenIDToTypeMap).toString());
398*16467b97STreehugger Robot        #         assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
399*16467b97STreehugger Robot        #         assertEquals(expectedTypeToTokenList,
400*16467b97STreehugger Robot        #                                  realElements(g.composite.typeToTokenList).toString());
401*16467b97STreehugger Robot
402*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
403*16467b97STreehugger Robot        # }
404*16467b97STreehugger Robot
405*16467b97STreehugger Robot        # @Test public void testCombinedImportsCombined() throws Exception {
406*16467b97STreehugger Robot        #         // for now, we don't allow combined to import combined
407*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
408*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
409*16467b97STreehugger Robot        #         String slave =
410*16467b97STreehugger Robot        #                 "grammar S;\n" + // A, B, C token type order
411*16467b97STreehugger Robot        #                 "tokens { A; B; C; }\n" +
412*16467b97STreehugger Robot        #                 "x : 'x' INT {System.out.println(\"S.x\");} ;\n" +
413*16467b97STreehugger Robot        #                 "INT : '0'..'9'+ ;\n" +
414*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n";
415*16467b97STreehugger Robot        #         mkdir(tmpdir);
416*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
417*16467b97STreehugger Robot
418*16467b97STreehugger Robot        #         String master =
419*16467b97STreehugger Robot        #                 "grammar M;\n" +
420*16467b97STreehugger Robot        #                 "import S;\n" +
421*16467b97STreehugger Robot        #                 "s : x INT ;\n";
422*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
423*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
424*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
425*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
426*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
427*16467b97STreehugger Robot        #         g.parseAndBuildAST();
428*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
429*16467b97STreehugger Robot
430*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size());
431*16467b97STreehugger Robot        #         String expectedError = "error(161): "+tmpdir.toString().replaceFirst("\\-[0-9]+","")+"/M.g:2:8: combined grammar M cannot import combined grammar S";
432*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, expectedError, equeue.errors.get(0).toString().replaceFirst("\\-[0-9]+",""));
433*16467b97STreehugger Robot        # }
434*16467b97STreehugger Robot
435*16467b97STreehugger Robot        # @Test public void testSameStringTwoNames() throws Exception {
436*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
437*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
438*16467b97STreehugger Robot        #         String slave =
439*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
440*16467b97STreehugger Robot        #                 "tokens { A='a'; }\n" +
441*16467b97STreehugger Robot        #                 "x : A {System.out.println(\"S.x\");} ;\n";
442*16467b97STreehugger Robot        #         mkdir(tmpdir);
443*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
444*16467b97STreehugger Robot        #         String slave2 =
445*16467b97STreehugger Robot        #                 "parser grammar T;\n" +
446*16467b97STreehugger Robot        #                 "tokens { X='a'; }\n" +
447*16467b97STreehugger Robot        #                 "y : X {System.out.println(\"T.y\");} ;\n";
448*16467b97STreehugger Robot        #         mkdir(tmpdir);
449*16467b97STreehugger Robot        #         writeFile(tmpdir, "T.g", slave2);
450*16467b97STreehugger Robot
451*16467b97STreehugger Robot        #         String master =
452*16467b97STreehugger Robot        #                 "grammar M;\n" +
453*16467b97STreehugger Robot        #                 "import S,T;\n" +
454*16467b97STreehugger Robot        #                 "s : x y ;\n" +
455*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
456*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
457*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
458*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
459*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
460*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
461*16467b97STreehugger Robot        #         g.parseAndBuildAST();
462*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
463*16467b97STreehugger Robot
464*16467b97STreehugger Robot        #         String expectedTokenIDToTypeMap = "[A=4, WS=6, X=5]";
465*16467b97STreehugger Robot        #         String expectedStringLiteralToTypeMap = "{'a'=4}";
466*16467b97STreehugger Robot        #         String expectedTypeToTokenList = "[A, X, WS]";
467*16467b97STreehugger Robot
468*16467b97STreehugger Robot        #         assertEquals(expectedTokenIDToTypeMap,
469*16467b97STreehugger Robot        #                                  realElements(g.composite.tokenIDToTypeMap).toString());
470*16467b97STreehugger Robot        #         assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
471*16467b97STreehugger Robot        #         assertEquals(expectedTypeToTokenList,
472*16467b97STreehugger Robot        #                                  realElements(g.composite.typeToTokenList).toString());
473*16467b97STreehugger Robot
474*16467b97STreehugger Robot        #         Object expectedArg = "X='a'";
475*16467b97STreehugger Robot        #         Object expectedArg2 = "A";
476*16467b97STreehugger Robot        #         int expectedMsgID = ErrorManager.MSG_TOKEN_ALIAS_CONFLICT;
477*16467b97STreehugger Robot        #         GrammarSemanticsMessage expectedMessage =
478*16467b97STreehugger Robot        #                 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
479*16467b97STreehugger Robot        #         checkGrammarSemanticsError(equeue, expectedMessage);
480*16467b97STreehugger Robot
481*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size());
482*16467b97STreehugger Robot
483*16467b97STreehugger Robot        #         String expectedError =
484*16467b97STreehugger Robot        #                 "error(158): T.g:2:10: cannot alias X='a'; string already assigned to A";
485*16467b97STreehugger Robot        #         assertEquals(expectedError, equeue.errors.get(0).toString());
486*16467b97STreehugger Robot        # }
487*16467b97STreehugger Robot
488*16467b97STreehugger Robot        # @Test public void testSameNameTwoStrings() throws Exception {
489*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
490*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
491*16467b97STreehugger Robot        #         String slave =
492*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
493*16467b97STreehugger Robot        #                 "tokens { A='a'; }\n" +
494*16467b97STreehugger Robot        #                 "x : A {System.out.println(\"S.x\");} ;\n";
495*16467b97STreehugger Robot        #         mkdir(tmpdir);
496*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
497*16467b97STreehugger Robot        #         String slave2 =
498*16467b97STreehugger Robot        #                 "parser grammar T;\n" +
499*16467b97STreehugger Robot        #                 "tokens { A='x'; }\n" +
500*16467b97STreehugger Robot        #                 "y : A {System.out.println(\"T.y\");} ;\n";
501*16467b97STreehugger Robot
502*16467b97STreehugger Robot        #         writeFile(tmpdir, "T.g", slave2);
503*16467b97STreehugger Robot
504*16467b97STreehugger Robot        #         String master =
505*16467b97STreehugger Robot        #                 "grammar M;\n" +
506*16467b97STreehugger Robot        #                 "import S,T;\n" +
507*16467b97STreehugger Robot        #                 "s : x y ;\n" +
508*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
509*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
510*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
511*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
512*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
513*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
514*16467b97STreehugger Robot        #         g.parseAndBuildAST();
515*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
516*16467b97STreehugger Robot
517*16467b97STreehugger Robot        #         String expectedTokenIDToTypeMap = "[A=4, T__6=6, WS=5]";
518*16467b97STreehugger Robot        #         String expectedStringLiteralToTypeMap = "{'a'=4, 'x'=6}";
519*16467b97STreehugger Robot        #         String expectedTypeToTokenList = "[A, WS, T__6]";
520*16467b97STreehugger Robot
521*16467b97STreehugger Robot        #         assertEquals(expectedTokenIDToTypeMap,
522*16467b97STreehugger Robot        #                                  realElements(g.composite.tokenIDToTypeMap).toString());
523*16467b97STreehugger Robot        #         assertEquals(expectedStringLiteralToTypeMap, sortMapToString(g.composite.stringLiteralToTypeMap));
524*16467b97STreehugger Robot        #         assertEquals(expectedTypeToTokenList,
525*16467b97STreehugger Robot        #                                  realElements(g.composite.typeToTokenList).toString());
526*16467b97STreehugger Robot
527*16467b97STreehugger Robot        #         Object expectedArg = "A='x'";
528*16467b97STreehugger Robot        #         Object expectedArg2 = "'a'";
529*16467b97STreehugger Robot        #         int expectedMsgID = ErrorManager.MSG_TOKEN_ALIAS_REASSIGNMENT;
530*16467b97STreehugger Robot        #         GrammarSemanticsMessage expectedMessage =
531*16467b97STreehugger Robot        #                 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg, expectedArg2);
532*16467b97STreehugger Robot        #         checkGrammarSemanticsError(equeue, expectedMessage);
533*16467b97STreehugger Robot
534*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size());
535*16467b97STreehugger Robot
536*16467b97STreehugger Robot        #         String expectedError =
537*16467b97STreehugger Robot        #                 "error(159): T.g:2:10: cannot alias A='x'; token name already assigned to 'a'";
538*16467b97STreehugger Robot        #         assertEquals(expectedError, equeue.errors.get(0).toString());
539*16467b97STreehugger Robot        # }
540*16467b97STreehugger Robot
541*16467b97STreehugger Robot        # @Test public void testImportedTokenVocabIgnoredWithWarning() throws Exception {
542*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
543*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
544*16467b97STreehugger Robot        #         String slave =
545*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
546*16467b97STreehugger Robot        #                 "options {tokenVocab=whatever;}\n" +
547*16467b97STreehugger Robot        #                 "tokens { A='a'; }\n" +
548*16467b97STreehugger Robot        #                 "x : A {System.out.println(\"S.x\");} ;\n";
549*16467b97STreehugger Robot        #         mkdir(tmpdir);
550*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
551*16467b97STreehugger Robot
552*16467b97STreehugger Robot        #         String master =
553*16467b97STreehugger Robot        #                 "grammar M;\n" +
554*16467b97STreehugger Robot        #                 "import S;\n" +
555*16467b97STreehugger Robot        #                 "s : x ;\n" +
556*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
557*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
558*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
559*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
560*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
561*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
562*16467b97STreehugger Robot        #         g.parseAndBuildAST();
563*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
564*16467b97STreehugger Robot
565*16467b97STreehugger Robot        #         Object expectedArg = "S";
566*16467b97STreehugger Robot        #         int expectedMsgID = ErrorManager.MSG_TOKEN_VOCAB_IN_DELEGATE;
567*16467b97STreehugger Robot        #         GrammarSemanticsMessage expectedMessage =
568*16467b97STreehugger Robot        #                 new GrammarSemanticsMessage(expectedMsgID, g, null, expectedArg);
569*16467b97STreehugger Robot        #         checkGrammarSemanticsWarning(equeue, expectedMessage);
570*16467b97STreehugger Robot
571*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
572*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 1, equeue.warnings.size());
573*16467b97STreehugger Robot
574*16467b97STreehugger Robot        #         String expectedError =
575*16467b97STreehugger Robot        #                 "warning(160): S.g:2:10: tokenVocab option ignored in imported grammar S";
576*16467b97STreehugger Robot        #         assertEquals(expectedError, equeue.warnings.get(0).toString());
577*16467b97STreehugger Robot        # }
578*16467b97STreehugger Robot
579*16467b97STreehugger Robot        # @Test public void testImportedTokenVocabWorksInRoot() throws Exception {
580*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
581*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
582*16467b97STreehugger Robot        #         String slave =
583*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
584*16467b97STreehugger Robot        #                 "tokens { A='a'; }\n" +
585*16467b97STreehugger Robot        #                 "x : A {System.out.println(\"S.x\");} ;\n";
586*16467b97STreehugger Robot        #         mkdir(tmpdir);
587*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
588*16467b97STreehugger Robot
589*16467b97STreehugger Robot        #         String tokens =
590*16467b97STreehugger Robot        #                 "A=99\n";
591*16467b97STreehugger Robot        #         writeFile(tmpdir, "Test.tokens", tokens);
592*16467b97STreehugger Robot
593*16467b97STreehugger Robot        #         String master =
594*16467b97STreehugger Robot        #                 "grammar M;\n" +
595*16467b97STreehugger Robot        #                 "options {tokenVocab=Test;}\n" +
596*16467b97STreehugger Robot        #                 "import S;\n" +
597*16467b97STreehugger Robot        #                 "s : x ;\n" +
598*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
599*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
600*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
601*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
602*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
603*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
604*16467b97STreehugger Robot        #         g.parseAndBuildAST();
605*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
606*16467b97STreehugger Robot
607*16467b97STreehugger Robot        #         String expectedTokenIDToTypeMap = "[A=99, WS=101]";
608*16467b97STreehugger Robot        #         String expectedStringLiteralToTypeMap = "{'a'=100}";
609*16467b97STreehugger Robot        #         String expectedTypeToTokenList = "[A, 'a', WS]";
610*16467b97STreehugger Robot
611*16467b97STreehugger Robot        #         assertEquals(expectedTokenIDToTypeMap,
612*16467b97STreehugger Robot        #                                  realElements(g.composite.tokenIDToTypeMap).toString());
613*16467b97STreehugger Robot        #         assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
614*16467b97STreehugger Robot        #         assertEquals(expectedTypeToTokenList,
615*16467b97STreehugger Robot        #                                  realElements(g.composite.typeToTokenList).toString());
616*16467b97STreehugger Robot
617*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
618*16467b97STreehugger Robot        # }
619*16467b97STreehugger Robot
620*16467b97STreehugger Robot        # @Test public void testSyntaxErrorsInImportsNotThrownOut() throws Exception {
621*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
622*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
623*16467b97STreehugger Robot        #         String slave =
624*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
625*16467b97STreehugger Robot        #                 "options {toke\n";
626*16467b97STreehugger Robot        #         mkdir(tmpdir);
627*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
628*16467b97STreehugger Robot
629*16467b97STreehugger Robot        #         String master =
630*16467b97STreehugger Robot        #                 "grammar M;\n" +
631*16467b97STreehugger Robot        #                 "import S;\n" +
632*16467b97STreehugger Robot        #                 "s : x ;\n" +
633*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
634*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
635*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
636*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
637*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
638*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
639*16467b97STreehugger Robot        #         g.parseAndBuildAST();
640*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
641*16467b97STreehugger Robot
642*16467b97STreehugger Robot        #         // whole bunch of errors from bad S.g file
643*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 5, equeue.errors.size());
644*16467b97STreehugger Robot        # }
645*16467b97STreehugger Robot
646*16467b97STreehugger Robot        # @Test public void testSyntaxErrorsInImportsNotThrownOut2() throws Exception {
647*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
648*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
649*16467b97STreehugger Robot        #         String slave =
650*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
651*16467b97STreehugger Robot        #                 ": A {System.out.println(\"S.x\");} ;\n";
652*16467b97STreehugger Robot        #         mkdir(tmpdir);
653*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
654*16467b97STreehugger Robot
655*16467b97STreehugger Robot        #         String master =
656*16467b97STreehugger Robot        #                 "grammar M;\n" +
657*16467b97STreehugger Robot        #                 "import S;\n" +
658*16467b97STreehugger Robot        #                 "s : x ;\n" +
659*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
660*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
661*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
662*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
663*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
664*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
665*16467b97STreehugger Robot        #         g.parseAndBuildAST();
666*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
667*16467b97STreehugger Robot
668*16467b97STreehugger Robot        #         // whole bunch of errors from bad S.g file
669*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 3, equeue.errors.size());
670*16467b97STreehugger Robot        # }
671*16467b97STreehugger Robot
672*16467b97STreehugger Robot
673*16467b97STreehugger Robot    def testDelegatorRuleOverridesDelegate(self):
674*16467b97STreehugger Robot        slave = textwrap.dedent(
675*16467b97STreehugger Robot        r'''
676*16467b97STreehugger Robot        parser grammar S6;
677*16467b97STreehugger Robot        options {
678*16467b97STreehugger Robot            language=Python;
679*16467b97STreehugger Robot        }
680*16467b97STreehugger Robot        @members {
681*16467b97STreehugger Robot            def capture(self, t):
682*16467b97STreehugger Robot                self.gM6.capture(t)
683*16467b97STreehugger Robot        }
684*16467b97STreehugger Robot        a : b {self.capture("S.a");} ;
685*16467b97STreehugger Robot        b : B ;
686*16467b97STreehugger Robot        ''')
687*16467b97STreehugger Robot
688*16467b97STreehugger Robot        master = textwrap.dedent(
689*16467b97STreehugger Robot        r'''
690*16467b97STreehugger Robot        grammar M6;
691*16467b97STreehugger Robot        options {
692*16467b97STreehugger Robot            language=Python;
693*16467b97STreehugger Robot        }
694*16467b97STreehugger Robot        import S6;
695*16467b97STreehugger Robot        b : 'b'|'c' ;
696*16467b97STreehugger Robot        WS : (' '|'\n') {self.skip()} ;
697*16467b97STreehugger Robot        ''')
698*16467b97STreehugger Robot
699*16467b97STreehugger Robot        found = self.execParser(
700*16467b97STreehugger Robot            master, 'a',
701*16467b97STreehugger Robot            slaves=[slave],
702*16467b97STreehugger Robot            input="c"
703*16467b97STreehugger Robot            )
704*16467b97STreehugger Robot
705*16467b97STreehugger Robot        self.failUnlessEqual("S.a", found)
706*16467b97STreehugger Robot
707*16467b97STreehugger Robot
708*16467b97STreehugger Robot    #     @Test public void testDelegatorRuleOverridesLookaheadInDelegate() throws Exception {
709*16467b97STreehugger Robot    #             String slave =
710*16467b97STreehugger Robot    #                     "parser grammar JavaDecl;\n" +
711*16467b97STreehugger Robot    #                     "type : 'int' ;\n" +
712*16467b97STreehugger Robot    #                     "decl : type ID ';'\n" +
713*16467b97STreehugger Robot    #                     "     | type ID init ';' {System.out.println(\"JavaDecl: \"+$decl.text);}\n" +
714*16467b97STreehugger Robot    #                     "     ;\n" +
715*16467b97STreehugger Robot    #                     "init : '=' INT ;\n" ;
716*16467b97STreehugger Robot    #             mkdir(tmpdir);
717*16467b97STreehugger Robot    #             writeFile(tmpdir, "JavaDecl.g", slave);
718*16467b97STreehugger Robot    #             String master =
719*16467b97STreehugger Robot    #                     "grammar Java;\n" +
720*16467b97STreehugger Robot    #                     "import JavaDecl;\n" +
721*16467b97STreehugger Robot    #                     "prog : decl ;\n" +
722*16467b97STreehugger Robot    #                     "type : 'int' | 'float' ;\n" +
723*16467b97STreehugger Robot    #                     "\n" +
724*16467b97STreehugger Robot    #                     "ID  : 'a'..'z'+ ;\n" +
725*16467b97STreehugger Robot    #                     "INT : '0'..'9'+ ;\n" +
726*16467b97STreehugger Robot    #                     "WS : (' '|'\\n') {skip();} ;\n" ;
727*16467b97STreehugger Robot    #             // for float to work in decl, type must be overridden
728*16467b97STreehugger Robot    #             String found = execParser("Java.g", master, "JavaParser", "JavaLexer",
729*16467b97STreehugger Robot    #                                                               "prog", "float x = 3;", debug);
730*16467b97STreehugger Robot    #             assertEquals("JavaDecl: floatx=3;\n", found);
731*16467b97STreehugger Robot    #     }
732*16467b97STreehugger Robot
733*16467b97STreehugger Robot    # @Test public void testDelegatorRuleOverridesDelegates() throws Exception {
734*16467b97STreehugger Robot    #     String slave =
735*16467b97STreehugger Robot    #         "parser grammar S;\n" +
736*16467b97STreehugger Robot    #         "a : b {System.out.println(\"S.a\");} ;\n" +
737*16467b97STreehugger Robot    #         "b : B ;\n" ;
738*16467b97STreehugger Robot    #     mkdir(tmpdir);
739*16467b97STreehugger Robot    #     writeFile(tmpdir, "S.g", slave);
740*16467b97STreehugger Robot
741*16467b97STreehugger Robot    #     String slave2 =
742*16467b97STreehugger Robot    #         "parser grammar T;\n" +
743*16467b97STreehugger Robot    #         "tokens { A='x'; }\n" +
744*16467b97STreehugger Robot    #         "b : B {System.out.println(\"T.b\");} ;\n";
745*16467b97STreehugger Robot    #     writeFile(tmpdir, "T.g", slave2);
746*16467b97STreehugger Robot
747*16467b97STreehugger Robot    #     String master =
748*16467b97STreehugger Robot    #         "grammar M;\n" +
749*16467b97STreehugger Robot    #         "import S, T;\n" +
750*16467b97STreehugger Robot    #         "b : 'b'|'c' {System.out.println(\"M.b\");}|B|A ;\n" +
751*16467b97STreehugger Robot    #         "WS : (' '|'\\n') {skip();} ;\n" ;
752*16467b97STreehugger Robot    #     String found = execParser("M.g", master, "MParser", "MLexer",
753*16467b97STreehugger Robot    #                               "a", "c", debug);
754*16467b97STreehugger Robot    #     assertEquals("M.b\n" +
755*16467b97STreehugger Robot    #                  "S.a\n", found);
756*16467b97STreehugger Robot    # }
757*16467b97STreehugger Robot
758*16467b97STreehugger Robot    # LEXER INHERITANCE
759*16467b97STreehugger Robot
760*16467b97STreehugger Robot    def testLexerDelegatorInvokesDelegateRule(self):
761*16467b97STreehugger Robot        slave = textwrap.dedent(
762*16467b97STreehugger Robot        r'''
763*16467b97STreehugger Robot        lexer grammar S7;
764*16467b97STreehugger Robot        options {
765*16467b97STreehugger Robot            language=Python;
766*16467b97STreehugger Robot        }
767*16467b97STreehugger Robot        @members {
768*16467b97STreehugger Robot            def capture(self, t):
769*16467b97STreehugger Robot                self.gM7.capture(t)
770*16467b97STreehugger Robot        }
771*16467b97STreehugger Robot        A : 'a' {self.capture("S.A ");} ;
772*16467b97STreehugger Robot        C : 'c' ;
773*16467b97STreehugger Robot        ''')
774*16467b97STreehugger Robot
775*16467b97STreehugger Robot        master = textwrap.dedent(
776*16467b97STreehugger Robot        r'''
777*16467b97STreehugger Robot        lexer grammar M7;
778*16467b97STreehugger Robot        options {
779*16467b97STreehugger Robot            language=Python;
780*16467b97STreehugger Robot        }
781*16467b97STreehugger Robot        import S7;
782*16467b97STreehugger Robot        B : 'b' ;
783*16467b97STreehugger Robot        WS : (' '|'\n') {self.skip()} ;
784*16467b97STreehugger Robot        ''')
785*16467b97STreehugger Robot
786*16467b97STreehugger Robot        found = self.execLexer(
787*16467b97STreehugger Robot            master,
788*16467b97STreehugger Robot            slaves=[slave],
789*16467b97STreehugger Robot            input="abc"
790*16467b97STreehugger Robot            )
791*16467b97STreehugger Robot
792*16467b97STreehugger Robot        self.failUnlessEqual("S.A abc", found)
793*16467b97STreehugger Robot
794*16467b97STreehugger Robot
795*16467b97STreehugger Robot    def testLexerDelegatorRuleOverridesDelegate(self):
796*16467b97STreehugger Robot        slave = textwrap.dedent(
797*16467b97STreehugger Robot        r'''
798*16467b97STreehugger Robot        lexer grammar S8;
799*16467b97STreehugger Robot        options {
800*16467b97STreehugger Robot            language=Python;
801*16467b97STreehugger Robot        }
802*16467b97STreehugger Robot        @members {
803*16467b97STreehugger Robot            def capture(self, t):
804*16467b97STreehugger Robot                self.gM8.capture(t)
805*16467b97STreehugger Robot        }
806*16467b97STreehugger Robot        A : 'a' {self.capture("S.A")} ;
807*16467b97STreehugger Robot        ''')
808*16467b97STreehugger Robot
809*16467b97STreehugger Robot        master = textwrap.dedent(
810*16467b97STreehugger Robot        r'''
811*16467b97STreehugger Robot        lexer grammar M8;
812*16467b97STreehugger Robot        options {
813*16467b97STreehugger Robot            language=Python;
814*16467b97STreehugger Robot        }
815*16467b97STreehugger Robot        import S8;
816*16467b97STreehugger Robot        A : 'a' {self.capture("M.A ");} ;
817*16467b97STreehugger Robot        WS : (' '|'\n') {self.skip()} ;
818*16467b97STreehugger Robot        ''')
819*16467b97STreehugger Robot
820*16467b97STreehugger Robot        found = self.execLexer(
821*16467b97STreehugger Robot            master,
822*16467b97STreehugger Robot            slaves=[slave],
823*16467b97STreehugger Robot            input="a"
824*16467b97STreehugger Robot            )
825*16467b97STreehugger Robot
826*16467b97STreehugger Robot        self.failUnlessEqual("M.A a", found)
827*16467b97STreehugger Robot
828*16467b97STreehugger Robot        # @Test public void testLexerDelegatorRuleOverridesDelegateLeavingNoRules() throws Exception {
829*16467b97STreehugger Robot        #         // M.Tokens has nothing to predict tokens from S.  Should
830*16467b97STreehugger Robot        #         // not include S.Tokens alt in this case?
831*16467b97STreehugger Robot        #         String slave =
832*16467b97STreehugger Robot        #                 "lexer grammar S;\n" +
833*16467b97STreehugger Robot        #                 "A : 'a' {System.out.println(\"S.A\");} ;\n";
834*16467b97STreehugger Robot        #         mkdir(tmpdir);
835*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
836*16467b97STreehugger Robot        #         String master =
837*16467b97STreehugger Robot        #                 "lexer grammar M;\n" +
838*16467b97STreehugger Robot        #                 "import S;\n" +
839*16467b97STreehugger Robot        #                 "A : 'a' {System.out.println(\"M.A\");} ;\n" +
840*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
841*16467b97STreehugger Robot        #         writeFile(tmpdir, "/M.g", master);
842*16467b97STreehugger Robot
843*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
844*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
845*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
846*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
847*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
848*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
849*16467b97STreehugger Robot        #         g.parseAndBuildAST();
850*16467b97STreehugger Robot        #         composite.assignTokenTypes();
851*16467b97STreehugger Robot        #         composite.defineGrammarSymbols();
852*16467b97STreehugger Robot        #         composite.createNFAs();
853*16467b97STreehugger Robot        #         g.createLookaheadDFAs(false);
854*16467b97STreehugger Robot
855*16467b97STreehugger Robot        #         // predict only alts from M not S
856*16467b97STreehugger Robot        #         String expectingDFA =
857*16467b97STreehugger Robot        #                 ".s0-'a'->.s1\n" +
858*16467b97STreehugger Robot        #                 ".s0-{'\\n', ' '}->:s3=>2\n" +
859*16467b97STreehugger Robot        #                 ".s1-<EOT>->:s2=>1\n";
860*16467b97STreehugger Robot        #         org.antlr.analysis.DFA dfa = g.getLookaheadDFA(1);
861*16467b97STreehugger Robot        #         FASerializer serializer = new FASerializer(g);
862*16467b97STreehugger Robot        #         String result = serializer.serialize(dfa.startState);
863*16467b97STreehugger Robot        #         assertEquals(expectingDFA, result);
864*16467b97STreehugger Robot
865*16467b97STreehugger Robot        #         // must not be a "unreachable alt: Tokens" error
866*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
867*16467b97STreehugger Robot        # }
868*16467b97STreehugger Robot
869*16467b97STreehugger Robot        # @Test public void testInvalidImportMechanism() throws Exception {
870*16467b97STreehugger Robot        #         // M.Tokens has nothing to predict tokens from S.  Should
871*16467b97STreehugger Robot        #         // not include S.Tokens alt in this case?
872*16467b97STreehugger Robot        #         String slave =
873*16467b97STreehugger Robot        #                 "lexer grammar S;\n" +
874*16467b97STreehugger Robot        #                 "A : 'a' {System.out.println(\"S.A\");} ;\n";
875*16467b97STreehugger Robot        #         mkdir(tmpdir);
876*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
877*16467b97STreehugger Robot        #         String master =
878*16467b97STreehugger Robot        #                 "tree grammar M;\n" +
879*16467b97STreehugger Robot        #                 "import S;\n" +
880*16467b97STreehugger Robot        #                 "a : A ;";
881*16467b97STreehugger Robot        #         writeFile(tmpdir, "/M.g", master);
882*16467b97STreehugger Robot
883*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
884*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
885*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
886*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
887*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
888*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
889*16467b97STreehugger Robot        #         g.parseAndBuildAST();
890*16467b97STreehugger Robot
891*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size());
892*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.warnings.size());
893*16467b97STreehugger Robot
894*16467b97STreehugger Robot        #         String expectedError =
895*16467b97STreehugger Robot        #                 "error(161): "+tmpdir.toString().replaceFirst("\\-[0-9]+","")+"/M.g:2:8: tree grammar M cannot import lexer grammar S";
896*16467b97STreehugger Robot        #         assertEquals(expectedError, equeue.errors.get(0).toString().replaceFirst("\\-[0-9]+",""));
897*16467b97STreehugger Robot        # }
898*16467b97STreehugger Robot
899*16467b97STreehugger Robot        # @Test public void testSyntacticPredicateRulesAreNotInherited() throws Exception {
900*16467b97STreehugger Robot        #         // if this compiles, it means that synpred1_S is defined in S.java
901*16467b97STreehugger Robot        #         // but not MParser.java.  MParser has its own synpred1_M which must
902*16467b97STreehugger Robot        #         // be separate to compile.
903*16467b97STreehugger Robot        #         String slave =
904*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
905*16467b97STreehugger Robot        #                 "a : 'a' {System.out.println(\"S.a1\");}\n" +
906*16467b97STreehugger Robot        #                 "  | 'a' {System.out.println(\"S.a2\");}\n" +
907*16467b97STreehugger Robot        #                 "  ;\n" +
908*16467b97STreehugger Robot        #                 "b : 'x' | 'y' {;} ;\n"; // preds generated but not need in DFA here
909*16467b97STreehugger Robot        #         mkdir(tmpdir);
910*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
911*16467b97STreehugger Robot        #         String master =
912*16467b97STreehugger Robot        #                 "grammar M;\n" +
913*16467b97STreehugger Robot        #                 "options {backtrack=true;}\n" +
914*16467b97STreehugger Robot        #                 "import S;\n" +
915*16467b97STreehugger Robot        #                 "start : a b ;\n" +
916*16467b97STreehugger Robot        #                 "nonsense : 'q' | 'q' {;} ;" + // forces def of preds here in M
917*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
918*16467b97STreehugger Robot        #         String found = execParser("M.g", master, "MParser", "MLexer",
919*16467b97STreehugger Robot        #                                                           "start", "ax", debug);
920*16467b97STreehugger Robot        #         assertEquals("S.a1\n", found);
921*16467b97STreehugger Robot        # }
922*16467b97STreehugger Robot
923*16467b97STreehugger Robot        # @Test public void testKeywordVSIDGivesNoWarning() throws Exception {
924*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
925*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
926*16467b97STreehugger Robot        #         String slave =
927*16467b97STreehugger Robot        #                 "lexer grammar S;\n" +
928*16467b97STreehugger Robot        #                 "A : 'abc' {System.out.println(\"S.A\");} ;\n" +
929*16467b97STreehugger Robot        #                 "ID : 'a'..'z'+ ;\n";
930*16467b97STreehugger Robot        #         mkdir(tmpdir);
931*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
932*16467b97STreehugger Robot        #         String master =
933*16467b97STreehugger Robot        #                 "grammar M;\n" +
934*16467b97STreehugger Robot        #                 "import S;\n" +
935*16467b97STreehugger Robot        #                 "a : A {System.out.println(\"M.a\");} ;\n" +
936*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
937*16467b97STreehugger Robot        #         String found = execParser("M.g", master, "MParser", "MLexer",
938*16467b97STreehugger Robot        #                                                           "a", "abc", debug);
939*16467b97STreehugger Robot
940*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
941*16467b97STreehugger Robot        #         assertEquals("unexpected warnings: "+equeue, 0, equeue.warnings.size());
942*16467b97STreehugger Robot
943*16467b97STreehugger Robot        #         assertEquals("S.A\nM.a\n", found);
944*16467b97STreehugger Robot        # }
945*16467b97STreehugger Robot
946*16467b97STreehugger Robot        # @Test public void testWarningForUndefinedToken() throws Exception {
947*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
948*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
949*16467b97STreehugger Robot        #         String slave =
950*16467b97STreehugger Robot        #                 "lexer grammar S;\n" +
951*16467b97STreehugger Robot        #                 "A : 'abc' {System.out.println(\"S.A\");} ;\n";
952*16467b97STreehugger Robot        #         mkdir(tmpdir);
953*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
954*16467b97STreehugger Robot        #         String master =
955*16467b97STreehugger Robot        #                 "grammar M;\n" +
956*16467b97STreehugger Robot        #                 "import S;\n" +
957*16467b97STreehugger Robot        #                 "a : ABC A {System.out.println(\"M.a\");} ;\n" +
958*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
959*16467b97STreehugger Robot        #         // A is defined in S but M should still see it and not give warning.
960*16467b97STreehugger Robot        #         // only problem is ABC.
961*16467b97STreehugger Robot
962*16467b97STreehugger Robot        #         rawGenerateAndBuildRecognizer("M.g", master, "MParser", "MLexer", debug);
963*16467b97STreehugger Robot
964*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
965*16467b97STreehugger Robot        #         assertEquals("unexpected warnings: "+equeue, 1, equeue.warnings.size());
966*16467b97STreehugger Robot
967*16467b97STreehugger Robot        #         String expectedError =
968*16467b97STreehugger Robot        #                 "warning(105): "+tmpdir.toString().replaceFirst("\\-[0-9]+","")+"/M.g:3:5: no lexer rule corresponding to token: ABC";
969*16467b97STreehugger Robot        #         assertEquals(expectedError, equeue.warnings.get(0).toString().replaceFirst("\\-[0-9]+",""));
970*16467b97STreehugger Robot        # }
971*16467b97STreehugger Robot
972*16467b97STreehugger Robot        # /** Make sure that M can import S that imports T. */
973*16467b97STreehugger Robot        # @Test public void test3LevelImport() throws Exception {
974*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
975*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
976*16467b97STreehugger Robot        #         String slave =
977*16467b97STreehugger Robot        #                 "parser grammar T;\n" +
978*16467b97STreehugger Robot        #                 "a : T ;\n" ;
979*16467b97STreehugger Robot        #         mkdir(tmpdir);
980*16467b97STreehugger Robot        #         writeFile(tmpdir, "T.g", slave);
981*16467b97STreehugger Robot        #         String slave2 =
982*16467b97STreehugger Robot        #                 "parser grammar S;\n" + // A, B, C token type order
983*16467b97STreehugger Robot        #                 "import T;\n" +
984*16467b97STreehugger Robot        #                 "a : S ;\n" ;
985*16467b97STreehugger Robot        #         mkdir(tmpdir);
986*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave2);
987*16467b97STreehugger Robot
988*16467b97STreehugger Robot        #         String master =
989*16467b97STreehugger Robot        #                 "grammar M;\n" +
990*16467b97STreehugger Robot        #                 "import S;\n" +
991*16467b97STreehugger Robot        #                 "a : M ;\n" ;
992*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
993*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
994*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
995*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
996*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
997*16467b97STreehugger Robot        #         g.parseAndBuildAST();
998*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
999*16467b97STreehugger Robot        #         g.composite.defineGrammarSymbols();
1000*16467b97STreehugger Robot
1001*16467b97STreehugger Robot        #         String expectedTokenIDToTypeMap = "[M=6, S=5, T=4]";
1002*16467b97STreehugger Robot        #         String expectedStringLiteralToTypeMap = "{}";
1003*16467b97STreehugger Robot        #         String expectedTypeToTokenList = "[T, S, M]";
1004*16467b97STreehugger Robot
1005*16467b97STreehugger Robot        #         assertEquals(expectedTokenIDToTypeMap,
1006*16467b97STreehugger Robot        #                                  realElements(g.composite.tokenIDToTypeMap).toString());
1007*16467b97STreehugger Robot        #         assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
1008*16467b97STreehugger Robot        #         assertEquals(expectedTypeToTokenList,
1009*16467b97STreehugger Robot        #                                  realElements(g.composite.typeToTokenList).toString());
1010*16467b97STreehugger Robot
1011*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1012*16467b97STreehugger Robot
1013*16467b97STreehugger Robot        #         boolean ok =
1014*16467b97STreehugger Robot        #                 rawGenerateAndBuildRecognizer("M.g", master, "MParser", null, false);
1015*16467b97STreehugger Robot        #         boolean expecting = true; // should be ok
1016*16467b97STreehugger Robot        #         assertEquals(expecting, ok);
1017*16467b97STreehugger Robot        # }
1018*16467b97STreehugger Robot
1019*16467b97STreehugger Robot        # @Test public void testBigTreeOfImports() throws Exception {
1020*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
1021*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
1022*16467b97STreehugger Robot        #         String slave =
1023*16467b97STreehugger Robot        #                 "parser grammar T;\n" +
1024*16467b97STreehugger Robot        #                 "x : T ;\n" ;
1025*16467b97STreehugger Robot        #         mkdir(tmpdir);
1026*16467b97STreehugger Robot        #         writeFile(tmpdir, "T.g", slave);
1027*16467b97STreehugger Robot        #         slave =
1028*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
1029*16467b97STreehugger Robot        #                 "import T;\n" +
1030*16467b97STreehugger Robot        #                 "y : S ;\n" ;
1031*16467b97STreehugger Robot        #         mkdir(tmpdir);
1032*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
1033*16467b97STreehugger Robot
1034*16467b97STreehugger Robot        #         slave =
1035*16467b97STreehugger Robot        #                 "parser grammar C;\n" +
1036*16467b97STreehugger Robot        #                 "i : C ;\n" ;
1037*16467b97STreehugger Robot        #         mkdir(tmpdir);
1038*16467b97STreehugger Robot        #         writeFile(tmpdir, "C.g", slave);
1039*16467b97STreehugger Robot        #         slave =
1040*16467b97STreehugger Robot        #                 "parser grammar B;\n" +
1041*16467b97STreehugger Robot        #                 "j : B ;\n" ;
1042*16467b97STreehugger Robot        #         mkdir(tmpdir);
1043*16467b97STreehugger Robot        #         writeFile(tmpdir, "B.g", slave);
1044*16467b97STreehugger Robot        #         slave =
1045*16467b97STreehugger Robot        #                 "parser grammar A;\n" +
1046*16467b97STreehugger Robot        #                 "import B,C;\n" +
1047*16467b97STreehugger Robot        #                 "k : A ;\n" ;
1048*16467b97STreehugger Robot        #         mkdir(tmpdir);
1049*16467b97STreehugger Robot        #         writeFile(tmpdir, "A.g", slave);
1050*16467b97STreehugger Robot
1051*16467b97STreehugger Robot        #         String master =
1052*16467b97STreehugger Robot        #                 "grammar M;\n" +
1053*16467b97STreehugger Robot        #                 "import S,A;\n" +
1054*16467b97STreehugger Robot        #                 "a : M ;\n" ;
1055*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
1056*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
1057*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
1058*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
1059*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
1060*16467b97STreehugger Robot        #         g.parseAndBuildAST();
1061*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
1062*16467b97STreehugger Robot        #         g.composite.defineGrammarSymbols();
1063*16467b97STreehugger Robot
1064*16467b97STreehugger Robot        #         String expectedTokenIDToTypeMap = "[A=8, B=6, C=7, M=9, S=5, T=4]";
1065*16467b97STreehugger Robot        #         String expectedStringLiteralToTypeMap = "{}";
1066*16467b97STreehugger Robot        #         String expectedTypeToTokenList = "[T, S, B, C, A, M]";
1067*16467b97STreehugger Robot
1068*16467b97STreehugger Robot        #         assertEquals(expectedTokenIDToTypeMap,
1069*16467b97STreehugger Robot        #                                  realElements(g.composite.tokenIDToTypeMap).toString());
1070*16467b97STreehugger Robot        #         assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
1071*16467b97STreehugger Robot        #         assertEquals(expectedTypeToTokenList,
1072*16467b97STreehugger Robot        #                                  realElements(g.composite.typeToTokenList).toString());
1073*16467b97STreehugger Robot
1074*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1075*16467b97STreehugger Robot
1076*16467b97STreehugger Robot        #         boolean ok =
1077*16467b97STreehugger Robot        #                 rawGenerateAndBuildRecognizer("M.g", master, "MParser", null, false);
1078*16467b97STreehugger Robot        #         boolean expecting = true; // should be ok
1079*16467b97STreehugger Robot        #         assertEquals(expecting, ok);
1080*16467b97STreehugger Robot        # }
1081*16467b97STreehugger Robot
1082*16467b97STreehugger Robot        # @Test public void testRulesVisibleThroughMultilevelImport() throws Exception {
1083*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
1084*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
1085*16467b97STreehugger Robot        #         String slave =
1086*16467b97STreehugger Robot        #                 "parser grammar T;\n" +
1087*16467b97STreehugger Robot        #                 "x : T ;\n" ;
1088*16467b97STreehugger Robot        #         mkdir(tmpdir);
1089*16467b97STreehugger Robot        #         writeFile(tmpdir, "T.g", slave);
1090*16467b97STreehugger Robot        #         String slave2 =
1091*16467b97STreehugger Robot        #                 "parser grammar S;\n" + // A, B, C token type order
1092*16467b97STreehugger Robot        #                 "import T;\n" +
1093*16467b97STreehugger Robot        #                 "a : S ;\n" ;
1094*16467b97STreehugger Robot        #         mkdir(tmpdir);
1095*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave2);
1096*16467b97STreehugger Robot
1097*16467b97STreehugger Robot        #         String master =
1098*16467b97STreehugger Robot        #                 "grammar M;\n" +
1099*16467b97STreehugger Robot        #                 "import S;\n" +
1100*16467b97STreehugger Robot        #                 "a : M x ;\n" ; // x MUST BE VISIBLE TO M
1101*16467b97STreehugger Robot        #         writeFile(tmpdir, "M.g", master);
1102*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
1103*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
1104*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
1105*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
1106*16467b97STreehugger Robot        #         g.parseAndBuildAST();
1107*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
1108*16467b97STreehugger Robot        #         g.composite.defineGrammarSymbols();
1109*16467b97STreehugger Robot
1110*16467b97STreehugger Robot        #         String expectedTokenIDToTypeMap = "[M=6, S=5, T=4]";
1111*16467b97STreehugger Robot        #         String expectedStringLiteralToTypeMap = "{}";
1112*16467b97STreehugger Robot        #         String expectedTypeToTokenList = "[T, S, M]";
1113*16467b97STreehugger Robot
1114*16467b97STreehugger Robot        #         assertEquals(expectedTokenIDToTypeMap,
1115*16467b97STreehugger Robot        #                                  realElements(g.composite.tokenIDToTypeMap).toString());
1116*16467b97STreehugger Robot        #         assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
1117*16467b97STreehugger Robot        #         assertEquals(expectedTypeToTokenList,
1118*16467b97STreehugger Robot        #                                  realElements(g.composite.typeToTokenList).toString());
1119*16467b97STreehugger Robot
1120*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1121*16467b97STreehugger Robot        # }
1122*16467b97STreehugger Robot
1123*16467b97STreehugger Robot        # @Test public void testNestedComposite() throws Exception {
1124*16467b97STreehugger Robot        #         // Wasn't compiling. http://www.antlr.org/jira/browse/ANTLR-438
1125*16467b97STreehugger Robot        #         ErrorQueue equeue = new ErrorQueue();
1126*16467b97STreehugger Robot        #         ErrorManager.setErrorListener(equeue);
1127*16467b97STreehugger Robot        #         String gstr =
1128*16467b97STreehugger Robot        #                 "lexer grammar L;\n" +
1129*16467b97STreehugger Robot        #                 "T1: '1';\n" +
1130*16467b97STreehugger Robot        #                 "T2: '2';\n" +
1131*16467b97STreehugger Robot        #                 "T3: '3';\n" +
1132*16467b97STreehugger Robot        #                 "T4: '4';\n" ;
1133*16467b97STreehugger Robot        #         mkdir(tmpdir);
1134*16467b97STreehugger Robot        #         writeFile(tmpdir, "L.g", gstr);
1135*16467b97STreehugger Robot        #         gstr =
1136*16467b97STreehugger Robot        #                 "parser grammar G1;\n" +
1137*16467b97STreehugger Robot        #                 "s: a | b;\n" +
1138*16467b97STreehugger Robot        #                 "a: T1;\n" +
1139*16467b97STreehugger Robot        #                 "b: T2;\n" ;
1140*16467b97STreehugger Robot        #         mkdir(tmpdir);
1141*16467b97STreehugger Robot        #         writeFile(tmpdir, "G1.g", gstr);
1142*16467b97STreehugger Robot
1143*16467b97STreehugger Robot        #         gstr =
1144*16467b97STreehugger Robot        #                 "parser grammar G2;\n" +
1145*16467b97STreehugger Robot        #                 "import G1;\n" +
1146*16467b97STreehugger Robot        #                 "a: T3;\n" ;
1147*16467b97STreehugger Robot        #         mkdir(tmpdir);
1148*16467b97STreehugger Robot        #         writeFile(tmpdir, "G2.g", gstr);
1149*16467b97STreehugger Robot        #         String G3str =
1150*16467b97STreehugger Robot        #                 "grammar G3;\n" +
1151*16467b97STreehugger Robot        #                 "import G2;\n" +
1152*16467b97STreehugger Robot        #                 "b: T4;\n" ;
1153*16467b97STreehugger Robot        #         mkdir(tmpdir);
1154*16467b97STreehugger Robot        #         writeFile(tmpdir, "G3.g", G3str);
1155*16467b97STreehugger Robot
1156*16467b97STreehugger Robot        #         Tool antlr = newTool(new String[] {"-lib", tmpdir});
1157*16467b97STreehugger Robot        #         CompositeGrammar composite = new CompositeGrammar();
1158*16467b97STreehugger Robot        #         Grammar g = new Grammar(antlr,tmpdir+"/G3.g",composite);
1159*16467b97STreehugger Robot        #         composite.setDelegationRoot(g);
1160*16467b97STreehugger Robot        #         g.parseAndBuildAST();
1161*16467b97STreehugger Robot        #         g.composite.assignTokenTypes();
1162*16467b97STreehugger Robot        #         g.composite.defineGrammarSymbols();
1163*16467b97STreehugger Robot
1164*16467b97STreehugger Robot        #         String expectedTokenIDToTypeMap = "[T1=4, T2=5, T3=6, T4=7]";
1165*16467b97STreehugger Robot        #         String expectedStringLiteralToTypeMap = "{}";
1166*16467b97STreehugger Robot        #         String expectedTypeToTokenList = "[T1, T2, T3, T4]";
1167*16467b97STreehugger Robot
1168*16467b97STreehugger Robot        #         assertEquals(expectedTokenIDToTypeMap,
1169*16467b97STreehugger Robot        #                                  realElements(g.composite.tokenIDToTypeMap).toString());
1170*16467b97STreehugger Robot        #         assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
1171*16467b97STreehugger Robot        #         assertEquals(expectedTypeToTokenList,
1172*16467b97STreehugger Robot        #                                  realElements(g.composite.typeToTokenList).toString());
1173*16467b97STreehugger Robot
1174*16467b97STreehugger Robot        #         assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
1175*16467b97STreehugger Robot
1176*16467b97STreehugger Robot        #         boolean ok =
1177*16467b97STreehugger Robot        #                 rawGenerateAndBuildRecognizer("G3.g", G3str, "G3Parser", null, false);
1178*16467b97STreehugger Robot        #         boolean expecting = true; // should be ok
1179*16467b97STreehugger Robot        #         assertEquals(expecting, ok);
1180*16467b97STreehugger Robot        # }
1181*16467b97STreehugger Robot
1182*16467b97STreehugger Robot        # @Test public void testHeadersPropogatedCorrectlyToImportedGrammars() throws Exception {
1183*16467b97STreehugger Robot        #         String slave =
1184*16467b97STreehugger Robot        #                 "parser grammar S;\n" +
1185*16467b97STreehugger Robot        #                 "a : B {System.out.print(\"S.a\");} ;\n";
1186*16467b97STreehugger Robot        #         mkdir(tmpdir);
1187*16467b97STreehugger Robot        #         writeFile(tmpdir, "S.g", slave);
1188*16467b97STreehugger Robot        #         String master =
1189*16467b97STreehugger Robot        #                 "grammar M;\n" +
1190*16467b97STreehugger Robot        #                 "import S;\n" +
1191*16467b97STreehugger Robot        #                 "@header{package mypackage;}\n" +
1192*16467b97STreehugger Robot        #                 "@lexer::header{package mypackage;}\n" +
1193*16467b97STreehugger Robot        #                 "s : a ;\n" +
1194*16467b97STreehugger Robot        #                 "B : 'b' ;" + // defines B from inherited token space
1195*16467b97STreehugger Robot        #                 "WS : (' '|'\\n') {skip();} ;\n" ;
1196*16467b97STreehugger Robot        #         boolean ok = antlr("M.g", "M.g", master, debug);
1197*16467b97STreehugger Robot        #         boolean expecting = true; // should be ok
1198*16467b97STreehugger Robot        #         assertEquals(expecting, ok);
1199*16467b97STreehugger Robot        # }
1200*16467b97STreehugger Robot
1201*16467b97STreehugger Robot
1202*16467b97STreehugger Robotif __name__ == '__main__':
1203*16467b97STreehugger Robot    unittest.main()
1204