Fixed #29: Parsers: Implement parsing memoization

Fixed #77 : Parser: ShortTermMemoryParser should be called separately
Fixed #78 : Remove VariableNode usage
Fixed #79 : ConceptManager: Implement compile caching
Fixed #80 : SheerkaExecute : parsers_key is not correctly computed
Fixed #81 : ValidateConceptEvaluator : Validate concept's where and pre clauses right after the parsing
Fixed #82 : SheerkaIsAManager: isa() failed when the set as a body
Fixed #83 : ValidateConceptEvaluator : Support BNF and SYA Concepts
Fixed #84 : ExpressionParser: Implement the parser as a standard parser
Fixed #85 : Services: Give order to services
Fixed #86 : cannot manage smart_get_attr(the short, color)
This commit is contained in:
2021-06-07 21:14:03 +02:00
parent 1059ce25c5
commit 7dcaa9c111
92 changed files with 4263 additions and 1890 deletions
+32 -36
View File
@@ -8,16 +8,18 @@ from core.concept import DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF, Concept
from core.global_symbols import NotInit
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import Keywords, Tokenizer, LexerError
from parsers.BaseExpressionParser import VariableNode, ExprNode
from parsers.BaseParser import UnexpectedEofParsingError
from parsers.BnfDefinitionParser import BnfDefinitionParser
from parsers.BnfNodeParser import OrderedChoice, ConceptExpression, StrMatch, Sequence, RegExMatch, OneOrMore, \
VariableExpression
from parsers.DefConceptParser import DefConceptParser, NameNode, SyntaxErrorNode, CannotHandleParsingError
from parsers.DefConceptParser import UnexpectedTokenParsingError, DefConceptNode
from parsers.ExpressionParser import ExpressionParser
from parsers.FunctionParser import FunctionParser
from parsers.PythonParser import PythonParser, PythonNode
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.parsers.parsers_utils import compute_expected_array, SCWC, CV, compare_with_test_object
from tests.parsers.parsers_utils import compute_expected_array, SCWC, compare_with_test_object, CIO
def get_def_concept(name, where=None, pre=None, post=None, body=None, definition=None, bnf_def=None, ret=None):
@@ -26,9 +28,9 @@ def get_def_concept(name, where=None, pre=None, post=None, body=None, definition
if body:
def_concept.body = get_concept_part(body)
if where:
def_concept.where = get_concept_part(where)
def_concept.where = get_concept_part(where, use_expression=True)
if pre:
def_concept.pre = get_concept_part(pre)
def_concept.pre = get_concept_part(pre, use_expression=True)
if post:
def_concept.post = get_concept_part(post)
if ret:
@@ -46,11 +48,21 @@ def get_def_concept(name, where=None, pre=None, post=None, body=None, definition
return def_concept
def get_concept_part(part):
if isinstance(part, str):
node = PythonNode(part.strip(), ast.parse(part.strip(), mode="eval"))
def get_concept_part(part, use_expression=False):
if use_expression:
node = VariableNode(0, 0, [], part)
return ReturnValueConcept(
who="parsers.DefConcept",
who="parsers.Expression",
status=True,
value=ParserResultConcept(
source=part,
parser=ExpressionParser(),
value=node))
if isinstance(part, str):
node = PythonNode(part.lstrip(), ast.parse(part.lstrip(), mode="eval"))
return ReturnValueConcept(
who="parsers.Python",
status=True,
value=ParserResultConcept(
source=part,
@@ -61,7 +73,7 @@ def get_concept_part(part):
# node = PythonNode(part.strip(), ast.parse(part.strip(), mode="eval"))
nodes = compute_expected_array({}, part.source, [SCWC(part.first, part.last, *part.content)])
return ReturnValueConcept(
who="parsers.DefConcept",
who="parsers.Python",
status=True,
value=ParserResultConcept(
source=part.source,
@@ -70,9 +82,9 @@ def get_concept_part(part):
try_parsed=nodes[0]))
if isinstance(part, PN):
node = PythonNode(part.source.strip(), ast.parse(part.source.strip(), mode=part.mode))
node = PythonNode(part.source.lstrip(), ast.parse(part.source.lstrip(), mode=part.mode))
return ReturnValueConcept(
who="parsers.DefConcept",
who="parsers.Python",
status=True,
value=ParserResultConcept(
source=part.source,
@@ -81,7 +93,7 @@ def get_concept_part(part):
if isinstance(part, PythonNode):
return ReturnValueConcept(
who="parsers.DefConcept",
who="parsers.Python",
status=True,
value=ParserResultConcept(
source=part.source,
@@ -248,7 +260,7 @@ class TestDefConceptParser(TestUsingMemoryBasedSheerka):
assert isinstance(res.value, ParserResultConcept)
part_mapping = "body" if part == "as" else part
args = {part_mapping: get_concept_part("True")}
args = {part_mapping: "True"}
expected = get_def_concept("foo", **args)
assert node == expected
@@ -260,28 +272,6 @@ class TestDefConceptParser(TestUsingMemoryBasedSheerka):
assert not res.status
assert sheerka.isinstance(return_value, BuiltinConcepts.TOO_MANY_ERRORS)
def test_i_can_parse_complex_def_concept_statement(self):
text = """def concept a mult b
where a,b
pre isinstance(a, int) and isinstance(b, int)
as res = a * b
ret a if isinstance(a, Concept) else self
"""
sheerka, context, parser, *concepts = self.init_parser()
res = parser.parse(context, ParserInput(text))
return_value = res.value
expected_concept = get_def_concept(
name="a mult b",
where="a,b\n",
pre="isinstance(a, int) and isinstance(b, int)\n",
body=PN("res = a * b\n", "exec"),
ret="a if isinstance(a, Concept) else self\n"
)
assert res.status
assert isinstance(return_value, ParserResultConcept)
assert return_value.value == expected_concept
def test_i_can_parse_mutilines_declarations(self):
text = """
def concept add one to a as
@@ -547,7 +537,10 @@ from give me the date !
assert isinstance(res.value, ParserResultConcept)
assert isinstance(node, DefConceptNode)
assert sheerka.isinstance(node.where, BuiltinConcepts.RETURN_VALUE)
compare_with_test_object(node.where.body.body, CV(concepts[0], pre=True))
where_condition = node.where.body.body
assert isinstance(where_condition, ExprNode)
concept_found = where_condition.compiled[0].objects["__o_00__"]
compare_with_test_object(concept_found, CIO(concepts[0]))
text = "def concept foo x y pre x is a y"
res = parser.parse(context, ParserInput(text))
@@ -559,7 +552,10 @@ from give me the date !
assert isinstance(res.value, ParserResultConcept)
assert isinstance(node, DefConceptNode)
assert sheerka.isinstance(node.pre, BuiltinConcepts.RETURN_VALUE)
compare_with_test_object(node.pre.body.body, CV(concepts[0], pre=True))
pre_condition = node.pre.body.body
assert isinstance(pre_condition, ExprNode)
concept_found = pre_condition.compiled[0].objects["__o_00__"]
compare_with_test_object(concept_found, CIO(concepts[0]))
def test_i_can_parse_bnf_concept_with_regex(self):
sheerka, context, parser, number = self.init_parser("number")