Implemented FunctionParser

This commit is contained in:
2020-09-17 14:11:09 +02:00
parent 8a866880bc
commit 177a6b1d5f
40 changed files with 1752 additions and 561 deletions
+56 -20
View File
@@ -6,13 +6,16 @@ from core.builtin_concepts import ParserResultConcept, BuiltinConcepts, ReturnVa
from core.concept import DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF, Concept, CV
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import Keywords, Tokenizer, LexerError
from parsers.BaseNodeParser import SCN, SCWC
from parsers.BnfNodeParser import OrderedChoice, ConceptExpression, StrMatch
from parsers.BnfParser import BnfParser
from parsers.DefaultParser import DefaultParser, NameNode, SyntaxErrorNode, CannotHandleErrorNode, IsaConceptNode
from parsers.DefaultParser import DefaultParser, NameNode, SyntaxErrorNode, CannotHandleErrorNode
from parsers.DefaultParser import UnexpectedTokenErrorNode, DefConceptNode
from parsers.FunctionParser import FunctionParser
from parsers.PythonParser import PythonParser, PythonNode
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.parsers.parsers_utils import get_node, compute_expected_array
def get_def_concept(name, where=None, pre=None, post=None, body=None, definition=None, bnf_def=None, ret=None):
@@ -52,6 +55,18 @@ def get_concept_part(part):
parser=PythonParser(),
value=node))
if isinstance(part, FN):
# 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.Default",
status=True,
value=ParserResultConcept(
source=part.source,
parser=FunctionParser(),
value=nodes[0],
try_parsed=nodes[0]))
if isinstance(part, PN):
node = PythonNode(part.source.strip(), ast.parse(part.source.strip(), mode=part.mode))
return ReturnValueConcept(
@@ -84,6 +99,17 @@ class PN:
mode: str # compilation mode
@dataclass
class FN:
"""
Function Node
"""
source: str
first: str
last: str
content: list
class TestDefaultParser(TestUsingMemoryBasedSheerka):
def init_parser(self, *concepts):
@@ -117,7 +143,7 @@ class TestDefaultParser(TestUsingMemoryBasedSheerka):
def test_i_can_parse_complex_def_concept_statement(self):
text = """def concept a mult b
where a,b
pre isinstance(b, int)
pre isinstance(a, int) and isinstance(b, int)
post isinstance(res, a)
as res = a * b
ret a if isinstance(a, Concept) else self
@@ -128,8 +154,8 @@ ret a if isinstance(a, Concept) else self
expected_concept = get_def_concept(
name="a mult b",
where="a,b\n",
pre="isinstance(b, int)\n",
post="isinstance(res, a)\n",
pre="isinstance(a, int) and isinstance(b, int)\n",
post=FN("isinstance(res, a)\n", "isinstance(", ")", ["res", ", ", "a"]),
body=PN("res = a * b\n", "exec"),
ret="a if isinstance(a, Concept) else self\n"
)
@@ -354,24 +380,21 @@ def concept add one to a as
assert context.sheerka.isinstance(res.value, BuiltinConcepts.NOT_FOR_ME)
assert isinstance(res.value.body[0], CannotHandleErrorNode)
def test_i_can_parse_is_a(self):
text = "the name of my 'concept' isa the name of the set"
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(text))
expected = IsaConceptNode([],
concept=NameNode(list(Tokenizer("the name of my 'concept'"))),
set=NameNode(list(Tokenizer("the name of the set"))))
assert res.status
assert res.who == parser.name
assert res.value.source == text
assert isinstance(res.value, ParserResultConcept)
assert res.value.value == expected
# def test_i_can_parse_is_a(self):
# text = "the name of my 'concept' isa the name of the set"
# sheerka, context, parser = self.init_parser()
# res = parser.parse(context, ParserInput(text))
# expected = IsaConceptNode([],
# concept=NameNode(list(Tokenizer("the name of my 'concept'"))),
# set=NameNode(list(Tokenizer("the name of the set"))))
#
# assert res.status
# assert res.who == parser.name
# assert res.value.source == text
# assert isinstance(res.value, ParserResultConcept)
# assert res.value.value == expected
@pytest.mark.parametrize("text", [
"concept",
"isa number",
"name isa",
"def",
"def concept_name"
])
@@ -383,6 +406,19 @@ def concept add one to a as
assert sheerka.isinstance(res.body, BuiltinConcepts.ERROR)
assert isinstance(res.body.body[0], UnexpectedTokenErrorNode)
@pytest.mark.parametrize("text", [
"concept",
"isa number",
"name isa",
])
def test_i_cannot_parse_not_for_me_entries(self, text):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(text))
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME)
assert isinstance(res.body.body[0], CannotHandleErrorNode)
@pytest.mark.parametrize("text, error_msg, error_text", [
("'name", "Missing Trailing quote", "'name"),
("foo isa 'name", "Missing Trailing quote", "'name"),