We can now use concept sets in BNF definitions
This commit is contained in:
+72
-6
@@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka import Sheerka, ExecutionContext
|
||||
from core.tokenizer import Tokenizer, TokenKind, LexerError
|
||||
@@ -17,6 +18,11 @@ def get_context():
|
||||
return ExecutionContext("sheerka", Event(), sheerka)
|
||||
|
||||
|
||||
class ClassWithName():
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("'str'", StrMatch("str")),
|
||||
("1", StrMatch("1")),
|
||||
@@ -41,12 +47,6 @@ def get_context():
|
||||
("(1|*) +", Sequence(OrderedChoice(StrMatch("1"), StrMatch("*")), StrMatch("+"))),
|
||||
("1, :&", Sequence(StrMatch("1"), StrMatch(","), StrMatch(":"), StrMatch("&"))),
|
||||
("(1 )", StrMatch("1")),
|
||||
("foo", ConceptExpression("foo")),
|
||||
("foo*", ZeroOrMore(ConceptExpression("foo"))),
|
||||
("foo 'and' bar+", Sequence(ConceptExpression("foo"), StrMatch("and"), OneOrMore(ConceptExpression("bar")))),
|
||||
("foo | bar?", OrderedChoice(ConceptExpression("foo"), Optional(ConceptExpression("bar")))),
|
||||
("'str' = var", Sequence(StrMatch("str"), StrMatch("="), ConceptExpression("var"))),
|
||||
("'str''='var", Sequence(StrMatch("str"), StrMatch("="), ConceptExpression("var"))),
|
||||
("'str'=var", StrMatch("str", rule_name="var")),
|
||||
("'foo'?=var", Optional(StrMatch("foo"), rule_name="var")),
|
||||
("('foo'?)=var", Optional(StrMatch("foo"), rule_name="var")),
|
||||
@@ -75,6 +75,47 @@ def test_i_can_parse_regex(expression, expected):
|
||||
assert res.value.source == expression
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("foo", Concept("foo").init_key()),
|
||||
("foo*", ZeroOrMore(Concept("foo").init_key())),
|
||||
("foo 'and' bar+", Sequence(Concept("foo").init_key(), StrMatch("and"), OneOrMore(Concept("bar").init_key()))),
|
||||
("foo | bar?", OrderedChoice(Concept("foo").init_key(), Optional(Concept("bar").init_key()))),
|
||||
("'str' = var", Sequence(StrMatch("str"), StrMatch("="), Concept("var").init_key())),
|
||||
("'str''='var", Sequence(StrMatch("str"), StrMatch("="), Concept("var").init_key())),
|
||||
])
|
||||
def test_i_can_parse_regex_with_concept(expression, expected):
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
var = Concept("var")
|
||||
context = get_context()
|
||||
|
||||
for c in (foo, bar, var):
|
||||
context.sheerka.add_in_cache(c)
|
||||
parser = BnfParser()
|
||||
res = parser.parse(context, Tokenizer(expression))
|
||||
|
||||
assert not parser.has_error
|
||||
assert res.status
|
||||
assert res.value.value == expected
|
||||
assert res.value.source == expression
|
||||
|
||||
|
||||
def test_i_can_parse_regex_with_concept_when_the_concept_is_still_under_definition():
|
||||
expression = "foo"
|
||||
expected = ConceptExpression("foo")
|
||||
|
||||
context = get_context()
|
||||
context.obj = ClassWithName("foo")
|
||||
|
||||
parser = BnfParser()
|
||||
res = parser.parse(context, Tokenizer(expression))
|
||||
|
||||
assert not parser.has_error
|
||||
assert res.status
|
||||
assert res.value.value == expected
|
||||
assert res.value.source == expression
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expression, error", [
|
||||
("1 ", UnexpectedEndOfFileError()),
|
||||
("1|", UnexpectedEndOfFileError()),
|
||||
@@ -117,3 +158,28 @@ def test_i_can_use_the_result_of_regex_parsing_to_parse_a_text():
|
||||
res = concept_parser.parse(context, "twenty")
|
||||
assert res.status
|
||||
assert res.value.body == [cnode("foo", 0, 0, "twenty")]
|
||||
|
||||
|
||||
def test_i_cannot_parse_when_too_many_concepts():
|
||||
foo1 = Concept(name="foo", body="1")
|
||||
foo2 = Concept(name="foo", body="2")
|
||||
context = get_context()
|
||||
context.sheerka.cache_by_key["foo"] = [foo1, foo2]
|
||||
|
||||
regex_parser = BnfParser()
|
||||
res = regex_parser.parse(context, "foo")
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.CANNOT_RESOLVE_CONCEPT)
|
||||
assert res.value.body == ('key', 'foo')
|
||||
|
||||
|
||||
def test_i_cannot_parse_when_unknown_concept():
|
||||
context = get_context()
|
||||
|
||||
regex_parser = BnfParser()
|
||||
res = regex_parser.parse(get_context(), "foo")
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert res.value.body == ('key', 'foo')
|
||||
|
||||
Reference in New Issue
Block a user