1import unittest 2import re 3import textwrap 4import antlr3 5import 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# super().__init__(*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.assertEqual( 57# expecting, found, 58# "{!r} != {!r} (for input {!r})".format(expecting, found, input)) 59 60 61# def testSimple(self): 62# grammar = textwrap.dedent( 63# r""" 64# grammar T; 65# options { 66# language=Python3; 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.assertEqual(expecting, found) 79 80 81# def testSemPred(self): 82# grammar = textwrap.dedent( 83# r""" 84# grammar T; 85# options { 86# language=Python3; 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.assertEqual(expecting, found) 99 100# def testTernaryExpr(self): 101# grammar = textwrap.dedent( 102# r""" 103# grammar T; 104# options { 105# language=Python3; 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=Python3; 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=Python3; 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=Python3; 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=Python3; 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=Python3; 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=Python3; 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=Python3; 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=Python3; 448# output=AST; 449# } 450# s : e { self.capture("v={}, ".format($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 467if __name__ == '__main__': 468 unittest.main() 469