Implemented a first and basic version of a Rete rule engine

This commit is contained in:
2021-02-09 16:06:32 +01:00
parent 821dbed189
commit a2a8d5c5e5
110 changed files with 7301 additions and 1654 deletions
+24 -73
View File
@@ -1,13 +1,14 @@
from dataclasses import dataclass, field
from dataclasses import dataclass
import core.builtin_helpers
import core.utils
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, ParserResultConcept
from core.concept import ConceptParts, DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
from core.concept import DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF
from core.global_symbols import NotInit
from core.sheerka.services.SheerkaExecute import ParserInput, SheerkaExecute
from core.tokenizer import TokenKind, Keywords
from parsers.BaseCustomGrammarParser import BaseCustomGrammarParser, SyntaxErrorNode
from parsers.BaseParser import Node, ParsingError, NotInitializedNode, UnexpectedTokenParsingError
from parsers.BaseCustomGrammarParser import BaseCustomGrammarParser, SyntaxErrorNode, NameNode, CustomGrammarParserNode
from parsers.BaseParser import ParsingError, UnexpectedTokenParsingError
from parsers.BnfDefinitionParser import BnfDefinitionParser
@@ -17,15 +18,7 @@ class ParsingException(Exception):
@dataclass()
class DefConceptParsingResult(Node):
"""
Base node for all default parser nodes
"""
tokens: list = field(compare=False, repr=False)
@dataclass()
class DefConceptParsingError(DefConceptParsingResult, ParsingError):
class DefConceptParsingError(CustomGrammarParserNode, ParsingError):
pass
@@ -38,63 +31,21 @@ class CannotHandleParsingError(DefConceptParsingError):
@dataclass()
class NameNode(DefConceptParsingResult):
def get_name(self):
name = ""
first = True
for token in self.tokens:
if token.type == TokenKind.EOF:
break
if token.type == TokenKind.WHITESPACE:
continue
if not first:
name += " "
name += token.value[1:-1] if token.type == TokenKind.STRING else str(token.value)
first = False
return name
def __repr__(self):
return self.get_name()
def __eq__(self, other):
if not isinstance(other, NameNode):
return False
return self.get_name() == other.get_name()
def __hash__(self):
return hash(self.get_name())
@dataclass()
class DefConceptNode(DefConceptParsingResult):
name: NameNode = NotInitializedNode()
where: ReturnValueConcept = NotInitializedNode()
pre: ReturnValueConcept = NotInitializedNode()
post: ReturnValueConcept = NotInitializedNode()
body: ReturnValueConcept = NotInitializedNode()
ret: ReturnValueConcept = NotInitializedNode()
definition: ReturnValueConcept = NotInitializedNode()
class DefConceptNode(CustomGrammarParserNode):
name: NameNode = NotInit
where: ReturnValueConcept = NotInit
pre: ReturnValueConcept = NotInit
post: ReturnValueConcept = NotInit
body: ReturnValueConcept = NotInit
ret: ReturnValueConcept = NotInit
definition: ReturnValueConcept = NotInit
definition_type: str = None
def get_asts(self):
asts = {}
for part_key in ConceptParts:
prop_value = getattr(self, part_key.value)
if isinstance(prop_value, ReturnValueConcept) and \
isinstance(prop_value.body, ParserResultConcept) and \
hasattr(prop_value.body.body, "ast_"):
asts[part_key] = prop_value
return asts
@dataclass()
class IsaConceptNode(DefConceptParsingResult):
concept: NameNode = NotInitializedNode()
set: NameNode = NotInitializedNode()
class IsaConceptNode(CustomGrammarParserNode):
concept: NameNode = NotInit
set: NameNode = NotInit
class DefConceptParser(BaseCustomGrammarParser):
@@ -201,12 +152,12 @@ class DefConceptParser(BaseCustomGrammarParser):
def get_concept_definition(self, current_concept_def, parts):
if Keywords.FROM not in parts:
return None, NotInitializedNode()
return None, NotInit
tokens = parts[Keywords.FROM]
if len(tokens) == 1:
self.add_error(SyntaxErrorNode([], f"Empty '{tokens[0].value}' declaration."), False)
return None, NotInitializedNode()
return None, NotInit
if tokens[1].value == Keywords.BNF.value:
return self.get_concept_bnf_definition(current_concept_def, core.utils.strip_tokens(tokens[2:]))
@@ -216,7 +167,7 @@ class DefConceptParser(BaseCustomGrammarParser):
def get_concept_bnf_definition(self, current_concept_def, tokens):
if len(tokens) == 0:
self.add_error(SyntaxErrorNode([], "Empty 'bnf' declaration"), False)
return None, NotInitializedNode()
return None, NotInit
if tokens[0].type == TokenKind.COLON:
tokens = self.get_body(tokens[1:])
@@ -233,7 +184,7 @@ class DefConceptParser(BaseCustomGrammarParser):
if not parsing_result.status:
self.add_error(parsing_result.value)
return None, NotInitializedNode()
return None, NotInit
return DEFINITION_TYPE_BNF, parsing_result
@@ -243,7 +194,7 @@ class DefConceptParser(BaseCustomGrammarParser):
tokens = core.utils.strip_tokens(tokens[start:])
if len(tokens) == 0:
self.add_error(SyntaxErrorNode([], f"Empty 'from' declaration."), False)
return None, NotInitializedNode()
return None, NotInit
if tokens[0].type == TokenKind.COLON:
tokens = self.get_body(tokens[1:])
@@ -252,7 +203,7 @@ class DefConceptParser(BaseCustomGrammarParser):
def get_ast(self, keyword, parts):
if keyword not in parts:
return NotInitializedNode()
return NotInit
tokens = parts[keyword]
if len(tokens) == 1: