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