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
+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