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 TestAutoAST(testbase.ANTLRTest): 9*16467b97STreehugger Robot def parserClass(self, base): 10*16467b97STreehugger Robot class TParser(base): 11*16467b97STreehugger Robot def __init__(self, *args, **kwargs): 12*16467b97STreehugger Robot super().__init__(*args, **kwargs) 13*16467b97STreehugger Robot 14*16467b97STreehugger Robot self._errors = [] 15*16467b97STreehugger Robot self._output = "" 16*16467b97STreehugger Robot 17*16467b97STreehugger Robot 18*16467b97STreehugger Robot def capture(self, t): 19*16467b97STreehugger Robot self._output += t 20*16467b97STreehugger Robot 21*16467b97STreehugger Robot 22*16467b97STreehugger Robot def traceIn(self, ruleName, ruleIndex): 23*16467b97STreehugger Robot self.traces.append('>'+ruleName) 24*16467b97STreehugger Robot 25*16467b97STreehugger Robot 26*16467b97STreehugger Robot def traceOut(self, ruleName, ruleIndex): 27*16467b97STreehugger Robot self.traces.append('<'+ruleName) 28*16467b97STreehugger Robot 29*16467b97STreehugger Robot 30*16467b97STreehugger Robot def emitErrorMessage(self, msg): 31*16467b97STreehugger Robot self._errors.append(msg) 32*16467b97STreehugger Robot 33*16467b97STreehugger Robot 34*16467b97STreehugger Robot return TParser 35*16467b97STreehugger Robot 36*16467b97STreehugger Robot 37*16467b97STreehugger Robot def lexerClass(self, base): 38*16467b97STreehugger Robot class TLexer(base): 39*16467b97STreehugger Robot def __init__(self, *args, **kwargs): 40*16467b97STreehugger Robot super().__init__(*args, **kwargs) 41*16467b97STreehugger Robot 42*16467b97STreehugger Robot self._output = "" 43*16467b97STreehugger Robot 44*16467b97STreehugger Robot 45*16467b97STreehugger Robot def capture(self, t): 46*16467b97STreehugger Robot self._output += t 47*16467b97STreehugger Robot 48*16467b97STreehugger Robot 49*16467b97STreehugger Robot def traceIn(self, ruleName, ruleIndex): 50*16467b97STreehugger Robot self.traces.append('>'+ruleName) 51*16467b97STreehugger Robot 52*16467b97STreehugger Robot 53*16467b97STreehugger Robot def traceOut(self, ruleName, ruleIndex): 54*16467b97STreehugger Robot self.traces.append('<'+ruleName) 55*16467b97STreehugger Robot 56*16467b97STreehugger Robot 57*16467b97STreehugger Robot def recover(self, input, re): 58*16467b97STreehugger Robot # no error recovery yet, just crash! 59*16467b97STreehugger Robot raise 60*16467b97STreehugger Robot 61*16467b97STreehugger Robot return TLexer 62*16467b97STreehugger Robot 63*16467b97STreehugger Robot 64*16467b97STreehugger Robot def execParser(self, grammar, grammarEntry, input, expectErrors=False): 65*16467b97STreehugger Robot lexerCls, parserCls = self.compileInlineGrammar(grammar) 66*16467b97STreehugger Robot 67*16467b97STreehugger Robot cStream = antlr3.StringStream(input) 68*16467b97STreehugger Robot lexer = lexerCls(cStream) 69*16467b97STreehugger Robot tStream = antlr3.CommonTokenStream(lexer) 70*16467b97STreehugger Robot parser = parserCls(tStream) 71*16467b97STreehugger Robot r = getattr(parser, grammarEntry)() 72*16467b97STreehugger Robot 73*16467b97STreehugger Robot if not expectErrors: 74*16467b97STreehugger Robot self.assertEqual(len(parser._errors), 0, parser._errors) 75*16467b97STreehugger Robot 76*16467b97STreehugger Robot result = "" 77*16467b97STreehugger Robot 78*16467b97STreehugger Robot if r: 79*16467b97STreehugger Robot if hasattr(r, 'result'): 80*16467b97STreehugger Robot result += r.result 81*16467b97STreehugger Robot 82*16467b97STreehugger Robot if r.tree: 83*16467b97STreehugger Robot result += r.tree.toStringTree() 84*16467b97STreehugger Robot 85*16467b97STreehugger Robot if not expectErrors: 86*16467b97STreehugger Robot return result 87*16467b97STreehugger Robot 88*16467b97STreehugger Robot else: 89*16467b97STreehugger Robot return result, parser._errors 90*16467b97STreehugger Robot 91*16467b97STreehugger Robot 92*16467b97STreehugger Robot def execTreeParser(self, grammar, grammarEntry, treeGrammar, treeEntry, input): 93*16467b97STreehugger Robot lexerCls, parserCls = self.compileInlineGrammar(grammar) 94*16467b97STreehugger Robot walkerCls = self.compileInlineGrammar(treeGrammar) 95*16467b97STreehugger Robot 96*16467b97STreehugger Robot cStream = antlr3.StringStream(input) 97*16467b97STreehugger Robot lexer = lexerCls(cStream) 98*16467b97STreehugger Robot tStream = antlr3.CommonTokenStream(lexer) 99*16467b97STreehugger Robot parser = parserCls(tStream) 100*16467b97STreehugger Robot r = getattr(parser, grammarEntry)() 101*16467b97STreehugger Robot nodes = antlr3.tree.CommonTreeNodeStream(r.tree) 102*16467b97STreehugger Robot nodes.setTokenStream(tStream) 103*16467b97STreehugger Robot walker = walkerCls(nodes) 104*16467b97STreehugger Robot r = getattr(walker, treeEntry)() 105*16467b97STreehugger Robot 106*16467b97STreehugger Robot if r: 107*16467b97STreehugger Robot return r.tree.toStringTree() 108*16467b97STreehugger Robot 109*16467b97STreehugger Robot return "" 110*16467b97STreehugger Robot 111*16467b97STreehugger Robot 112*16467b97STreehugger Robot def testTokenList(self): 113*16467b97STreehugger Robot grammar = textwrap.dedent( 114*16467b97STreehugger Robot r''' 115*16467b97STreehugger Robot grammar foo; 116*16467b97STreehugger Robot options {language=Python3;output=AST;} 117*16467b97STreehugger Robot a : ID INT ; 118*16467b97STreehugger Robot ID : 'a'..'z'+ ; 119*16467b97STreehugger Robot INT : '0'..'9'+; 120*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN}; 121*16467b97STreehugger Robot ''') 122*16467b97STreehugger Robot 123*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc 34") 124*16467b97STreehugger Robot self.assertEqual("abc 34", found); 125*16467b97STreehugger Robot 126*16467b97STreehugger Robot 127*16467b97STreehugger Robot def testTokenListInSingleAltBlock(self): 128*16467b97STreehugger Robot grammar = textwrap.dedent( 129*16467b97STreehugger Robot r''' 130*16467b97STreehugger Robot grammar foo; 131*16467b97STreehugger Robot options {language=Python3;output=AST;} 132*16467b97STreehugger Robot a : (ID INT) ; 133*16467b97STreehugger Robot ID : 'a'..'z'+ ; 134*16467b97STreehugger Robot INT : '0'..'9'+; 135*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 136*16467b97STreehugger Robot ''') 137*16467b97STreehugger Robot 138*16467b97STreehugger Robot found = self.execParser(grammar,"a", "abc 34") 139*16467b97STreehugger Robot self.assertEqual("abc 34", found) 140*16467b97STreehugger Robot 141*16467b97STreehugger Robot 142*16467b97STreehugger Robot def testSimpleRootAtOuterLevel(self): 143*16467b97STreehugger Robot grammar = textwrap.dedent( 144*16467b97STreehugger Robot r''' 145*16467b97STreehugger Robot grammar foo; 146*16467b97STreehugger Robot options {language=Python3;output=AST;} 147*16467b97STreehugger Robot a : ID^ INT ; 148*16467b97STreehugger Robot ID : 'a'..'z'+ ; 149*16467b97STreehugger Robot INT : '0'..'9'+; 150*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 151*16467b97STreehugger Robot ''') 152*16467b97STreehugger Robot 153*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc 34") 154*16467b97STreehugger Robot self.assertEqual("(abc 34)", found) 155*16467b97STreehugger Robot 156*16467b97STreehugger Robot 157*16467b97STreehugger Robot def testSimpleRootAtOuterLevelReverse(self): 158*16467b97STreehugger Robot grammar = textwrap.dedent( 159*16467b97STreehugger Robot r''' 160*16467b97STreehugger Robot grammar T; 161*16467b97STreehugger Robot options {language=Python3;output=AST;} 162*16467b97STreehugger Robot a : INT ID^ ; 163*16467b97STreehugger Robot ID : 'a'..'z'+ ; 164*16467b97STreehugger Robot INT : '0'..'9'+; 165*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 166*16467b97STreehugger Robot ''') 167*16467b97STreehugger Robot 168*16467b97STreehugger Robot found = self.execParser(grammar, "a", "34 abc") 169*16467b97STreehugger Robot self.assertEqual("(abc 34)", found) 170*16467b97STreehugger Robot 171*16467b97STreehugger Robot 172*16467b97STreehugger Robot def testBang(self): 173*16467b97STreehugger Robot grammar = textwrap.dedent( 174*16467b97STreehugger Robot r''' 175*16467b97STreehugger Robot grammar T; 176*16467b97STreehugger Robot options {language=Python3;output=AST;} 177*16467b97STreehugger Robot a : ID INT! ID! INT ; 178*16467b97STreehugger Robot ID : 'a'..'z'+ ; 179*16467b97STreehugger Robot INT : '0'..'9'+; 180*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 181*16467b97STreehugger Robot ''') 182*16467b97STreehugger Robot 183*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc 34 dag 4532") 184*16467b97STreehugger Robot self.assertEqual("abc 4532", found) 185*16467b97STreehugger Robot 186*16467b97STreehugger Robot 187*16467b97STreehugger Robot def testOptionalThenRoot(self): 188*16467b97STreehugger Robot grammar = textwrap.dedent( 189*16467b97STreehugger Robot r''' 190*16467b97STreehugger Robot grammar T; 191*16467b97STreehugger Robot options {language=Python3;output=AST;} 192*16467b97STreehugger Robot a : ( ID INT )? ID^ ; 193*16467b97STreehugger Robot ID : 'a'..'z'+ ; 194*16467b97STreehugger Robot INT : '0'..'9'+; 195*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 196*16467b97STreehugger Robot ''') 197*16467b97STreehugger Robot 198*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 1 b") 199*16467b97STreehugger Robot self.assertEqual("(b a 1)", found) 200*16467b97STreehugger Robot 201*16467b97STreehugger Robot 202*16467b97STreehugger Robot def testLabeledStringRoot(self): 203*16467b97STreehugger Robot grammar = textwrap.dedent( 204*16467b97STreehugger Robot r''' 205*16467b97STreehugger Robot grammar T; 206*16467b97STreehugger Robot options {language=Python3;output=AST;} 207*16467b97STreehugger Robot a : v='void'^ ID ';' ; 208*16467b97STreehugger Robot ID : 'a'..'z'+ ; 209*16467b97STreehugger Robot INT : '0'..'9'+; 210*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 211*16467b97STreehugger Robot ''') 212*16467b97STreehugger Robot 213*16467b97STreehugger Robot found = self.execParser(grammar, "a", "void foo;") 214*16467b97STreehugger Robot self.assertEqual("(void foo ;)", found) 215*16467b97STreehugger Robot 216*16467b97STreehugger Robot 217*16467b97STreehugger Robot def testWildcard(self): 218*16467b97STreehugger Robot grammar = textwrap.dedent( 219*16467b97STreehugger Robot r''' 220*16467b97STreehugger Robot grammar T; 221*16467b97STreehugger Robot options {language=Python3;output=AST;} 222*16467b97STreehugger Robot a : v='void'^ . ';' ; 223*16467b97STreehugger Robot ID : 'a'..'z'+ ; 224*16467b97STreehugger Robot INT : '0'..'9'+; 225*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 226*16467b97STreehugger Robot ''') 227*16467b97STreehugger Robot 228*16467b97STreehugger Robot found = self.execParser(grammar, "a", "void foo;") 229*16467b97STreehugger Robot self.assertEqual("(void foo ;)", found) 230*16467b97STreehugger Robot 231*16467b97STreehugger Robot 232*16467b97STreehugger Robot def testWildcardRoot(self): 233*16467b97STreehugger Robot grammar = textwrap.dedent( 234*16467b97STreehugger Robot r''' 235*16467b97STreehugger Robot grammar T; 236*16467b97STreehugger Robot options {language=Python3;output=AST;} 237*16467b97STreehugger Robot a : v='void' .^ ';' ; 238*16467b97STreehugger Robot ID : 'a'..'z'+ ; 239*16467b97STreehugger Robot INT : '0'..'9'+; 240*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 241*16467b97STreehugger Robot ''') 242*16467b97STreehugger Robot 243*16467b97STreehugger Robot found = self.execParser(grammar, "a", "void foo;") 244*16467b97STreehugger Robot self.assertEqual("(foo void ;)", found) 245*16467b97STreehugger Robot 246*16467b97STreehugger Robot 247*16467b97STreehugger Robot def testWildcardRootWithLabel(self): 248*16467b97STreehugger Robot grammar = textwrap.dedent( 249*16467b97STreehugger Robot r''' 250*16467b97STreehugger Robot grammar T; 251*16467b97STreehugger Robot options {language=Python3;output=AST;} 252*16467b97STreehugger Robot a : v='void' x=.^ ';' ; 253*16467b97STreehugger Robot ID : 'a'..'z'+ ; 254*16467b97STreehugger Robot INT : '0'..'9'+; 255*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 256*16467b97STreehugger Robot ''') 257*16467b97STreehugger Robot 258*16467b97STreehugger Robot found = self.execParser(grammar, "a", "void foo;") 259*16467b97STreehugger Robot self.assertEqual("(foo void ;)", found) 260*16467b97STreehugger Robot 261*16467b97STreehugger Robot 262*16467b97STreehugger Robot def testWildcardRootWithListLabel(self): 263*16467b97STreehugger Robot grammar = textwrap.dedent( 264*16467b97STreehugger Robot r''' 265*16467b97STreehugger Robot grammar T; 266*16467b97STreehugger Robot options {language=Python3;output=AST;} 267*16467b97STreehugger Robot a : v='void' x=.^ ';' ; 268*16467b97STreehugger Robot ID : 'a'..'z'+ ; 269*16467b97STreehugger Robot INT : '0'..'9'+; 270*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 271*16467b97STreehugger Robot ''') 272*16467b97STreehugger Robot 273*16467b97STreehugger Robot found = self.execParser(grammar, "a", "void foo;") 274*16467b97STreehugger Robot self.assertEqual("(foo void ;)", found) 275*16467b97STreehugger Robot 276*16467b97STreehugger Robot 277*16467b97STreehugger Robot def testWildcardBangWithListLabel(self): 278*16467b97STreehugger Robot grammar = textwrap.dedent( 279*16467b97STreehugger Robot r''' 280*16467b97STreehugger Robot grammar T; 281*16467b97STreehugger Robot options {language=Python3;output=AST;} 282*16467b97STreehugger Robot a : v='void' x=.! ';' ; 283*16467b97STreehugger Robot ID : 'a'..'z'+ ; 284*16467b97STreehugger Robot INT : '0'..'9'+; 285*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 286*16467b97STreehugger Robot ''') 287*16467b97STreehugger Robot 288*16467b97STreehugger Robot found = self.execParser(grammar, "a", "void foo;") 289*16467b97STreehugger Robot self.assertEqual("void ;", found) 290*16467b97STreehugger Robot 291*16467b97STreehugger Robot 292*16467b97STreehugger Robot def testRootRoot(self): 293*16467b97STreehugger Robot grammar = textwrap.dedent( 294*16467b97STreehugger Robot r''' 295*16467b97STreehugger Robot grammar T; 296*16467b97STreehugger Robot options {language=Python3;output=AST;} 297*16467b97STreehugger Robot a : ID^ INT^ ID ; 298*16467b97STreehugger Robot ID : 'a'..'z'+ ; 299*16467b97STreehugger Robot INT : '0'..'9'+; 300*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 301*16467b97STreehugger Robot ''') 302*16467b97STreehugger Robot 303*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 34 c") 304*16467b97STreehugger Robot self.assertEqual("(34 a c)", found) 305*16467b97STreehugger Robot 306*16467b97STreehugger Robot 307*16467b97STreehugger Robot def testRootRoot2(self): 308*16467b97STreehugger Robot grammar = textwrap.dedent( 309*16467b97STreehugger Robot r''' 310*16467b97STreehugger Robot grammar T; 311*16467b97STreehugger Robot options {language=Python3;output=AST;} 312*16467b97STreehugger Robot a : ID INT^ ID^ ; 313*16467b97STreehugger Robot ID : 'a'..'z'+ ; 314*16467b97STreehugger Robot INT : '0'..'9'+; 315*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 316*16467b97STreehugger Robot ''') 317*16467b97STreehugger Robot 318*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 34 c") 319*16467b97STreehugger Robot self.assertEqual("(c (34 a))", found) 320*16467b97STreehugger Robot 321*16467b97STreehugger Robot 322*16467b97STreehugger Robot def testRootThenRootInLoop(self): 323*16467b97STreehugger Robot grammar = textwrap.dedent( 324*16467b97STreehugger Robot r''' 325*16467b97STreehugger Robot grammar T; 326*16467b97STreehugger Robot options {language=Python3;output=AST;} 327*16467b97STreehugger Robot a : ID^ (INT '*'^ ID)+ ; 328*16467b97STreehugger Robot ID : 'a'..'z'+ ; 329*16467b97STreehugger Robot INT : '0'..'9'+; 330*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 331*16467b97STreehugger Robot ''') 332*16467b97STreehugger Robot 333*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 34 * b 9 * c") 334*16467b97STreehugger Robot self.assertEqual("(* (* (a 34) b 9) c)", found) 335*16467b97STreehugger Robot 336*16467b97STreehugger Robot 337*16467b97STreehugger Robot def testNestedSubrule(self): 338*16467b97STreehugger Robot grammar = textwrap.dedent( 339*16467b97STreehugger Robot r''' 340*16467b97STreehugger Robot grammar T; 341*16467b97STreehugger Robot options {language=Python3;output=AST;} 342*16467b97STreehugger Robot a : 'void' (({pass}ID|INT) ID | 'null' ) ';' ; 343*16467b97STreehugger Robot ID : 'a'..'z'+ ; 344*16467b97STreehugger Robot INT : '0'..'9'+; 345*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 346*16467b97STreehugger Robot ''') 347*16467b97STreehugger Robot 348*16467b97STreehugger Robot found = self.execParser(grammar, "a", "void a b;") 349*16467b97STreehugger Robot self.assertEqual("void a b ;", found) 350*16467b97STreehugger Robot 351*16467b97STreehugger Robot 352*16467b97STreehugger Robot def testInvokeRule(self): 353*16467b97STreehugger Robot grammar = textwrap.dedent( 354*16467b97STreehugger Robot r''' 355*16467b97STreehugger Robot grammar T; 356*16467b97STreehugger Robot options {language=Python3;output=AST;} 357*16467b97STreehugger Robot a : type ID ; 358*16467b97STreehugger Robot type : {pass}'int' | 'float' ; 359*16467b97STreehugger Robot ID : 'a'..'z'+ ; 360*16467b97STreehugger Robot INT : '0'..'9'+; 361*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 362*16467b97STreehugger Robot ''') 363*16467b97STreehugger Robot 364*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a") 365*16467b97STreehugger Robot self.assertEqual("int a", found) 366*16467b97STreehugger Robot 367*16467b97STreehugger Robot 368*16467b97STreehugger Robot def testInvokeRuleAsRoot(self): 369*16467b97STreehugger Robot grammar = textwrap.dedent( 370*16467b97STreehugger Robot r''' 371*16467b97STreehugger Robot grammar T; 372*16467b97STreehugger Robot options {language=Python3;output=AST;} 373*16467b97STreehugger Robot a : type^ ID ; 374*16467b97STreehugger Robot type : {pass}'int' | 'float' ; 375*16467b97STreehugger Robot ID : 'a'..'z'+ ; 376*16467b97STreehugger Robot INT : '0'..'9'+; 377*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 378*16467b97STreehugger Robot ''') 379*16467b97STreehugger Robot 380*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a") 381*16467b97STreehugger Robot self.assertEqual("(int a)", found) 382*16467b97STreehugger Robot 383*16467b97STreehugger Robot 384*16467b97STreehugger Robot def testInvokeRuleAsRootWithLabel(self): 385*16467b97STreehugger Robot grammar = textwrap.dedent( 386*16467b97STreehugger Robot r''' 387*16467b97STreehugger Robot grammar T; 388*16467b97STreehugger Robot options {language=Python3;output=AST;} 389*16467b97STreehugger Robot a : x=type^ ID ; 390*16467b97STreehugger Robot type : {pass}'int' | 'float' ; 391*16467b97STreehugger Robot ID : 'a'..'z'+ ; 392*16467b97STreehugger Robot INT : '0'..'9'+; 393*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 394*16467b97STreehugger Robot ''') 395*16467b97STreehugger Robot 396*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a") 397*16467b97STreehugger Robot self.assertEqual("(int a)", found) 398*16467b97STreehugger Robot 399*16467b97STreehugger Robot 400*16467b97STreehugger Robot def testInvokeRuleAsRootWithListLabel(self): 401*16467b97STreehugger Robot grammar = textwrap.dedent( 402*16467b97STreehugger Robot r''' 403*16467b97STreehugger Robot grammar T; 404*16467b97STreehugger Robot options {language=Python3;output=AST;} 405*16467b97STreehugger Robot a : x+=type^ ID ; 406*16467b97STreehugger Robot type : {pass}'int' | 'float' ; 407*16467b97STreehugger Robot ID : 'a'..'z'+ ; 408*16467b97STreehugger Robot INT : '0'..'9'+; 409*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 410*16467b97STreehugger Robot ''') 411*16467b97STreehugger Robot 412*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a") 413*16467b97STreehugger Robot self.assertEqual("(int a)", found) 414*16467b97STreehugger Robot 415*16467b97STreehugger Robot 416*16467b97STreehugger Robot def testRuleRootInLoop(self): 417*16467b97STreehugger Robot grammar = textwrap.dedent( 418*16467b97STreehugger Robot r''' 419*16467b97STreehugger Robot grammar T; 420*16467b97STreehugger Robot options {language=Python3;output=AST;} 421*16467b97STreehugger Robot a : ID ('+'^ ID)* ; 422*16467b97STreehugger Robot ID : 'a'..'z'+ ; 423*16467b97STreehugger Robot INT : '0'..'9'+; 424*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 425*16467b97STreehugger Robot ''') 426*16467b97STreehugger Robot 427*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a+b+c+d") 428*16467b97STreehugger Robot self.assertEqual("(+ (+ (+ a b) c) d)", found) 429*16467b97STreehugger Robot 430*16467b97STreehugger Robot 431*16467b97STreehugger Robot def testRuleInvocationRuleRootInLoop(self): 432*16467b97STreehugger Robot grammar = textwrap.dedent( 433*16467b97STreehugger Robot r''' 434*16467b97STreehugger Robot grammar T; 435*16467b97STreehugger Robot options {language=Python3;output=AST;} 436*16467b97STreehugger Robot a : ID (op^ ID)* ; 437*16467b97STreehugger Robot op : {pass}'+' | '-' ; 438*16467b97STreehugger Robot ID : 'a'..'z'+ ; 439*16467b97STreehugger Robot INT : '0'..'9'+; 440*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 441*16467b97STreehugger Robot ''') 442*16467b97STreehugger Robot 443*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a+b+c-d") 444*16467b97STreehugger Robot self.assertEqual("(- (+ (+ a b) c) d)", found) 445*16467b97STreehugger Robot 446*16467b97STreehugger Robot 447*16467b97STreehugger Robot def testTailRecursion(self): 448*16467b97STreehugger Robot grammar = textwrap.dedent( 449*16467b97STreehugger Robot r''' 450*16467b97STreehugger Robot grammar T; 451*16467b97STreehugger Robot options {language=Python3;output=AST;} 452*16467b97STreehugger Robot s : a ; 453*16467b97STreehugger Robot a : atom ('exp'^ a)? ; 454*16467b97STreehugger Robot atom : INT ; 455*16467b97STreehugger Robot ID : 'a'..'z'+ ; 456*16467b97STreehugger Robot INT : '0'..'9'+; 457*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 458*16467b97STreehugger Robot ''') 459*16467b97STreehugger Robot 460*16467b97STreehugger Robot found = self.execParser(grammar, "s", "3 exp 4 exp 5") 461*16467b97STreehugger Robot self.assertEqual("(exp 3 (exp 4 5))", found) 462*16467b97STreehugger Robot 463*16467b97STreehugger Robot 464*16467b97STreehugger Robot def testSet(self): 465*16467b97STreehugger Robot grammar = textwrap.dedent( 466*16467b97STreehugger Robot r''' 467*16467b97STreehugger Robot grammar T; 468*16467b97STreehugger Robot options {language=Python3;output=AST;} 469*16467b97STreehugger Robot a : ID|INT ; 470*16467b97STreehugger Robot ID : 'a'..'z'+ ; 471*16467b97STreehugger Robot INT : '0'..'9'+; 472*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 473*16467b97STreehugger Robot ''') 474*16467b97STreehugger Robot 475*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc") 476*16467b97STreehugger Robot self.assertEqual("abc", found) 477*16467b97STreehugger Robot 478*16467b97STreehugger Robot 479*16467b97STreehugger Robot def testSetRoot(self): 480*16467b97STreehugger Robot grammar = textwrap.dedent( 481*16467b97STreehugger Robot r''' 482*16467b97STreehugger Robot grammar T; 483*16467b97STreehugger Robot options {language=Python3;output=AST;} 484*16467b97STreehugger Robot a : ('+' | '-')^ ID ; 485*16467b97STreehugger Robot ID : 'a'..'z'+ ; 486*16467b97STreehugger Robot INT : '0'..'9'+; 487*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 488*16467b97STreehugger Robot ''') 489*16467b97STreehugger Robot 490*16467b97STreehugger Robot found = self.execParser(grammar, "a", "+abc") 491*16467b97STreehugger Robot self.assertEqual("(+ abc)", found) 492*16467b97STreehugger Robot 493*16467b97STreehugger Robot 494*16467b97STreehugger Robot @testbase.broken( 495*16467b97STreehugger Robot "FAILS until antlr.g rebuilt in v3", testbase.GrammarCompileError) 496*16467b97STreehugger Robot def testSetRootWithLabel(self): 497*16467b97STreehugger Robot grammar = textwrap.dedent( 498*16467b97STreehugger Robot r''' 499*16467b97STreehugger Robot grammar T; 500*16467b97STreehugger Robot options {language=Python3;output=AST;} 501*16467b97STreehugger Robot a : x=('+' | '-')^ ID ; 502*16467b97STreehugger Robot ID : 'a'..'z'+ ; 503*16467b97STreehugger Robot INT : '0'..'9'+; 504*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 505*16467b97STreehugger Robot ''') 506*16467b97STreehugger Robot 507*16467b97STreehugger Robot found = self.execParser(grammar, "a", "+abc") 508*16467b97STreehugger Robot self.assertEqual("(+ abc)", found) 509*16467b97STreehugger Robot 510*16467b97STreehugger Robot 511*16467b97STreehugger Robot def testSetAsRuleRootInLoop(self): 512*16467b97STreehugger Robot grammar = textwrap.dedent( 513*16467b97STreehugger Robot r''' 514*16467b97STreehugger Robot grammar T; 515*16467b97STreehugger Robot options {language=Python3;output=AST;} 516*16467b97STreehugger Robot a : ID (('+'|'-')^ ID)* ; 517*16467b97STreehugger Robot ID : 'a'..'z'+ ; 518*16467b97STreehugger Robot INT : '0'..'9'+; 519*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 520*16467b97STreehugger Robot ''') 521*16467b97STreehugger Robot 522*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a+b-c") 523*16467b97STreehugger Robot self.assertEqual("(- (+ a b) c)", found) 524*16467b97STreehugger Robot 525*16467b97STreehugger Robot 526*16467b97STreehugger Robot def testNotSet(self): 527*16467b97STreehugger Robot grammar = textwrap.dedent( 528*16467b97STreehugger Robot r''' 529*16467b97STreehugger Robot grammar T; 530*16467b97STreehugger Robot options {language=Python3;output=AST;} 531*16467b97STreehugger Robot a : ~ID '+' INT ; 532*16467b97STreehugger Robot ID : 'a'..'z'+ ; 533*16467b97STreehugger Robot INT : '0'..'9'+; 534*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 535*16467b97STreehugger Robot ''') 536*16467b97STreehugger Robot 537*16467b97STreehugger Robot found = self.execParser(grammar, "a", "34+2") 538*16467b97STreehugger Robot self.assertEqual("34 + 2", found) 539*16467b97STreehugger Robot 540*16467b97STreehugger Robot 541*16467b97STreehugger Robot def testNotSetWithLabel(self): 542*16467b97STreehugger Robot grammar = textwrap.dedent( 543*16467b97STreehugger Robot r''' 544*16467b97STreehugger Robot grammar T; 545*16467b97STreehugger Robot options {language=Python3;output=AST;} 546*16467b97STreehugger Robot a : x=~ID '+' INT ; 547*16467b97STreehugger Robot ID : 'a'..'z'+ ; 548*16467b97STreehugger Robot INT : '0'..'9'+; 549*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 550*16467b97STreehugger Robot ''') 551*16467b97STreehugger Robot 552*16467b97STreehugger Robot found = self.execParser(grammar, "a", "34+2") 553*16467b97STreehugger Robot self.assertEqual("34 + 2", found) 554*16467b97STreehugger Robot 555*16467b97STreehugger Robot 556*16467b97STreehugger Robot def testNotSetWithListLabel(self): 557*16467b97STreehugger Robot grammar = textwrap.dedent( 558*16467b97STreehugger Robot r''' 559*16467b97STreehugger Robot grammar T; 560*16467b97STreehugger Robot options {language=Python3;output=AST;} 561*16467b97STreehugger Robot a : x=~ID '+' INT ; 562*16467b97STreehugger Robot ID : 'a'..'z'+ ; 563*16467b97STreehugger Robot INT : '0'..'9'+; 564*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 565*16467b97STreehugger Robot ''') 566*16467b97STreehugger Robot 567*16467b97STreehugger Robot found = self.execParser(grammar, "a", "34+2") 568*16467b97STreehugger Robot self.assertEqual("34 + 2", found) 569*16467b97STreehugger Robot 570*16467b97STreehugger Robot 571*16467b97STreehugger Robot def testNotSetRoot(self): 572*16467b97STreehugger Robot grammar = textwrap.dedent( 573*16467b97STreehugger Robot r''' 574*16467b97STreehugger Robot grammar T; 575*16467b97STreehugger Robot options {language=Python3;output=AST;} 576*16467b97STreehugger Robot a : ~'+'^ INT ; 577*16467b97STreehugger Robot ID : 'a'..'z'+ ; 578*16467b97STreehugger Robot INT : '0'..'9'+; 579*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 580*16467b97STreehugger Robot ''') 581*16467b97STreehugger Robot 582*16467b97STreehugger Robot found = self.execParser(grammar, "a", "34 55") 583*16467b97STreehugger Robot self.assertEqual("(34 55)", found) 584*16467b97STreehugger Robot 585*16467b97STreehugger Robot 586*16467b97STreehugger Robot def testNotSetRootWithLabel(self): 587*16467b97STreehugger Robot grammar = textwrap.dedent( 588*16467b97STreehugger Robot r''' 589*16467b97STreehugger Robot grammar T; 590*16467b97STreehugger Robot options {language=Python3;output=AST;} 591*16467b97STreehugger Robot a : ~'+'^ INT ; 592*16467b97STreehugger Robot ID : 'a'..'z'+ ; 593*16467b97STreehugger Robot INT : '0'..'9'+; 594*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 595*16467b97STreehugger Robot ''') 596*16467b97STreehugger Robot 597*16467b97STreehugger Robot found = self.execParser(grammar, "a", "34 55") 598*16467b97STreehugger Robot self.assertEqual("(34 55)", found) 599*16467b97STreehugger Robot 600*16467b97STreehugger Robot 601*16467b97STreehugger Robot def testNotSetRootWithListLabel(self): 602*16467b97STreehugger Robot grammar = textwrap.dedent( 603*16467b97STreehugger Robot r''' 604*16467b97STreehugger Robot grammar T; 605*16467b97STreehugger Robot options {language=Python3;output=AST;} 606*16467b97STreehugger Robot a : ~'+'^ INT ; 607*16467b97STreehugger Robot ID : 'a'..'z'+ ; 608*16467b97STreehugger Robot INT : '0'..'9'+; 609*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 610*16467b97STreehugger Robot ''') 611*16467b97STreehugger Robot 612*16467b97STreehugger Robot found = self.execParser(grammar, "a", "34 55") 613*16467b97STreehugger Robot self.assertEqual("(34 55)", found) 614*16467b97STreehugger Robot 615*16467b97STreehugger Robot 616*16467b97STreehugger Robot def testNotSetRuleRootInLoop(self): 617*16467b97STreehugger Robot grammar = textwrap.dedent( 618*16467b97STreehugger Robot r''' 619*16467b97STreehugger Robot grammar T; 620*16467b97STreehugger Robot options {language=Python3;output=AST;} 621*16467b97STreehugger Robot a : INT (~INT^ INT)* ; 622*16467b97STreehugger Robot blort : '+' ; 623*16467b97STreehugger Robot ID : 'a'..'z'+ ; 624*16467b97STreehugger Robot INT : '0'..'9'+; 625*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 626*16467b97STreehugger Robot ''') 627*16467b97STreehugger Robot 628*16467b97STreehugger Robot found = self.execParser(grammar, "a", "3+4+5") 629*16467b97STreehugger Robot self.assertEqual("(+ (+ 3 4) 5)", found) 630*16467b97STreehugger Robot 631*16467b97STreehugger Robot 632*16467b97STreehugger Robot @testbase.broken("FIXME: What happened to the semicolon?", AssertionError) 633*16467b97STreehugger Robot def testTokenLabelReuse(self): 634*16467b97STreehugger Robot # check for compilation problem due to multiple defines 635*16467b97STreehugger Robot grammar = textwrap.dedent( 636*16467b97STreehugger Robot r''' 637*16467b97STreehugger Robot grammar T; 638*16467b97STreehugger Robot options {language=Python3;output=AST;} 639*16467b97STreehugger Robot a returns [result] : id=ID id=ID {$result = "2nd id="+$id.text+";"} ; 640*16467b97STreehugger Robot ID : 'a'..'z'+ ; 641*16467b97STreehugger Robot INT : '0'..'9'+; 642*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 643*16467b97STreehugger Robot ''') 644*16467b97STreehugger Robot 645*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 646*16467b97STreehugger Robot self.assertEqual("2nd id=b;a b", found) 647*16467b97STreehugger Robot 648*16467b97STreehugger Robot 649*16467b97STreehugger Robot def testTokenLabelReuse2(self): 650*16467b97STreehugger Robot # check for compilation problem due to multiple defines 651*16467b97STreehugger Robot grammar = textwrap.dedent( 652*16467b97STreehugger Robot r''' 653*16467b97STreehugger Robot grammar T; 654*16467b97STreehugger Robot options {language=Python3;output=AST;} 655*16467b97STreehugger Robot a returns [result]: id=ID id=ID^ {$result = "2nd id="+$id.text+','} ; 656*16467b97STreehugger Robot ID : 'a'..'z'+ ; 657*16467b97STreehugger Robot INT : '0'..'9'+; 658*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 659*16467b97STreehugger Robot ''') 660*16467b97STreehugger Robot 661*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 662*16467b97STreehugger Robot self.assertEqual("2nd id=b,(b a)", found) 663*16467b97STreehugger Robot 664*16467b97STreehugger Robot 665*16467b97STreehugger Robot def testTokenListLabelReuse(self): 666*16467b97STreehugger Robot # check for compilation problem due to multiple defines 667*16467b97STreehugger Robot # make sure ids has both ID tokens 668*16467b97STreehugger Robot grammar = textwrap.dedent( 669*16467b97STreehugger Robot r''' 670*16467b97STreehugger Robot grammar T; 671*16467b97STreehugger Robot options {language=Python3;output=AST;} 672*16467b97STreehugger Robot a returns [result] : ids+=ID ids+=ID {$result = "id list=[{}],".format(",".join([t.text for t in $ids]))} ; 673*16467b97STreehugger Robot ID : 'a'..'z'+ ; 674*16467b97STreehugger Robot INT : '0'..'9'+; 675*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 676*16467b97STreehugger Robot ''') 677*16467b97STreehugger Robot 678*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 679*16467b97STreehugger Robot expecting = "id list=[a,b],a b" 680*16467b97STreehugger Robot self.assertEqual(expecting, found) 681*16467b97STreehugger Robot 682*16467b97STreehugger Robot 683*16467b97STreehugger Robot def testTokenListLabelReuse2(self): 684*16467b97STreehugger Robot # check for compilation problem due to multiple defines 685*16467b97STreehugger Robot # make sure ids has both ID tokens 686*16467b97STreehugger Robot grammar = textwrap.dedent( 687*16467b97STreehugger Robot r''' 688*16467b97STreehugger Robot grammar T; 689*16467b97STreehugger Robot options {language=Python3;output=AST;} 690*16467b97STreehugger Robot a returns [result] : ids+=ID^ ids+=ID {$result = "id list=[{}],".format(",".join([t.text for t in $ids]))} ; 691*16467b97STreehugger Robot ID : 'a'..'z'+ ; 692*16467b97STreehugger Robot INT : '0'..'9'+; 693*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 694*16467b97STreehugger Robot ''') 695*16467b97STreehugger Robot 696*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 697*16467b97STreehugger Robot expecting = "id list=[a,b],(a b)" 698*16467b97STreehugger Robot self.assertEqual(expecting, found) 699*16467b97STreehugger Robot 700*16467b97STreehugger Robot 701*16467b97STreehugger Robot def testTokenListLabelRuleRoot(self): 702*16467b97STreehugger Robot grammar = textwrap.dedent( 703*16467b97STreehugger Robot r''' 704*16467b97STreehugger Robot grammar T; 705*16467b97STreehugger Robot options {language=Python3;output=AST;} 706*16467b97STreehugger Robot a : id+=ID^ ; 707*16467b97STreehugger Robot ID : 'a'..'z'+ ; 708*16467b97STreehugger Robot INT : '0'..'9'+; 709*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 710*16467b97STreehugger Robot ''') 711*16467b97STreehugger Robot 712*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 713*16467b97STreehugger Robot self.assertEqual("a", found) 714*16467b97STreehugger Robot 715*16467b97STreehugger Robot 716*16467b97STreehugger Robot def testTokenListLabelBang(self): 717*16467b97STreehugger Robot grammar = textwrap.dedent( 718*16467b97STreehugger Robot r''' 719*16467b97STreehugger Robot grammar T; 720*16467b97STreehugger Robot options {language=Python3;output=AST;} 721*16467b97STreehugger Robot a : id+=ID! ; 722*16467b97STreehugger Robot ID : 'a'..'z'+ ; 723*16467b97STreehugger Robot INT : '0'..'9'+; 724*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 725*16467b97STreehugger Robot ''') 726*16467b97STreehugger Robot 727*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 728*16467b97STreehugger Robot self.assertEqual("", found) 729*16467b97STreehugger Robot 730*16467b97STreehugger Robot 731*16467b97STreehugger Robot def testRuleListLabel(self): 732*16467b97STreehugger Robot grammar = textwrap.dedent( 733*16467b97STreehugger Robot r''' 734*16467b97STreehugger Robot grammar T; 735*16467b97STreehugger Robot options {language=Python3;output=AST;} 736*16467b97STreehugger Robot a returns [result]: x+=b x+=b { 737*16467b97STreehugger Robot t=$x[1] 738*16467b97STreehugger Robot $result = "2nd x="+t.toStringTree()+','; 739*16467b97STreehugger Robot }; 740*16467b97STreehugger Robot b : ID; 741*16467b97STreehugger Robot ID : 'a'..'z'+ ; 742*16467b97STreehugger Robot INT : '0'..'9'+; 743*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 744*16467b97STreehugger Robot ''') 745*16467b97STreehugger Robot 746*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 747*16467b97STreehugger Robot self.assertEqual("2nd x=b,a b", found) 748*16467b97STreehugger Robot 749*16467b97STreehugger Robot 750*16467b97STreehugger Robot def testRuleListLabelRuleRoot(self): 751*16467b97STreehugger Robot grammar = textwrap.dedent( 752*16467b97STreehugger Robot r''' 753*16467b97STreehugger Robot grammar T; 754*16467b97STreehugger Robot options {language=Python3;output=AST;} 755*16467b97STreehugger Robot a returns [result] : ( x+=b^ )+ { 756*16467b97STreehugger Robot $result = "x="+$x[1].toStringTree()+','; 757*16467b97STreehugger Robot } ; 758*16467b97STreehugger Robot b : ID; 759*16467b97STreehugger Robot ID : 'a'..'z'+ ; 760*16467b97STreehugger Robot INT : '0'..'9'+; 761*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 762*16467b97STreehugger Robot ''') 763*16467b97STreehugger Robot 764*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 765*16467b97STreehugger Robot self.assertEqual("x=(b a),(b a)", found) 766*16467b97STreehugger Robot 767*16467b97STreehugger Robot 768*16467b97STreehugger Robot def testRuleListLabelBang(self): 769*16467b97STreehugger Robot grammar = textwrap.dedent( 770*16467b97STreehugger Robot r''' 771*16467b97STreehugger Robot grammar T; 772*16467b97STreehugger Robot options {language=Python3;output=AST;} 773*16467b97STreehugger Robot a returns [result] : x+=b! x+=b { 774*16467b97STreehugger Robot $result = "1st x="+$x[0].toStringTree()+','; 775*16467b97STreehugger Robot } ; 776*16467b97STreehugger Robot b : ID; 777*16467b97STreehugger Robot ID : 'a'..'z'+ ; 778*16467b97STreehugger Robot INT : '0'..'9'+; 779*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 780*16467b97STreehugger Robot ''') 781*16467b97STreehugger Robot 782*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 783*16467b97STreehugger Robot self.assertEqual("1st x=a,b", found) 784*16467b97STreehugger Robot 785*16467b97STreehugger Robot 786*16467b97STreehugger Robot def testComplicatedMelange(self): 787*16467b97STreehugger Robot # check for compilation problem 788*16467b97STreehugger Robot grammar = textwrap.dedent( 789*16467b97STreehugger Robot r''' 790*16467b97STreehugger Robot grammar T; 791*16467b97STreehugger Robot options {language=Python3;output=AST;} 792*16467b97STreehugger Robot a : A b=B b=B c+=C c+=C D {s = $D.text} ; 793*16467b97STreehugger Robot A : 'a' ; 794*16467b97STreehugger Robot B : 'b' ; 795*16467b97STreehugger Robot C : 'c' ; 796*16467b97STreehugger Robot D : 'd' ; 797*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 798*16467b97STreehugger Robot ''') 799*16467b97STreehugger Robot 800*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b b c c d") 801*16467b97STreehugger Robot self.assertEqual("a b b c c d", found) 802*16467b97STreehugger Robot 803*16467b97STreehugger Robot 804*16467b97STreehugger Robot def testReturnValueWithAST(self): 805*16467b97STreehugger Robot grammar = textwrap.dedent( 806*16467b97STreehugger Robot r''' 807*16467b97STreehugger Robot grammar foo; 808*16467b97STreehugger Robot options {language=Python3;output=AST;} 809*16467b97STreehugger Robot a returns [result] : ID b { $result = str($b.i) + '\n';} ; 810*16467b97STreehugger Robot b returns [i] : INT {$i=int($INT.text);} ; 811*16467b97STreehugger Robot ID : 'a'..'z'+ ; 812*16467b97STreehugger Robot INT : '0'..'9'+; 813*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 814*16467b97STreehugger Robot ''') 815*16467b97STreehugger Robot 816*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc 34") 817*16467b97STreehugger Robot self.assertEqual("34\nabc 34", found) 818*16467b97STreehugger Robot 819*16467b97STreehugger Robot 820*16467b97STreehugger Robot def testSetLoop(self): 821*16467b97STreehugger Robot grammar = textwrap.dedent( 822*16467b97STreehugger Robot r''' 823*16467b97STreehugger Robot grammar T; 824*16467b97STreehugger Robot options { language=Python3;output=AST; } 825*16467b97STreehugger Robot r : (INT|ID)+ ; 826*16467b97STreehugger Robot ID : 'a'..'z' + ; 827*16467b97STreehugger Robot INT : '0'..'9' +; 828*16467b97STreehugger Robot WS: (' ' | '\n' | '\\t')+ {$channel = HIDDEN}; 829*16467b97STreehugger Robot ''') 830*16467b97STreehugger Robot 831*16467b97STreehugger Robot found = self.execParser(grammar, "r", "abc 34 d") 832*16467b97STreehugger Robot self.assertEqual("abc 34 d", found) 833*16467b97STreehugger Robot 834*16467b97STreehugger Robot 835*16467b97STreehugger Robot def testExtraTokenInSimpleDecl(self): 836*16467b97STreehugger Robot grammar = textwrap.dedent( 837*16467b97STreehugger Robot r''' 838*16467b97STreehugger Robot grammar foo; 839*16467b97STreehugger Robot options {language=Python3;output=AST;} 840*16467b97STreehugger Robot decl : type^ ID '='! INT ';'! ; 841*16467b97STreehugger Robot type : 'int' | 'float' ; 842*16467b97STreehugger Robot ID : 'a'..'z'+ ; 843*16467b97STreehugger Robot INT : '0'..'9'+; 844*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 845*16467b97STreehugger Robot ''') 846*16467b97STreehugger Robot 847*16467b97STreehugger Robot found, errors = self.execParser(grammar, "decl", "int 34 x=1;", 848*16467b97STreehugger Robot expectErrors=True) 849*16467b97STreehugger Robot self.assertEqual(["line 1:4 extraneous input '34' expecting ID"], 850*16467b97STreehugger Robot errors) 851*16467b97STreehugger Robot self.assertEqual("(int x 1)", found) # tree gets correct x and 1 tokens 852*16467b97STreehugger Robot 853*16467b97STreehugger Robot 854*16467b97STreehugger Robot def testMissingIDInSimpleDecl(self): 855*16467b97STreehugger Robot grammar = textwrap.dedent( 856*16467b97STreehugger Robot r''' 857*16467b97STreehugger Robot grammar foo; 858*16467b97STreehugger Robot options {language=Python3;output=AST;} 859*16467b97STreehugger Robot tokens {EXPR;} 860*16467b97STreehugger Robot decl : type^ ID '='! INT ';'! ; 861*16467b97STreehugger Robot type : 'int' | 'float' ; 862*16467b97STreehugger Robot ID : 'a'..'z'+ ; 863*16467b97STreehugger Robot INT : '0'..'9'+; 864*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 865*16467b97STreehugger Robot ''') 866*16467b97STreehugger Robot 867*16467b97STreehugger Robot found, errors = self.execParser(grammar, "decl", "int =1;", 868*16467b97STreehugger Robot expectErrors=True) 869*16467b97STreehugger Robot self.assertEqual(["line 1:4 missing ID at '='"], errors) 870*16467b97STreehugger Robot self.assertEqual("(int <missing ID> 1)", found) # tree gets invented ID token 871*16467b97STreehugger Robot 872*16467b97STreehugger Robot 873*16467b97STreehugger Robot def testMissingSetInSimpleDecl(self): 874*16467b97STreehugger Robot grammar = textwrap.dedent( 875*16467b97STreehugger Robot r''' 876*16467b97STreehugger Robot grammar foo; 877*16467b97STreehugger Robot options {language=Python3;output=AST;} 878*16467b97STreehugger Robot tokens {EXPR;} 879*16467b97STreehugger Robot decl : type^ ID '='! INT ';'! ; 880*16467b97STreehugger Robot type : 'int' | 'float' ; 881*16467b97STreehugger Robot ID : 'a'..'z'+ ; 882*16467b97STreehugger Robot INT : '0'..'9'+; 883*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 884*16467b97STreehugger Robot ''') 885*16467b97STreehugger Robot 886*16467b97STreehugger Robot found, errors = self.execParser(grammar, "decl", "x=1;", 887*16467b97STreehugger Robot expectErrors=True) 888*16467b97STreehugger Robot self.assertEqual(["line 1:0 mismatched input 'x' expecting set None"], errors) 889*16467b97STreehugger Robot self.assertEqual("(<error: x> x 1)", found) # tree gets invented ID token 890*16467b97STreehugger Robot 891*16467b97STreehugger Robot 892*16467b97STreehugger Robot def testMissingTokenGivesErrorNode(self): 893*16467b97STreehugger Robot grammar = textwrap.dedent( 894*16467b97STreehugger Robot r''' 895*16467b97STreehugger Robot grammar foo; 896*16467b97STreehugger Robot options {language=Python3;output=AST;} 897*16467b97STreehugger Robot a : ID INT ; // follow is EOF 898*16467b97STreehugger Robot ID : 'a'..'z'+ ; 899*16467b97STreehugger Robot INT : '0'..'9'+; 900*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 901*16467b97STreehugger Robot ''') 902*16467b97STreehugger Robot 903*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "abc", expectErrors=True) 904*16467b97STreehugger Robot self.assertEqual(["line 1:3 missing INT at '<EOF>'"], errors) 905*16467b97STreehugger Robot self.assertEqual("abc <missing INT>", found) 906*16467b97STreehugger Robot 907*16467b97STreehugger Robot 908*16467b97STreehugger Robot def testMissingTokenGivesErrorNodeInInvokedRule(self): 909*16467b97STreehugger Robot grammar = textwrap.dedent( 910*16467b97STreehugger Robot r''' 911*16467b97STreehugger Robot grammar foo; 912*16467b97STreehugger Robot options {language=Python3;output=AST;} 913*16467b97STreehugger Robot a : b ; 914*16467b97STreehugger Robot b : ID INT ; // follow should see EOF 915*16467b97STreehugger Robot ID : 'a'..'z'+ ; 916*16467b97STreehugger Robot INT : '0'..'9'+; 917*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 918*16467b97STreehugger Robot ''') 919*16467b97STreehugger Robot 920*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "abc", expectErrors=True) 921*16467b97STreehugger Robot self.assertEqual(["line 1:3 mismatched input '<EOF>' expecting INT"], errors) 922*16467b97STreehugger Robot self.assertEqual("<mismatched token: <EOF>, resync=abc>", found) 923*16467b97STreehugger Robot 924*16467b97STreehugger Robot 925*16467b97STreehugger Robot def testExtraTokenGivesErrorNode(self): 926*16467b97STreehugger Robot grammar = textwrap.dedent( 927*16467b97STreehugger Robot r''' 928*16467b97STreehugger Robot grammar foo; 929*16467b97STreehugger Robot options {language=Python3;output=AST;} 930*16467b97STreehugger Robot a : b c ; 931*16467b97STreehugger Robot b : ID ; 932*16467b97STreehugger Robot c : INT ; 933*16467b97STreehugger Robot ID : 'a'..'z'+ ; 934*16467b97STreehugger Robot INT : '0'..'9'+; 935*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 936*16467b97STreehugger Robot ''') 937*16467b97STreehugger Robot 938*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "abc ick 34", 939*16467b97STreehugger Robot expectErrors=True) 940*16467b97STreehugger Robot self.assertEqual(["line 1:4 extraneous input 'ick' expecting INT"], 941*16467b97STreehugger Robot errors) 942*16467b97STreehugger Robot self.assertEqual("abc 34", found) 943*16467b97STreehugger Robot 944*16467b97STreehugger Robot 945*16467b97STreehugger Robot def testMissingFirstTokenGivesErrorNode(self): 946*16467b97STreehugger Robot grammar = textwrap.dedent( 947*16467b97STreehugger Robot r''' 948*16467b97STreehugger Robot grammar foo; 949*16467b97STreehugger Robot options {language=Python3;output=AST;} 950*16467b97STreehugger Robot a : ID INT ; 951*16467b97STreehugger Robot ID : 'a'..'z'+ ; 952*16467b97STreehugger Robot INT : '0'..'9'+; 953*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 954*16467b97STreehugger Robot ''') 955*16467b97STreehugger Robot 956*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "34", expectErrors=True) 957*16467b97STreehugger Robot self.assertEqual(["line 1:0 missing ID at '34'"], errors) 958*16467b97STreehugger Robot self.assertEqual("<missing ID> 34", found) 959*16467b97STreehugger Robot 960*16467b97STreehugger Robot 961*16467b97STreehugger Robot def testMissingFirstTokenGivesErrorNode2(self): 962*16467b97STreehugger Robot grammar = textwrap.dedent( 963*16467b97STreehugger Robot r''' 964*16467b97STreehugger Robot grammar foo; 965*16467b97STreehugger Robot options {language=Python3;output=AST;} 966*16467b97STreehugger Robot a : b c ; 967*16467b97STreehugger Robot b : ID ; 968*16467b97STreehugger Robot c : INT ; 969*16467b97STreehugger Robot ID : 'a'..'z'+ ; 970*16467b97STreehugger Robot INT : '0'..'9'+; 971*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 972*16467b97STreehugger Robot ''') 973*16467b97STreehugger Robot 974*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "34", expectErrors=True) 975*16467b97STreehugger Robot 976*16467b97STreehugger Robot # finds an error at the first token, 34, and re-syncs. 977*16467b97STreehugger Robot # re-synchronizing does not consume a token because 34 follows 978*16467b97STreehugger Robot # ref to rule b (start of c). It then matches 34 in c. 979*16467b97STreehugger Robot self.assertEqual(["line 1:0 missing ID at '34'"], errors) 980*16467b97STreehugger Robot self.assertEqual("<missing ID> 34", found) 981*16467b97STreehugger Robot 982*16467b97STreehugger Robot 983*16467b97STreehugger Robot def testNoViableAltGivesErrorNode(self): 984*16467b97STreehugger Robot grammar = textwrap.dedent( 985*16467b97STreehugger Robot r''' 986*16467b97STreehugger Robot grammar foo; 987*16467b97STreehugger Robot options {language=Python3;output=AST;} 988*16467b97STreehugger Robot a : b | c ; 989*16467b97STreehugger Robot b : ID ; 990*16467b97STreehugger Robot c : INT ; 991*16467b97STreehugger Robot ID : 'a'..'z'+ ; 992*16467b97STreehugger Robot S : '*' ; 993*16467b97STreehugger Robot INT : '0'..'9'+; 994*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN} ; 995*16467b97STreehugger Robot ''') 996*16467b97STreehugger Robot 997*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "*", expectErrors=True) 998*16467b97STreehugger Robot self.assertEqual(["line 1:0 no viable alternative at input '*'"], 999*16467b97STreehugger Robot errors) 1000*16467b97STreehugger Robot self.assertEqual("<unexpected: [@0,0:0='*',<S>,1:0], resync=*>", 1001*16467b97STreehugger Robot found) 1002*16467b97STreehugger Robot 1003*16467b97STreehugger Robot 1004*16467b97STreehugger Robotif __name__ == '__main__': 1005*16467b97STreehugger Robot unittest.main() 1006