10.12., 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit 7ea1fb30 authored by di68kap's avatar di68kap

- test_grammar function tested (and corrected)

parent fee343d4
......@@ -34,7 +34,11 @@ from .syntaxtree import Node, traverse, remove_enclosing_delimiters, reduce_sing
from .versionnumber import __version__
__all__ = ['EBNFGrammar',
__all__ = ['get_ebnf_scanner',
'get_ebnf_grammar',
'get_ebnf_transformer',
'get_ebnf_compiler',
'EBNFGrammar',
'EBNFTransformer',
'EBNFCompilerError',
'EBNFCompiler',
......
......@@ -56,7 +56,8 @@ try:
except ImportError:
import re
from .toolkit import is_logging, log_dir, logfile_basename, escape_re, sane_parser_name
from .toolkit import is_logging, log_dir, logfile_basename, escape_re, sane_parser_name, \
compact_sexpr
from .syntaxtree import WHITESPACE_KEYWORD, TOKEN_KEYWORD, ZOMBIE_PARSER, Node, \
mock_syntax_tree
from DHParser.toolkit import load_if_file, error_messages
......@@ -1090,24 +1091,29 @@ def test_grammar(test_suite, parser_factory, transformer_factory):
for test_name, test_code in tests['match'].items():
cst = parser(test_code, parser_name)
tests['__cst__'][test_name] = cst
tests.setdefault('__cst__', {})[test_name] = cst
if cst.error_flag:
errata.append("Test %s for parser %s : didn't match: \n%s" %
(test_name, parser_name,
error_messages(test_code, cst.collect_errors())))
errata.append('Match test "%s" for parser "%s" failed:\n\tExpr.: %s\n\t%s' %
(test_name, parser_name, '\n\t'.join(test_code.split('\n')),
'\n\t'.join(error_messages(test_code, cst.collect_errors()))))
elif "cst" in tests and mock_syntax_tree(tests["cst"][test_name]) != cst:
errata.append("Test %s for parser %s : wrong CST: \n%s" %
errata.append('Concrete syntax tree test "%s" for parser "%s" failed:\n%s' %
(test_name, parser_name, cst.as_sexpr()))
elif "ast" in tests:
ast = transform(cst)
tests['__ast__'][test_name] = ast
if mock_syntax_tree(tests["ast"][test_name]) != ast:
errata.append("Test %s for parser %s : wrong AST: \n%s" %
(test_name, parser_name, ast.as_sexpr()))
ast = copy.deepcopy(cst)
transform(ast)
tests.setdefault('__ast__', {})[test_name] = ast
compare = mock_syntax_tree(tests["ast"][test_name])
if compare != ast:
errata.append('Abstract syntax tree test "%s" for parser "%s" failed:'
'\n\tExpr.: %s\n\tExpected: %s\n\tReceived: %s'
% (test_name, parser_name, '\n\t'.join(test_code.split('\n')),
compact_sexpr(ast.as_sexpr()),
compact_sexpr(compare.as_sexpr())))
for test_name, test_code in tests['fail'].items():
cst = parser(test_code, parser_name)
if not cst.error_flag:
errata.append("Test %s for parser %s : shouldn't have matched!" %
(test_name, parser_name))
errata.append('Fail test "%s" for parser "%s" yields match instead of '
'expected failure!' % (test_name, parser_name))
return errata
......@@ -167,7 +167,8 @@ class Node:
return str(self.result)
def __eq__(self, other):
return str(self.parser) == str(other.parser) and self.result == other.result
# return str(self.parser) == str(other.parser) and self.result == other.result
return self.tag_name == other.tag_name and self.result == other.result
def __hash__(self):
return hash((str(self.parser), ))
......@@ -421,7 +422,8 @@ def mock_syntax_tree(sexpr):
def next_block(s):
s = s.strip()
while s[0] != ')':
assert s[0] == '(', s
if s[0] != '(': raise ValueError('"(" expected, not ' + s[:10])
# assert s[0] == '(', s
level = 1;
i = 1
while level > 0:
......@@ -434,7 +436,8 @@ def mock_syntax_tree(sexpr):
s = s[i:].strip()
sexpr = sexpr.strip()
assert sexpr[0] == '(', sexpr
if sexpr[0] != '(': raise ValueError('"(" expected, not ' + sexpr[:10])
# assert sexpr[0] == '(', sexpr
sexpr = sexpr[1:].strip()
m = re.match('\w+', sexpr)
name = sexpr[:m.end()]
......
......@@ -26,7 +26,7 @@ sys.path.extend(['../', './'])
from DHParser.toolkit import is_logging, compile_python_object
from DHParser.syntaxtree import no_operation, traverse, remove_expendables, \
replace_by_single_child, reduce_single_child, flatten, TOKEN_KEYWORD
from DHParser.parsers import compile_source
from DHParser.parsers import compile_source, test_grammar
from DHParser.ebnf import get_ebnf_grammar, get_ebnf_transformer, get_ebnf_compiler
from DHParser.dsl import parser_factory, DHPARSER_IMPORTS
......@@ -62,12 +62,56 @@ class TestGrammarTest:
2: "314",
},
"fail": {
1: "21F",
2: "G123"
3: "21F",
4: "G123"
}
},
"term": {
"match": {
1: "4 * 5",
2: "20 / 4",
3: "20 / 4 * 3"
},
"ast": {
1: "(term (factor 4) (TOKEN__ *) (factor 5))",
2: "(term (factor 20) (TOKEN__ /) (factor 4))",
3: "(term (term (factor 20) (TOKEN__ /) (factor 4)) (TOKEN__ *) (factor 3))"
},
"fail": {
4: "4 + 5",
5: "20 / 4 - 3"
}
}
}
failure_cases = {
"term": {
"match": {
1: "4 + 5", # error: this should fail
2: "20 / 4",
3: "20 / 4 * 3"
},
"ast": {
1: "(term (factor 4) (TOKEN__ *) (factor 5))",
2: "(term (factor 20) (TOKEN__ /) (factor 4))",
3: "(term (term (factor 19) (TOKEN__ /) (factor 4)) (TOKEN__ *) (factor 3))" # error 19 != 20
},
"fail": {
4: "4 * 5", # error: this should match
5: "20 / 4 - 3"
}
}
}
def test_test_grammar(self):
parser_fac = parser_factory(ARITHMETIC_EBNF)
trans_fac = lambda : ARITHMETIC_EBNFTransform
errata = test_grammar(self.cases, parser_fac, trans_fac)
assert not errata
errata = test_grammar(self.failure_cases, parser_fac, trans_fac)
# for e in errata:
# print(e)
assert len(errata) == 3
class TestInfiLoopsAndRecursion:
def test_direct_left_recursion(self):
......
......@@ -24,7 +24,9 @@ import sys
sys.path.extend(['../', './'])
from DHParser.toolkit import compact_sexpr
from DHParser.syntaxtree import traverse, mock_syntax_tree
from DHParser.syntaxtree import traverse, mock_syntax_tree, reduce_single_child, \
replace_by_single_child, flatten, remove_expendables, TOKEN_KEYWORD
from DHParser.dsl import parser_factory
class MockParser:
......@@ -86,10 +88,23 @@ class TestNode:
assert len(found) == 2
assert found[0].result == 'x' and found[1].result == 'y'
def test_equality(self):
def test_equality1(self):
assert self.unique_tree == self.unique_tree
assert self.recurr_tree != self.unique_tree
assert mock_syntax_tree('(a (b c))') != mock_syntax_tree('(a (b d))')
assert mock_syntax_tree('(a (b c))') == mock_syntax_tree('(a (b c))')
def test_equality2(self):
ebnf = 'term = term ("*"|"/") factor | factor\nfactor = /[0-9]+/~'
att = {"term": [replace_by_single_child, flatten],
"factor": [remove_expendables, reduce_single_child],
(TOKEN_KEYWORD): [remove_expendables, reduce_single_child],
"": [remove_expendables, replace_by_single_child]}
parser = parser_factory(ebnf)()
tree = parser("20 / 4 * 3")
traverse(tree, att)
compare_tree = mock_syntax_tree("(term (term (factor 20) (TOKEN__ /) (factor 4)) (TOKEN__ *) (factor 3))")
assert tree == compare_tree
def test_copy(self):
cpy = copy.deepcopy(self.unique_tree)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment