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.

310 lines
7.6 KiB

import unittest
import textwrap
import antlr3
import antlr3.tree
import testbase
import sys
from io import StringIO
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 testOverrideMain(self):
grammar = textwrap.dedent(
r"""lexer grammar T3;
options {
language = Python3;
}
@main {
def main(argv):
raise RuntimeError("no")
}
ID: ('a'..'z' | '\u00c0'..'\u00ff')+;
WS: ' '+ { $channel = HIDDEN };
""")
stdout = StringIO()
lexerMod = self.compileInlineGrammar(grammar, returnModule=True)
self.assertRaises(RuntimeError, lexerMod.main, ['lexer.py'])
def testLexerFromFile(self):
input = "foo bar"
inputPath = self.writeFile("input.txt", input)
grammar = textwrap.dedent(
r"""lexer grammar T1;
options {
language = Python3;
}
ID: 'a'..'z'+;
WS: ' '+ { $channel = HIDDEN };
""")
stdout = StringIO()
lexerMod = self.compileInlineGrammar(grammar, returnModule=True)
lexerMod.main(
['lexer.py', inputPath],
stdout=stdout
)
self.assertEqual(len(stdout.getvalue().splitlines()), 3)
def testLexerFromStdIO(self):
input = "foo bar"
grammar = textwrap.dedent(
r"""lexer grammar T2;
options {
language = Python3;
}
ID: 'a'..'z'+;
WS: ' '+ { $channel = HIDDEN };
""")
stdout = StringIO()
lexerMod = self.compileInlineGrammar(grammar, returnModule=True)
lexerMod.main(
['lexer.py'],
stdin=StringIO(input),
stdout=stdout
)
self.assertEqual(len(stdout.getvalue().splitlines()), 3)
def testLexerEncoding(self):
input = "föö bär"
grammar = textwrap.dedent(
r"""lexer grammar T3;
options {
language = Python3;
}
ID: ('a'..'z' | '\u00c0'..'\u00ff')+;
WS: ' '+ { $channel = HIDDEN };
""")
stdout = StringIO()
lexerMod = self.compileInlineGrammar(grammar, returnModule=True)
lexerMod.main(
['lexer.py'],
stdin=StringIO(input),
stdout=stdout
)
self.assertEqual(len(stdout.getvalue().splitlines()), 3)
def testCombined(self):
input = "foo bar"
grammar = textwrap.dedent(
r"""grammar T4;
options {
language = Python3;
}
r returns [res]: (ID)+ EOF { $res = $text };
ID: 'a'..'z'+;
WS: ' '+ { $channel = HIDDEN };
""")
stdout = StringIO()
lexerMod, parserMod = self.compileInlineGrammar(grammar, returnModule=True)
parserMod.main(
['combined.py', '--rule', 'r'],
stdin=StringIO(input),
stdout=stdout
)
stdout = stdout.getvalue()
self.assertEqual(len(stdout.splitlines()), 1, stdout)
def testCombinedOutputAST(self):
input = "foo + bar"
grammar = textwrap.dedent(
r"""grammar T5;
options {
language = Python3;
output = AST;
}
r: ID OP^ ID EOF!;
ID: 'a'..'z'+;
OP: '+';
WS: ' '+ { $channel = HIDDEN };
""")
stdout = StringIO()
lexerMod, parserMod = self.compileInlineGrammar(grammar, returnModule=True)
parserMod.main(
['combined.py', '--rule', 'r'],
stdin=StringIO(input),
stdout=stdout
)
stdout = stdout.getvalue().strip()
self.assertEqual(stdout, "(+ foo bar)")
def testTreeParser(self):
grammar = textwrap.dedent(
r'''grammar T6;
options {
language = Python3;
output = AST;
}
r: ID OP^ ID EOF!;
ID: 'a'..'z'+;
OP: '+';
WS: ' '+ { $channel = HIDDEN };
''')
treeGrammar = textwrap.dedent(
r'''tree grammar T6Walker;
options {
language=Python3;
ASTLabelType=CommonTree;
tokenVocab=T6;
}
r returns [res]: ^(OP a=ID b=ID)
{ $res = "{} {} {}".format($a.text, $OP.text, $b.text) }
;
''')
lexerMod, parserMod = self.compileInlineGrammar(grammar, returnModule=True)
walkerMod = self.compileInlineGrammar(treeGrammar, returnModule=True)
stdout = StringIO()
walkerMod.main(
['walker.py', '--rule', 'r', '--parser', 'T6Parser', '--parser-rule', 'r', '--lexer', 'T6Lexer'],
stdin=StringIO("a+b"),
stdout=stdout
)
stdout = stdout.getvalue().strip()
self.assertEqual(stdout, "'a + b'")
def testTreeParserRewrite(self):
grammar = textwrap.dedent(
r'''grammar T7;
options {
language = Python3;
output = AST;
}
r: ID OP^ ID EOF!;
ID: 'a'..'z'+;
OP: '+';
WS: ' '+ { $channel = HIDDEN };
''')
treeGrammar = textwrap.dedent(
r'''tree grammar T7Walker;
options {
language=Python3;
ASTLabelType=CommonTree;
tokenVocab=T7;
output=AST;
}
tokens {
ARG;
}
r: ^(OP a=ID b=ID) -> ^(OP ^(ARG ID) ^(ARG ID));
''')
lexerMod, parserMod = self.compileInlineGrammar(grammar, returnModule=True)
walkerMod = self.compileInlineGrammar(treeGrammar, returnModule=True)
stdout = StringIO()
walkerMod.main(
['walker.py', '--rule', 'r', '--parser', 'T7Parser', '--parser-rule', 'r', '--lexer', 'T7Lexer'],
stdin=StringIO("a+b"),
stdout=stdout
)
stdout = stdout.getvalue().strip()
self.assertEqual(stdout, "(+ (ARG a) (ARG b))")
def testGrammarImport(self):
slave = textwrap.dedent(
r'''
parser grammar T8S;
options {
language=Python3;
}
a : B;
''')
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']
master = textwrap.dedent(
r'''
grammar T8M;
options {
language=Python3;
}
import T8S;
s returns [res]: a { $res = $a.text };
B : 'b' ; // defines B from inherited token space
WS : (' '|'\n') {self.skip()} ;
''')
stdout = StringIO()
lexerMod, parserMod = self.compileInlineGrammar(master, returnModule=True)
parserMod.main(
['import.py', '--rule', 's'],
stdin=StringIO("b"),
stdout=stdout
)
stdout = stdout.getvalue().strip()
self.assertEqual(stdout, "'b'")
if __name__ == '__main__':
unittest.main()