Added first version of DebugManager. Implemented draft of the rule engine

This commit is contained in:
2020-11-20 13:41:45 +01:00
parent cd066881b4
commit 315f8ea09b
156 changed files with 8388 additions and 2852 deletions
+9 -3
View File
@@ -1,7 +1,7 @@
from core.concept import CC, Concept, ConceptParts, DoNotResolve, CIO
from core.tokenizer import Tokenizer, TokenKind, Token
from parsers.BaseNodeParser import scnode, utnode, cnode, SCWC, CNC, short_cnode, SourceCodeWithConceptNode, CN, UTN, \
SCN
SCN, RN
from parsers.SyaNodeParser import SyaConceptParserHelper
@@ -108,6 +108,12 @@ def get_node(
sub_expr.fix_pos(node)
return sub_expr
if isinstance(sub_expr, RN):
start, length = _index(expression_as_tokens, sub_expr.source, skip)
sub_expr.start = start
sub_expr.end = start + length - 1
return sub_expr
if isinstance(sub_expr, (CNC, CC, CN)):
concept_node = get_node(
concepts_map,
@@ -164,7 +170,7 @@ def get_node(
concept_found = concepts_map.get(concept_key, None)
if concept_found:
concept_found = Concept().update_from(concept_found) # make a copy when massively used in tests
if sya and len(concept_found.metadata.variables) > 0 and not is_bnf:
if sya and len(concept_found.get_metadata().variables) > 0 and not is_bnf:
return SyaConceptParserHelper(concept_found, start, start + length - 1)
elif init_empty_body:
node = CNC(concept_found, start, start + length - 1, source=sub_expr, exclude_body=exclude_body)
@@ -183,7 +189,7 @@ def init_body(item, concept, value):
del (item.compiled["body"])
return
if not concept or concept.metadata.body or ConceptParts.BODY in item.compiled:
if not concept or concept.get_metadata().body or ConceptParts.BODY in item.compiled:
return
item.compiled[ConceptParts.BODY] = DoNotResolve(value)
+10 -4
View File
@@ -2,7 +2,7 @@ import pytest
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept, DEFINITION_TYPE_DEF
from core.sheerka.services.SheerkaExecute import ParserInput
from parsers.AtomNodeParser import AtomNodeParser
from parsers.SequenceNodeParser import SequenceNodeParser
from parsers.BaseNodeParser import cnode, utnode, CNC, SCN, CN
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -17,9 +17,9 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
singleton=singleton)
if use_sheerka:
parser = AtomNodeParser(sheerka=sheerka)
parser = SequenceNodeParser(sheerka=sheerka)
else:
parser = AtomNodeParser()
parser = SequenceNodeParser()
parser.init_from_concepts(context, updated_concepts)
return sheerka, context, parser
@@ -351,7 +351,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
lexer_nodes = res.body.body
assert res.status
assert lexer_nodes[0].concept.metadata.is_evaluated == expected_is_evaluated
assert lexer_nodes[0].concept.get_metadata().is_evaluated == expected_is_evaluated
def test_the_parser_always_return_a_new_instance_of_the_concept(self):
concepts_map = {
@@ -376,3 +376,9 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME)
def test_i_do_not_parse_rules_instead_of_concepts(self):
sheerka, context, parser = self.init_parser({})
res = parser.parse(context, ParserInput("r:|20:"))
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME)
+12 -8
View File
@@ -38,22 +38,26 @@ class TestBaseCustomGrammarParser(TestUsingMemoryBasedSheerka):
return sheerka, context, parser
@pytest.mark.parametrize("text, expected", [
("when xxx yyy", {Keywords.WHEN: "when xxx yyy"}),
("when uuu vvv print xxx yyy", {Keywords.WHEN: "when uuu vvv ", Keywords.PRINT: "print xxx yyy"}),
("print xxx yyy when uuu vvv", {Keywords.WHEN: "when uuu vvv", Keywords.PRINT: "print xxx yyy "}),
(" when xxx", {Keywords.WHEN: "when xxx"}),
@pytest.mark.parametrize("text, strip_tokens, expected", [
("when xxx yyy", False, {Keywords.WHEN: "when xxx yyy"}),
("when uuu vvv print xxx yyy", False, {Keywords.WHEN: "when uuu vvv ", Keywords.PRINT: "print xxx yyy"}),
("print xxx yyy when uuu vvv", False, {Keywords.WHEN: "when uuu vvv", Keywords.PRINT: "print xxx yyy "}),
(" when xxx", False, {Keywords.WHEN: "when xxx"}),
("when xxx yyy", True, {Keywords.WHEN: "when xxx yyy"}),
("when uuu vvv print xxx yyy", True, {Keywords.WHEN: "when uuu vvv", Keywords.PRINT: "print xxx yyy"}),
("print xxx yyy when uuu vvv", True, {Keywords.WHEN: "when uuu vvv", Keywords.PRINT: "print xxx yyy"}),
(" when xxx", True, {Keywords.WHEN: "when xxx"}),
])
def test_i_can_get_parts(self, text, expected):
def test_i_can_get_parts(self, text, strip_tokens, expected):
sheerka, context, parser = self.init_parser(text)
res = parser.get_parts(["when", "print"])
res = parser.get_parts(["when", "print"], strip_tokens=strip_tokens)
self.compare_results(res, expected)
def test_i_can_get_parts_when_multilines(self):
text = """when
def func(x):
return x+1
\treturn x+1
func(a)
"""
expected = {Keywords.WHEN: "when def func(x):\n\treturn x+1\nfunc(a)\n"}
+3 -3
View File
@@ -51,7 +51,7 @@ class TestBaseNodeParser(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(bar)
concept = Concept("foo").init_key()
concept.bnf = bnf
concept.set_bnf(bnf)
sheerka.set_id_if_needed(concept, False)
res = BaseNodeParser.get_concepts_by_first_token(context, [concept])
@@ -72,7 +72,7 @@ class TestBaseNodeParser(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(baz)
foo = Concept("foo").init_key()
foo.bnf = OrderedChoice(ConceptExpression("bar"), ConceptExpression("baz"), StrMatch("qux"))
foo.set_bnf(OrderedChoice(ConceptExpression("bar"), ConceptExpression("baz"), StrMatch("qux")))
sheerka.set_id_if_needed(foo, False)
res = BaseNodeParser.get_concepts_by_first_token(context, [bar, baz, foo])
@@ -99,7 +99,7 @@ class TestBaseNodeParser(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(bar)
foo = Concept("foo").init_key()
foo.bnf = OrderedChoice(ConceptExpression("one"), ConceptExpression("bar"), StrMatch("qux"))
foo.set_bnf(OrderedChoice(ConceptExpression("one"), ConceptExpression("bar"), StrMatch("qux")))
sheerka.set_id_if_needed(foo, False)
res = BaseNodeParser.get_concepts_by_first_token(context, [bar, foo], use_sheerka=True)
-20
View File
@@ -4,26 +4,6 @@ from core.tokenizer import Tokenizer, TokenKind, Token
from parsers.BaseParser import BaseParser, BaseSplitIterParser
@pytest.mark.parametrize("text, expected_text", [
("hello world", "hello world"),
("'hello' 'world'", "'hello' 'world'"),
("def concept a from", "def concept a from"),
("()[]{}1=1.5+-/*><&é", "()[]{}1=1.5+-/*><&é"),
("execute(c:concept_name:)", "execute(c:concept_name:)")
])
def test_i_can_get_text_from_tokens(text, expected_text):
tokens = list(Tokenizer(text))
assert BaseParser.get_text_from_tokens(tokens) == expected_text
@pytest.mark.parametrize("text, custom, expected_text", [
("execute(c:concept_name:)", {TokenKind.CONCEPT: lambda t: f"__C__{t.value[0]}"}, "execute(__C__concept_name)")
])
def test_i_can_get_text_from_tokens_with_custom_switcher(text, custom, expected_text):
tokens = list(Tokenizer(text))
assert BaseParser.get_text_from_tokens(tokens, custom) == expected_text
@pytest.mark.parametrize("text, expected", [
("", ["<eof>"]),
+39 -39
View File
@@ -1,11 +1,11 @@
import pytest
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept, ConceptParts, DoNotResolve, CC, DEFINITION_TYPE_BNF
from core.concept import Concept, ConceptParts, DoNotResolve, CC, DEFINITION_TYPE_BNF, NotInit
from core.sheerka.services.SheerkaExecute import ParserInput
from parsers.BaseNodeParser import CNC, UTN, CN
from parsers.BnfNodeParser import StrMatch, TerminalNode, NonTerminalNode, Sequence, OrderedChoice, \
Optional, ZeroOrMore, OneOrMore, ConceptExpression, UnOrderedChoice, BnfNodeParser
from parsers.BnfParser import BnfParser
from parsers.BnfDefinitionParser import BnfDefinitionParser
import tests.parsers.parsers_utils
from tests.BaseTest import BaseTest
@@ -137,11 +137,11 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
@staticmethod
def update_bnf(context, concept):
bnf_parser = BnfParser()
res = bnf_parser.parse(context, concept.metadata.definition)
bnf_parser = BnfDefinitionParser()
res = bnf_parser.parse(context, concept.get_metadata().definition)
if res.status:
concept.bnf = res.value.value
concept.metadata.definition_type = DEFINITION_TYPE_BNF
concept.set_bnf(res.value.value)
concept.get_metadata().definition_type = DEFINITION_TYPE_BNF
else:
raise Exception(res)
return concept
@@ -572,16 +572,16 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
# explicit validations of the compiled
concept_foo = sequences[0][0].concept
assert concept_foo.body == BuiltinConcepts.NOT_INITIALIZED
assert concept_foo.compiled == {ConceptParts.BODY: DoNotResolve("one two")}
assert concept_foo.body == NotInit
assert concept_foo.get_compiled() == {ConceptParts.BODY: DoNotResolve("one two")}
concept_bar = sequences[1][0].concept
assert concept_bar.body == BuiltinConcepts.NOT_INITIALIZED
assert concept_bar.compiled == {
assert concept_bar.body == NotInit
assert concept_bar.get_compiled() == {
ConceptParts.BODY: concept_foo,
"foo": concept_foo
}
assert id(concept_bar.compiled[ConceptParts.BODY]) == id(concept_bar.compiled["foo"])
assert id(concept_bar.get_compiled()[ConceptParts.BODY]) == id(concept_bar.get_compiled()["foo"])
def test_i_can_refer_to_other_concepts_with_body(self):
my_map = {
@@ -598,12 +598,12 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
# explicit validations of the compiled
concept_foo = sequences[0][0].concept
assert concept_foo.body == BuiltinConcepts.NOT_INITIALIZED
assert len(concept_foo.compiled) == 0 # because there is a body defined in the metadata
assert concept_foo.body == NotInit
assert len(concept_foo.get_compiled()) == 0 # because there is a body defined in the metadata
concept_bar = sequences[1][0].concept
assert concept_bar.body == BuiltinConcepts.NOT_INITIALIZED
assert concept_bar.compiled == {
assert concept_bar.body == NotInit
assert concept_bar.get_compiled() == {
ConceptParts.BODY: concept_foo,
"foo": concept_foo
}
@@ -625,19 +625,19 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
# explicit validations of the compiled
concept_foo = sequences[0][0].concept
assert concept_foo.body == BuiltinConcepts.NOT_INITIALIZED
assert concept_foo.compiled == {ConceptParts.BODY: DoNotResolve("one two")}
assert concept_foo.body == NotInit
assert concept_foo.get_compiled() == {ConceptParts.BODY: DoNotResolve("one two")}
concept_bar = sequences[1][0].concept
assert concept_bar.body == BuiltinConcepts.NOT_INITIALIZED
assert concept_bar.compiled == {
assert concept_bar.body == NotInit
assert concept_bar.get_compiled() == {
ConceptParts.BODY: concept_foo,
"foo": concept_foo
}
concept_baz = sequences[2][0].concept
assert concept_baz.body == BuiltinConcepts.NOT_INITIALIZED
assert concept_baz.compiled == {
assert concept_baz.body == NotInit
assert concept_baz.get_compiled() == {
ConceptParts.BODY: concept_bar,
"bar": concept_bar
}
@@ -655,21 +655,21 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
expected = [CN("bar", source="twenty two")]
sequences = self.validate_get_concepts_sequences(my_map, text, expected)
concept_bar = sequences[0].concept
assert concept_bar.compiled == {
assert concept_bar.get_compiled() == {
ConceptParts.BODY: DoNotResolve("twenty two"),
"foo": my_map["foo"],
}
assert concept_bar.compiled["foo"].compiled == {ConceptParts.BODY: DoNotResolve("twenty")}
assert concept_bar.get_compiled()["foo"].get_compiled() == {ConceptParts.BODY: DoNotResolve("twenty")}
text = "thirty one"
expected = [CN("bar", source="thirty one")]
sequences = self.validate_get_concepts_sequences(my_map, text, expected)
concept_bar = sequences[0].concept
assert concept_bar.compiled == {
assert concept_bar.get_compiled() == {
ConceptParts.BODY: DoNotResolve("thirty one"),
"foo": my_map["foo"],
}
assert concept_bar.compiled["foo"].compiled == {ConceptParts.BODY: DoNotResolve("thirty")}
assert concept_bar.get_compiled()["foo"].get_compiled() == {ConceptParts.BODY: DoNotResolve("thirty")}
text = "thirty three"
expected = [[CN("foo", source="thirty"), CN("three")], []]
@@ -712,21 +712,21 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
sheerka, context, sequences = self.exec_get_concepts_sequences(my_map, text, expected)
concept_bar = sequences[0].concept
assert concept_bar.compiled == {
assert concept_bar.get_compiled() == {
ConceptParts.BODY: DoNotResolve("twenty two"),
"foo": sheerka.new("foo"),
}
assert concept_bar.compiled["foo"].compiled == {} # as foo as a body
assert concept_bar.get_compiled()["foo"].get_compiled() == {} # as foo as a body
text = "thirty one"
expected = [CN("bar", source="thirty one")]
sequences = self.validate_get_concepts_sequences(my_map, text, expected)
concept_bar = sequences[0].concept
assert concept_bar.compiled == {
assert concept_bar.get_compiled() == {
ConceptParts.BODY: DoNotResolve("thirty one"),
"foo": sheerka.new("foo"),
}
assert concept_bar.compiled["foo"].compiled == {}
assert concept_bar.get_compiled()["foo"].get_compiled() == {}
def test_i_can_mix_zero_and_more_and_reference_to_other_concepts(self):
my_map = {
@@ -738,13 +738,13 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
expected = [CN("bar", source="one two three")]
sequences = self.validate_get_concepts_sequences(my_map, text, expected)
concept_bar = sequences[0].concept
assert concept_bar.compiled == {
assert concept_bar.get_compiled() == {
ConceptParts.BODY: DoNotResolve("one two three"),
"foo": [my_map["foo"], my_map["foo"], my_map["foo"]]
}
assert concept_bar.compiled["foo"][0].compiled == {ConceptParts.BODY: DoNotResolve("one")}
assert concept_bar.compiled["foo"][1].compiled == {ConceptParts.BODY: DoNotResolve("two")}
assert concept_bar.compiled["foo"][2].compiled == {ConceptParts.BODY: DoNotResolve("three")}
assert concept_bar.get_compiled()["foo"][0].get_compiled() == {ConceptParts.BODY: DoNotResolve("one")}
assert concept_bar.get_compiled()["foo"][1].get_compiled() == {ConceptParts.BODY: DoNotResolve("two")}
assert concept_bar.get_compiled()["foo"][2].get_compiled() == {ConceptParts.BODY: DoNotResolve("three")}
def test_i_can_parse_concept_reference_that_is_not_in_grammar(self):
my_map = {
@@ -763,7 +763,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
expected = [CN("foo", source="twenty one")]
sequences = self.validate_get_concepts_sequences(my_map, text, expected)
concept_foo = sequences[0].concept
assert concept_foo.compiled == {
assert concept_foo.get_compiled() == {
ConceptParts.BODY: DoNotResolve("twenty one"),
"unit": my_map["one"],
}
@@ -786,8 +786,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
# explicit validations of the compiled
concept_foo = sequences[0].concept
assert concept_foo.body == BuiltinConcepts.NOT_INITIALIZED
assert concept_foo.compiled == {'number': CC(my_map["number"], body=my_map["two"], two=my_map["two"]),
assert concept_foo.body == NotInit
assert concept_foo.get_compiled() == {'number': CC(my_map["number"], body=my_map["two"], two=my_map["two"]),
ConceptParts.BODY: DoNotResolve(value='twenty two')}
text = "twenty one"
@@ -796,8 +796,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
# explicit validations of the compiled
concept_foo = sequences[0].concept
assert concept_foo.body == BuiltinConcepts.NOT_INITIALIZED
assert concept_foo.compiled == {'number': CC(my_map["number"], body=my_map["one"], one=my_map["one"]),
assert concept_foo.body == NotInit
assert concept_foo.get_compiled() == {'number': CC(my_map["number"], body=my_map["one"], one=my_map["one"]),
ConceptParts.BODY: DoNotResolve(value='twenty one')}
@pytest.mark.parametrize("bar_expr, expected", [
@@ -1241,7 +1241,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
sheerka.concepts_grammars.clear() # simulate restart
for c in cmap.values():
sheerka.get_by_id(c.id).bnf = None
sheerka.get_by_id(c.id).set_bnf(None)
text = "thirty three"
expected = CNC("thirties",
+6 -6
View File
@@ -8,7 +8,7 @@ from parsers.BaseParser import UnexpectedTokenErrorNode
from parsers.BnfNodeParser import StrMatch, Optional, ZeroOrMore, OrderedChoice, Sequence, \
OneOrMore, ConceptExpression
from parsers.BnfNodeParser import BnfNodeParser
from parsers.BnfParser import BnfParser, UnexpectedEndOfFileError
from parsers.BnfDefinitionParser import BnfDefinitionParser, UnexpectedEndOfFileError
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -27,7 +27,7 @@ def update_concepts_ids(sheerka, parsing_expression):
if isinstance(parsing_expression, ConceptExpression):
if not parsing_expression.concept.id:
concept = sheerka.get_by_key(parsing_expression.concept.key)
parsing_expression.concept.metadata.id = concept.id
parsing_expression.concept.get_metadata().id = concept.id
for pe in parsing_expression.elements:
update_concepts_ids(sheerka, pe)
@@ -40,7 +40,7 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
def init_parser(self, *concepts):
sheerka, context, *updated = self.init_concepts(*concepts, singleton=True)
parser = BnfParser()
parser = BnfDefinitionParser()
return sheerka, context, parser, *updated
@@ -177,10 +177,10 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
sheerka, context, regex_parser, foo, bar = self.init_parser("foo", "bar")
for concept in [foo, bar]:
concept.metadata.definition_type = DEFINITION_TYPE_BNF
concept.get_metadata().definition_type = DEFINITION_TYPE_BNF
foo.bnf = regex_parser.parse(context, "'twenty' | 'thirty'").value.value
bar.bnf = regex_parser.parse(context, "foo ('one' | 'two')").value.value
foo.set_bnf(regex_parser.parse(context, "'twenty' | 'thirty'").value.value)
bar.set_bnf(regex_parser.parse(context, "foo ('one' | 'two')").value.value)
bnf_parser = BnfNodeParser()
bnf_parser.init_from_concepts(context, [foo, bar])
+4 -4
View File
@@ -9,7 +9,7 @@ from core.tokenizer import Keywords, Tokenizer, LexerError
from parsers.BaseNodeParser import SCWC
from parsers.BaseParser import NotInitializedNode, UnexpectedEofNode
from parsers.BnfNodeParser import OrderedChoice, ConceptExpression, StrMatch, Sequence
from parsers.BnfParser import BnfParser
from parsers.BnfDefinitionParser import BnfDefinitionParser
from parsers.DefConceptParser import DefConceptParser, NameNode, SyntaxErrorNode
from parsers.DefConceptParser import UnexpectedTokenErrorNode, DefConceptNode
from parsers.FunctionParser import FunctionParser
@@ -34,7 +34,7 @@ def get_def_concept(name, where=None, pre=None, post=None, body=None, definition
def_concept.ret = get_concept_part(ret)
if bnf_def:
def_concept.definition = ReturnValueConcept(
"parsers.Bnf",
"parsers.BnfDefinition",
True,
bnf_def)
def_concept.definition_type = DEFINITION_TYPE_BNF
@@ -346,7 +346,7 @@ def concept add one to a as:
node = res.value.value
definition = OrderedChoice(ConceptExpression(a_concept, rule_name="a_concept"), StrMatch("a_string"))
parser_result = ParserResultConcept(BnfParser(), "a_concept | 'a_string'", None, definition, definition)
parser_result = ParserResultConcept(BnfDefinitionParser(), "a_concept | 'a_string'", None, definition, definition)
expected = get_def_concept(name="name", body="__definition[0]", bnf_def=parser_result)
assert res.status
@@ -515,7 +515,7 @@ from give me the date !
assert res.status
assert concept_defined.name.tokens == list(Tokenizer("def concept x", yield_eof=False))
def test_i_can_parse_when_ambiguity_in_where_pre_clause(self):
def test_i_can_parse_when_ambiguity_in_where_or_pre_clause(self):
sheerka, context, parser, *concepts = self.init_parser(
Concept("x is a y", pre="in_context(BuiltinConcepts.EVAL_QUESTION_REQUESTED)"),
Concept("x is a y")
+19 -19
View File
@@ -7,7 +7,7 @@ from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
def variable_def(concept, prop_name):
for name, value in concept.metadata.variables:
for name, value in concept.get_metadata().variables:
if name == prop_name:
return value
@@ -61,8 +61,8 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1
assert results[0].status
assert concept_found == concept
assert not concept_found.metadata.need_validation
assert not concept_found.metadata.is_evaluated
assert not concept_found.get_metadata().need_validation
assert not concept_found.get_metadata().is_evaluated
def test_i_can_parse_concepts_defined_several_times(self):
sheerka = self.get_sheerka(singleton=True)
@@ -79,11 +79,11 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert results[0].status
assert results[0].value.value.name == "hello a"
assert variable_def(results[0].value.value, "a") == "world"
assert results[0].value.value.metadata.need_validation
assert results[0].value.value.get_metadata().need_validation
assert results[1].status
assert results[1].value.value.name == "hello world"
assert not results[1].value.value.metadata.need_validation
assert not results[1].value.value.get_metadata().need_validation
def test_i_can_parse_a_concept_with_variables(self):
sheerka = self.get_sheerka(singleton=True)
@@ -98,8 +98,8 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
concept_found = results[0].value.value
assert concept_found == CMV(concept, a="10", b="5")
assert concept_found.metadata.need_validation
assert not concept_found.metadata.is_evaluated
assert concept_found.get_metadata().need_validation
assert not concept_found.get_metadata().is_evaluated
def test_i_can_parse_a_concept_with_duplicate_variables(self):
sheerka = self.get_sheerka(singleton=True)
@@ -114,7 +114,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
concept_found = results[0].value.value
assert concept_found == CMV(concept, a="10", b="5")
assert concept_found.metadata.need_validation
assert concept_found.get_metadata().need_validation
def test_i_can_parse_concept_when_defined_using_from_def(self):
sheerka, context, plus = self.init_concepts(
@@ -128,8 +128,8 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1
assert results[0].status
assert concept_found == CMV(plus, a="10", b="5")
assert concept_found.metadata.need_validation
assert not concept_found.metadata.is_evaluated
assert concept_found.get_metadata().need_validation
assert not concept_found.get_metadata().is_evaluated
def test_i_can_parse_concept_token(self):
sheerka, context, foo = self.init_concepts("foo")
@@ -141,8 +141,8 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1
assert results[0].status
assert concept_found == foo
assert not concept_found.metadata.need_validation
assert concept_found.metadata.is_evaluated
assert not concept_found.get_metadata().need_validation
assert concept_found.get_metadata().is_evaluated
def test_i_can_parse_concept_with_concept_tokens(self):
sheerka, context, one, two, plus = self.init_concepts(
@@ -158,8 +158,8 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1
assert results[0].status
assert concept_found == CMV(plus, a="c:one:", b="c:two:")
assert concept_found.metadata.need_validation
assert not concept_found.metadata.is_evaluated
assert concept_found.get_metadata().need_validation
assert not concept_found.get_metadata().is_evaluated
def test_i_can_parse_when_expression_contains_keyword(self):
sheerka, context, isa, def_concept = self.init_concepts(
@@ -174,8 +174,8 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1
assert results[0].status
assert concept_found == CMV(isa, c="z")
assert concept_found.metadata.need_validation
assert not concept_found.metadata.is_evaluated
assert concept_found.get_metadata().need_validation
assert not concept_found.get_metadata().is_evaluated
source = "def concept z"
results = ExactConceptParser().parse(context, ParserInput(source))
@@ -184,8 +184,8 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1
assert results[0].status
assert concept_found == CMV(def_concept, a="z")
assert concept_found.metadata.need_validation
assert not concept_found.metadata.is_evaluated
assert concept_found.get_metadata().need_validation
assert not concept_found.get_metadata().is_evaluated
def test_i_can_manage_unknown_concept(self):
context = self.get_context(self.get_sheerka(singleton=True))
@@ -218,4 +218,4 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
# assert len(results) == 1
# assert results[0].status
# assert results[0].value.value == concept
# assert not results[0].value.value.metadata.need_validation
# assert not results[0].value.value.get_metadata().need_validation
+8 -8
View File
@@ -33,14 +33,14 @@ class TestExpressionParser(TestUsingMemoryBasedSheerka):
@pytest.mark.parametrize("expression, expected", [
("one complicated expression", n("one complicated expression")),
# ("function_call(a,b,c)", n("function_call(a,b,c)")),
# ("one expression or another expression", OrNode(n("one expression"), n("another expression"))),
# ("one expression and another expression", AndNode(n("one expression"), n("another expression"))),
# ("one or two or three", OrNode(n("one"), n("two"), n("three"))),
# ("one and two and three", AndNode(n("one"), n("two"), n("three"))),
# ("one or two and three", OrNode(n("one"), AndNode(n("two"), n("three")))),
# ("one and two or three", OrNode(AndNode(n("one"), n("two")), n("three"))),
# ("one and (two or three)", AndNode(n("one"), OrNode(n("two"), n("three")))),
("function_call(a,b,c)", n("function_call(a,b,c)")),
("one expression or another expression", OrNode(n("one expression"), n("another expression"))),
("one expression and another expression", AndNode(n("one expression"), n("another expression"))),
("one or two or three", OrNode(n("one"), n("two"), n("three"))),
("one and two and three", AndNode(n("one"), n("two"), n("three"))),
("one or two and three", OrNode(n("one"), AndNode(n("two"), n("three")))),
("one and two or three", OrNode(AndNode(n("one"), n("two")), n("three"))),
("one and (two or three)", AndNode(n("one"), OrNode(n("two"), n("three")))),
])
def test_i_can_parse_expression(self, expression, expected):
sheerka, context, parser = self.init_parser()
+70 -4
View File
@@ -1,12 +1,20 @@
import pytest
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from core.sheerka.services.SheerkaExecute import ParserInput
from core.sheerka.services.SheerkaRuleManager import FormatAstRawText, RulePredicate, FormatAstVariable
from core.tokenizer import Keywords, Tokenizer
from parsers.BaseCustomGrammarParser import KeywordNotFound
from parsers.FormatRuleParser import FormatRuleParser, FormatAstRawText, FormatRuleNode
from parsers.FormatRuleParser import FormatRuleParser, FormatRuleNode
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
cmap = {}
cmap = {
"is a": Concept("x is a y").def_var("x").def_var("y"),
"is a question": Concept("x is a y", pre="is_question()").def_var("x").def_var("y"),
"a is good": Concept("a is good").def_var("a"),
"b is good": Concept("b is good").def_var("b"),
}
class TestFormatRuleParser(TestUsingMemoryBasedSheerka):
@@ -45,16 +53,47 @@ class TestFormatRuleParser(TestUsingMemoryBasedSheerka):
res = parser.parse(context, ParserInput(text))
parser_result = res.body
format_rule = res.body.body
rule = format_rule.rule
rules = format_rule.rule
format_ast = format_rule.format_ast
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert isinstance(format_rule, FormatRuleNode)
assert self.dump_tokens(format_rule.tokens[Keywords.WHEN][1:]) == self.dump_tokens(
Tokenizer("isinstance(last_value(), Concept)", False))
assert self.dump_tokens(format_rule.tokens[Keywords.PRINT][1:]) == self.dump_tokens(
Tokenizer("hello world!", False))
assert sheerka.isinstance(rule, BuiltinConcepts.RETURN_VALUE)
assert len(rules) == 1
assert isinstance(rules[0], RulePredicate)
assert format_ast == FormatAstRawText("hello world!")
def test_when_is_parsed_in_the_context_of_a_question(self):
sheerka, context, parser = self.init_parser()
text = "when foo is a bar print hello world"
res = parser.parse(context, ParserInput(text))
format_rule = res.body.body
rules = format_rule.rule
assert res.status
assert len(rules) == 1
assert isinstance(rules[0], RulePredicate)
assert rules[0].predicate.body.body.get_metadata().pre == "is_question()"
def test_when_can_support_multiple_possibilities(self):
sheerka, context, parser = self.init_parser()
text = "when foo is good print hello world"
res = parser.parse(context, ParserInput(text))
format_rule = res.body.body
rules = format_rule.rule
assert res.status
assert len(rules) == 2
assert rules[0].predicate.body.body.get_metadata().name == "a is good"
assert rules[1].predicate.body.body.get_metadata().name == "b is good"
@pytest.mark.parametrize("text, error", [
("hello world", [KeywordNotFound(None, keywords=['when', 'print'])]),
("when True", [KeywordNotFound([], keywords=['print'])]),
@@ -69,3 +108,30 @@ class TestFormatRuleParser(TestUsingMemoryBasedSheerka):
assert not res.status
assert sheerka.isinstance(not_for_me, BuiltinConcepts.NOT_FOR_ME)
assert not_for_me.reason == error
@pytest.mark.parametrize("text, expected_error", [
("when a b print hello world!", BuiltinConcepts.TOO_MANY_ERRORS),
])
def test_i_cannot_parse_invalid_predicates(self, text, expected_error):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(text))
assert not res.status
assert sheerka.isinstance(res.body, expected_error)
@pytest.mark.parametrize("expr, expected", [
("hello world", FormatAstRawText("hello world")),
("{id}", FormatAstVariable("id")),
])
def test_i_can_parse_valid_print_expression(self, expr, expected):
sheerka, context, parser = self.init_parser()
text = "when True print " + expr
res = parser.parse(context, ParserInput(text))
format_rule = res.body.body
format_ast = format_rule.format_ast
assert res.status
assert format_ast == expected
+73 -5
View File
@@ -1,8 +1,9 @@
import pytest
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from core.rule import Rule
from core.sheerka.services.SheerkaExecute import ParserInput
from parsers.BaseNodeParser import SCN, SCWC, CN, UTN, CNC
from parsers.BaseNodeParser import SCN, SCWC, CN, UTN, CNC, RN
from parsers.FunctionParser import FunctionParser, FN
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -76,6 +77,16 @@ class TestFunctionParser(TestUsingMemoryBasedSheerka):
assert res == expected
def test_i_can_parse_function_when_rule(self):
sheerka, context, parser = self.init_parser()
parser.reset_parser(context, ParserInput("func(r:|1:)"))
parser.parser_input.next_token()
res = parser.parse_function()
assert res == FN("func(", ")", ["r:|1:"])
@pytest.mark.parametrize("text, expected", [
("func()", SCN("func()")),
(" func()", SCN("func()")),
@@ -118,6 +129,63 @@ class TestFunctionParser(TestUsingMemoryBasedSheerka):
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert expressions == resolved_expected
def test_i_can_parse_when_the_parameter_is_not_a_concept(self):
"""
It's not a concept, but it can be a valid short term memory object
:return:
"""
sheerka, context, parser = self.init_parser()
text = "func(unknown_concept)"
res = parser.parse(context, ParserInput(text))
assert res.status
def test_i_cannot_parse_when_the_concept_is_not_found(self):
"""
We do not check yet if it's a valid concept
If you find a cheap way to do so, simply remove this test
:return:
"""
sheerka, context, parser = self.init_parser()
text = "func(c:|xxx:)"
res = parser.parse(context, ParserInput(text))
assert res.status
def test_i_can_parse_when_rules(self):
sheerka, context, parser = self.init_parser()
text = "func(r:|1:)"
expected = SCWC("func(", ")", RN("1"))
resolved_expected = compute_expected_array(cmap, text, [expected])[0]
res = parser.parse(context, ParserInput(text))
parser_result = res.body
expression = res.body.body
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert expression == resolved_expected
assert expression.python_node is not None
assert expression.return_value is not None
# def test_i_cannot_parse_when_rule_not_found(self):
# sheerka, context, parser = self.init_parser()
# text = "func(r:|fake:)"
# expected = SCWC("func(", ")", RN("fake"))
# resolved_expected = compute_expected_array(cmap, text, [expected])[0]
#
# res = parser.parse(context, ParserInput(text))
# parser_result = res.body
# expression = res.body.body
#
# assert not res.status
# assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
# assert expression == resolved_expected
# assert expression.python_node is not None
# assert expression.return_value is not None
@pytest.mark.parametrize("text, expected_error_type", [
("one", BuiltinConcepts.NOT_FOR_ME),
("$*!", BuiltinConcepts.NOT_FOR_ME),
@@ -138,7 +206,7 @@ class TestFunctionParser(TestUsingMemoryBasedSheerka):
@pytest.mark.parametrize("text, expected", [
("func(one two)", SCWC("func(", ")", "one", "two")),
])
def test_i_can_detect_non_function(self, text, expected):
def test_i_can_detect_none_function(self, text, expected):
sheerka, context, parser = self.init_parser()
resolved_expected = compute_expected_array(cmap, text, [expected])[0]
@@ -169,11 +237,11 @@ class TestFunctionParser(TestUsingMemoryBasedSheerka):
concept = res.body.body.nodes[0].concept
assert res.status
assert isinstance(concept.compiled["a"], Concept)
assert isinstance(concept.get_compiled()["a"], Concept)
# three is not recognized,
# so it will be transformed into list of ReturnValueConcept that indicate how to recognized it
assert isinstance(concept.compiled["b"], list)
for item in concept.compiled["b"]:
assert isinstance(concept.get_compiled()["b"], list)
for item in concept.get_compiled()["b"]:
assert sheerka.isinstance(item, BuiltinConcepts.RETURN_VALUE)
+52 -6
View File
@@ -2,10 +2,10 @@ import ast
import core.utils
import pytest
from core.builtin_concepts import ParserResultConcept, NotForMeConcept
from core.builtin_concepts import ParserResultConcept, NotForMeConcept, BuiltinConcepts
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import LexerError
from parsers.PythonParser import PythonNode, PythonParser, PythonErrorNode
from core.tokenizer import LexerError, TokenKind
from parsers.PythonParser import PythonNode, PythonParser, PythonErrorNode, ConceptDetected
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -70,6 +70,52 @@ class TestPythonParser(TestUsingMemoryBasedSheerka):
assert res.value.value == PythonNode(
"__C__KEY_name__ID_id__C__ + 1",
ast.parse(encoded + "+1", mode="eval"))
assert res.value.value.concepts == {
encoded: ("name", "id")
}
assert len(res.value.value.objects) == 1
assert res.value.value.objects[encoded].type == TokenKind.CONCEPT
assert res.value.value.objects[encoded].value == ("name", "id")
def test_i_can_parse_a_rule(self):
text = "r:name|id: + 1"
parser = PythonParser()
res = parser.parse(self.get_context(), ParserInput(text))
encoded = core.utils.encode_concept(("name", "id"), "R")
assert res
assert res.value.source == "r:name|id: + 1"
assert res.value.value == PythonNode(
"__R__KEY_name__ID_id__R__ + 1",
ast.parse(encoded + "+1", mode="eval"))
assert len(res.value.value.objects) == 1
assert res.value.value.objects[encoded].type == TokenKind.RULE
assert res.value.value.objects[encoded].value == ("name", "id")
def test_i_can_parse_a_rule_2(self):
text = "r:name|id:.name"
parser = PythonParser()
res = parser.parse(self.get_context(), ParserInput(text))
encoded = core.utils.encode_concept(("name", "id"), "R")
assert res
assert res.value.source == "r:name|id:.name"
assert res.value.value == PythonNode(
"__R__KEY_name__ID_id__R__.name",
ast.parse(encoded + ".name", mode="eval"))
assert len(res.value.value.objects) == 1
assert res.value.value.objects[encoded].type == TokenKind.RULE
assert res.value.value.objects[encoded].value == ("name", "id")
@pytest.mark.parametrize("text, expected_id", [
("foo", "foo"),
("c:foo:", "__C__KEY_foo__ID_00None00__C__")
])
def test_i_cannot_parse_simple_concepts(self, text, expected_id):
sheerka, context, foo = self.init_concepts("foo")
parser = PythonParser()
res = parser.parse(context, ParserInput(text))
assert not res.status
assert sheerka.isinstance(res.value, BuiltinConcepts.NOT_FOR_ME)
assert res.value.reason == [ConceptDetected(expected_id)]
+50 -10
View File
@@ -1,11 +1,13 @@
import ast
import pytest
import core.utils
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts, ReturnValueConcept
from core.concept import Concept
from core.rule import Rule
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import Token, TokenKind, Tokenizer
from parsers.BaseNodeParser import ConceptNode, UnrecognizedTokensNode
from parsers.BaseNodeParser import ConceptNode, UnrecognizedTokensNode, RuleNode
from parsers.PythonParser import PythonNode
from parsers.PythonWithConceptsParser import PythonWithConceptsParser
from parsers.UnrecognizedNodeParser import UnrecognizedNodeParser
@@ -23,6 +25,10 @@ def ret_val(*args):
tokens = [Token(TokenKind.IDENTIFIER, item.name, 0, 0, 0)]
result.append(ConceptNode(item, index, index, tokens, item.name))
index += 1
elif isinstance(item, Rule):
tokens = [Token(TokenKind.RULE, (None, item.id), 0, 0, 0)]
result.append(RuleNode(item, index, index, tokens, f"r:|{item.id}:"))
index += 1
else:
tokens = list(Tokenizer(item))
result.append(UnrecognizedTokensNode(index, index + len(tokens) - 1, tokens))
@@ -69,7 +75,7 @@ class TestPythonWithConceptsParser(TestUsingMemoryBasedSheerka):
assert isinstance(return_value, PythonNode)
assert return_value.source == "foo + 1"
assert return_value.get_dump(return_value.ast_) == to_str_ast("__C__foo__C__ + 1")
assert return_value.concepts["__C__foo__C__"] == foo
assert return_value.objects["__C__foo__C__"] == foo
def test_i_can_parse_concepts_and_python_when_concept_is_known(self):
context = self.get_context()
@@ -89,7 +95,7 @@ class TestPythonWithConceptsParser(TestUsingMemoryBasedSheerka):
assert isinstance(return_value, PythonNode)
assert return_value.source == "foo + 1"
assert return_value.get_dump(return_value.ast_) == to_str_ast("__C__foo__1001__C__ + 1")
assert return_value.concepts["__C__foo__1001__C__"] == foo
assert return_value.objects["__C__foo__1001__C__"] == foo
def test_i_can_parse_when_concept_name_has_invalid_characters(self):
context = self.get_context()
@@ -102,7 +108,7 @@ class TestPythonWithConceptsParser(TestUsingMemoryBasedSheerka):
return_value = result.value.value
assert result.status
assert return_value.concepts["__C__foo0et000000__1001__C__"] == foo
assert return_value.objects["__C__foo0et000000__1001__C__"] == foo
def test_i_can_parse_when_multiple_concepts(self):
sheerka, context, foo, bar = self.init_concepts("foo", "bar")
@@ -120,8 +126,42 @@ class TestPythonWithConceptsParser(TestUsingMemoryBasedSheerka):
assert isinstance(return_value, PythonNode)
assert return_value.source == "func(foo, bar)"
assert return_value.get_dump(return_value.ast_) == to_str_ast("func(__C__foo__1001__C__, __C__bar__1002__C__)")
assert return_value.concepts["__C__foo__1001__C__"] == foo
assert return_value.concepts["__C__bar__1002__C__"] == bar
assert return_value.objects["__C__foo__1001__C__"] == foo
assert return_value.objects["__C__bar__1002__C__"] == bar
def test_i_can_parse_when_python_and_rule(self):
context = self.get_context()
rule = Rule().set_id("rule_id")
input_return_value = ret_val(rule, " + 1")
parser = PythonWithConceptsParser()
result = parser.parse(context, input_return_value.body)
wrapper = result.value
return_value = result.value.value
assert result.status
assert result.who == parser.name
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
assert wrapper.source == "r:|rule_id: + 1"
assert isinstance(return_value, PythonNode)
assert return_value.source == "r:|rule_id: + 1"
assert return_value.get_dump(return_value.ast_) == to_str_ast("__R____rule_id__R__ + 1")
assert return_value.objects["__R____rule_id__R__"] == rule
def test_python_ids_mappings_are_correct_when_rules_with_the_same_id(self):
context = self.get_context()
rule1 = Rule().set_id("rule_id")
rule2 = Rule().set_id("rule_id")
input_return_value = ret_val(rule1, "+", rule2)
parser = PythonWithConceptsParser()
result = parser.parse(context, input_return_value.body)
return_value = result.value.value
assert result.status
assert return_value.objects["__R____rule_id__R__"] == rule1
assert return_value.objects["__R____rule_id_1__R__"] == rule2
def test_python_ids_mappings_are_correct_when_concepts_with_the_same_name(self):
context = self.get_context()
@@ -137,10 +177,10 @@ class TestPythonWithConceptsParser(TestUsingMemoryBasedSheerka):
return_value = result.value.value
assert result.status
assert return_value.concepts["__C__foo__C__"] == foo1
assert return_value.concepts["__C__foo_1__C__"] == foo2
assert return_value.concepts["__C__foo__1001__C__"] == foo3
assert return_value.concepts["__C__foo__1002__C__"] == foo4
assert return_value.objects["__C__foo__C__"] == foo1
assert return_value.objects["__C__foo_1__C__"] == foo2
assert return_value.objects["__C__foo__1001__C__"] == foo3
assert return_value.objects["__C__foo__1002__C__"] == foo4
def test_i_cannot_parse_if_syntax_error(self):
context = self.get_context()
+101
View File
@@ -0,0 +1,101 @@
import pytest
from core.builtin_concepts import BuiltinConcepts
from core.sheerka.services.SheerkaExecute import ParserInput
from parsers.RuleParser import RuleParser, RuleNotFound
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
my_rules = {("__rets", "list(__rets)")}
class TestRuleParser(TestUsingMemoryBasedSheerka):
sheerka = None
@classmethod
def setup_class(cls):
t = cls()
cls.sheerka, context, _ = t.init_parser(my_rules)
def init_parser(self, rules=None):
if rules is not None:
sheerka, context, *concepts = self.init_format_rules(*rules)
else:
sheerka = TestRuleParser.sheerka
context = self.get_context(sheerka)
parser = RuleParser()
return sheerka, context, parser
def test_i_cannot_parse_is_empty(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(""))
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.IS_EMPTY)
def test_i_cannot_parse_when_not_for_me(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput("hello world!"))
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME)
def test_i_cannot_parse_a_rule_by_name(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput("r:1:"))
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_IMPLEMENTED)
def test_i_cannot_parse_an_unknown_rule(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput("r:|999999:"))
error = res.body
errors_causes = res.body.body
assert not res.status
assert sheerka.isinstance(error, BuiltinConcepts.ERROR)
assert errors_causes == [RuleNotFound("999999")]
def test_i_can_parse_rule(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput("r:|1:"))
parser_result = res.body
rules = res.body.body
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert len(rules) == 1
assert rules[0].id == "1"
def test_rule_recognition_is_deferred_when_id_is_a_string(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput("r:|xxx:"))
parser_result = res.body
rules = res.body.body
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert len(rules) == 1
assert rules[0].id == "xxx"
assert rules[0].metadata.action_type == "deferred"
@pytest.mark.parametrize("text", [
"r:|1:xxx",
"xxxr:|1:",
"r:|1: + 1"
])
def test_i_can_only_parse_simple_rule(self, text):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(text))
not_for_me = res.body
assert not res.status
assert sheerka.isinstance(not_for_me, BuiltinConcepts.NOT_FOR_ME)
+27 -24
View File
@@ -1,7 +1,7 @@
import pytest
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept, CIO
from core.sheerka.services.SheerkaComparisonManager import SheerkaComparisonManager
from core.concept import Concept, CIO, ALL_ATTRIBUTES
from core.global_symbols import CONCEPT_COMPARISON_CONTEXT
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import Tokenizer
from parsers.BaseNodeParser import utnode, ConceptNode, cnode, short_cnode, UnrecognizedTokensNode, \
@@ -54,14 +54,16 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
cmap["plus"].set_prop(BuiltinConcepts.ASSOCIATIVITY, "right")
cmap["mult"].set_prop(BuiltinConcepts.ASSOCIATIVITY, "right")
cmap["minus"].set_prop(BuiltinConcepts.ASSOCIATIVITY, "right")
TestSyaNodeParser.sheerka.services[SheerkaComparisonManager.NAME].set_is_greater_than(context,
BuiltinConcepts.PRECEDENCE,
cmap["mult"],
cmap["plus"])
TestSyaNodeParser.sheerka.services[SheerkaComparisonManager.NAME].set_is_greater_than(context,
BuiltinConcepts.PRECEDENCE,
cmap["mult"],
cmap["minus"])
TestSyaNodeParser.sheerka.set_is_greater_than(context,
BuiltinConcepts.PRECEDENCE,
cmap["mult"],
cmap["plus"],
CONCEPT_COMPARISON_CONTEXT)
TestSyaNodeParser.sheerka.set_is_greater_than(context,
BuiltinConcepts.PRECEDENCE,
cmap["mult"],
cmap["minus"],
CONCEPT_COMPARISON_CONTEXT)
# TestSyaNodeParser.sheerka.force_sya_def(context, [
# (cmap["plus"].id, 5, SyaAssociativity.Right),
@@ -91,6 +93,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
sheerka = TestSyaNodeParser.sheerka
context = self.get_context(sheerka)
concepts = cmap.values()
ALL_ATTRIBUTES.clear()
if post_init_concepts:
post_init_concepts(sheerka, context)
@@ -967,7 +970,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
' 7:<ws> => PUSH_UNREC',
' 8:: => ??',
" _: => RECOG [[UTN('twenty '), CN((1001)one)], [CN((1016)twenties)]]",
" _: => POP ConceptNode(concept='(1016)twenties', source='twenty one', start=4, end=6, ConceptParts.BODY='DoNotResolve(value='twenty one')', unit='(1001)one')",
" _: => POP ConceptNode(concept='(1016)twenties', source='twenty one', start=4, end=6, #body#='DoNotResolve(value='twenty one')', unit='(1001)one')",
' 9:<ws> => EAT',
' 10:three => PUSH_UNREC',
' 11:<EOF> => ??',
@@ -978,7 +981,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
])
def test_i_can_debug(self, expression, expected_debugs):
sheerka, context, parser = self.init_parser()
context.add_to_private_hints(BuiltinConcepts.DEBUG)
context.debug_enabled = True
res = parser.infix_to_postfix(context, ParserInput(expression))
assert len(res) == len(expected_debugs)
@@ -1000,10 +1003,10 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
# check the compiled
expected_concept = lexer_nodes[0].concept
assert expected_concept.compiled["a"] == cmap["one"]
assert expected_concept.compiled["b"] == cmap["mult"]
assert expected_concept.compiled["b"].compiled["a"] == cmap["two"]
assert expected_concept.compiled["b"].compiled["b"] == cmap["three"]
assert expected_concept.get_compiled()["a"] == cmap["one"]
assert expected_concept.get_compiled()["b"] == cmap["mult"]
assert expected_concept.get_compiled()["b"].get_compiled()["a"] == cmap["two"]
assert expected_concept.get_compiled()["b"].get_compiled()["b"] == cmap["three"]
def test_i_can_parse_when_python_code(self):
sheerka, context, parser = self.init_parser()
@@ -1019,9 +1022,9 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
# check the compiled
expected_concept = lexer_nodes[0].concept
assert len(expected_concept.compiled["a"]) == 1
assert len(expected_concept.get_compiled()["a"]) == 1
return_value_a = expected_concept.compiled["a"][0]
return_value_a = expected_concept.get_compiled()["a"][0]
assert sheerka.isinstance(return_value_a, BuiltinConcepts.RETURN_VALUE)
assert return_value_a.status
assert sheerka.isinstance(return_value_a.body, BuiltinConcepts.PARSER_RESULT)
@@ -1044,8 +1047,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
# check the compiled
expected_concept = lexer_nodes[0].concept
assert sheerka.isinstance(expected_concept.compiled["a"], "twenties")
assert expected_concept.compiled["a"].compiled["unit"] == cmap["one"]
assert sheerka.isinstance(expected_concept.get_compiled()["a"], "twenties")
assert expected_concept.get_compiled()["a"].get_compiled()["unit"] == cmap["one"]
def test_i_can_parse_sequences(self):
sheerka, context, parser = self.init_parser()
@@ -1062,9 +1065,9 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
ConceptNode(cmap["suffixed"], 10, 12, source="suffixed two")]
# check the compiled
concept_plus_a = lexer_nodes[0].concept.compiled["a"]
concept_plus_b = lexer_nodes[0].concept.compiled["b"]
concept_suffixed_a = lexer_nodes[1].concept.compiled["a"]
concept_plus_a = lexer_nodes[0].concept.get_compiled()["a"]
concept_plus_b = lexer_nodes[0].concept.get_compiled()["b"]
concept_suffixed_a = lexer_nodes[1].concept.get_compiled()["a"]
assert concept_plus_a == cmap["one"]
assert len(concept_plus_b) == 1
@@ -1199,7 +1202,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
concept_found = lexer_nodes[0].concept
for unrecognized in expected_unrecognized:
assert isinstance(concept_found.compiled[unrecognized], UnrecognizedTokensNode)
assert isinstance(concept_found.get_compiled()[unrecognized], UnrecognizedTokensNode)
@pytest.mark.parametrize("text, expected", [
("x$!# suffixed one", [utnode(0, 4, "x$!# "), cnode("suffixed __var__0", 5, 7, "suffixed one")]),
+57 -54
View File
@@ -1,8 +1,11 @@
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts
from core.concept import Concept, CC
from core.tokenizer import Tokenizer, TokenKind
from parsers.SequenceNodeParser import SequenceNodeParser
from parsers.BaseNodeParser import ConceptNode, UnrecognizedTokensNode, scnode, cnode, \
utnode, SyaAssociativity, CN, CNC, UTN, SourceCodeWithConceptNode, SCWC, SourceCodeNode
from parsers.BnfNodeParser import BnfNodeParser
from parsers.SyaNodeParser import SyaNodeParser
from parsers.UnrecognizedNodeParser import UnrecognizedNodeParser
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -14,7 +17,7 @@ def get_input_nodes_from(my_concepts_map, full_expr, *args):
if isinstance(n, CC):
concept = n.concept or Concept.update_from(my_concepts_map[n.concept_key])
for k, v in n.compiled.items():
concept.compiled[k] = _get_real_node(v)
concept.get_compiled()[k] = _get_real_node(v)
return concept
if isinstance(n, (utnode, UTN)):
@@ -26,7 +29,7 @@ def get_input_nodes_from(my_concepts_map, full_expr, *args):
tokens = full_expr_as_tokens[n.start: n.end + 1]
if hasattr(n, "compiled"):
for k, v in n.compiled.items():
concept.compiled[k] = _get_real_node(v)
concept.get_compiled()[k] = _get_real_node(v)
return ConceptNode(concept, n.start, n.end, tokens)
if isinstance(n, SCWC):
@@ -118,45 +121,45 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
concept = res.body.concept
assert concept == concepts_map["5params"]
assert len(concept.compiled["a"]) == 1
assert sheerka.isinstance(concept.compiled["a"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.compiled["a"][0].status
assert concept.compiled["a"][0].who == "parsers.AtomNode"
assert concept.compiled["a"][0].body.body == [cnode("one", 1, 1, "one")]
assert len(concept.get_compiled()["a"]) == 1
assert sheerka.isinstance(concept.get_compiled()["a"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.get_compiled()["a"][0].status
assert concept.get_compiled()["a"][0].who == "parsers." + SequenceNodeParser.NAME
assert concept.get_compiled()["a"][0].body.body == [cnode("one", 1, 1, "one")]
assert len(concept.compiled["b"]) == 1
assert sheerka.isinstance(concept.compiled["b"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.compiled["b"][0].status
assert concept.compiled["b"][0].who == "parsers.AtomNode"
assert concept.compiled["b"][0].body.body == [cnode("two", 1, 1, "two"), cnode("three", 3, 3, "three")]
assert len(concept.get_compiled()["b"]) == 1
assert sheerka.isinstance(concept.get_compiled()["b"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.get_compiled()["b"][0].status
assert concept.get_compiled()["b"][0].who == "parsers." + SequenceNodeParser.NAME
assert concept.get_compiled()["b"][0].body.body == [cnode("two", 1, 1, "two"), cnode("three", 3, 3, "three")]
assert len(concept.compiled["c"]) == 1
assert sheerka.isinstance(concept.compiled["c"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.compiled["c"][0].status
assert concept.compiled["c"][0].who == "parsers.BnfNode"
assert len(concept.get_compiled()["c"]) == 1
assert sheerka.isinstance(concept.get_compiled()["c"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.get_compiled()["c"][0].status
assert concept.get_compiled()["c"][0].who == "parsers." + BnfNodeParser.NAME
expected_nodes = compute_expected_array(
concepts_map,
" twenty one ",
[CNC("twenties", source="twenty one", unit="one")])
assert concept.compiled["c"][0].body.body == expected_nodes
assert concept.get_compiled()["c"][0].body.body == expected_nodes
assert len(concept.compiled["d"]) == 1
assert sheerka.isinstance(concept.compiled["d"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.compiled["d"][0].status
assert concept.compiled["d"][0].who == "parsers.Python"
assert concept.compiled["d"][0].body.source == " 1 + 2 "
assert len(concept.get_compiled()["d"]) == 1
assert sheerka.isinstance(concept.get_compiled()["d"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.get_compiled()["d"][0].status
assert concept.get_compiled()["d"][0].who == "parsers.Python"
assert concept.get_compiled()["d"][0].body.source == " 1 + 2 "
assert len(concept.compiled["e"]) == 1
assert sheerka.isinstance(concept.compiled["e"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.compiled["e"][0].status
assert concept.compiled["e"][0].who == "parsers.SyaNode"
assert len(concept.get_compiled()["e"]) == 1
assert sheerka.isinstance(concept.get_compiled()["e"][0], BuiltinConcepts.RETURN_VALUE)
assert concept.get_compiled()["e"][0].status
assert concept.get_compiled()["e"][0].who == "parsers." + SyaNodeParser.NAME
expected_nodes = compute_expected_array(
concepts_map,
" one plus two mult three ",
[CNC("plus", a="one", b=CC("mult", a="two", b="three"))],
exclude_body=True)
assert concept.compiled["e"][0].body.body == expected_nodes
assert concept.get_compiled()["e"][0].body.body == expected_nodes
# # sanity check, I can evaluate the concept
# evaluated = sheerka.evaluate_concept(self.get_context(sheerka, eval_body=True), concept)
@@ -177,25 +180,25 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
assert res.status
assert res.body.concept == concepts_map["plus"]
assert len(res.body.concept.compiled["a"]) == 1
assert res.body.concept.compiled["a"][0].status
assert res.body.concept.compiled["a"][0].who == "parsers.Python"
assert res.body.concept.compiled["a"][0].body.source == "1 "
assert len(res.body.concept.get_compiled()["a"]) == 1
assert res.body.concept.get_compiled()["a"][0].status
assert res.body.concept.get_compiled()["a"][0].who == "parsers.Python"
assert res.body.concept.get_compiled()["a"][0].body.source == "1 "
assert res.body.concept.compiled["b"] == concepts_map["mult"]
assert sheerka.isinstance(res.body.concept.compiled["b"].compiled["a"][0], BuiltinConcepts.RETURN_VALUE)
assert res.body.concept.compiled["b"].compiled["a"][0].status
assert res.body.concept.compiled["b"].compiled["a"][0].who == "parsers.Python"
assert res.body.concept.compiled["b"].compiled["a"][0].body.source == " 2 "
assert res.body.concept.get_compiled()["b"] == concepts_map["mult"]
assert sheerka.isinstance(res.body.concept.get_compiled()["b"].get_compiled()["a"][0], BuiltinConcepts.RETURN_VALUE)
assert res.body.concept.get_compiled()["b"].get_compiled()["a"][0].status
assert res.body.concept.get_compiled()["b"].get_compiled()["a"][0].who == "parsers.Python"
assert res.body.concept.get_compiled()["b"].get_compiled()["a"][0].body.source == " 2 "
assert sheerka.isinstance(res.body.concept.compiled["b"].compiled["b"][0], BuiltinConcepts.RETURN_VALUE)
assert res.body.concept.compiled["b"].compiled["b"][0].status
assert res.body.concept.compiled["b"].compiled["b"][0].who == "parsers.BnfNode"
assert sheerka.isinstance(res.body.concept.get_compiled()["b"].get_compiled()["b"][0], BuiltinConcepts.RETURN_VALUE)
assert res.body.concept.get_compiled()["b"].get_compiled()["b"][0].status
assert res.body.concept.get_compiled()["b"].get_compiled()["b"][0].who == "parsers.Bnf"
expected_nodes = compute_expected_array(
concepts_map,
" twenty two",
[CNC("twenties", source="twenty two", unit="two")])
assert res.body.concept.compiled["b"].compiled["b"][0].body.body == expected_nodes
assert res.body.concept.get_compiled()["b"].get_compiled()["b"][0].body.body == expected_nodes
# def test_i_can_validate_and_evaluate_a_concept_node_with_python(self):
# sheerka, context, parser = self.init_parser()
@@ -211,12 +214,12 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
#
# assert res.status
# assert res.body.concept == concepts_map["plus"]
# assert res.body.concept.compiled["a"] == concepts_map["one"]
# assert len(res.body.concept.compiled["b"]) == 1
# assert sheerka.isinstance(res.body.concept.compiled["b"][0], BuiltinConcepts.RETURN_VALUE)
# assert res.body.concept.compiled["b"][0].status
# assert res.body.concept.compiled["b"][0].who == "parsers.Python"
# assert res.body.concept.compiled["b"][0].body.source == "1 + 1"
# assert res.body.concept.get_compiled()["a"] == concepts_map["one"]
# assert len(res.body.concept.get_compiled()["b"]) == 1
# assert sheerka.isinstance(res.body.concept.get_compiled()["b"][0], BuiltinConcepts.RETURN_VALUE)
# assert res.body.concept.get_compiled()["b"][0].status
# assert res.body.concept.get_compiled()["b"][0].who == "parsers.Python"
# assert res.body.concept.get_compiled()["b"][0].body.source == "1 + 1"
#
# # # evaluate
# # context = self.get_context(sheerka, eval_body=True)
@@ -231,10 +234,10 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
#
# assert res.status
# assert res.body.concept == concepts_map["plus"]
# assert res.body.concept.compiled["a"] == concepts_map["one"]
# assert len(res.body.concept.compiled["b"]) == 1
# assert res.body.concept.compiled["b"][0].status
# assert res.body.concept.compiled["b"][0].who == "parsers.BnfNode"
# assert res.body.concept.get_compiled()["a"] == concepts_map["one"]
# assert len(res.body.concept.get_compiled()["b"]) == 1
# assert res.body.concept.get_compiled()["b"][0].status
# assert res.body.concept.get_compiled()["b"][0].who == "parsers.BnfNode"
#
# # evaluate
# context = self.get_context(sheerka, eval_body=True)
@@ -336,7 +339,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert parser_result.source == expression
assert len(actual_nodes) == 1
assert actual_nodes[0].nodes[0].concept.metadata.is_evaluated # 'a plus b' is recognized as concept definition
assert actual_nodes[0].nodes[0].concept.get_metadata().is_evaluated # 'a plus b' is recognized as concept definition
def test_i_can_parse_unrecognized_source_code_with_concept_node_when_var_in_short_term_memory(self):
sheerka, context, parser = self.init_parser()
@@ -355,7 +358,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert parser_result.source == expression
assert len(actual_nodes) == 1
assert not actual_nodes[0].nodes[0].concept.metadata.is_evaluated # 'a plus b' need to be evaluated
assert not actual_nodes[0].nodes[0].concept.get_metadata().is_evaluated # 'a plus b' need to be evaluated
def test_i_can_parse_unrecognized_sya_concept_that_references_source_code(self):
sheerka, context, parser = self.init_parser()
@@ -381,8 +384,8 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
expression, [CN("hello_sya", source="hello get_user_name(twenty one)")],
exclude_body=True)
assert actual_nodes == expected_array
assert isinstance(actual_nodes[0].concept.compiled["a"], list)
assert sheerka.isinstance(actual_nodes[0].concept.compiled["a"][0], BuiltinConcepts.RETURN_VALUE)
assert isinstance(actual_nodes[0].concept.get_compiled()["a"], list)
assert sheerka.isinstance(actual_nodes[0].concept.get_compiled()["a"][0], BuiltinConcepts.RETURN_VALUE)
def test_i_can_parse_sequences(self):
sheerka, context, parser = self.init_parser()