1import unittest 2import textwrap 3import antlr3 4import antlr3.tree 5import testbase 6import sys 7 8class T(testbase.ANTLRTest): 9 def setUp(self): 10 self.oldPath = sys.path[:] 11 sys.path.insert(0, self.baseDir) 12 13 14 def tearDown(self): 15 sys.path = self.oldPath 16 17 18 def parserClass(self, base): 19 class TParser(base): 20 def __init__(self, *args, **kwargs): 21 super().__init__(*args, **kwargs) 22 23 self._output = "" 24 25 26 def capture(self, t): 27 self._output += t 28 29 30 def traceIn(self, ruleName, ruleIndex): 31 self.traces.append('>'+ruleName) 32 33 34 def traceOut(self, ruleName, ruleIndex): 35 self.traces.append('<'+ruleName) 36 37 38 def recover(self, input, re): 39 # no error recovery yet, just crash! 40 raise 41 42 return TParser 43 44 45 def lexerClass(self, base): 46 class TLexer(base): 47 def __init__(self, *args, **kwargs): 48 super().__init__(*args, **kwargs) 49 50 self._output = "" 51 52 53 def capture(self, t): 54 self._output += t 55 56 57 def traceIn(self, ruleName, ruleIndex): 58 self.traces.append('>'+ruleName) 59 60 61 def traceOut(self, ruleName, ruleIndex): 62 self.traces.append('<'+ruleName) 63 64 65 def recover(self, input): 66 # no error recovery yet, just crash! 67 raise 68 69 return TLexer 70 71 72 def execParser(self, grammar, grammarEntry, slaves, input): 73 for slave in slaves: 74 parserName = self.writeInlineGrammar(slave)[0] 75 # slave parsers are imported as normal python modules 76 # to force reloading current version, purge module from sys.modules 77 if parserName + 'Parser' in sys.modules: 78 del sys.modules[parserName + 'Parser'] 79 80 lexerCls, parserCls = self.compileInlineGrammar(grammar) 81 82 cStream = antlr3.StringStream(input) 83 lexer = lexerCls(cStream) 84 tStream = antlr3.CommonTokenStream(lexer) 85 parser = parserCls(tStream) 86 getattr(parser, grammarEntry)() 87 88 return parser._output 89 90 91 def execLexer(self, grammar, slaves, input): 92 for slave in slaves: 93 parserName = self.writeInlineGrammar(slave)[0] 94 # slave parsers are imported as normal python modules 95 # to force reloading current version, purge module from sys.modules 96 if parserName + 'Parser' in sys.modules: 97 del sys.modules[parserName + 'Parser'] 98 99 lexerCls = self.compileInlineGrammar(grammar) 100 101 cStream = antlr3.StringStream(input) 102 lexer = lexerCls(cStream) 103 104 while True: 105 token = lexer.nextToken() 106 if token is None or token.type == antlr3.EOF: 107 break 108 109 lexer._output += token.text 110 111 return lexer._output 112 113 114 def testDelegatorInvokesDelegateRule(self): 115 slave = textwrap.dedent( 116 r''' 117 parser grammar S1; 118 options { 119 language=Python3; 120 } 121 @members { 122 def capture(self, t): 123 self.gM1.capture(t) 124 125 } 126 127 a : B { self.capture("S.a") } ; 128 ''') 129 130 master = textwrap.dedent( 131 r''' 132 grammar M1; 133 options { 134 language=Python3; 135 } 136 import S1; 137 s : a ; 138 B : 'b' ; // defines B from inherited token space 139 WS : (' '|'\n') {self.skip()} ; 140 ''') 141 142 found = self.execParser( 143 master, 's', 144 slaves=[slave], 145 input="b" 146 ) 147 148 self.assertEqual("S.a", found) 149 150 151 def testDelegatorInvokesDelegateRuleWithArgs(self): 152 slave = textwrap.dedent( 153 r''' 154 parser grammar S2; 155 options { 156 language=Python3; 157 } 158 @members { 159 def capture(self, t): 160 self.gM2.capture(t) 161 } 162 a[x] returns [y] : B {self.capture("S.a"); $y="1000";} ; 163 ''') 164 165 master = textwrap.dedent( 166 r''' 167 grammar M2; 168 options { 169 language=Python3; 170 } 171 import S2; 172 s : label=a[3] {self.capture($label.y);} ; 173 B : 'b' ; // defines B from inherited token space 174 WS : (' '|'\n') {self.skip()} ; 175 ''') 176 177 found = self.execParser( 178 master, 's', 179 slaves=[slave], 180 input="b" 181 ) 182 183 self.assertEqual("S.a1000", found) 184 185 186 def testDelegatorAccessesDelegateMembers(self): 187 slave = textwrap.dedent( 188 r''' 189 parser grammar S3; 190 options { 191 language=Python3; 192 } 193 @members { 194 def capture(self, t): 195 self.gM3.capture(t) 196 197 def foo(self): 198 self.capture("foo") 199 } 200 a : B ; 201 ''') 202 203 master = textwrap.dedent( 204 r''' 205 grammar M3; // uses no rules from the import 206 options { 207 language=Python3; 208 } 209 import S3; 210 s : 'b' {self.gS3.foo();} ; // gS is import pointer 211 WS : (' '|'\n') {self.skip()} ; 212 ''') 213 214 found = self.execParser( 215 master, 's', 216 slaves=[slave], 217 input="b" 218 ) 219 220 self.assertEqual("foo", found) 221 222 223 def testDelegatorInvokesFirstVersionOfDelegateRule(self): 224 slave = textwrap.dedent( 225 r''' 226 parser grammar S4; 227 options { 228 language=Python3; 229 } 230 @members { 231 def capture(self, t): 232 self.gM4.capture(t) 233 } 234 a : b {self.capture("S.a");} ; 235 b : B ; 236 ''') 237 238 slave2 = textwrap.dedent( 239 r''' 240 parser grammar T4; 241 options { 242 language=Python3; 243 } 244 @members { 245 def capture(self, t): 246 self.gM4.capture(t) 247 } 248 a : B {self.capture("T.a");} ; // hidden by S.a 249 ''') 250 251 master = textwrap.dedent( 252 r''' 253 grammar M4; 254 options { 255 language=Python3; 256 } 257 import S4,T4; 258 s : a ; 259 B : 'b' ; 260 WS : (' '|'\n') {self.skip()} ; 261 ''') 262 263 found = self.execParser( 264 master, 's', 265 slaves=[slave, slave2], 266 input="b" 267 ) 268 269 self.assertEqual("S.a", found) 270 271 272 def testDelegatesSeeSameTokenType(self): 273 slave = textwrap.dedent( 274 r''' 275 parser grammar S5; // A, B, C token type order 276 options { 277 language=Python3; 278 } 279 tokens { A; B; C; } 280 @members { 281 def capture(self, t): 282 self.gM5.capture(t) 283 } 284 x : A {self.capture("S.x ");} ; 285 ''') 286 287 slave2 = textwrap.dedent( 288 r''' 289 parser grammar T5; 290 options { 291 language=Python3; 292 } 293 tokens { C; B; A; } /// reverse order 294 @members { 295 def capture(self, t): 296 self.gM5.capture(t) 297 } 298 y : A {self.capture("T.y");} ; 299 ''') 300 301 master = textwrap.dedent( 302 r''' 303 grammar M5; 304 options { 305 language=Python3; 306 } 307 import S5,T5; 308 s : x y ; // matches AA, which should be "aa" 309 B : 'b' ; // another order: B, A, C 310 A : 'a' ; 311 C : 'c' ; 312 WS : (' '|'\n') {self.skip()} ; 313 ''') 314 315 found = self.execParser( 316 master, 's', 317 slaves=[slave, slave2], 318 input="aa" 319 ) 320 321 self.assertEqual("S.x T.y", found) 322 323 324 def testDelegatorRuleOverridesDelegate(self): 325 slave = textwrap.dedent( 326 r''' 327 parser grammar S6; 328 options { 329 language=Python3; 330 } 331 @members { 332 def capture(self, t): 333 self.gM6.capture(t) 334 } 335 a : b {self.capture("S.a");} ; 336 b : B ; 337 ''') 338 339 master = textwrap.dedent( 340 r''' 341 grammar M6; 342 options { 343 language=Python3; 344 } 345 import S6; 346 b : 'b'|'c' ; 347 WS : (' '|'\n') {self.skip()} ; 348 ''') 349 350 found = self.execParser( 351 master, 'a', 352 slaves=[slave], 353 input="c" 354 ) 355 356 self.assertEqual("S.a", found) 357 358 359 # LEXER INHERITANCE 360 361 def testLexerDelegatorInvokesDelegateRule(self): 362 slave = textwrap.dedent( 363 r''' 364 lexer grammar S7; 365 options { 366 language=Python3; 367 } 368 @members { 369 def capture(self, t): 370 self.gM7.capture(t) 371 } 372 A : 'a' {self.capture("S.A ");} ; 373 C : 'c' ; 374 ''') 375 376 master = textwrap.dedent( 377 r''' 378 lexer grammar M7; 379 options { 380 language=Python3; 381 } 382 import S7; 383 B : 'b' ; 384 WS : (' '|'\n') {self.skip()} ; 385 ''') 386 387 found = self.execLexer( 388 master, 389 slaves=[slave], 390 input="abc" 391 ) 392 393 self.assertEqual("S.A abc", found) 394 395 396 def testLexerDelegatorRuleOverridesDelegate(self): 397 slave = textwrap.dedent( 398 r''' 399 lexer grammar S8; 400 options { 401 language=Python3; 402 } 403 @members { 404 def capture(self, t): 405 self.gM8.capture(t) 406 } 407 A : 'a' {self.capture("S.A")} ; 408 ''') 409 410 master = textwrap.dedent( 411 r''' 412 lexer grammar M8; 413 options { 414 language=Python3; 415 } 416 import S8; 417 A : 'a' {self.capture("M.A ");} ; 418 WS : (' '|'\n') {self.skip()} ; 419 ''') 420 421 found = self.execLexer( 422 master, 423 slaves=[slave], 424 input="a" 425 ) 426 427 self.assertEqual("M.A a", found) 428 429 430if __name__ == '__main__': 431 unittest.main() 432