I can define and eval BNF definitions

This commit is contained in:
2019-12-17 21:19:44 +01:00
parent c668cc46d2
commit 88cd3162be
25 changed files with 1099 additions and 569 deletions
+8 -4
View File
@@ -1,14 +1,13 @@
from core.ast.nodes import python_to_concept
from core.builtin_concepts import ParserResultConcept, ReturnValueConcept, BuiltinConcepts
from core.builtin_concepts import ParserResultConcept, ReturnValueConcept
from core.builtin_helpers import get_names
from core.concept import Concept
from evaluators.BaseEvaluator import OneReturnValueEvaluator
from parsers.ConceptLexerParser import ParsingExpression, ParsingExpressionVisitor
from parsers.DefaultParser import DefConceptNode
import functools
import logging
from parsers.PythonParser import PythonGetNamesVisitor, PythonNode
from parsers.PythonParser import PythonNode
log = logging.getLogger(__name__)
@@ -23,7 +22,12 @@ class ConceptOrRuleNameVisitor(ParsingExpressionVisitor):
self.names = set()
def visit_ConceptMatch(self, node):
self.names.add(node.rule_name or node.concept_name)
if node.rule_name:
self.names.add(node.rule_name)
elif isinstance(node.concept, Concept):
self.names.add(node.concept.name)
else:
self.names.add(node.concept)
def visit_all(self, node):
if node.rule_name:
+6 -2
View File
@@ -4,12 +4,16 @@ from core.concept import Concept, ConceptParts
from evaluators.BaseEvaluator import OneReturnValueEvaluator
import logging
from parsers.BaseParser import BaseParser
log = logging.getLogger(__name__)
class ConceptEvaluator(OneReturnValueEvaluator):
"""
The concept evaluatuor is the main class that know what to do with a concept
It verifies the PRE
If ok, can execute or not the BODY
Then checks the POST conditions
"""
NAME = "Concept"
evaluation_steps = [BuiltinConcepts.EVALUATION, BuiltinConcepts.AFTER_EVALUATION]
+92
View File
@@ -0,0 +1,92 @@
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts
from evaluators.BaseEvaluator import OneReturnValueEvaluator
import logging
from parsers.ConceptLexerParser import ConceptNode, TerminalNode, NonTerminalNode, ConceptMatch
log = logging.getLogger(__name__)
class ConceptNodeEvaluator(OneReturnValueEvaluator):
"""
After a BNF is recognized, generates the concept or the list concepts
"""
NAME = "ConceptNode"
def __init__(self):
super().__init__(self.NAME, 60) # more than the ConceptNodeEvaluator
def matches(self, context, return_value):
if not return_value.status:
return False
if not isinstance(return_value.value, ParserResultConcept):
return False
return (isinstance(return_value.value.value, ConceptNode) or
(
hasattr(return_value.value.value, "__iter__") and
len(return_value.value.value) > 0 and
isinstance(return_value.value.value[0], ConceptNode)
))
def eval(self, context, return_value):
"""
From a concept node, creates a new concept
and makes sure that the properties are correctly set
"""
sheerka = context.sheerka
nodes = return_value.value.value
if not hasattr(nodes, "__iter__"):
nodes = [nodes]
concepts = []
for node in nodes:
concept = sheerka.new(node.concept.key)
concept = self.update_concept(sheerka, concept, node.underlying)
concepts.append(concept)
if len(concepts) == 1:
return sheerka.ret(
self.name,
True,
concepts[0],
parents=[return_value])
raise NotImplementedError("Not yet")
def update_concept(self, sheerka, concept, underlying):
"""
Updates the property of the concept
"""
def _add_prop(c, prop_name, value):
"""
Adds a new entry,
makes a list if the property already exists
"""
if prop_name not in c.props or c.props[prop_name].value is None:
c.set_prop(prop_name, value)
else:
new_value = [c.props[prop_name].value, value]
c.set_prop(prop_name, new_value)
parsing_expression = underlying.parsing_expression
if parsing_expression.rule_name:
_add_prop(concept, parsing_expression.rule_name, underlying.source)
if isinstance(underlying, NonTerminalNode):
for child in underlying.children:
if isinstance(child.parsing_expression, ConceptMatch):
new_concept = sheerka.new(child.parsing_expression.concept.key)
_add_prop(concept, child.parsing_expression.rule_name, new_concept)
if sheerka.isinstance(new_concept, BuiltinConcepts.UNKNOWN_CONCEPT):
continue
else:
self.update_concept(sheerka, new_concept, child.children[0])
else:
self.update_concept(sheerka, concept, child)
return concept
+2 -1
View File
@@ -1,5 +1,4 @@
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
import core.builtin_helpers
from evaluators.BaseEvaluator import AllReturnValuesEvaluator, BaseEvaluator
import logging
@@ -13,6 +12,8 @@ class MultipleSameSuccessEvaluator(AllReturnValuesEvaluator):
"""
Used to filter the responses
It has a low priority to let other evaluators try to resolve the errors
It reduces the responses when several evaluators give the same answer
"""
NAME = "MultipleSameSuccess"
+2
View File
@@ -11,6 +11,8 @@ class OneSuccessEvaluator(AllReturnValuesEvaluator):
"""
Used to filter the responses
It has a low priority to let other evaluators try to resolve the errors
Make sure that there is only one successful answer
"""
NAME = "OneSuccess"
+4
View File
@@ -15,6 +15,10 @@ log = logging.getLogger(__name__)
class PythonEvaluator(OneReturnValueEvaluator):
NAME = "Python"
"""
Evaluate a Python node, ie, evaluate some Python code
"""
def __init__(self):
super().__init__(self.NAME, 50)
+2
View File
@@ -12,6 +12,8 @@ class TooManySuccessEvaluator(AllReturnValuesEvaluator):
"""
Used to filter the responses
It has a low priority to let other evaluators try to resolve the errors
Raises an error when that are several successful answers, with different values
"""
NAME = "TooManySuccess"