Fixed #9 : I can parse 'def concept'
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
import pytest
|
||||
|
||||
from common.utils import unstr_concept
|
||||
from conftest import NewOntology
|
||||
from helpers import get_concepts
|
||||
from parsers.BnfDefinitionParser import BnfDefinitionParser
|
||||
from parsers.parser_utils import UnexpectedEof, UnexpectedToken
|
||||
from parsers.peg_parser import ConceptExpression, OneOrMore, Optional, OrderedChoice, RegExMatch, Sequence, StrMatch, \
|
||||
VariableExpression, ZeroOrMore
|
||||
|
||||
|
||||
def _cexp(concept_str, rule_name=None):
|
||||
concept_name, concept_id = unstr_concept(concept_str)
|
||||
return ConceptExpression(concept_id, rule_name or concept_name)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("'str'", StrMatch("str")),
|
||||
("1", StrMatch("1")),
|
||||
(" 1", StrMatch("1")),
|
||||
(",", StrMatch(",")),
|
||||
("r'str'", RegExMatch("str")),
|
||||
("'foo'?", Optional(StrMatch("foo"))),
|
||||
("'foo'*", ZeroOrMore(StrMatch("foo"))),
|
||||
("'foo'+", OneOrMore(StrMatch("foo"))),
|
||||
("1 | 2 | 3", OrderedChoice(StrMatch("1"), StrMatch("2"), StrMatch("3"))),
|
||||
("1|2|3", OrderedChoice(StrMatch("1"), StrMatch("2"), StrMatch("3"))),
|
||||
("1'|' 2 '|' 3", Sequence(StrMatch("1"), StrMatch("|"), StrMatch("2"), StrMatch("|"), StrMatch("3"))),
|
||||
("1 2 'foo'", Sequence(StrMatch("1"), StrMatch("2"), StrMatch("foo"))),
|
||||
("1 2 | 3 4+", OrderedChoice(
|
||||
Sequence(StrMatch("1"), StrMatch("2")),
|
||||
Sequence(StrMatch("3"), OneOrMore(StrMatch("4"))))),
|
||||
("1 (2 | 3) 4+", Sequence(
|
||||
StrMatch("1"),
|
||||
OrderedChoice(StrMatch("2"), StrMatch("3")),
|
||||
OneOrMore(StrMatch("4")))),
|
||||
("(1|2)+", OneOrMore(OrderedChoice(StrMatch("1"), StrMatch("2")))),
|
||||
("(1 2)+", OneOrMore(Sequence(StrMatch("1"), StrMatch("2")))),
|
||||
("1 *", Sequence(StrMatch("1"), StrMatch("*"))),
|
||||
("1 ?", Sequence(StrMatch("1"), StrMatch("?"))),
|
||||
("1 +", Sequence(StrMatch("1"), StrMatch("+"))),
|
||||
("(1|*) +", Sequence(OrderedChoice(StrMatch("1"), StrMatch("*")), StrMatch("+"))),
|
||||
("1, :&", Sequence(StrMatch("1"), StrMatch(","), StrMatch(":"), StrMatch("&"))),
|
||||
("(1 )", StrMatch("1")),
|
||||
("'str'=var", StrMatch("str", rule_name="var")),
|
||||
("'foo'?=var", Optional(StrMatch("foo"), rule_name="var")),
|
||||
("('foo'?)=var", Optional(StrMatch("foo"), rule_name="var")),
|
||||
("'foo'*=var", ZeroOrMore(StrMatch("foo"), rule_name="var")),
|
||||
("('foo'*)=var", ZeroOrMore(StrMatch("foo"), rule_name="var")),
|
||||
("'foo'+=var", OneOrMore(StrMatch("foo"), rule_name="var")),
|
||||
("('foo'+)=var", OneOrMore(StrMatch("foo"), rule_name="var")),
|
||||
("'foo'=var?", Optional(StrMatch("foo", rule_name="var"))),
|
||||
("('foo'=var)?", Optional(StrMatch("foo", rule_name="var"))),
|
||||
("'foo'=var*", ZeroOrMore(StrMatch("foo", rule_name="var"))),
|
||||
("('foo'=var)*", ZeroOrMore(StrMatch("foo", rule_name="var"))),
|
||||
("'foo'=var+", OneOrMore(StrMatch("foo", rule_name="var"))),
|
||||
("('foo'=var)+", OneOrMore(StrMatch("foo", rule_name="var"))),
|
||||
("r'str'=var", RegExMatch("str", rule_name="var")),
|
||||
("r'foo'?=var", Optional(RegExMatch("foo"), rule_name="var")),
|
||||
("(r'foo'?)=var", Optional(RegExMatch("foo"), rule_name="var")),
|
||||
("r'foo'*=var", ZeroOrMore(RegExMatch("foo"), rule_name="var")),
|
||||
("(r'foo'*)=var", ZeroOrMore(RegExMatch("foo"), rule_name="var")),
|
||||
("r'foo'+=var", OneOrMore(RegExMatch("foo"), rule_name="var")),
|
||||
("(r'foo'+)=var", OneOrMore(RegExMatch("foo"), rule_name="var")),
|
||||
("r'foo'=var?", Optional(RegExMatch("foo", rule_name="var"))),
|
||||
("(r'foo'=var)?", Optional(RegExMatch("foo", rule_name="var"))),
|
||||
("r'foo'=var*", ZeroOrMore(RegExMatch("foo", rule_name="var"))),
|
||||
("(r'foo'=var)*", ZeroOrMore(RegExMatch("foo", rule_name="var"))),
|
||||
("r'foo'=var+", OneOrMore(RegExMatch("foo", rule_name="var"))),
|
||||
("(r'foo'=var)+", OneOrMore(RegExMatch("foo", rule_name="var"))),
|
||||
("(1 | 2 | 3)=var", OrderedChoice(StrMatch("1"), StrMatch("2"), StrMatch("3"), rule_name="var")),
|
||||
("(1 2)=var", Sequence(StrMatch("1"), StrMatch("2"), rule_name="var")),
|
||||
("(1 2)+=var", OneOrMore(Sequence(StrMatch("1"), StrMatch("2")), rule_name="var")),
|
||||
("(1 2)=var+", OneOrMore(Sequence(StrMatch("1"), StrMatch("2"), rule_name="var"))),
|
||||
("(1=a 2=b)=c", Sequence(StrMatch("1", rule_name="a"), StrMatch("2", rule_name="b"), rule_name="c")),
|
||||
("(1*=a)", ZeroOrMore(StrMatch("1"), rule_name="a")),
|
||||
("'a'* 'b'+", Sequence(ZeroOrMore(StrMatch("a")), OneOrMore(StrMatch("b")))),
|
||||
("('a'* 'b'+)", Sequence(ZeroOrMore(StrMatch("a")), OneOrMore(StrMatch("b")))),
|
||||
("('a'*=x 'b'+=y)=z", Sequence(
|
||||
ZeroOrMore(StrMatch("a"), rule_name="x"),
|
||||
OneOrMore(StrMatch("b"), rule_name="y"), rule_name="z")),
|
||||
("'--filter'",
|
||||
Sequence(StrMatch("-", skip_whitespace=False), StrMatch("-", skip_whitespace=False), StrMatch("filter")))
|
||||
])
|
||||
def test_i_can_parse_simple_bnf_definition(context, expression, expected):
|
||||
parser = BnfDefinitionParser(context, expression)
|
||||
res = parser.parse()
|
||||
|
||||
assert res == expected
|
||||
assert not parser.error_sink
|
||||
assert parser.source == expression
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("foo", _cexp("c:foo#1001:")),
|
||||
("foo*", ZeroOrMore(_cexp("c:foo#1001:"))),
|
||||
("foo 'and' bar+", Sequence(_cexp("c:foo#1001:"), StrMatch("and"), OneOrMore(_cexp("c:bar#1002:")))),
|
||||
("foo | bar?", OrderedChoice(_cexp("c:foo#1001:"), Optional(_cexp("c:bar#1002:")))),
|
||||
("'str' = var", Sequence(StrMatch("str"), StrMatch("="), _cexp("c:var#1003:"))),
|
||||
("'str''='var", Sequence(StrMatch("str"), StrMatch("="), _cexp("c:var#1003:"))),
|
||||
("foo=f", _cexp("c:foo#1001:", "f")),
|
||||
("foo=f 'constant'", Sequence(_cexp("c:foo#1001:", "f"), StrMatch("constant"))),
|
||||
("def 'concept'", Sequence(_cexp("c:def#1004:"), StrMatch("concept"))),
|
||||
("c:foo:", _cexp("c:foo#1001:")),
|
||||
("c:#1001:", _cexp("c:foo#1001:")),
|
||||
])
|
||||
def test_i_can_parse_bnf_definition_with_concepts(context, expression, expected):
|
||||
with NewOntology(context, "test_i_can_parse_bnf_definition_with_concept"):
|
||||
get_concepts(context, "foo", "bar", "var", "def", use_sheerka=True)
|
||||
|
||||
parser = BnfDefinitionParser(context, expression)
|
||||
res = parser.parse()
|
||||
|
||||
assert res == expected
|
||||
assert not parser.error_sink
|
||||
assert parser.source == expression
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("x", VariableExpression("x")),
|
||||
("x bar", Sequence(VariableExpression("x"), _cexp("c:bar#1001:"))),
|
||||
("bar x", Sequence(_cexp("c:bar#1001:"), VariableExpression("x"))),
|
||||
("x 'and' bar", Sequence(VariableExpression("x"), StrMatch("and"), _cexp("c:bar#1001:"))),
|
||||
("x | bar", OrderedChoice(VariableExpression("x"), _cexp("c:bar#1001:"))),
|
||||
("x*", ZeroOrMore(VariableExpression("x"))),
|
||||
("x+", OneOrMore(VariableExpression("x"))),
|
||||
("'str' = x", Sequence(StrMatch("str"), StrMatch("="), VariableExpression("x"))),
|
||||
("'str''='x", Sequence(StrMatch("str"), StrMatch("="), VariableExpression("x"))),
|
||||
("foo=x", VariableExpression("x")),
|
||||
])
|
||||
def test_i_can_parse_bnf_definition_with_variables(context, expression, expected):
|
||||
with NewOntology(context, "test_i_can_parse_bnf_definition_with_variables"):
|
||||
get_concepts(context, "bar", use_sheerka=True)
|
||||
|
||||
parser = BnfDefinitionParser(context, expression)
|
||||
res = parser.parse()
|
||||
|
||||
assert res == expected
|
||||
assert not parser.error_sink
|
||||
assert parser.source == expression
|
||||
|
||||
|
||||
def test_i_can_parse_when_the_concept_is_still_under_creation(context):
|
||||
# I want to parse something like
|
||||
# def concept add from bnf add | mult
|
||||
# 'add' is used while being under construction
|
||||
# 'add' must not be detected as a variable
|
||||
parser = BnfDefinitionParser(context, "add | 'mult'", concept_name="add")
|
||||
res = parser.parse()
|
||||
|
||||
assert res == OrderedChoice(_cexp("c:add:"), StrMatch("mult"))
|
||||
assert not parser.error_sink
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expression, error", [
|
||||
("1 ", UnexpectedEof),
|
||||
("1|", UnexpectedEof),
|
||||
("(1|)", UnexpectedToken),
|
||||
("1=", UnexpectedToken),
|
||||
])
|
||||
def test_i_can_detect_errors(context, expression, error):
|
||||
parser = BnfDefinitionParser(context, expression)
|
||||
res = parser.parse()
|
||||
|
||||
assert res is None
|
||||
assert len(parser.error_sink) > 0
|
||||
assert isinstance(parser.error_sink[0], error)
|
||||
Reference in New Issue
Block a user