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 TestRewriteAST(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 base.__init__(self, *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 base.__init__(self, *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.assertEquals(len(parser._errors), 0, parser._errors) 75*16467b97STreehugger Robot 76*16467b97STreehugger Robot result = "" 77*16467b97STreehugger Robot 78*16467b97STreehugger Robot if r is not None: 79*16467b97STreehugger Robot if hasattr(r, 'result'): 80*16467b97STreehugger Robot result += r.result 81*16467b97STreehugger Robot 82*16467b97STreehugger Robot if r.tree is not None: 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 is not None: 107*16467b97STreehugger Robot return r.tree.toStringTree() 108*16467b97STreehugger Robot 109*16467b97STreehugger Robot return "" 110*16467b97STreehugger Robot 111*16467b97STreehugger Robot 112*16467b97STreehugger Robot def testDelete(self): 113*16467b97STreehugger Robot grammar = textwrap.dedent( 114*16467b97STreehugger Robot r''' 115*16467b97STreehugger Robot grammar T; 116*16467b97STreehugger Robot options {language=Python;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.assertEquals("", found) 125*16467b97STreehugger Robot 126*16467b97STreehugger Robot 127*16467b97STreehugger Robot def testSingleToken(self): 128*16467b97STreehugger Robot grammar = textwrap.dedent( 129*16467b97STreehugger Robot r''' 130*16467b97STreehugger Robot grammar T; 131*16467b97STreehugger Robot options {language=Python;output=AST;} 132*16467b97STreehugger Robot a : ID -> ID; 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") 139*16467b97STreehugger Robot self.assertEquals("abc", found) 140*16467b97STreehugger Robot 141*16467b97STreehugger Robot 142*16467b97STreehugger Robot def testSingleTokenToNewNode(self): 143*16467b97STreehugger Robot grammar = textwrap.dedent( 144*16467b97STreehugger Robot r''' 145*16467b97STreehugger Robot grammar T; 146*16467b97STreehugger Robot options {language=Python;output=AST;} 147*16467b97STreehugger Robot a : ID -> ID["x"]; 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") 154*16467b97STreehugger Robot self.assertEquals("x", found) 155*16467b97STreehugger Robot 156*16467b97STreehugger Robot 157*16467b97STreehugger Robot def testSingleTokenToNewNodeRoot(self): 158*16467b97STreehugger Robot grammar = textwrap.dedent( 159*16467b97STreehugger Robot r''' 160*16467b97STreehugger Robot grammar T; 161*16467b97STreehugger Robot options {language=Python;output=AST;} 162*16467b97STreehugger Robot a : ID -> ^(ID["x"] INT); 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", "abc") 169*16467b97STreehugger Robot self.assertEquals("(x INT)", found) 170*16467b97STreehugger Robot 171*16467b97STreehugger Robot 172*16467b97STreehugger Robot def testSingleTokenToNewNode2(self): 173*16467b97STreehugger Robot # Allow creation of new nodes w/o args. 174*16467b97STreehugger Robot grammar = textwrap.dedent( 175*16467b97STreehugger Robot r''' 176*16467b97STreehugger Robot grammar TT; 177*16467b97STreehugger Robot options {language=Python;output=AST;} 178*16467b97STreehugger Robot a : ID -> ID[ ]; 179*16467b97STreehugger Robot ID : 'a'..'z'+ ; 180*16467b97STreehugger Robot INT : '0'..'9'+; 181*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 182*16467b97STreehugger Robot ''') 183*16467b97STreehugger Robot 184*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc") 185*16467b97STreehugger Robot self.assertEquals("ID", found) 186*16467b97STreehugger Robot 187*16467b97STreehugger Robot 188*16467b97STreehugger Robot def testSingleCharLiteral(self): 189*16467b97STreehugger Robot grammar = textwrap.dedent( 190*16467b97STreehugger Robot r''' 191*16467b97STreehugger Robot grammar T; 192*16467b97STreehugger Robot options {language=Python;output=AST;} 193*16467b97STreehugger Robot a : 'c' -> 'c'; 194*16467b97STreehugger Robot ID : 'a'..'z'+ ; 195*16467b97STreehugger Robot INT : '0'..'9'+; 196*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 197*16467b97STreehugger Robot ''') 198*16467b97STreehugger Robot 199*16467b97STreehugger Robot found = self.execParser(grammar, "a", "c") 200*16467b97STreehugger Robot self.assertEquals("c", found) 201*16467b97STreehugger Robot 202*16467b97STreehugger Robot 203*16467b97STreehugger Robot def testSingleStringLiteral(self): 204*16467b97STreehugger Robot grammar = textwrap.dedent( 205*16467b97STreehugger Robot r''' 206*16467b97STreehugger Robot grammar T; 207*16467b97STreehugger Robot options {language=Python;output=AST;} 208*16467b97STreehugger Robot a : 'ick' -> 'ick'; 209*16467b97STreehugger Robot ID : 'a'..'z'+ ; 210*16467b97STreehugger Robot INT : '0'..'9'+; 211*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 212*16467b97STreehugger Robot ''') 213*16467b97STreehugger Robot 214*16467b97STreehugger Robot found = self.execParser(grammar, "a", "ick") 215*16467b97STreehugger Robot self.assertEquals("ick", found) 216*16467b97STreehugger Robot 217*16467b97STreehugger Robot 218*16467b97STreehugger Robot def testSingleRule(self): 219*16467b97STreehugger Robot grammar = textwrap.dedent( 220*16467b97STreehugger Robot r''' 221*16467b97STreehugger Robot grammar T; 222*16467b97STreehugger Robot options {language=Python;output=AST;} 223*16467b97STreehugger Robot a : b -> b; 224*16467b97STreehugger Robot b : ID ; 225*16467b97STreehugger Robot ID : 'a'..'z'+ ; 226*16467b97STreehugger Robot INT : '0'..'9'+; 227*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 228*16467b97STreehugger Robot ''') 229*16467b97STreehugger Robot 230*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc") 231*16467b97STreehugger Robot self.assertEquals("abc", found) 232*16467b97STreehugger Robot 233*16467b97STreehugger Robot 234*16467b97STreehugger Robot def testReorderTokens(self): 235*16467b97STreehugger Robot grammar = textwrap.dedent( 236*16467b97STreehugger Robot r''' 237*16467b97STreehugger Robot grammar T; 238*16467b97STreehugger Robot options {language=Python;output=AST;} 239*16467b97STreehugger Robot a : ID INT -> INT ID; 240*16467b97STreehugger Robot ID : 'a'..'z'+ ; 241*16467b97STreehugger Robot INT : '0'..'9'+; 242*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 243*16467b97STreehugger Robot ''') 244*16467b97STreehugger Robot 245*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc 34") 246*16467b97STreehugger Robot self.assertEquals("34 abc", found) 247*16467b97STreehugger Robot 248*16467b97STreehugger Robot 249*16467b97STreehugger Robot def testReorderTokenAndRule(self): 250*16467b97STreehugger Robot grammar = textwrap.dedent( 251*16467b97STreehugger Robot r''' 252*16467b97STreehugger Robot grammar T; 253*16467b97STreehugger Robot options {language=Python;output=AST;} 254*16467b97STreehugger Robot a : b INT -> INT b; 255*16467b97STreehugger Robot b : ID ; 256*16467b97STreehugger Robot ID : 'a'..'z'+ ; 257*16467b97STreehugger Robot INT : '0'..'9'+; 258*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 259*16467b97STreehugger Robot ''') 260*16467b97STreehugger Robot 261*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc 34") 262*16467b97STreehugger Robot self.assertEquals("34 abc", found) 263*16467b97STreehugger Robot 264*16467b97STreehugger Robot 265*16467b97STreehugger Robot def testTokenTree(self): 266*16467b97STreehugger Robot grammar = textwrap.dedent( 267*16467b97STreehugger Robot r''' 268*16467b97STreehugger Robot grammar T; 269*16467b97STreehugger Robot options {language=Python;output=AST;} 270*16467b97STreehugger Robot a : ID INT -> ^(INT ID); 271*16467b97STreehugger Robot ID : 'a'..'z'+ ; 272*16467b97STreehugger Robot INT : '0'..'9'+; 273*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 274*16467b97STreehugger Robot ''') 275*16467b97STreehugger Robot 276*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc 34") 277*16467b97STreehugger Robot self.assertEquals("(34 abc)", found) 278*16467b97STreehugger Robot 279*16467b97STreehugger Robot 280*16467b97STreehugger Robot def testTokenTreeAfterOtherStuff(self): 281*16467b97STreehugger Robot grammar = textwrap.dedent( 282*16467b97STreehugger Robot r''' 283*16467b97STreehugger Robot grammar T; 284*16467b97STreehugger Robot options {language=Python;output=AST;} 285*16467b97STreehugger Robot a : 'void' ID INT -> 'void' ^(INT ID); 286*16467b97STreehugger Robot ID : 'a'..'z'+ ; 287*16467b97STreehugger Robot INT : '0'..'9'+; 288*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 289*16467b97STreehugger Robot ''') 290*16467b97STreehugger Robot 291*16467b97STreehugger Robot found = self.execParser(grammar, "a", "void abc 34") 292*16467b97STreehugger Robot self.assertEquals("void (34 abc)", found) 293*16467b97STreehugger Robot 294*16467b97STreehugger Robot 295*16467b97STreehugger Robot def testNestedTokenTreeWithOuterLoop(self): 296*16467b97STreehugger Robot # verify that ID and INT both iterate over outer index variable 297*16467b97STreehugger Robot grammar = textwrap.dedent( 298*16467b97STreehugger Robot r''' 299*16467b97STreehugger Robot grammar T; 300*16467b97STreehugger Robot options {language=Python;output=AST;} 301*16467b97STreehugger Robot tokens {DUH;} 302*16467b97STreehugger Robot a : ID INT ID INT -> ^( DUH ID ^( DUH INT) )+ ; 303*16467b97STreehugger Robot ID : 'a'..'z'+ ; 304*16467b97STreehugger Robot INT : '0'..'9'+; 305*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 306*16467b97STreehugger Robot ''') 307*16467b97STreehugger Robot 308*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 1 b 2") 309*16467b97STreehugger Robot self.assertEquals("(DUH a (DUH 1)) (DUH b (DUH 2))", found) 310*16467b97STreehugger Robot 311*16467b97STreehugger Robot 312*16467b97STreehugger Robot def testOptionalSingleToken(self): 313*16467b97STreehugger Robot grammar = textwrap.dedent( 314*16467b97STreehugger Robot r''' 315*16467b97STreehugger Robot grammar T; 316*16467b97STreehugger Robot options {language=Python;output=AST;} 317*16467b97STreehugger Robot a : ID -> ID? ; 318*16467b97STreehugger Robot ID : 'a'..'z'+ ; 319*16467b97STreehugger Robot INT : '0'..'9'+; 320*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 321*16467b97STreehugger Robot ''') 322*16467b97STreehugger Robot 323*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc") 324*16467b97STreehugger Robot self.assertEquals("abc", found) 325*16467b97STreehugger Robot 326*16467b97STreehugger Robot 327*16467b97STreehugger Robot def testClosureSingleToken(self): 328*16467b97STreehugger Robot grammar = textwrap.dedent( 329*16467b97STreehugger Robot r''' 330*16467b97STreehugger Robot grammar T; 331*16467b97STreehugger Robot options {language=Python;output=AST;} 332*16467b97STreehugger Robot a : ID ID -> ID* ; 333*16467b97STreehugger Robot ID : 'a'..'z'+ ; 334*16467b97STreehugger Robot INT : '0'..'9'+; 335*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 336*16467b97STreehugger Robot ''') 337*16467b97STreehugger Robot 338*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 339*16467b97STreehugger Robot self.assertEquals("a b", found) 340*16467b97STreehugger Robot 341*16467b97STreehugger Robot 342*16467b97STreehugger Robot def testPositiveClosureSingleToken(self): 343*16467b97STreehugger Robot grammar = textwrap.dedent( 344*16467b97STreehugger Robot r''' 345*16467b97STreehugger Robot grammar T; 346*16467b97STreehugger Robot options {language=Python;output=AST;} 347*16467b97STreehugger Robot a : ID ID -> ID+ ; 348*16467b97STreehugger Robot ID : 'a'..'z'+ ; 349*16467b97STreehugger Robot INT : '0'..'9'+; 350*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 351*16467b97STreehugger Robot ''') 352*16467b97STreehugger Robot 353*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 354*16467b97STreehugger Robot self.assertEquals("a b", found) 355*16467b97STreehugger Robot 356*16467b97STreehugger Robot 357*16467b97STreehugger Robot def testOptionalSingleRule(self): 358*16467b97STreehugger Robot grammar = textwrap.dedent( 359*16467b97STreehugger Robot r''' 360*16467b97STreehugger Robot grammar T; 361*16467b97STreehugger Robot options {language=Python;output=AST;} 362*16467b97STreehugger Robot a : b -> b?; 363*16467b97STreehugger Robot b : ID ; 364*16467b97STreehugger Robot ID : 'a'..'z'+ ; 365*16467b97STreehugger Robot INT : '0'..'9'+; 366*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 367*16467b97STreehugger Robot ''') 368*16467b97STreehugger Robot 369*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc") 370*16467b97STreehugger Robot self.assertEquals("abc", found) 371*16467b97STreehugger Robot 372*16467b97STreehugger Robot 373*16467b97STreehugger Robot def testClosureSingleRule(self): 374*16467b97STreehugger Robot grammar = textwrap.dedent( 375*16467b97STreehugger Robot r''' 376*16467b97STreehugger Robot grammar T; 377*16467b97STreehugger Robot options {language=Python;output=AST;} 378*16467b97STreehugger Robot a : b b -> b*; 379*16467b97STreehugger Robot b : ID ; 380*16467b97STreehugger Robot ID : 'a'..'z'+ ; 381*16467b97STreehugger Robot INT : '0'..'9'+; 382*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 383*16467b97STreehugger Robot ''') 384*16467b97STreehugger Robot 385*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 386*16467b97STreehugger Robot self.assertEquals("a b", found) 387*16467b97STreehugger Robot 388*16467b97STreehugger Robot 389*16467b97STreehugger Robot def testClosureOfLabel(self): 390*16467b97STreehugger Robot grammar = textwrap.dedent( 391*16467b97STreehugger Robot r''' 392*16467b97STreehugger Robot grammar T; 393*16467b97STreehugger Robot options {language=Python;output=AST;} 394*16467b97STreehugger Robot a : x+=b x+=b -> $x*; 395*16467b97STreehugger Robot b : ID ; 396*16467b97STreehugger Robot ID : 'a'..'z'+ ; 397*16467b97STreehugger Robot INT : '0'..'9'+; 398*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 399*16467b97STreehugger Robot ''') 400*16467b97STreehugger Robot 401*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 402*16467b97STreehugger Robot self.assertEquals("a b", found) 403*16467b97STreehugger Robot 404*16467b97STreehugger Robot 405*16467b97STreehugger Robot def testOptionalLabelNoListLabel(self): 406*16467b97STreehugger Robot grammar = textwrap.dedent( 407*16467b97STreehugger Robot r''' 408*16467b97STreehugger Robot grammar T; 409*16467b97STreehugger Robot options {language=Python;output=AST;} 410*16467b97STreehugger Robot a : (x=ID)? -> $x?; 411*16467b97STreehugger Robot ID : 'a'..'z'+ ; 412*16467b97STreehugger Robot INT : '0'..'9'+; 413*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 414*16467b97STreehugger Robot ''') 415*16467b97STreehugger Robot 416*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 417*16467b97STreehugger Robot self.assertEquals("a", found) 418*16467b97STreehugger Robot 419*16467b97STreehugger Robot 420*16467b97STreehugger Robot def testPositiveClosureSingleRule(self): 421*16467b97STreehugger Robot grammar = textwrap.dedent( 422*16467b97STreehugger Robot r''' 423*16467b97STreehugger Robot grammar T; 424*16467b97STreehugger Robot options {language=Python;output=AST;} 425*16467b97STreehugger Robot a : b b -> b+; 426*16467b97STreehugger Robot b : ID ; 427*16467b97STreehugger Robot ID : 'a'..'z'+ ; 428*16467b97STreehugger Robot INT : '0'..'9'+; 429*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 430*16467b97STreehugger Robot ''') 431*16467b97STreehugger Robot 432*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 433*16467b97STreehugger Robot self.assertEquals("a b", found) 434*16467b97STreehugger Robot 435*16467b97STreehugger Robot 436*16467b97STreehugger Robot def testSinglePredicateT(self): 437*16467b97STreehugger Robot grammar = textwrap.dedent( 438*16467b97STreehugger Robot r''' 439*16467b97STreehugger Robot grammar T; 440*16467b97STreehugger Robot options {language=Python;output=AST;} 441*16467b97STreehugger Robot a : ID -> {True}? ID -> ; 442*16467b97STreehugger Robot ID : 'a'..'z'+ ; 443*16467b97STreehugger Robot INT : '0'..'9'+; 444*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 445*16467b97STreehugger Robot ''') 446*16467b97STreehugger Robot 447*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc") 448*16467b97STreehugger Robot self.assertEquals("abc", found) 449*16467b97STreehugger Robot 450*16467b97STreehugger Robot 451*16467b97STreehugger Robot def testSinglePredicateF(self): 452*16467b97STreehugger Robot grammar = textwrap.dedent( 453*16467b97STreehugger Robot r''' 454*16467b97STreehugger Robot grammar T; 455*16467b97STreehugger Robot options {language=Python;output=AST;} 456*16467b97STreehugger Robot a : ID -> {False}? ID -> ; 457*16467b97STreehugger Robot ID : 'a'..'z'+ ; 458*16467b97STreehugger Robot INT : '0'..'9'+; 459*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 460*16467b97STreehugger Robot ''') 461*16467b97STreehugger Robot 462*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc") 463*16467b97STreehugger Robot self.assertEquals("", found) 464*16467b97STreehugger Robot 465*16467b97STreehugger Robot 466*16467b97STreehugger Robot def testMultiplePredicate(self): 467*16467b97STreehugger Robot grammar = textwrap.dedent( 468*16467b97STreehugger Robot r''' 469*16467b97STreehugger Robot grammar T; 470*16467b97STreehugger Robot options {language=Python;output=AST;} 471*16467b97STreehugger Robot a : ID INT -> {False}? ID 472*16467b97STreehugger Robot -> {True}? INT 473*16467b97STreehugger Robot -> 474*16467b97STreehugger Robot ; 475*16467b97STreehugger Robot ID : 'a'..'z'+ ; 476*16467b97STreehugger Robot INT : '0'..'9'+; 477*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 478*16467b97STreehugger Robot ''') 479*16467b97STreehugger Robot 480*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 2") 481*16467b97STreehugger Robot self.assertEquals("2", found) 482*16467b97STreehugger Robot 483*16467b97STreehugger Robot 484*16467b97STreehugger Robot def testMultiplePredicateTrees(self): 485*16467b97STreehugger Robot grammar = textwrap.dedent( 486*16467b97STreehugger Robot r''' 487*16467b97STreehugger Robot grammar T; 488*16467b97STreehugger Robot options {language=Python;output=AST;} 489*16467b97STreehugger Robot a : ID INT -> {False}? ^(ID INT) 490*16467b97STreehugger Robot -> {True}? ^(INT ID) 491*16467b97STreehugger Robot -> ID 492*16467b97STreehugger Robot ; 493*16467b97STreehugger Robot ID : 'a'..'z'+ ; 494*16467b97STreehugger Robot INT : '0'..'9'+; 495*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 496*16467b97STreehugger Robot ''') 497*16467b97STreehugger Robot 498*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 2") 499*16467b97STreehugger Robot self.assertEquals("(2 a)", found) 500*16467b97STreehugger Robot 501*16467b97STreehugger Robot 502*16467b97STreehugger Robot def testSimpleTree(self): 503*16467b97STreehugger Robot grammar = textwrap.dedent( 504*16467b97STreehugger Robot r''' 505*16467b97STreehugger Robot grammar T; 506*16467b97STreehugger Robot options {language=Python;output=AST;} 507*16467b97STreehugger Robot a : op INT -> ^(op INT); 508*16467b97STreehugger Robot op : '+'|'-' ; 509*16467b97STreehugger Robot ID : 'a'..'z'+ ; 510*16467b97STreehugger Robot INT : '0'..'9'+; 511*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 512*16467b97STreehugger Robot ''') 513*16467b97STreehugger Robot 514*16467b97STreehugger Robot found = self.execParser(grammar, "a", "-34") 515*16467b97STreehugger Robot self.assertEquals("(- 34)", found) 516*16467b97STreehugger Robot 517*16467b97STreehugger Robot 518*16467b97STreehugger Robot def testSimpleTree2(self): 519*16467b97STreehugger Robot grammar = textwrap.dedent( 520*16467b97STreehugger Robot r''' 521*16467b97STreehugger Robot grammar T; 522*16467b97STreehugger Robot options {language=Python;output=AST;} 523*16467b97STreehugger Robot a : op INT -> ^(INT op); 524*16467b97STreehugger Robot op : '+'|'-' ; 525*16467b97STreehugger Robot ID : 'a'..'z'+ ; 526*16467b97STreehugger Robot INT : '0'..'9'+; 527*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 528*16467b97STreehugger Robot ''') 529*16467b97STreehugger Robot 530*16467b97STreehugger Robot found = self.execParser(grammar, "a", "+ 34") 531*16467b97STreehugger Robot self.assertEquals("(34 +)", found) 532*16467b97STreehugger Robot 533*16467b97STreehugger Robot 534*16467b97STreehugger Robot 535*16467b97STreehugger Robot def testNestedTrees(self): 536*16467b97STreehugger Robot grammar = textwrap.dedent( 537*16467b97STreehugger Robot r''' 538*16467b97STreehugger Robot grammar T; 539*16467b97STreehugger Robot options {language=Python;output=AST;} 540*16467b97STreehugger Robot a : 'var' (ID ':' type ';')+ -> ^('var' ^(':' ID type)+) ; 541*16467b97STreehugger Robot type : 'int' | 'float' ; 542*16467b97STreehugger Robot ID : 'a'..'z'+ ; 543*16467b97STreehugger Robot INT : '0'..'9'+; 544*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 545*16467b97STreehugger Robot ''') 546*16467b97STreehugger Robot 547*16467b97STreehugger Robot found = self.execParser(grammar, "a", "var a:int; b:float;") 548*16467b97STreehugger Robot self.assertEquals("(var (: a int) (: b float))", found) 549*16467b97STreehugger Robot 550*16467b97STreehugger Robot 551*16467b97STreehugger Robot def testImaginaryTokenCopy(self): 552*16467b97STreehugger Robot grammar = textwrap.dedent( 553*16467b97STreehugger Robot r''' 554*16467b97STreehugger Robot grammar T; 555*16467b97STreehugger Robot options {language=Python;output=AST;} 556*16467b97STreehugger Robot tokens {VAR;} 557*16467b97STreehugger Robot a : ID (',' ID)*-> ^(VAR ID)+ ; 558*16467b97STreehugger Robot type : 'int' | 'float' ; 559*16467b97STreehugger Robot ID : 'a'..'z'+ ; 560*16467b97STreehugger Robot INT : '0'..'9'+; 561*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 562*16467b97STreehugger Robot ''') 563*16467b97STreehugger Robot 564*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a,b,c") 565*16467b97STreehugger Robot self.assertEquals("(VAR a) (VAR b) (VAR c)", found) 566*16467b97STreehugger Robot 567*16467b97STreehugger Robot 568*16467b97STreehugger Robot def testTokenUnreferencedOnLeftButDefined(self): 569*16467b97STreehugger Robot grammar = textwrap.dedent( 570*16467b97STreehugger Robot r''' 571*16467b97STreehugger Robot grammar T; 572*16467b97STreehugger Robot options {language=Python;output=AST;} 573*16467b97STreehugger Robot tokens {VAR;} 574*16467b97STreehugger Robot a : b -> ID ; 575*16467b97STreehugger Robot b : ID ; 576*16467b97STreehugger Robot ID : 'a'..'z'+ ; 577*16467b97STreehugger Robot INT : '0'..'9'+; 578*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 579*16467b97STreehugger Robot ''') 580*16467b97STreehugger Robot 581*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 582*16467b97STreehugger Robot self.assertEquals("ID", found) 583*16467b97STreehugger Robot 584*16467b97STreehugger Robot 585*16467b97STreehugger Robot def testImaginaryTokenCopySetText(self): 586*16467b97STreehugger Robot grammar = textwrap.dedent( 587*16467b97STreehugger Robot r''' 588*16467b97STreehugger Robot grammar T; 589*16467b97STreehugger Robot options {language=Python;output=AST;} 590*16467b97STreehugger Robot tokens {VAR;} 591*16467b97STreehugger Robot a : ID (',' ID)*-> ^(VAR["var"] ID)+ ; 592*16467b97STreehugger Robot type : 'int' | 'float' ; 593*16467b97STreehugger Robot ID : 'a'..'z'+ ; 594*16467b97STreehugger Robot INT : '0'..'9'+; 595*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 596*16467b97STreehugger Robot ''') 597*16467b97STreehugger Robot 598*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a,b,c") 599*16467b97STreehugger Robot self.assertEquals("(var a) (var b) (var c)", found) 600*16467b97STreehugger Robot 601*16467b97STreehugger Robot 602*16467b97STreehugger Robot def testImaginaryTokenNoCopyFromToken(self): 603*16467b97STreehugger Robot grammar = textwrap.dedent( 604*16467b97STreehugger Robot r''' 605*16467b97STreehugger Robot grammar T; 606*16467b97STreehugger Robot options {language=Python;output=AST;} 607*16467b97STreehugger Robot tokens {BLOCK;} 608*16467b97STreehugger Robot a : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ; 609*16467b97STreehugger Robot type : 'int' | 'float' ; 610*16467b97STreehugger Robot ID : 'a'..'z'+ ; 611*16467b97STreehugger Robot INT : '0'..'9'+; 612*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 613*16467b97STreehugger Robot ''') 614*16467b97STreehugger Robot 615*16467b97STreehugger Robot found = self.execParser(grammar, "a", "{a b c}") 616*16467b97STreehugger Robot self.assertEquals("({ a b c)", found) 617*16467b97STreehugger Robot 618*16467b97STreehugger Robot 619*16467b97STreehugger Robot def testImaginaryTokenNoCopyFromTokenSetText(self): 620*16467b97STreehugger Robot grammar = textwrap.dedent( 621*16467b97STreehugger Robot r''' 622*16467b97STreehugger Robot grammar T; 623*16467b97STreehugger Robot options {language=Python;output=AST;} 624*16467b97STreehugger Robot tokens {BLOCK;} 625*16467b97STreehugger Robot a : lc='{' ID+ '}' -> ^(BLOCK[$lc,"block"] ID+) ; 626*16467b97STreehugger Robot type : 'int' | 'float' ; 627*16467b97STreehugger Robot ID : 'a'..'z'+ ; 628*16467b97STreehugger Robot INT : '0'..'9'+; 629*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 630*16467b97STreehugger Robot ''') 631*16467b97STreehugger Robot 632*16467b97STreehugger Robot found = self.execParser(grammar, "a", "{a b c}") 633*16467b97STreehugger Robot self.assertEquals("(block a b c)", found) 634*16467b97STreehugger Robot 635*16467b97STreehugger Robot 636*16467b97STreehugger Robot def testMixedRewriteAndAutoAST(self): 637*16467b97STreehugger Robot grammar = textwrap.dedent( 638*16467b97STreehugger Robot r''' 639*16467b97STreehugger Robot grammar T; 640*16467b97STreehugger Robot options {language=Python;output=AST;} 641*16467b97STreehugger Robot tokens {BLOCK;} 642*16467b97STreehugger Robot a : b b^ ; // 2nd b matches only an INT; can make it root 643*16467b97STreehugger Robot b : ID INT -> INT ID 644*16467b97STreehugger Robot | INT 645*16467b97STreehugger Robot ; 646*16467b97STreehugger Robot ID : 'a'..'z'+ ; 647*16467b97STreehugger Robot INT : '0'..'9'+; 648*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 649*16467b97STreehugger Robot ''') 650*16467b97STreehugger Robot 651*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 1 2") 652*16467b97STreehugger Robot self.assertEquals("(2 1 a)", found) 653*16467b97STreehugger Robot 654*16467b97STreehugger Robot 655*16467b97STreehugger Robot def testSubruleWithRewrite(self): 656*16467b97STreehugger Robot grammar = textwrap.dedent( 657*16467b97STreehugger Robot r''' 658*16467b97STreehugger Robot grammar T; 659*16467b97STreehugger Robot options {language=Python;output=AST;} 660*16467b97STreehugger Robot tokens {BLOCK;} 661*16467b97STreehugger Robot a : b b ; 662*16467b97STreehugger Robot b : (ID INT -> INT ID | INT INT -> INT+ ) 663*16467b97STreehugger Robot ; 664*16467b97STreehugger Robot ID : 'a'..'z'+ ; 665*16467b97STreehugger Robot INT : '0'..'9'+; 666*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 667*16467b97STreehugger Robot ''') 668*16467b97STreehugger Robot 669*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a 1 2 3") 670*16467b97STreehugger Robot self.assertEquals("1 a 2 3", found) 671*16467b97STreehugger Robot 672*16467b97STreehugger Robot 673*16467b97STreehugger Robot def testSubruleWithRewrite2(self): 674*16467b97STreehugger Robot grammar = textwrap.dedent( 675*16467b97STreehugger Robot r''' 676*16467b97STreehugger Robot grammar T; 677*16467b97STreehugger Robot options {language=Python;output=AST;} 678*16467b97STreehugger Robot tokens {TYPE;} 679*16467b97STreehugger Robot a : b b ; 680*16467b97STreehugger Robot b : 'int' 681*16467b97STreehugger Robot ( ID -> ^(TYPE 'int' ID) 682*16467b97STreehugger Robot | ID '=' INT -> ^(TYPE 'int' ID INT) 683*16467b97STreehugger Robot ) 684*16467b97STreehugger Robot ';' 685*16467b97STreehugger Robot ; 686*16467b97STreehugger Robot ID : 'a'..'z'+ ; 687*16467b97STreehugger Robot INT : '0'..'9'+; 688*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 689*16467b97STreehugger Robot ''') 690*16467b97STreehugger Robot 691*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a; int b=3;") 692*16467b97STreehugger Robot self.assertEquals("(TYPE int a) (TYPE int b 3)", found) 693*16467b97STreehugger Robot 694*16467b97STreehugger Robot 695*16467b97STreehugger Robot def testNestedRewriteShutsOffAutoAST(self): 696*16467b97STreehugger Robot grammar = textwrap.dedent( 697*16467b97STreehugger Robot r''' 698*16467b97STreehugger Robot grammar T; 699*16467b97STreehugger Robot options {language=Python;output=AST;} 700*16467b97STreehugger Robot tokens {BLOCK;} 701*16467b97STreehugger Robot a : b b ; 702*16467b97STreehugger Robot b : ID ( ID (last=ID -> $last)+ ) ';' // get last ID 703*16467b97STreehugger Robot | INT // should still get auto AST construction 704*16467b97STreehugger Robot ; 705*16467b97STreehugger Robot ID : 'a'..'z'+ ; 706*16467b97STreehugger Robot INT : '0'..'9'+; 707*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 708*16467b97STreehugger Robot ''') 709*16467b97STreehugger Robot 710*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b c d; 42") 711*16467b97STreehugger Robot self.assertEquals("d 42", found) 712*16467b97STreehugger Robot 713*16467b97STreehugger Robot 714*16467b97STreehugger Robot def testRewriteActions(self): 715*16467b97STreehugger Robot grammar = textwrap.dedent( 716*16467b97STreehugger Robot r''' 717*16467b97STreehugger Robot grammar T; 718*16467b97STreehugger Robot options {language=Python;output=AST;} 719*16467b97STreehugger Robot a : atom -> ^({self.adaptor.create(INT,"9")} atom) ; 720*16467b97STreehugger Robot atom : INT ; 721*16467b97STreehugger Robot ID : 'a'..'z'+ ; 722*16467b97STreehugger Robot INT : '0'..'9'+; 723*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 724*16467b97STreehugger Robot ''') 725*16467b97STreehugger Robot 726*16467b97STreehugger Robot found = self.execParser(grammar, "a", "3") 727*16467b97STreehugger Robot self.assertEquals("(9 3)", found) 728*16467b97STreehugger Robot 729*16467b97STreehugger Robot 730*16467b97STreehugger Robot def testRewriteActions2(self): 731*16467b97STreehugger Robot grammar = textwrap.dedent( 732*16467b97STreehugger Robot r''' 733*16467b97STreehugger Robot grammar T; 734*16467b97STreehugger Robot options {language=Python;output=AST;} 735*16467b97STreehugger Robot a : atom -> {self.adaptor.create(INT,"9")} atom ; 736*16467b97STreehugger Robot atom : INT ; 737*16467b97STreehugger Robot ID : 'a'..'z'+ ; 738*16467b97STreehugger Robot INT : '0'..'9'+; 739*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 740*16467b97STreehugger Robot ''') 741*16467b97STreehugger Robot 742*16467b97STreehugger Robot found = self.execParser(grammar, "a", "3") 743*16467b97STreehugger Robot self.assertEquals("9 3", found) 744*16467b97STreehugger Robot 745*16467b97STreehugger Robot 746*16467b97STreehugger Robot def testRefToOldValue(self): 747*16467b97STreehugger Robot grammar = textwrap.dedent( 748*16467b97STreehugger Robot r''' 749*16467b97STreehugger Robot grammar T; 750*16467b97STreehugger Robot options {language=Python;output=AST;} 751*16467b97STreehugger Robot tokens {BLOCK;} 752*16467b97STreehugger Robot a : (atom -> atom) (op='+' r=atom -> ^($op $a $r) )* ; 753*16467b97STreehugger Robot atom : INT ; 754*16467b97STreehugger Robot ID : 'a'..'z'+ ; 755*16467b97STreehugger Robot INT : '0'..'9'+; 756*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 757*16467b97STreehugger Robot ''') 758*16467b97STreehugger Robot 759*16467b97STreehugger Robot found = self.execParser(grammar, "a", "3+4+5") 760*16467b97STreehugger Robot self.assertEquals("(+ (+ 3 4) 5)", found) 761*16467b97STreehugger Robot 762*16467b97STreehugger Robot 763*16467b97STreehugger Robot def testCopySemanticsForRules(self): 764*16467b97STreehugger Robot grammar = textwrap.dedent( 765*16467b97STreehugger Robot r''' 766*16467b97STreehugger Robot grammar T; 767*16467b97STreehugger Robot options {language=Python;output=AST;} 768*16467b97STreehugger Robot tokens {BLOCK;} 769*16467b97STreehugger Robot a : atom -> ^(atom atom) ; // NOT CYCLE! (dup atom) 770*16467b97STreehugger Robot atom : INT ; 771*16467b97STreehugger Robot ID : 'a'..'z'+ ; 772*16467b97STreehugger Robot INT : '0'..'9'+; 773*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 774*16467b97STreehugger Robot ''') 775*16467b97STreehugger Robot 776*16467b97STreehugger Robot found = self.execParser(grammar, "a", "3") 777*16467b97STreehugger Robot self.assertEquals("(3 3)", found) 778*16467b97STreehugger Robot 779*16467b97STreehugger Robot 780*16467b97STreehugger Robot def testCopySemanticsForRules2(self): 781*16467b97STreehugger Robot # copy type as a root for each invocation of (...)+ in rewrite 782*16467b97STreehugger Robot grammar = textwrap.dedent( 783*16467b97STreehugger Robot r''' 784*16467b97STreehugger Robot grammar T; 785*16467b97STreehugger Robot options {language=Python;output=AST;} 786*16467b97STreehugger Robot a : type ID (',' ID)* ';' -> ^(type ID)+ ; 787*16467b97STreehugger Robot type : 'int' ; 788*16467b97STreehugger Robot ID : 'a'..'z'+ ; 789*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 790*16467b97STreehugger Robot ''') 791*16467b97STreehugger Robot 792*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a,b,c;") 793*16467b97STreehugger Robot self.assertEquals("(int a) (int b) (int c)", found) 794*16467b97STreehugger Robot 795*16467b97STreehugger Robot 796*16467b97STreehugger Robot def testCopySemanticsForRules3(self): 797*16467b97STreehugger Robot # copy type *and* modifier even though it's optional 798*16467b97STreehugger Robot # for each invocation of (...)+ in rewrite 799*16467b97STreehugger Robot grammar = textwrap.dedent( 800*16467b97STreehugger Robot r''' 801*16467b97STreehugger Robot grammar T; 802*16467b97STreehugger Robot options {language=Python;output=AST;} 803*16467b97STreehugger Robot a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ; 804*16467b97STreehugger Robot type : 'int' ; 805*16467b97STreehugger Robot modifier : 'public' ; 806*16467b97STreehugger Robot ID : 'a'..'z'+ ; 807*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 808*16467b97STreehugger Robot ''') 809*16467b97STreehugger Robot 810*16467b97STreehugger Robot found = self.execParser(grammar, "a", "public int a,b,c;") 811*16467b97STreehugger Robot self.assertEquals("(int public a) (int public b) (int public c)", found) 812*16467b97STreehugger Robot 813*16467b97STreehugger Robot 814*16467b97STreehugger Robot def testCopySemanticsForRules3Double(self): 815*16467b97STreehugger Robot # copy type *and* modifier even though it's optional 816*16467b97STreehugger Robot # for each invocation of (...)+ in rewrite 817*16467b97STreehugger Robot grammar = textwrap.dedent( 818*16467b97STreehugger Robot r''' 819*16467b97STreehugger Robot grammar T; 820*16467b97STreehugger Robot options {language=Python;output=AST;} 821*16467b97STreehugger Robot a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ^(type modifier? ID)+ ; 822*16467b97STreehugger Robot type : 'int' ; 823*16467b97STreehugger Robot modifier : 'public' ; 824*16467b97STreehugger Robot ID : 'a'..'z'+ ; 825*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 826*16467b97STreehugger Robot ''') 827*16467b97STreehugger Robot 828*16467b97STreehugger Robot found = self.execParser(grammar, "a", "public int a,b,c;") 829*16467b97STreehugger Robot self.assertEquals("(int public a) (int public b) (int public c) (int public a) (int public b) (int public c)", found) 830*16467b97STreehugger Robot 831*16467b97STreehugger Robot 832*16467b97STreehugger Robot def testCopySemanticsForRules4(self): 833*16467b97STreehugger Robot # copy type *and* modifier even though it's optional 834*16467b97STreehugger Robot # for each invocation of (...)+ in rewrite 835*16467b97STreehugger Robot grammar = textwrap.dedent( 836*16467b97STreehugger Robot r''' 837*16467b97STreehugger Robot grammar T; 838*16467b97STreehugger Robot options {language=Python;output=AST;} 839*16467b97STreehugger Robot tokens {MOD;} 840*16467b97STreehugger Robot a : modifier? type ID (',' ID)* ';' -> ^(type ^(MOD modifier)? ID)+ ; 841*16467b97STreehugger Robot type : 'int' ; 842*16467b97STreehugger Robot modifier : 'public' ; 843*16467b97STreehugger Robot ID : 'a'..'z'+ ; 844*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 845*16467b97STreehugger Robot ''') 846*16467b97STreehugger Robot 847*16467b97STreehugger Robot found = self.execParser(grammar, "a", "public int a,b,c;") 848*16467b97STreehugger Robot self.assertEquals("(int (MOD public) a) (int (MOD public) b) (int (MOD public) c)", found) 849*16467b97STreehugger Robot 850*16467b97STreehugger Robot 851*16467b97STreehugger Robot def testCopySemanticsLists(self): 852*16467b97STreehugger Robot grammar = textwrap.dedent( 853*16467b97STreehugger Robot r''' 854*16467b97STreehugger Robot grammar T; 855*16467b97STreehugger Robot options {language=Python;output=AST;} 856*16467b97STreehugger Robot tokens {MOD;} 857*16467b97STreehugger Robot a : ID (',' ID)* ';' -> ID+ ID+ ; 858*16467b97STreehugger Robot ID : 'a'..'z'+ ; 859*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 860*16467b97STreehugger Robot ''') 861*16467b97STreehugger Robot 862*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a,b,c;") 863*16467b97STreehugger Robot self.assertEquals("a b c a b c", found) 864*16467b97STreehugger Robot 865*16467b97STreehugger Robot 866*16467b97STreehugger Robot def testCopyRuleLabel(self): 867*16467b97STreehugger Robot grammar = textwrap.dedent( 868*16467b97STreehugger Robot r''' 869*16467b97STreehugger Robot grammar T; 870*16467b97STreehugger Robot options {language=Python;output=AST;} 871*16467b97STreehugger Robot tokens {BLOCK;} 872*16467b97STreehugger Robot a : x=b -> $x $x; 873*16467b97STreehugger Robot b : ID ; 874*16467b97STreehugger Robot ID : 'a'..'z'+ ; 875*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 876*16467b97STreehugger Robot ''') 877*16467b97STreehugger Robot 878*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 879*16467b97STreehugger Robot self.assertEquals("a a", found) 880*16467b97STreehugger Robot 881*16467b97STreehugger Robot 882*16467b97STreehugger Robot def testCopyRuleLabel2(self): 883*16467b97STreehugger Robot grammar = textwrap.dedent( 884*16467b97STreehugger Robot r''' 885*16467b97STreehugger Robot grammar T; 886*16467b97STreehugger Robot options {language=Python;output=AST;} 887*16467b97STreehugger Robot tokens {BLOCK;} 888*16467b97STreehugger Robot a : x=b -> ^($x $x); 889*16467b97STreehugger Robot b : ID ; 890*16467b97STreehugger Robot ID : 'a'..'z'+ ; 891*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 892*16467b97STreehugger Robot ''') 893*16467b97STreehugger Robot 894*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 895*16467b97STreehugger Robot self.assertEquals("(a a)", found) 896*16467b97STreehugger Robot 897*16467b97STreehugger Robot 898*16467b97STreehugger Robot def testQueueingOfTokens(self): 899*16467b97STreehugger Robot grammar = textwrap.dedent( 900*16467b97STreehugger Robot r''' 901*16467b97STreehugger Robot grammar T; 902*16467b97STreehugger Robot options {language=Python;output=AST;} 903*16467b97STreehugger Robot a : 'int' ID (',' ID)* ';' -> ^('int' ID+) ; 904*16467b97STreehugger Robot op : '+'|'-' ; 905*16467b97STreehugger Robot ID : 'a'..'z'+ ; 906*16467b97STreehugger Robot INT : '0'..'9'+; 907*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 908*16467b97STreehugger Robot ''') 909*16467b97STreehugger Robot 910*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a,b,c;") 911*16467b97STreehugger Robot self.assertEquals("(int a b c)", found) 912*16467b97STreehugger Robot 913*16467b97STreehugger Robot 914*16467b97STreehugger Robot def testCopyOfTokens(self): 915*16467b97STreehugger Robot grammar = textwrap.dedent( 916*16467b97STreehugger Robot r''' 917*16467b97STreehugger Robot grammar T; 918*16467b97STreehugger Robot options {language=Python;output=AST;} 919*16467b97STreehugger Robot a : 'int' ID ';' -> 'int' ID 'int' ID ; 920*16467b97STreehugger Robot op : '+'|'-' ; 921*16467b97STreehugger Robot ID : 'a'..'z'+ ; 922*16467b97STreehugger Robot INT : '0'..'9'+; 923*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 924*16467b97STreehugger Robot ''') 925*16467b97STreehugger Robot 926*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a;") 927*16467b97STreehugger Robot self.assertEquals("int a int a", found) 928*16467b97STreehugger Robot 929*16467b97STreehugger Robot 930*16467b97STreehugger Robot def testTokenCopyInLoop(self): 931*16467b97STreehugger Robot grammar = textwrap.dedent( 932*16467b97STreehugger Robot r''' 933*16467b97STreehugger Robot grammar T; 934*16467b97STreehugger Robot options {language=Python;output=AST;} 935*16467b97STreehugger Robot a : 'int' ID (',' ID)* ';' -> ^('int' ID)+ ; 936*16467b97STreehugger Robot op : '+'|'-' ; 937*16467b97STreehugger Robot ID : 'a'..'z'+ ; 938*16467b97STreehugger Robot INT : '0'..'9'+; 939*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 940*16467b97STreehugger Robot ''') 941*16467b97STreehugger Robot 942*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a,b,c;") 943*16467b97STreehugger Robot self.assertEquals("(int a) (int b) (int c)", found) 944*16467b97STreehugger Robot 945*16467b97STreehugger Robot 946*16467b97STreehugger Robot def testTokenCopyInLoopAgainstTwoOthers(self): 947*16467b97STreehugger Robot # must smear 'int' copies across as root of multiple trees 948*16467b97STreehugger Robot grammar = textwrap.dedent( 949*16467b97STreehugger Robot r''' 950*16467b97STreehugger Robot grammar T; 951*16467b97STreehugger Robot options {language=Python;output=AST;} 952*16467b97STreehugger Robot a : 'int' ID ':' INT (',' ID ':' INT)* ';' -> ^('int' ID INT)+ ; 953*16467b97STreehugger Robot op : '+'|'-' ; 954*16467b97STreehugger Robot ID : 'a'..'z'+ ; 955*16467b97STreehugger Robot INT : '0'..'9'+; 956*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 957*16467b97STreehugger Robot ''') 958*16467b97STreehugger Robot 959*16467b97STreehugger Robot found = self.execParser(grammar, "a", "int a:1,b:2,c:3;") 960*16467b97STreehugger Robot self.assertEquals("(int a 1) (int b 2) (int c 3)", found) 961*16467b97STreehugger Robot 962*16467b97STreehugger Robot 963*16467b97STreehugger Robot def testListRefdOneAtATime(self): 964*16467b97STreehugger Robot grammar = textwrap.dedent( 965*16467b97STreehugger Robot r''' 966*16467b97STreehugger Robot grammar T; 967*16467b97STreehugger Robot options {language=Python;output=AST;} 968*16467b97STreehugger Robot a : ID+ -> ID ID ID ; // works if 3 input IDs 969*16467b97STreehugger Robot op : '+'|'-' ; 970*16467b97STreehugger Robot ID : 'a'..'z'+ ; 971*16467b97STreehugger Robot INT : '0'..'9'+; 972*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 973*16467b97STreehugger Robot ''') 974*16467b97STreehugger Robot 975*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b c") 976*16467b97STreehugger Robot self.assertEquals("a b c", found) 977*16467b97STreehugger Robot 978*16467b97STreehugger Robot 979*16467b97STreehugger Robot def testSplitListWithLabels(self): 980*16467b97STreehugger Robot grammar = textwrap.dedent( 981*16467b97STreehugger Robot r''' 982*16467b97STreehugger Robot grammar T; 983*16467b97STreehugger Robot options {language=Python;output=AST;} 984*16467b97STreehugger Robot tokens {VAR;} 985*16467b97STreehugger Robot a : first=ID others+=ID* -> $first VAR $others+ ; 986*16467b97STreehugger Robot op : '+'|'-' ; 987*16467b97STreehugger Robot ID : 'a'..'z'+ ; 988*16467b97STreehugger Robot INT : '0'..'9'+; 989*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 990*16467b97STreehugger Robot ''') 991*16467b97STreehugger Robot 992*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b c") 993*16467b97STreehugger Robot self.assertEquals("a VAR b c", found) 994*16467b97STreehugger Robot 995*16467b97STreehugger Robot 996*16467b97STreehugger Robot def testComplicatedMelange(self): 997*16467b97STreehugger Robot grammar = textwrap.dedent( 998*16467b97STreehugger Robot r''' 999*16467b97STreehugger Robot grammar T; 1000*16467b97STreehugger Robot options {language=Python;output=AST;} 1001*16467b97STreehugger Robot tokens {BLOCK;} 1002*16467b97STreehugger Robot a : A A b=B B b=B c+=C C c+=C D {s=$D.text} -> A+ B+ C+ D ; 1003*16467b97STreehugger Robot type : 'int' | 'float' ; 1004*16467b97STreehugger Robot A : 'a' ; 1005*16467b97STreehugger Robot B : 'b' ; 1006*16467b97STreehugger Robot C : 'c' ; 1007*16467b97STreehugger Robot D : 'd' ; 1008*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1009*16467b97STreehugger Robot ''') 1010*16467b97STreehugger Robot 1011*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a a b b b c c c d") 1012*16467b97STreehugger Robot self.assertEquals("a a b b b c c c d", found) 1013*16467b97STreehugger Robot 1014*16467b97STreehugger Robot 1015*16467b97STreehugger Robot def testRuleLabel(self): 1016*16467b97STreehugger Robot grammar = textwrap.dedent( 1017*16467b97STreehugger Robot r''' 1018*16467b97STreehugger Robot grammar T; 1019*16467b97STreehugger Robot options {language=Python;output=AST;} 1020*16467b97STreehugger Robot tokens {BLOCK;} 1021*16467b97STreehugger Robot a : x=b -> $x; 1022*16467b97STreehugger Robot b : ID ; 1023*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1024*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1025*16467b97STreehugger Robot ''') 1026*16467b97STreehugger Robot 1027*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 1028*16467b97STreehugger Robot self.assertEquals("a", found) 1029*16467b97STreehugger Robot 1030*16467b97STreehugger Robot 1031*16467b97STreehugger Robot def testAmbiguousRule(self): 1032*16467b97STreehugger Robot grammar = textwrap.dedent( 1033*16467b97STreehugger Robot r''' 1034*16467b97STreehugger Robot grammar T; 1035*16467b97STreehugger Robot options {language=Python;output=AST;} 1036*16467b97STreehugger Robot a : ID a -> a | INT ; 1037*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1038*16467b97STreehugger Robot INT: '0'..'9'+ ; 1039*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1040*16467b97STreehugger Robot ''') 1041*16467b97STreehugger Robot 1042*16467b97STreehugger Robot found = self.execParser(grammar, 1043*16467b97STreehugger Robot "a", "abc 34") 1044*16467b97STreehugger Robot self.assertEquals("34", found) 1045*16467b97STreehugger Robot 1046*16467b97STreehugger Robot 1047*16467b97STreehugger Robot def testRuleListLabel(self): 1048*16467b97STreehugger Robot grammar = textwrap.dedent( 1049*16467b97STreehugger Robot r''' 1050*16467b97STreehugger Robot grammar T; 1051*16467b97STreehugger Robot options {language=Python;output=AST;} 1052*16467b97STreehugger Robot tokens {BLOCK;} 1053*16467b97STreehugger Robot a : x+=b x+=b -> $x+; 1054*16467b97STreehugger Robot b : ID ; 1055*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1056*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1057*16467b97STreehugger Robot ''') 1058*16467b97STreehugger Robot 1059*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 1060*16467b97STreehugger Robot self.assertEquals("a b", found) 1061*16467b97STreehugger Robot 1062*16467b97STreehugger Robot 1063*16467b97STreehugger Robot def testRuleListLabel2(self): 1064*16467b97STreehugger Robot grammar = textwrap.dedent( 1065*16467b97STreehugger Robot r''' 1066*16467b97STreehugger Robot grammar T; 1067*16467b97STreehugger Robot options {language=Python;output=AST;} 1068*16467b97STreehugger Robot tokens {BLOCK;} 1069*16467b97STreehugger Robot a : x+=b x+=b -> $x $x*; 1070*16467b97STreehugger Robot b : ID ; 1071*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1072*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1073*16467b97STreehugger Robot ''') 1074*16467b97STreehugger Robot 1075*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 1076*16467b97STreehugger Robot self.assertEquals("a b", found) 1077*16467b97STreehugger Robot 1078*16467b97STreehugger Robot 1079*16467b97STreehugger Robot def testOptional(self): 1080*16467b97STreehugger Robot grammar = textwrap.dedent( 1081*16467b97STreehugger Robot r''' 1082*16467b97STreehugger Robot grammar T; 1083*16467b97STreehugger Robot options {language=Python;output=AST;} 1084*16467b97STreehugger Robot tokens {BLOCK;} 1085*16467b97STreehugger Robot a : x=b (y=b)? -> $x $y?; 1086*16467b97STreehugger Robot b : ID ; 1087*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1088*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1089*16467b97STreehugger Robot ''') 1090*16467b97STreehugger Robot 1091*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 1092*16467b97STreehugger Robot self.assertEquals("a", found) 1093*16467b97STreehugger Robot 1094*16467b97STreehugger Robot 1095*16467b97STreehugger Robot def testOptional2(self): 1096*16467b97STreehugger Robot grammar = textwrap.dedent( 1097*16467b97STreehugger Robot r''' 1098*16467b97STreehugger Robot grammar T; 1099*16467b97STreehugger Robot options {language=Python;output=AST;} 1100*16467b97STreehugger Robot tokens {BLOCK;} 1101*16467b97STreehugger Robot a : x=ID (y=b)? -> $x $y?; 1102*16467b97STreehugger Robot b : ID ; 1103*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1104*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1105*16467b97STreehugger Robot ''') 1106*16467b97STreehugger Robot 1107*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 1108*16467b97STreehugger Robot self.assertEquals("a b", found) 1109*16467b97STreehugger Robot 1110*16467b97STreehugger Robot 1111*16467b97STreehugger Robot def testOptional3(self): 1112*16467b97STreehugger Robot grammar = textwrap.dedent( 1113*16467b97STreehugger Robot r''' 1114*16467b97STreehugger Robot grammar T; 1115*16467b97STreehugger Robot options {language=Python;output=AST;} 1116*16467b97STreehugger Robot tokens {BLOCK;} 1117*16467b97STreehugger Robot a : x=ID (y=b)? -> ($x $y)?; 1118*16467b97STreehugger Robot b : ID ; 1119*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1120*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1121*16467b97STreehugger Robot ''') 1122*16467b97STreehugger Robot 1123*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 1124*16467b97STreehugger Robot self.assertEquals("a b", found) 1125*16467b97STreehugger Robot 1126*16467b97STreehugger Robot 1127*16467b97STreehugger Robot def testOptional4(self): 1128*16467b97STreehugger Robot grammar = textwrap.dedent( 1129*16467b97STreehugger Robot r''' 1130*16467b97STreehugger Robot grammar T; 1131*16467b97STreehugger Robot options {language=Python;output=AST;} 1132*16467b97STreehugger Robot tokens {BLOCK;} 1133*16467b97STreehugger Robot a : x+=ID (y=b)? -> ($x $y)?; 1134*16467b97STreehugger Robot b : ID ; 1135*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1136*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1137*16467b97STreehugger Robot ''') 1138*16467b97STreehugger Robot 1139*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 1140*16467b97STreehugger Robot self.assertEquals("a b", found) 1141*16467b97STreehugger Robot 1142*16467b97STreehugger Robot 1143*16467b97STreehugger Robot def testOptional5(self): 1144*16467b97STreehugger Robot grammar = textwrap.dedent( 1145*16467b97STreehugger Robot r''' 1146*16467b97STreehugger Robot grammar T; 1147*16467b97STreehugger Robot options {language=Python;output=AST;} 1148*16467b97STreehugger Robot tokens {BLOCK;} 1149*16467b97STreehugger Robot a : ID -> ID? ; // match an ID to optional ID 1150*16467b97STreehugger Robot b : ID ; 1151*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1152*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1153*16467b97STreehugger Robot ''') 1154*16467b97STreehugger Robot 1155*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a") 1156*16467b97STreehugger Robot self.assertEquals("a", found) 1157*16467b97STreehugger Robot 1158*16467b97STreehugger Robot 1159*16467b97STreehugger Robot def testArbitraryExprType(self): 1160*16467b97STreehugger Robot grammar = textwrap.dedent( 1161*16467b97STreehugger Robot r''' 1162*16467b97STreehugger Robot grammar T; 1163*16467b97STreehugger Robot options {language=Python;output=AST;} 1164*16467b97STreehugger Robot tokens {BLOCK;} 1165*16467b97STreehugger Robot a : x+=b x+=b -> {CommonTree(None)}; 1166*16467b97STreehugger Robot b : ID ; 1167*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1168*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1169*16467b97STreehugger Robot ''') 1170*16467b97STreehugger Robot 1171*16467b97STreehugger Robot found = self.execParser(grammar, "a", "a b") 1172*16467b97STreehugger Robot self.assertEquals("", found) 1173*16467b97STreehugger Robot 1174*16467b97STreehugger Robot 1175*16467b97STreehugger Robot def testSet(self): 1176*16467b97STreehugger Robot grammar = textwrap.dedent( 1177*16467b97STreehugger Robot r''' 1178*16467b97STreehugger Robot grammar T; 1179*16467b97STreehugger Robot options {language=Python;output=AST;} 1180*16467b97STreehugger Robot a: (INT|ID)+ -> INT+ ID+ ; 1181*16467b97STreehugger Robot INT: '0'..'9'+; 1182*16467b97STreehugger Robot ID : 'a'..'z'+; 1183*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1184*16467b97STreehugger Robot ''') 1185*16467b97STreehugger Robot 1186*16467b97STreehugger Robot found = self.execParser(grammar, "a", "2 a 34 de") 1187*16467b97STreehugger Robot self.assertEquals("2 34 a de", found) 1188*16467b97STreehugger Robot 1189*16467b97STreehugger Robot 1190*16467b97STreehugger Robot def testSet2(self): 1191*16467b97STreehugger Robot grammar = textwrap.dedent( 1192*16467b97STreehugger Robot r''' 1193*16467b97STreehugger Robot grammar T; 1194*16467b97STreehugger Robot options {language=Python;output=AST;} 1195*16467b97STreehugger Robot a: (INT|ID) -> INT? ID? ; 1196*16467b97STreehugger Robot INT: '0'..'9'+; 1197*16467b97STreehugger Robot ID : 'a'..'z'+; 1198*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1199*16467b97STreehugger Robot ''') 1200*16467b97STreehugger Robot 1201*16467b97STreehugger Robot found = self.execParser(grammar, "a", "2") 1202*16467b97STreehugger Robot self.assertEquals("2", found) 1203*16467b97STreehugger Robot 1204*16467b97STreehugger Robot 1205*16467b97STreehugger Robot @testbase.broken("http://www.antlr.org:8888/browse/ANTLR-162", 1206*16467b97STreehugger Robot antlr3.tree.RewriteEmptyStreamException) 1207*16467b97STreehugger Robot def testSetWithLabel(self): 1208*16467b97STreehugger Robot grammar = textwrap.dedent( 1209*16467b97STreehugger Robot r''' 1210*16467b97STreehugger Robot grammar T; 1211*16467b97STreehugger Robot options {language=Python;output=AST;} 1212*16467b97STreehugger Robot a : x=(INT|ID) -> $x ; 1213*16467b97STreehugger Robot INT: '0'..'9'+; 1214*16467b97STreehugger Robot ID : 'a'..'z'+; 1215*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1216*16467b97STreehugger Robot ''') 1217*16467b97STreehugger Robot 1218*16467b97STreehugger Robot found = self.execParser(grammar, "a", "2") 1219*16467b97STreehugger Robot self.assertEquals("2", found) 1220*16467b97STreehugger Robot 1221*16467b97STreehugger Robot 1222*16467b97STreehugger Robot def testRewriteAction(self): 1223*16467b97STreehugger Robot grammar = textwrap.dedent( 1224*16467b97STreehugger Robot r''' 1225*16467b97STreehugger Robot grammar T; 1226*16467b97STreehugger Robot options {language=Python;output=AST;} 1227*16467b97STreehugger Robot tokens { FLOAT; } 1228*16467b97STreehugger Robot r 1229*16467b97STreehugger Robot : INT -> {CommonTree(CommonToken(type=FLOAT, text=$INT.text+".0"))} 1230*16467b97STreehugger Robot ; 1231*16467b97STreehugger Robot INT : '0'..'9'+; 1232*16467b97STreehugger Robot WS: (' ' | '\n' | '\t')+ {$channel = HIDDEN;}; 1233*16467b97STreehugger Robot ''') 1234*16467b97STreehugger Robot 1235*16467b97STreehugger Robot found = self.execParser(grammar, "r", "25") 1236*16467b97STreehugger Robot self.assertEquals("25.0", found) 1237*16467b97STreehugger Robot 1238*16467b97STreehugger Robot 1239*16467b97STreehugger Robot def testOptionalSubruleWithoutRealElements(self): 1240*16467b97STreehugger Robot # copy type *and* modifier even though it's optional 1241*16467b97STreehugger Robot # for each invocation of (...)+ in rewrite 1242*16467b97STreehugger Robot grammar = textwrap.dedent( 1243*16467b97STreehugger Robot r""" 1244*16467b97STreehugger Robot grammar T; 1245*16467b97STreehugger Robot options {language=Python;output=AST;} 1246*16467b97STreehugger Robot tokens {PARMS;} 1247*16467b97STreehugger Robot 1248*16467b97STreehugger Robot modulo 1249*16467b97STreehugger Robot : 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms+)?) 1250*16467b97STreehugger Robot ; 1251*16467b97STreehugger Robot parms : '#'|ID; 1252*16467b97STreehugger Robot ID : ('a'..'z' | 'A'..'Z')+; 1253*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1254*16467b97STreehugger Robot """) 1255*16467b97STreehugger Robot 1256*16467b97STreehugger Robot found = self.execParser(grammar, "modulo", "modulo abc (x y #)") 1257*16467b97STreehugger Robot self.assertEquals("(modulo abc (PARMS x y #))", found) 1258*16467b97STreehugger Robot 1259*16467b97STreehugger Robot 1260*16467b97STreehugger Robot ## C A R D I N A L I T Y I S S U E S 1261*16467b97STreehugger Robot 1262*16467b97STreehugger Robot def testCardinality(self): 1263*16467b97STreehugger Robot grammar = textwrap.dedent( 1264*16467b97STreehugger Robot r''' 1265*16467b97STreehugger Robot grammar T; 1266*16467b97STreehugger Robot options {language=Python;output=AST;} 1267*16467b97STreehugger Robot tokens {BLOCK;} 1268*16467b97STreehugger Robot a : ID ID INT INT INT -> (ID INT)+; 1269*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1270*16467b97STreehugger Robot INT : '0'..'9'+; 1271*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1272*16467b97STreehugger Robot ''') 1273*16467b97STreehugger Robot 1274*16467b97STreehugger Robot try: 1275*16467b97STreehugger Robot self.execParser(grammar, "a", "a b 3 4 5") 1276*16467b97STreehugger Robot self.fail() 1277*16467b97STreehugger Robot except antlr3.tree.RewriteCardinalityException: 1278*16467b97STreehugger Robot pass 1279*16467b97STreehugger Robot 1280*16467b97STreehugger Robot 1281*16467b97STreehugger Robot def testCardinality2(self): 1282*16467b97STreehugger Robot grammar = textwrap.dedent( 1283*16467b97STreehugger Robot r''' 1284*16467b97STreehugger Robot grammar T; 1285*16467b97STreehugger Robot options {language=Python;output=AST;} 1286*16467b97STreehugger Robot a : ID+ -> ID ID ID ; // only 2 input IDs 1287*16467b97STreehugger Robot op : '+'|'-' ; 1288*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1289*16467b97STreehugger Robot INT : '0'..'9'+; 1290*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1291*16467b97STreehugger Robot ''') 1292*16467b97STreehugger Robot 1293*16467b97STreehugger Robot try: 1294*16467b97STreehugger Robot self.execParser(grammar, "a", "a b") 1295*16467b97STreehugger Robot self.fail() 1296*16467b97STreehugger Robot except antlr3.tree.RewriteCardinalityException: 1297*16467b97STreehugger Robot pass 1298*16467b97STreehugger Robot 1299*16467b97STreehugger Robot 1300*16467b97STreehugger Robot def testCardinality3(self): 1301*16467b97STreehugger Robot grammar = textwrap.dedent( 1302*16467b97STreehugger Robot r''' 1303*16467b97STreehugger Robot grammar T; 1304*16467b97STreehugger Robot options {language=Python;output=AST;} 1305*16467b97STreehugger Robot a : ID? INT -> ID INT ; 1306*16467b97STreehugger Robot op : '+'|'-' ; 1307*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1308*16467b97STreehugger Robot INT : '0'..'9'+; 1309*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1310*16467b97STreehugger Robot ''') 1311*16467b97STreehugger Robot 1312*16467b97STreehugger Robot try: 1313*16467b97STreehugger Robot self.execParser(grammar, "a", "3") 1314*16467b97STreehugger Robot self.fail() 1315*16467b97STreehugger Robot except antlr3.tree.RewriteEmptyStreamException: 1316*16467b97STreehugger Robot pass 1317*16467b97STreehugger Robot 1318*16467b97STreehugger Robot 1319*16467b97STreehugger Robot def testLoopCardinality(self): 1320*16467b97STreehugger Robot grammar = textwrap.dedent( 1321*16467b97STreehugger Robot r''' 1322*16467b97STreehugger Robot grammar T; 1323*16467b97STreehugger Robot options {language=Python;output=AST;} 1324*16467b97STreehugger Robot a : ID? INT -> ID+ INT ; 1325*16467b97STreehugger Robot op : '+'|'-' ; 1326*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1327*16467b97STreehugger Robot INT : '0'..'9'+; 1328*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1329*16467b97STreehugger Robot ''') 1330*16467b97STreehugger Robot 1331*16467b97STreehugger Robot try: 1332*16467b97STreehugger Robot self.execParser(grammar, "a", "3") 1333*16467b97STreehugger Robot self.fail() 1334*16467b97STreehugger Robot except antlr3.tree.RewriteEarlyExitException: 1335*16467b97STreehugger Robot pass 1336*16467b97STreehugger Robot 1337*16467b97STreehugger Robot 1338*16467b97STreehugger Robot def testWildcard(self): 1339*16467b97STreehugger Robot grammar = textwrap.dedent( 1340*16467b97STreehugger Robot r''' 1341*16467b97STreehugger Robot grammar T; 1342*16467b97STreehugger Robot options {language=Python;output=AST;} 1343*16467b97STreehugger Robot a : ID c=. -> $c; 1344*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1345*16467b97STreehugger Robot INT : '0'..'9'+; 1346*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1347*16467b97STreehugger Robot ''') 1348*16467b97STreehugger Robot 1349*16467b97STreehugger Robot found = self.execParser(grammar, "a", "abc 34") 1350*16467b97STreehugger Robot self.assertEquals("34", found) 1351*16467b97STreehugger Robot 1352*16467b97STreehugger Robot 1353*16467b97STreehugger Robot # E R R O R S 1354*16467b97STreehugger Robot 1355*16467b97STreehugger Robot def testExtraTokenInSimpleDecl(self): 1356*16467b97STreehugger Robot grammar = textwrap.dedent( 1357*16467b97STreehugger Robot r''' 1358*16467b97STreehugger Robot grammar foo; 1359*16467b97STreehugger Robot options {language=Python;output=AST;} 1360*16467b97STreehugger Robot tokens {EXPR;} 1361*16467b97STreehugger Robot decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1362*16467b97STreehugger Robot type : 'int' | 'float' ; 1363*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1364*16467b97STreehugger Robot INT : '0'..'9'+; 1365*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1366*16467b97STreehugger Robot ''') 1367*16467b97STreehugger Robot 1368*16467b97STreehugger Robot found, errors = self.execParser(grammar, "decl", "int 34 x=1;", 1369*16467b97STreehugger Robot expectErrors=True) 1370*16467b97STreehugger Robot self.assertEquals(["line 1:4 extraneous input u'34' expecting ID"], 1371*16467b97STreehugger Robot errors) 1372*16467b97STreehugger Robot self.assertEquals("(EXPR int x 1)", found) # tree gets correct x and 1 tokens 1373*16467b97STreehugger Robot 1374*16467b97STreehugger Robot 1375*16467b97STreehugger Robot #@testbase.broken("FIXME", AssertionError) 1376*16467b97STreehugger Robot def testMissingIDInSimpleDecl(self): 1377*16467b97STreehugger Robot grammar = textwrap.dedent( 1378*16467b97STreehugger Robot r''' 1379*16467b97STreehugger Robot grammar foo; 1380*16467b97STreehugger Robot options {language=Python;output=AST;} 1381*16467b97STreehugger Robot tokens {EXPR;} 1382*16467b97STreehugger Robot decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1383*16467b97STreehugger Robot type : 'int' | 'float' ; 1384*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1385*16467b97STreehugger Robot INT : '0'..'9'+; 1386*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1387*16467b97STreehugger Robot ''') 1388*16467b97STreehugger Robot 1389*16467b97STreehugger Robot found, errors = self.execParser(grammar, "decl", "int =1;", 1390*16467b97STreehugger Robot expectErrors=True) 1391*16467b97STreehugger Robot self.assertEquals(["line 1:4 missing ID at u'='"], errors) 1392*16467b97STreehugger Robot self.assertEquals("(EXPR int <missing ID> 1)", found) # tree gets invented ID token 1393*16467b97STreehugger Robot 1394*16467b97STreehugger Robot 1395*16467b97STreehugger Robot def testMissingSetInSimpleDecl(self): 1396*16467b97STreehugger Robot grammar = textwrap.dedent( 1397*16467b97STreehugger Robot r''' 1398*16467b97STreehugger Robot grammar foo; 1399*16467b97STreehugger Robot options {language=Python;output=AST;} 1400*16467b97STreehugger Robot tokens {EXPR;} 1401*16467b97STreehugger Robot decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ; 1402*16467b97STreehugger Robot type : 'int' | 'float' ; 1403*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1404*16467b97STreehugger Robot INT : '0'..'9'+; 1405*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1406*16467b97STreehugger Robot ''') 1407*16467b97STreehugger Robot 1408*16467b97STreehugger Robot found, errors = self.execParser(grammar, "decl", "x=1;", 1409*16467b97STreehugger Robot expectErrors=True) 1410*16467b97STreehugger Robot self.assertEquals(["line 1:0 mismatched input u'x' expecting set None"], 1411*16467b97STreehugger Robot errors); 1412*16467b97STreehugger Robot self.assertEquals("(EXPR <error: x> x 1)", found) # tree gets invented ID token 1413*16467b97STreehugger Robot 1414*16467b97STreehugger Robot 1415*16467b97STreehugger Robot def testMissingTokenGivesErrorNode(self): 1416*16467b97STreehugger Robot grammar = textwrap.dedent( 1417*16467b97STreehugger Robot r''' 1418*16467b97STreehugger Robot grammar foo; 1419*16467b97STreehugger Robot options {language=Python;output=AST;} 1420*16467b97STreehugger Robot a : ID INT -> ID INT ; 1421*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1422*16467b97STreehugger Robot INT : '0'..'9'+; 1423*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1424*16467b97STreehugger Robot ''') 1425*16467b97STreehugger Robot 1426*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "abc", 1427*16467b97STreehugger Robot expectErrors=True) 1428*16467b97STreehugger Robot self.assertEquals(["line 1:3 missing INT at '<EOF>'"], errors) 1429*16467b97STreehugger Robot # doesn't do in-line recovery for sets (yet?) 1430*16467b97STreehugger Robot self.assertEquals("abc <missing INT>", found) 1431*16467b97STreehugger Robot 1432*16467b97STreehugger Robot 1433*16467b97STreehugger Robot def testExtraTokenGivesErrorNode(self): 1434*16467b97STreehugger Robot grammar = textwrap.dedent( 1435*16467b97STreehugger Robot r''' 1436*16467b97STreehugger Robot grammar foo; 1437*16467b97STreehugger Robot options {language=Python;output=AST;} 1438*16467b97STreehugger Robot a : b c -> b c; 1439*16467b97STreehugger Robot b : ID -> ID ; 1440*16467b97STreehugger Robot c : INT -> INT ; 1441*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1442*16467b97STreehugger Robot INT : '0'..'9'+; 1443*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1444*16467b97STreehugger Robot ''') 1445*16467b97STreehugger Robot 1446*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "abc ick 34", 1447*16467b97STreehugger Robot expectErrors=True) 1448*16467b97STreehugger Robot self.assertEquals(["line 1:4 extraneous input u'ick' expecting INT"], 1449*16467b97STreehugger Robot errors) 1450*16467b97STreehugger Robot self.assertEquals("abc 34", found) 1451*16467b97STreehugger Robot 1452*16467b97STreehugger Robot 1453*16467b97STreehugger Robot #@testbase.broken("FIXME", AssertionError) 1454*16467b97STreehugger Robot def testMissingFirstTokenGivesErrorNode(self): 1455*16467b97STreehugger Robot grammar = textwrap.dedent( 1456*16467b97STreehugger Robot r''' 1457*16467b97STreehugger Robot grammar foo; 1458*16467b97STreehugger Robot options {language=Python;output=AST;} 1459*16467b97STreehugger Robot a : ID INT -> ID INT ; 1460*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1461*16467b97STreehugger Robot INT : '0'..'9'+; 1462*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1463*16467b97STreehugger Robot ''') 1464*16467b97STreehugger Robot 1465*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "34", expectErrors=True) 1466*16467b97STreehugger Robot self.assertEquals(["line 1:0 missing ID at u'34'"], errors) 1467*16467b97STreehugger Robot self.assertEquals("<missing ID> 34", found) 1468*16467b97STreehugger Robot 1469*16467b97STreehugger Robot 1470*16467b97STreehugger Robot #@testbase.broken("FIXME", AssertionError) 1471*16467b97STreehugger Robot def testMissingFirstTokenGivesErrorNode2(self): 1472*16467b97STreehugger Robot grammar = textwrap.dedent( 1473*16467b97STreehugger Robot r''' 1474*16467b97STreehugger Robot grammar foo; 1475*16467b97STreehugger Robot options {language=Python;output=AST;} 1476*16467b97STreehugger Robot a : b c -> b c; 1477*16467b97STreehugger Robot b : ID -> ID ; 1478*16467b97STreehugger Robot c : INT -> INT ; 1479*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1480*16467b97STreehugger Robot INT : '0'..'9'+; 1481*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1482*16467b97STreehugger Robot ''') 1483*16467b97STreehugger Robot 1484*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "34", expectErrors=True) 1485*16467b97STreehugger Robot # finds an error at the first token, 34, and re-syncs. 1486*16467b97STreehugger Robot # re-synchronizing does not consume a token because 34 follows 1487*16467b97STreehugger Robot # ref to rule b (start of c). It then matches 34 in c. 1488*16467b97STreehugger Robot self.assertEquals(["line 1:0 missing ID at u'34'"], errors) 1489*16467b97STreehugger Robot self.assertEquals("<missing ID> 34", found) 1490*16467b97STreehugger Robot 1491*16467b97STreehugger Robot 1492*16467b97STreehugger Robot def testNoViableAltGivesErrorNode(self): 1493*16467b97STreehugger Robot grammar = textwrap.dedent( 1494*16467b97STreehugger Robot r''' 1495*16467b97STreehugger Robot grammar foo; 1496*16467b97STreehugger Robot options {language=Python;output=AST;} 1497*16467b97STreehugger Robot a : b -> b | c -> c; 1498*16467b97STreehugger Robot b : ID -> ID ; 1499*16467b97STreehugger Robot c : INT -> INT ; 1500*16467b97STreehugger Robot ID : 'a'..'z'+ ; 1501*16467b97STreehugger Robot S : '*' ; 1502*16467b97STreehugger Robot INT : '0'..'9'+; 1503*16467b97STreehugger Robot WS : (' '|'\n') {$channel=HIDDEN;} ; 1504*16467b97STreehugger Robot ''') 1505*16467b97STreehugger Robot 1506*16467b97STreehugger Robot found, errors = self.execParser(grammar, "a", "*", expectErrors=True) 1507*16467b97STreehugger Robot # finds an error at the first token, 34, and re-syncs. 1508*16467b97STreehugger Robot # re-synchronizing does not consume a token because 34 follows 1509*16467b97STreehugger Robot # ref to rule b (start of c). It then matches 34 in c. 1510*16467b97STreehugger Robot self.assertEquals(["line 1:0 no viable alternative at input u'*'"], 1511*16467b97STreehugger Robot errors); 1512*16467b97STreehugger Robot self.assertEquals("<unexpected: [@0,0:0=u'*',<6>,1:0], resync=*>", 1513*16467b97STreehugger Robot found) 1514*16467b97STreehugger Robot 1515*16467b97STreehugger Robot 1516*16467b97STreehugger Robotif __name__ == '__main__': 1517*16467b97STreehugger Robot unittest.main() 1518