1 import unittest 2 import re 3 import textwrap 4 import antlr3 5 import testbase 6 7 8 # Left-recursion resolution is not yet enabled in the tool. 9 10 # class TestLeftRecursion(testbase.ANTLRTest): 11 # def parserClass(self, base): 12 # class TParser(base): 13 # def __init__(self, *args, **kwargs): 14 # base.__init__(self, *args, **kwargs) 15 16 # self._output = "" 17 18 19 # def capture(self, t): 20 # self._output += str(t) 21 22 23 # def recover(self, input, re): 24 # # no error recovery yet, just crash! 25 # raise 26 27 # return TParser 28 29 30 # def execParser(self, grammar, grammarEntry, input): 31 # lexerCls, parserCls = self.compileInlineGrammar(grammar) 32 33 # cStream = antlr3.StringStream(input) 34 # lexer = lexerCls(cStream) 35 # tStream = antlr3.CommonTokenStream(lexer) 36 # parser = parserCls(tStream) 37 # getattr(parser, grammarEntry)() 38 # return parser._output 39 40 41 # def runTests(self, grammar, tests, grammarEntry): 42 # lexerCls, parserCls = self.compileInlineGrammar(grammar) 43 44 # build_ast = re.search(r'output\s*=\s*AST', grammar) 45 46 # for input, expecting in tests: 47 # cStream = antlr3.StringStream(input) 48 # lexer = lexerCls(cStream) 49 # tStream = antlr3.CommonTokenStream(lexer) 50 # parser = parserCls(tStream) 51 # r = getattr(parser, grammarEntry)() 52 # found = parser._output 53 # if build_ast: 54 # found += r.tree.toStringTree() 55 56 # self.assertEquals( 57 # expecting, found, 58 # "%r != %r (for input %r)" % (expecting, found, input)) 59 60 61 # def testSimple(self): 62 # grammar = textwrap.dedent( 63 # r""" 64 # grammar T; 65 # options { 66 # language=Python; 67 # } 68 # s : a { self.capture($a.text) } ; 69 # a : a ID 70 # | ID 71 # ; 72 # ID : 'a'..'z'+ ; 73 # WS : (' '|'\n') {self.skip()} ; 74 # """) 75 76 # found = self.execParser(grammar, 's', 'a b c') 77 # expecting = "abc" 78 # self.assertEquals(expecting, found) 79 80 81 # def testSemPred(self): 82 # grammar = textwrap.dedent( 83 # r""" 84 # grammar T; 85 # options { 86 # language=Python; 87 # } 88 # s : a { self.capture($a.text) } ; 89 # a : a {True}? ID 90 # | ID 91 # ; 92 # ID : 'a'..'z'+ ; 93 # WS : (' '|'\n') {self.skip()} ; 94 # """) 95 96 # found = self.execParser(grammar, "s", "a b c") 97 # expecting = "abc" 98 # self.assertEquals(expecting, found) 99 100 # def testTernaryExpr(self): 101 # grammar = textwrap.dedent( 102 # r""" 103 # grammar T; 104 # options { 105 # language=Python; 106 # output=AST; 107 # } 108 # e : e '*'^ e 109 # | e '+'^ e 110 # | e '?'<assoc=right>^ e ':'! e 111 # | e '='<assoc=right>^ e 112 # | ID 113 # ; 114 # ID : 'a'..'z'+ ; 115 # WS : (' '|'\n') {self.skip()} ; 116 # """) 117 118 # tests = [ 119 # ("a", "a"), 120 # ("a+b", "(+ a b)"), 121 # ("a*b", "(* a b)"), 122 # ("a?b:c", "(? a b c)"), 123 # ("a=b=c", "(= a (= b c))"), 124 # ("a?b+c:d", "(? a (+ b c) d)"), 125 # ("a?b=c:d", "(? a (= b c) d)"), 126 # ("a? b?c:d : e", "(? a (? b c d) e)"), 127 # ("a?b: c?d:e", "(? a b (? c d e))"), 128 # ] 129 # self.runTests(grammar, tests, "e") 130 131 132 # def testDeclarationsUsingASTOperators(self): 133 # grammar = textwrap.dedent( 134 # r""" 135 # grammar T; 136 # options { 137 # language=Python; 138 # output=AST; 139 # } 140 # declarator 141 # : declarator '['^ e ']'! 142 # | declarator '['^ ']'! 143 # | declarator '('^ ')'! 144 # | '*'^ declarator // binds less tight than suffixes 145 # | '('! declarator ')'! 146 # | ID 147 # ; 148 # e : INT ; 149 # ID : 'a'..'z'+ ; 150 # INT : '0'..'9'+ ; 151 # WS : (' '|'\n') {self.skip()} ; 152 # """) 153 154 # tests = [ 155 # ("a", "a"), 156 # ("*a", "(* a)"), 157 # ("**a", "(* (* a))"), 158 # ("a[3]", "([ a 3)"), 159 # ("b[]", "([ b)"), 160 # ("(a)", "a"), 161 # ("a[]()", "(( ([ a))"), 162 # ("a[][]", "([ ([ a))"), 163 # ("*a[]", "(* ([ a))"), 164 # ("(*a)[]", "([ (* a))"), 165 # ] 166 # self.runTests(grammar, tests, "declarator") 167 168 169 # def testDeclarationsUsingRewriteOperators(self): 170 # grammar = textwrap.dedent( 171 # r""" 172 # grammar T; 173 # options { 174 # language=Python; 175 # output=AST; 176 # } 177 # declarator 178 # : declarator '[' e ']' -> ^('[' declarator e) 179 # | declarator '[' ']' -> ^('[' declarator) 180 # | declarator '(' ')' -> ^('(' declarator) 181 # | '*' declarator -> ^('*' declarator) // binds less tight than suffixes 182 # | '(' declarator ')' -> declarator 183 # | ID -> ID 184 # ; 185 # e : INT ; 186 # ID : 'a'..'z'+ ; 187 # INT : '0'..'9'+ ; 188 # WS : (' '|'\n') {self.skip()} ; 189 # """) 190 191 # tests = [ 192 # ("a", "a"), 193 # ("*a", "(* a)"), 194 # ("**a", "(* (* a))"), 195 # ("a[3]", "([ a 3)"), 196 # ("b[]", "([ b)"), 197 # ("(a)", "a"), 198 # ("a[]()", "(( ([ a))"), 199 # ("a[][]", "([ ([ a))"), 200 # ("*a[]", "(* ([ a))"), 201 # ("(*a)[]", "([ (* a))"), 202 # ] 203 # self.runTests(grammar, tests, "declarator") 204 205 206 # def testExpressionsUsingASTOperators(self): 207 # grammar = textwrap.dedent( 208 # r""" 209 # grammar T; 210 # options { 211 # language=Python; 212 # output=AST; 213 # } 214 # e : e '.'^ ID 215 # | e '.'^ 'this' 216 # | '-'^ e 217 # | e '*'^ e 218 # | e ('+'^|'-'^) e 219 # | INT 220 # | ID 221 # ; 222 # ID : 'a'..'z'+ ; 223 # INT : '0'..'9'+ ; 224 # WS : (' '|'\n') {self.skip()} ; 225 # """) 226 227 # tests = [ 228 # ("a", "a"), 229 # ("1", "1"), 230 # ("a+1", "(+ a 1)"), 231 # ("a*1", "(* a 1)"), 232 # ("a.b", "(. a b)"), 233 # ("a.this", "(. a this)"), 234 # ("a-b+c", "(+ (- a b) c)"), 235 # ("a+b*c", "(+ a (* b c))"), 236 # ("a.b+1", "(+ (. a b) 1)"), 237 # ("-a", "(- a)"), 238 # ("-a+b", "(+ (- a) b)"), 239 # ("-a.b", "(- (. a b))"), 240 # ] 241 # self.runTests(grammar, tests, "e") 242 243 244 # @testbase.broken( 245 # "Grammar compilation returns errors", testbase.GrammarCompileError) 246 # def testExpressionsUsingRewriteOperators(self): 247 # grammar = textwrap.dedent( 248 # r""" 249 # grammar T; 250 # options { 251 # language=Python; 252 # output=AST; 253 # } 254 # e : e '.' ID -> ^('.' e ID) 255 # | e '.' 'this' -> ^('.' e 'this') 256 # | '-' e -> ^('-' e) 257 # | e '*' b=e -> ^('*' e $b) 258 # | e (op='+'|op='-') b=e -> ^($op e $b) 259 # | INT -> INT 260 # | ID -> ID 261 # ; 262 # ID : 'a'..'z'+ ; 263 # INT : '0'..'9'+ ; 264 # WS : (' '|'\n') {self.skip()} ; 265 # """) 266 267 # tests = [ 268 # ("a", "a"), 269 # ("1", "1"), 270 # ("a+1", "(+ a 1)"), 271 # ("a*1", "(* a 1)"), 272 # ("a.b", "(. a b)"), 273 # ("a.this", "(. a this)"), 274 # ("a+b*c", "(+ a (* b c))"), 275 # ("a.b+1", "(+ (. a b) 1)"), 276 # ("-a", "(- a)"), 277 # ("-a+b", "(+ (- a) b)"), 278 # ("-a.b", "(- (. a b))"), 279 # ] 280 # self.runTests(grammar, tests, "e") 281 282 283 # def testExpressionAssociativity(self): 284 # grammar = textwrap.dedent( 285 # r""" 286 # grammar T; 287 # options { 288 # language=Python; 289 # output=AST; 290 # } 291 # e 292 # : e '.'^ ID 293 # | '-'^ e 294 # | e '^'<assoc=right>^ e 295 # | e '*'^ e 296 # | e ('+'^|'-'^) e 297 # | e ('='<assoc=right>^ |'+='<assoc=right>^) e 298 # | INT 299 # | ID 300 # ; 301 # ID : 'a'..'z'+ ; 302 # INT : '0'..'9'+ ; 303 # WS : (' '|'\n') {self.skip()} ; 304 # """) 305 306 # tests = [ 307 # ("a", "a"), 308 # ("1", "1"), 309 # ("a+1", "(+ a 1)"), 310 # ("a*1", "(* a 1)"), 311 # ("a.b", "(. a b)"), 312 # ("a-b+c", "(+ (- a b) c)"), 313 # ("a+b*c", "(+ a (* b c))"), 314 # ("a.b+1", "(+ (. a b) 1)"), 315 # ("-a", "(- a)"), 316 # ("-a+b", "(+ (- a) b)"), 317 # ("-a.b", "(- (. a b))"), 318 # ("a^b^c", "(^ a (^ b c))"), 319 # ("a=b=c", "(= a (= b c))"), 320 # ("a=b=c+d.e", "(= a (= b (+ c (. d e))))"), 321 # ] 322 # self.runTests(grammar, tests, "e") 323 324 325 # def testJavaExpressions(self): 326 # grammar = textwrap.dedent( 327 # r""" 328 # grammar T; 329 # options { 330 # language=Python; 331 # output=AST; 332 # } 333 # expressionList 334 # : e (','! e)* 335 # ; 336 # e : '('! e ')'! 337 # | 'this' 338 # | 'super' 339 # | INT 340 # | ID 341 # | type '.'^ 'class' 342 # | e '.'^ ID 343 # | e '.'^ 'this' 344 # | e '.'^ 'super' '('^ expressionList? ')'! 345 # | e '.'^ 'new'^ ID '('! expressionList? ')'! 346 # | 'new'^ type ( '(' expressionList? ')'! | (options {k=1;}:'[' e ']'!)+) // ugly; simplified 347 # | e '['^ e ']'! 348 # | '('^ type ')'! e 349 # | e ('++'^ | '--'^) 350 # | e '('^ expressionList? ')'! 351 # | ('+'^|'-'^|'++'^|'--'^) e 352 # | ('~'^|'!'^) e 353 # | e ('*'^|'/'^|'%'^) e 354 # | e ('+'^|'-'^) e 355 # | e ('<'^ '<' | '>'^ '>' '>' | '>'^ '>') e 356 # | e ('<='^ | '>='^ | '>'^ | '<'^) e 357 # | e 'instanceof'^ e 358 # | e ('=='^ | '!='^) e 359 # | e '&'^ e 360 # | e '^'<assoc=right>^ e 361 # | e '|'^ e 362 # | e '&&'^ e 363 # | e '||'^ e 364 # | e '?' e ':' e 365 # | e ('='<assoc=right>^ 366 # |'+='<assoc=right>^ 367 # |'-='<assoc=right>^ 368 # |'*='<assoc=right>^ 369 # |'/='<assoc=right>^ 370 # |'&='<assoc=right>^ 371 # |'|='<assoc=right>^ 372 # |'^='<assoc=right>^ 373 # |'>>='<assoc=right>^ 374 # |'>>>='<assoc=right>^ 375 # |'<<='<assoc=right>^ 376 # |'%='<assoc=right>^) e 377 # ; 378 # type: ID 379 # | ID '['^ ']'! 380 # | 'int' 381 # | 'int' '['^ ']'! 382 # ; 383 # ID : ('a'..'z'|'A'..'Z'|'_'|'$')+; 384 # INT : '0'..'9'+ ; 385 # WS : (' '|'\n') {self.skip()} ; 386 # """) 387 388 # tests = [ 389 # ("a", "a"), 390 # ("1", "1"), 391 # ("a+1", "(+ a 1)"), 392 # ("a*1", "(* a 1)"), 393 # ("a.b", "(. a b)"), 394 # ("a-b+c", "(+ (- a b) c)"), 395 # ("a+b*c", "(+ a (* b c))"), 396 # ("a.b+1", "(+ (. a b) 1)"), 397 # ("-a", "(- a)"), 398 # ("-a+b", "(+ (- a) b)"), 399 # ("-a.b", "(- (. a b))"), 400 # ("a^b^c", "(^ a (^ b c))"), 401 # ("a=b=c", "(= a (= b c))"), 402 # ("a=b=c+d.e", "(= a (= b (+ c (. d e))))"), 403 # ("a|b&c", "(| a (& b c))"), 404 # ("(a|b)&c", "(& (| a b) c)"), 405 # ("a > b", "(> a b)"), 406 # ("a >> b", "(> a b)"), # text is from one token 407 # ("a < b", "(< a b)"), 408 # ("(T)x", "(( T x)"), 409 # ("new A().b", "(. (new A () b)"), 410 # ("(T)t.f()", "(( (( T (. t f)))"), 411 # ("a.f(x)==T.c", "(== (( (. a f) x) (. T c))"), 412 # ("a.f().g(x,1)", "(( (. (( (. a f)) g) x 1)"), 413 # ("new T[((n-1) * x) + 1]", "(new T [ (+ (* (- n 1) x) 1))"), 414 # ] 415 # self.runTests(grammar, tests, "e") 416 417 418 # def testReturnValueAndActions(self): 419 # grammar = textwrap.dedent( 420 # r""" 421 # grammar T; 422 # options { 423 # language=Python; 424 # } 425 # s : e { self.capture($e.v) } ; 426 # e returns [v, ignored] 427 # : e '*' b=e {$v *= $b.v;} 428 # | e '+' b=e {$v += $b.v;} 429 # | INT {$v = int($INT.text);} 430 # ; 431 # INT : '0'..'9'+ ; 432 # WS : (' '|'\n') {self.skip()} ; 433 # """) 434 435 # tests = [ 436 # ("4", "4"), 437 # ("1+2", "3") 438 # ] 439 # self.runTests(grammar, tests, "s") 440 441 442 # def testReturnValueAndActionsAndASTs(self): 443 # grammar = textwrap.dedent( 444 # r""" 445 # grammar T; 446 # options { 447 # language=Python; 448 # output=AST; 449 # } 450 # s : e { self.capture("v=\%s, " \% $e.v) } ; 451 # e returns [v, ignored] 452 # : e '*'^ b=e {$v *= $b.v;} 453 # | e '+'^ b=e {$v += $b.v;} 454 # | INT {$v = int($INT.text);} 455 # ; 456 # INT : '0'..'9'+ ; 457 # WS : (' '|'\n') {self.skip()} ; 458 # """) 459 460 # tests = [ 461 # ("4", "v=4, 4"), 462 # ("1+2", "v=3, (+ 1 2)"), 463 # ] 464 # self.runTests(grammar, tests, "s") 465 466 467 if __name__ == '__main__': 468 unittest.main() 469