I can define and eval BNF definitions
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user