You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

432 lines
9.8 KiB

import unittest
import textwrap
import antlr3
import antlr3.tree
import testbase
import sys
class T(testbase.ANTLRTest):
def setUp(self):
self.oldPath = sys.path[:]
sys.path.insert(0, self.baseDir)
def tearDown(self):
sys.path = self.oldPath
def parserClass(self, base):
class TParser(base):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._output = ""
def capture(self, t):
self._output += t
def traceIn(self, ruleName, ruleIndex):
self.traces.append('>'+ruleName)
def traceOut(self, ruleName, ruleIndex):
self.traces.append('<'+ruleName)
def recover(self, input, re):
# no error recovery yet, just crash!
raise
return TParser
def lexerClass(self, base):
class TLexer(base):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._output = ""
def capture(self, t):
self._output += t
def traceIn(self, ruleName, ruleIndex):
self.traces.append('>'+ruleName)
def traceOut(self, ruleName, ruleIndex):
self.traces.append('<'+ruleName)
def recover(self, input):
# no error recovery yet, just crash!
raise
return TLexer
def execParser(self, grammar, grammarEntry, slaves, input):
for slave in slaves:
parserName = self.writeInlineGrammar(slave)[0]
# slave parsers are imported as normal python modules
# to force reloading current version, purge module from sys.modules
if parserName + 'Parser' in sys.modules:
del sys.modules[parserName + 'Parser']
lexerCls, parserCls = self.compileInlineGrammar(grammar)
cStream = antlr3.StringStream(input)
lexer = lexerCls(cStream)
tStream = antlr3.CommonTokenStream(lexer)
parser = parserCls(tStream)
getattr(parser, grammarEntry)()
return parser._output
def execLexer(self, grammar, slaves, input):
for slave in slaves:
parserName = self.writeInlineGrammar(slave)[0]
# slave parsers are imported as normal python modules
# to force reloading current version, purge module from sys.modules
if parserName + 'Parser' in sys.modules:
del sys.modules[parserName + 'Parser']
lexerCls = self.compileInlineGrammar(grammar)
cStream = antlr3.StringStream(input)
lexer = lexerCls(cStream)
while True:
token = lexer.nextToken()
if token is None or token.type == antlr3.EOF:
break
lexer._output += token.text
return lexer._output
def testDelegatorInvokesDelegateRule(self):
slave = textwrap.dedent(
r'''
parser grammar S1;
options {
language=Python3;
}
@members {
def capture(self, t):
self.gM1.capture(t)
}
a : B { self.capture("S.a") } ;
''')
master = textwrap.dedent(
r'''
grammar M1;
options {
language=Python3;
}
import S1;
s : a ;
B : 'b' ; // defines B from inherited token space
WS : (' '|'\n') {self.skip()} ;
''')
found = self.execParser(
master, 's',
slaves=[slave],
input="b"
)
self.assertEqual("S.a", found)
def testDelegatorInvokesDelegateRuleWithArgs(self):
slave = textwrap.dedent(
r'''
parser grammar S2;
options {
language=Python3;
}
@members {
def capture(self, t):
self.gM2.capture(t)
}
a[x] returns [y] : B {self.capture("S.a"); $y="1000";} ;
''')
master = textwrap.dedent(
r'''
grammar M2;
options {
language=Python3;
}
import S2;
s : label=a[3] {self.capture($label.y);} ;
B : 'b' ; // defines B from inherited token space
WS : (' '|'\n') {self.skip()} ;
''')
found = self.execParser(
master, 's',
slaves=[slave],
input="b"
)
self.assertEqual("S.a1000", found)
def testDelegatorAccessesDelegateMembers(self):
slave = textwrap.dedent(
r'''
parser grammar S3;
options {
language=Python3;
}
@members {
def capture(self, t):
self.gM3.capture(t)
def foo(self):
self.capture("foo")
}
a : B ;
''')
master = textwrap.dedent(
r'''
grammar M3; // uses no rules from the import
options {
language=Python3;
}
import S3;
s : 'b' {self.gS3.foo();} ; // gS is import pointer
WS : (' '|'\n') {self.skip()} ;
''')
found = self.execParser(
master, 's',
slaves=[slave],
input="b"
)
self.assertEqual("foo", found)
def testDelegatorInvokesFirstVersionOfDelegateRule(self):
slave = textwrap.dedent(
r'''
parser grammar S4;
options {
language=Python3;
}
@members {
def capture(self, t):
self.gM4.capture(t)
}
a : b {self.capture("S.a");} ;
b : B ;
''')
slave2 = textwrap.dedent(
r'''
parser grammar T4;
options {
language=Python3;
}
@members {
def capture(self, t):
self.gM4.capture(t)
}
a : B {self.capture("T.a");} ; // hidden by S.a
''')
master = textwrap.dedent(
r'''
grammar M4;
options {
language=Python3;
}
import S4,T4;
s : a ;
B : 'b' ;
WS : (' '|'\n') {self.skip()} ;
''')
found = self.execParser(
master, 's',
slaves=[slave, slave2],
input="b"
)
self.assertEqual("S.a", found)
def testDelegatesSeeSameTokenType(self):
slave = textwrap.dedent(
r'''
parser grammar S5; // A, B, C token type order
options {
language=Python3;
}
tokens { A; B; C; }
@members {
def capture(self, t):
self.gM5.capture(t)
}
x : A {self.capture("S.x ");} ;
''')
slave2 = textwrap.dedent(
r'''
parser grammar T5;
options {
language=Python3;
}
tokens { C; B; A; } /// reverse order
@members {
def capture(self, t):
self.gM5.capture(t)
}
y : A {self.capture("T.y");} ;
''')
master = textwrap.dedent(
r'''
grammar M5;
options {
language=Python3;
}
import S5,T5;
s : x y ; // matches AA, which should be "aa"
B : 'b' ; // another order: B, A, C
A : 'a' ;
C : 'c' ;
WS : (' '|'\n') {self.skip()} ;
''')
found = self.execParser(
master, 's',
slaves=[slave, slave2],
input="aa"
)
self.assertEqual("S.x T.y", found)
def testDelegatorRuleOverridesDelegate(self):
slave = textwrap.dedent(
r'''
parser grammar S6;
options {
language=Python3;
}
@members {
def capture(self, t):
self.gM6.capture(t)
}
a : b {self.capture("S.a");} ;
b : B ;
''')
master = textwrap.dedent(
r'''
grammar M6;
options {
language=Python3;
}
import S6;
b : 'b'|'c' ;
WS : (' '|'\n') {self.skip()} ;
''')
found = self.execParser(
master, 'a',
slaves=[slave],
input="c"
)
self.assertEqual("S.a", found)
# LEXER INHERITANCE
def testLexerDelegatorInvokesDelegateRule(self):
slave = textwrap.dedent(
r'''
lexer grammar S7;
options {
language=Python3;
}
@members {
def capture(self, t):
self.gM7.capture(t)
}
A : 'a' {self.capture("S.A ");} ;
C : 'c' ;
''')
master = textwrap.dedent(
r'''
lexer grammar M7;
options {
language=Python3;
}
import S7;
B : 'b' ;
WS : (' '|'\n') {self.skip()} ;
''')
found = self.execLexer(
master,
slaves=[slave],
input="abc"
)
self.assertEqual("S.A abc", found)
def testLexerDelegatorRuleOverridesDelegate(self):
slave = textwrap.dedent(
r'''
lexer grammar S8;
options {
language=Python3;
}
@members {
def capture(self, t):
self.gM8.capture(t)
}
A : 'a' {self.capture("S.A")} ;
''')
master = textwrap.dedent(
r'''
lexer grammar M8;
options {
language=Python3;
}
import S8;
A : 'a' {self.capture("M.A ");} ;
WS : (' '|'\n') {self.skip()} ;
''')
found = self.execLexer(
master,
slaves=[slave],
input="a"
)
self.assertEqual("M.A a", found)
if __name__ == '__main__':
unittest.main()