from core.builtin_concepts import BuiltinConcepts from core.rule import Rule from core.sheerka.services.SheerkaExecute import ParserInput from core.tokenizer import TokenKind from parsers.BaseParser import BaseParser, ParsingError, UnexpectedTokenParsingError, BaseParserInputParser class RuleNotFoundError(ParsingError): def __init__(self, id_as_tuple): self.key = id_as_tuple[0] self.id = id_as_tuple[1] def __repr__(self): return f"RuleNotFoundError(id={self.id}, key={self.key}" class RuleParser(BaseParserInputParser): """ Tries to recognize rules """ NAME = "Rule" def __init__(self, **kwargs): BaseParserInputParser.__init__(self, RuleParser.NAME, 80) def parse(self, context, parser_input: ParserInput): """ text can be string, but text can also be an list of tokens :param context: :param parser_input: :return: """ context.log(f"Parsing '{parser_input}'", self.name) sheerka = context.sheerka if parser_input.is_empty(): return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.IS_EMPTY)) if not self.reset_parser(context, parser_input): error = self.error_sink[0] context.log(f"Error found in tokenizer {error}", self.name) return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.ERROR, body=error)) parser_input.next_token() if parser_input.token.type != TokenKind.RULE: return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.NOT_FOR_ME, body=parser_input.as_text())) token = parser_input.token if parser_input.next_token(): reason = UnexpectedTokenParsingError("Only one rule supported", parser_input.token, [TokenKind.EOF]) return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.NOT_FOR_ME, body=parser_input.as_text(), reason=reason)) if token.value[1] is None: return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.NOT_IMPLEMENTED)) if token.value[1].isdigit(): rule = sheerka.get_rule_by_id(token.value[1]) else: rule = Rule().set_id(token.value[1]) rule.metadata.id_is_unresolved = True if sheerka.isinstance(rule, BuiltinConcepts.UNKNOWN_RULE): return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.ERROR, body=[RuleNotFoundError(token.value)])) body = sheerka.new(BuiltinConcepts.PARSER_RESULT, parser=self, source=parser_input.as_text(), body=[rule], try_parsed=[rule]) return sheerka.ret(self.name, True, body)