Fixed BNF parsing issues
This commit is contained in:
@@ -249,7 +249,7 @@ class BnfParser(BaseParser):
|
||||
# (for example of recursive bnf definition)
|
||||
if self.context.obj and hasattr(self.context.obj, "name"):
|
||||
if concept_name == str(self.context.obj.name):
|
||||
return ConceptExpression(concept_name)
|
||||
return self.eat_rule_name_if_needed(ConceptExpression(concept_name))
|
||||
|
||||
concept = self.context.get_concept(concept_name)
|
||||
if not self.sheerka.is_known(concept):
|
||||
@@ -264,7 +264,7 @@ class BnfParser(BaseParser):
|
||||
expr = ConceptGroupExpression(concept) if self.sheerka.isaset(self.context, concept) \
|
||||
else ConceptExpression(concept)
|
||||
expr.rule_name = concept.name
|
||||
return expr
|
||||
return self.eat_rule_name_if_needed(expr)
|
||||
|
||||
ret = StrMatch(core.utils.strip_quotes(token.value))
|
||||
self.next_token()
|
||||
|
||||
@@ -58,7 +58,7 @@ class NameNode(DefaultParserNode):
|
||||
if not first:
|
||||
name += " "
|
||||
|
||||
name += token.value[1:-1] if token.type == TokenKind.STRING else token.value
|
||||
name += token.value[1:-1] if token.type == TokenKind.STRING else str(token.value)
|
||||
first = False
|
||||
|
||||
return name
|
||||
|
||||
@@ -11,6 +11,16 @@ from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
|
||||
class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
|
||||
def init_scenario(self, init_expressions):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
for expression in init_expressions:
|
||||
res = sheerka.evaluate_user_input(expression)
|
||||
assert len(res) == 1, f"Failed to execute '{expression}'"
|
||||
assert res[0].status, f"Error while executing '{expression}'"
|
||||
|
||||
return sheerka
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("1 + 1", 2),
|
||||
("sheerka.test()", 'I have access to Sheerka !')
|
||||
@@ -522,8 +532,6 @@ as:
|
||||
assert res[0].body == 21
|
||||
|
||||
def test_i_can_mix_concept_of_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
definitions = [
|
||||
"def concept one as 1",
|
||||
"def concept two as 2",
|
||||
@@ -531,8 +539,7 @@ as:
|
||||
"def concept a plus b as a + b"
|
||||
]
|
||||
|
||||
for definition in definitions:
|
||||
sheerka.evaluate_user_input(definition)
|
||||
sheerka = self.init_scenario(definitions)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval 1 plus 2")
|
||||
assert len(res) == 1
|
||||
@@ -584,14 +591,28 @@ as:
|
||||
assert res[0].status
|
||||
assert res[0].body == 43
|
||||
|
||||
def test_i_can_use_bnf_alias(self):
|
||||
definitions = [
|
||||
"def concept two as 2",
|
||||
"def concept number",
|
||||
"two isa number",
|
||||
"def concept plus_one from bnf number=n1 'plus_one' as n1 + 1",
|
||||
]
|
||||
|
||||
sheerka = self.init_scenario(definitions)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval two plus_one")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == 3
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_i_can_evaluate_concept_of_concept_when_multiple_choices(self):
|
||||
def test_i_can_recognize_composition_of_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
definitions = [
|
||||
"def concept little a where a",
|
||||
"def concept blue a where a",
|
||||
"def concept little blue a where a",
|
||||
"def concept house"
|
||||
]
|
||||
|
||||
@@ -610,6 +631,24 @@ as:
|
||||
assert res[1].status
|
||||
assert res[1].body == "little blue(house)"
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_i_can_recognize_composition_of_concept_with_priority(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
definitions = [
|
||||
"def concept a plus b where a,b",
|
||||
"def concept a times b where a,b",
|
||||
"modify concept 1001 set priority = 1",
|
||||
"modify concept 1002 set priority = 2",
|
||||
]
|
||||
|
||||
for definition in definitions:
|
||||
sheerka.evaluate_user_input(definition)
|
||||
|
||||
res = sheerka.evaluate_user_input("1 plus 2 times 3")
|
||||
assert res[0].status
|
||||
# check that the priority is applied
|
||||
|
||||
def test_i_can_say_that_a_concept_isa_another_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.evaluate_user_input("def concept foo")
|
||||
@@ -790,6 +829,27 @@ as:
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_i_can_manage_missing_variables_from_bnf_parsing(self):
|
||||
definitions = [
|
||||
"def concept one as 1",
|
||||
"def concept number",
|
||||
"one isa number",
|
||||
"def concept hundreds from bnf number=n1 'hundred' ('and' number=n2)? where n1<10 and n2<100 as n1 * 100 + n2",
|
||||
]
|
||||
|
||||
sheerka = self.init_scenario(definitions)
|
||||
|
||||
res = sheerka.evaluate_user_input("one hundred")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "hundreds")
|
||||
|
||||
res = sheerka.evaluate_user_input("eval one hundred")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == "100"
|
||||
|
||||
def test_i_can_say_than_bnf_concept_isa_another_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.evaluate_user_input("def concept number")
|
||||
|
||||
@@ -16,9 +16,9 @@ class ClassWithName:
|
||||
self.name = name
|
||||
|
||||
|
||||
def c(name):
|
||||
def c(name, rule_name=None):
|
||||
concept = Concept(name).init_key()
|
||||
return ConceptExpression(concept, rule_name=name)
|
||||
return ConceptExpression(concept, rule_name=rule_name or name)
|
||||
|
||||
|
||||
eof_token = Token(TokenKind.EOF, "", 0, 0, 0)
|
||||
@@ -94,6 +94,7 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
("foo | bar?", OrderedChoice(c("foo"), Optional(c("bar")))),
|
||||
("'str' = var", Sequence(StrMatch("str"), StrMatch("="), c("var"))),
|
||||
("'str''='var", Sequence(StrMatch("str"), StrMatch("="), c("var"))),
|
||||
("foo=f", c("foo", "f")),
|
||||
])
|
||||
def test_i_can_parse_regex_with_concept(self, expression, expected):
|
||||
foo = Concept("foo")
|
||||
@@ -111,10 +112,11 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
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(self):
|
||||
expression = "foo"
|
||||
expected = ConceptExpression("foo")
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("foo", ConceptExpression("foo")),
|
||||
("foo=f", ConceptExpression("foo", rule_name="f")),
|
||||
])
|
||||
def test_i_can_parse_regex_with_concept_when_the_concept_is_still_under_definition(self, expression, expected):
|
||||
context = self.get_context()
|
||||
context.obj = ClassWithName("foo")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user