Fixed #49 : ExpressionParser: Implement ExpressionParser
This commit is contained in:
@@ -29,8 +29,6 @@ class SheerkaEvaluateRules(BaseService):
|
||||
self.sheerka.register_debug_vars(self.NAME, "evaluate_rules", "results")
|
||||
self.sheerka.register_debug_rules(self.NAME, "evaluate_rule", "*")
|
||||
|
||||
|
||||
|
||||
def reset_evaluators(self):
|
||||
# instantiate evaluators, once for all, only keep when it's enabled
|
||||
evaluators = [e_class() for e_class in self.sheerka.evaluators]
|
||||
|
||||
@@ -14,10 +14,10 @@ from core.rule import Rule, ACTION_TYPE_PRINT
|
||||
from core.sheerka.Sheerka import RECOGNIZED_BY_NAME, RECOGNIZED_BY_ID
|
||||
from core.sheerka.services.sheerka_service import BaseService, FailedToCompileError
|
||||
from core.tokenizer import Keywords, TokenKind, Token, IterParser
|
||||
from core.utils import index_tokens, COLORS, get_text_from_tokens
|
||||
from core.utils import index_tokens, COLORS, get_text_from_tokens, unstr_concept
|
||||
from evaluators.ConceptEvaluator import ConceptEvaluator
|
||||
from evaluators.PythonEvaluator import PythonEvaluator, Expando
|
||||
from parsers.BaseExpressionParser import AndNode, ExpressionVisitor, VariableNode, ComparisonNode
|
||||
from parsers.BaseExpressionParser import AndNode, ExpressionVisitor, VariableNode, ComparisonNode, FunctionNode
|
||||
from parsers.BaseNodeParser import SourceCodeWithConceptNode, ConceptNode, SourceCodeNode
|
||||
from parsers.LogicalOperatorParser import LogicalOperatorParser
|
||||
from parsers.PythonParser import PythonNode
|
||||
@@ -1127,7 +1127,6 @@ class ReteConditionExprVisitor(ExpressionVisitor):
|
||||
self.context = context
|
||||
self.var_counter = 0
|
||||
self.variables = {}
|
||||
self.res = []
|
||||
|
||||
def add_variable(self, target):
|
||||
var_name = f"__x_{self.var_counter:02}__"
|
||||
@@ -1135,35 +1134,71 @@ class ReteConditionExprVisitor(ExpressionVisitor):
|
||||
self.variables[target] = var_name
|
||||
return var_name
|
||||
|
||||
def init_variable_if_needed(self, node):
|
||||
def init_or_get_variable_from_name(self, node, conditions):
|
||||
if node.name not in self.variables:
|
||||
var_name = self.add_variable(node.name)
|
||||
self.res.append(Condition(V(var_name), "__name__", node.name))
|
||||
conditions.append(Condition(V(var_name), "__name__", node.name))
|
||||
|
||||
return V(self.variables[node.name])
|
||||
|
||||
def init_or_get_variable_from_attr(self, node, conditions):
|
||||
path = f"{node.name}.{node.attributes_str}"
|
||||
if path in self.variables:
|
||||
return self.variables[path]
|
||||
|
||||
root = self.init_or_get_variable_from_name(node, conditions)
|
||||
var_name = self.add_variable(path)
|
||||
variable = V(var_name)
|
||||
conditions.append(Condition(root, node.attributes_str, variable))
|
||||
return variable
|
||||
|
||||
def get_conditions(self, expr_node):
|
||||
self.res.clear()
|
||||
self.var_counter = 0
|
||||
self.variables.clear()
|
||||
|
||||
self.visit(expr_node)
|
||||
return AndConditions(self.res)
|
||||
conditions = self.visit(expr_node)
|
||||
return [AndConditions(conditions)]
|
||||
|
||||
def visit_VariableNode(self, expr_node):
|
||||
var_name = self.init_variable_if_needed(expr_node)
|
||||
conditions = []
|
||||
var_name = self.init_or_get_variable_from_name(expr_node, conditions)
|
||||
if expr_node.attributes_str is not None:
|
||||
self.res.append(Condition(var_name, expr_node.attributes_str, True))
|
||||
conditions.append(Condition(var_name, expr_node.attributes_str, True))
|
||||
return conditions
|
||||
|
||||
def visit_AndNode(self, expr_node: AndNode):
|
||||
conditions = []
|
||||
for node in expr_node.parts:
|
||||
self.visit(node)
|
||||
conditions.extend(self.visit(node))
|
||||
|
||||
return conditions
|
||||
|
||||
def visit_ComparisonNode(self, expr_node: ComparisonNode):
|
||||
if isinstance(expr_node.left, VariableNode):
|
||||
left = self.init_variable_if_needed(expr_node.left)
|
||||
conditions = []
|
||||
left = self.init_or_get_variable_from_name(expr_node.left, conditions)
|
||||
attr = expr_node.left.attributes_str or "__self__"
|
||||
right = eval(get_text_from_tokens(expr_node.right.tokens))
|
||||
self.res.append(Condition(left, attr, right))
|
||||
conditions.append(Condition(left, attr, right))
|
||||
return conditions
|
||||
else:
|
||||
raise FailedToCompileError(expr_node)
|
||||
raise FailedToCompileError([expr_node])
|
||||
|
||||
def visit_FunctionNode(self, expr_node: FunctionNode):
|
||||
if expr_node.first.value == "recognize(":
|
||||
return self.function_recognize(expr_node.parameters[0].value, expr_node.parameters[1].value)
|
||||
|
||||
def function_recognize(self, source, target):
|
||||
conditions = []
|
||||
body_var = self.init_or_get_variable_from_attr(source, conditions)
|
||||
conditions.append(Condition(body_var, "__is_concept__", True))
|
||||
if isinstance(target, VariableNode):
|
||||
conditions.append(Condition(body_var, "name", target.name))
|
||||
else:
|
||||
concept_key, concept_id = unstr_concept(target.value)
|
||||
if concept_id:
|
||||
conditions.append(Condition(body_var, "id", concept_id))
|
||||
elif concept_key:
|
||||
conditions.append(Condition(body_var, "name", concept_key))
|
||||
|
||||
return conditions
|
||||
|
||||
Reference in New Issue
Block a user