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
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()
|