Refactored sheerka execution flow + Enhanced log management

This commit is contained in:
2019-12-19 21:02:20 +01:00
parent 8dbe2e1b20
commit 5c95d918ad
32 changed files with 942 additions and 308 deletions
+29 -21
View File
@@ -5,11 +5,8 @@ import core.utils
from parsers.BaseParser import BaseParser, Node, ErrorNode, NotInitializedNode
from core.tokenizer import Tokenizer, TokenKind, Token, Keywords
from dataclasses import dataclass, field
import logging
from parsers.BnfParser import BnfParser
log = logging.getLogger(__name__)
from core.sheerka import ExecutionContext
@dataclass()
@@ -207,10 +204,10 @@ class DefaultParser(BaseParser):
"""
def __init__(self, **kwargs):
BaseParser.__init__(self, "DefaultParser")
BaseParser.__init__(self, "Default")
self.lexer_iter = None
self._current = None
self.context = None
self.context: ExecutionContext = None
self.text = None
self.sheerka = None
@@ -287,11 +284,12 @@ class DefaultParser(BaseParser):
def parse(self, context, text):
# default parser can only manage string text
if not isinstance(text, str):
log.debug(f"Failed to recognize '{text}'")
return context.sheerka.ret(
ret = context.sheerka.ret(
self.name,
False,
context.sheerka.new(BuiltinConcepts.NOT_FOR_ME, body=text))
self.log_result(context, text, ret)
return ret
self.reset_parser(context, text)
tree = self.parse_statement()
@@ -299,23 +297,29 @@ class DefaultParser(BaseParser):
# If a error is found it must be sent to error_sink
# tree must contain what was recognized
ret = self.sheerka.ret(
self.name,
not self.has_error,
self.sheerka.new(
if self.has_error and isinstance(self.error_sink[0], CannotHandleErrorNode):
body = self.sheerka.new(BuiltinConcepts.NOT_FOR_ME, body=self.error_sink)
else:
body = self.sheerka.new(
BuiltinConcepts.PARSER_RESULT,
parser=self,
source=text,
body=self.error_sink if self.has_error else tree,
try_parsed=tree))
try_parsed=tree)
self.log_result(log, text, ret)
ret = self.sheerka.ret(
self.name,
not self.has_error,
body)
self.log_result(context, text, ret)
return ret
def parse_statement(self):
token = self.get_token()
if token.value == Keywords.DEF:
self.next_token()
self.context.log(self.verbose_log, "Keyword DEF found.", self.name)
return self.parse_def_concept(token)
else:
return self.add_error(CannotHandleErrorNode([], self.text))
@@ -326,7 +330,6 @@ class DefaultParser(BaseParser):
"""
# init
log.debug("It may be a definition of a concept")
keywords_tokens = [def_token]
concept_found = DefConceptNode(keywords_tokens)
@@ -354,7 +357,6 @@ class DefaultParser(BaseParser):
concept_found.post = asts_found_by_parts[Keywords.POST]
concept_found.body = asts_found_by_parts[Keywords.AS]
log.debug(f"Found DefConcept node '{concept_found}'")
return concept_found
def regroup_tokens_by_parts(self, keywords_tokens):
@@ -412,7 +414,8 @@ class DefaultParser(BaseParser):
if TokenKind.NEWLINE in [t.type for t in name_tokens]:
self.add_error(SyntaxErrorNode(tokens_found_by_parts[Keywords.CONCEPT], "Newline are not allowed in name."))
return NameNode(name_tokens[name_first_token_index:]) # skip the first token
name_node = NameNode(name_tokens[name_first_token_index:]) # skip the first token
return name_node
def get_concept_definition(self, tokens_found_by_parts):
if tokens_found_by_parts[Keywords.FROM] is None:
@@ -448,8 +451,6 @@ class DefaultParser(BaseParser):
if keyword == Keywords.CONCEPT or keyword == Keywords.FROM:
continue # already done
log.debug("Processing part '" + keyword.name + "'")
tokens = tokens_found_by_parts[keyword]
if tokens is None:
continue # nothing to do
@@ -464,8 +465,15 @@ class DefaultParser(BaseParser):
continue
# ask the other parsers if they recognize the tokens
new_context = self.context.push(self.name)
parsing_result = core.builtin_helpers.expect_one(new_context, self.sheerka.parse(new_context, tokens))
new_context = self.context.push(self.name, desc=f"Parsing {keyword}")
new_context.log_new(self.verbose_log)
to_parse = self.sheerka.ret(
new_context.who,
True,
self.sheerka.new(BuiltinConcepts.USER_INPUT, body=tokens))
steps = [BuiltinConcepts.PARSING]
parsed = self.sheerka.execute(new_context, to_parse, steps, self.verbose_log)
parsing_result = core.builtin_helpers.expect_one(new_context, parsed)
if not parsing_result.status:
self.add_error(parsing_result.value)
continue