Added bnf when adding a new concept + Started logging filtering
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
from core.builtin_concepts import ParserResultConcept, ReturnValueConcept
|
||||
from core.ast.nodes import python_to_concept
|
||||
from core.builtin_concepts import ParserResultConcept, ReturnValueConcept, BuiltinConcepts
|
||||
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
|
||||
@@ -9,6 +13,23 @@ from parsers.PythonParser import PythonGetNamesVisitor, PythonNode
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ConceptOrRuleNameVisitor(ParsingExpressionVisitor):
|
||||
"""
|
||||
Gets the concepts referenced by BNF
|
||||
If a rule_name is given, it will also be considered as a potential property
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.names = set()
|
||||
|
||||
def visit_ConceptMatch(self, node):
|
||||
self.names.add(node.rule_name or node.concept_name)
|
||||
|
||||
def visit_all(self, node):
|
||||
if node.rule_name:
|
||||
self.names.add(node.rule_name)
|
||||
|
||||
|
||||
class AddConceptEvaluator(OneReturnValueEvaluator):
|
||||
"""
|
||||
Used to add a new concept
|
||||
@@ -32,7 +53,7 @@ class AddConceptEvaluator(OneReturnValueEvaluator):
|
||||
props_found = set()
|
||||
|
||||
concept = Concept(def_concept_node.name)
|
||||
for prop in ("where", "pre", "post", "body"):
|
||||
for prop in ("definition", "where", "pre", "post", "body"):
|
||||
# put back the sources
|
||||
part_ret_val = getattr(def_concept_node, prop)
|
||||
if not isinstance(part_ret_val, ReturnValueConcept) or not part_ret_val.status:
|
||||
@@ -43,35 +64,63 @@ class AddConceptEvaluator(OneReturnValueEvaluator):
|
||||
setattr(concept.metadata, prop, source)
|
||||
|
||||
# try to find what can be a property
|
||||
for p in self.get_props(part_ret_val):
|
||||
concept_name = [part.value for part in def_concept_node.name.tokens]
|
||||
for p in self.get_props(sheerka, part_ret_val, concept_name):
|
||||
props_found.add(p)
|
||||
|
||||
# Auto discovered properties must be referenced in the name
|
||||
# Note that with this method, the variables will be created in the order of appearance
|
||||
# add props order by appearance when possible
|
||||
for token in def_concept_node.name.tokens:
|
||||
if token.value in props_found:
|
||||
concept.set_prop(token.value, None)
|
||||
|
||||
# add the remaining properties
|
||||
for p in props_found:
|
||||
if p not in concept.props:
|
||||
concept.set_prop(p, None)
|
||||
|
||||
# finish initialisation
|
||||
concept.init_key(def_concept_node.name.tokens)
|
||||
concept.add_codes(def_concept_node.get_codes())
|
||||
concept.add_codes(def_concept_node.get_asts())
|
||||
if sheerka.is_success(def_concept_node.definition):
|
||||
concept.bnf = def_concept_node.definition.value.value
|
||||
|
||||
ret = sheerka.create_new_concept(context, concept)
|
||||
return sheerka.ret(self.name, ret.status, ret.value, parents=[return_value])
|
||||
|
||||
@staticmethod
|
||||
def get_source(ret_value):
|
||||
return ret_value.value.source if isinstance(ret_value.value, ParserResultConcept) \
|
||||
else ret_value.value.name
|
||||
return ret_value.value.source
|
||||
|
||||
@staticmethod
|
||||
def get_props(ret_value):
|
||||
if isinstance(ret_value.value, ParserResultConcept) and isinstance(ret_value.value.value, PythonNode):
|
||||
get_names_visitor = PythonGetNamesVisitor()
|
||||
get_names_visitor.visit(ret_value.value.value.ast_)
|
||||
return get_names_visitor.names
|
||||
def get_props(sheerka, ret_value, concept_name):
|
||||
"""
|
||||
Try to find out the variables
|
||||
This function can only be a draft, as there may be tons of different situations
|
||||
I guess that it can only be complete when will we have access to Sheerka memory
|
||||
"""
|
||||
|
||||
if isinstance(ret_value.value, Concept):
|
||||
return list(ret_value.value.props.keys())
|
||||
#
|
||||
# Case of python code
|
||||
#
|
||||
if isinstance(ret_value.value, ParserResultConcept) and isinstance(ret_value.value.value, PythonNode):
|
||||
python_node = ret_value.value.value
|
||||
as_concept_node = python_to_concept(python_node.ast_)
|
||||
variables = get_names(sheerka, as_concept_node)
|
||||
variables = filter(lambda x: x in concept_name, variables)
|
||||
return list(variables)
|
||||
|
||||
#
|
||||
# case of concept
|
||||
#
|
||||
if isinstance(ret_value.value, ParserResultConcept) and isinstance(ret_value.value.value, Concept):
|
||||
return list(ret_value.value.value.props.keys())
|
||||
|
||||
#
|
||||
# case of BNF
|
||||
#
|
||||
if isinstance(ret_value.value, ParserResultConcept) and isinstance(ret_value.value.value, ParsingExpression):
|
||||
visitor = ConceptOrRuleNameVisitor()
|
||||
visitor.visit(ret_value.value.value)
|
||||
return sorted(list(visitor.names))
|
||||
|
||||
return []
|
||||
|
||||
Reference in New Issue
Block a user