Working on #48 : Added BaseExprParser and BaseNodeParser.py
This commit is contained in:
+95
-58
@@ -62,11 +62,6 @@ class BaseParser:
|
||||
self.short_name = name
|
||||
self.priority = priority
|
||||
self.enabled = enabled
|
||||
|
||||
self.error_sink = []
|
||||
self.context: ExecutionContext = None
|
||||
self.sheerka = None
|
||||
self.parser_input: ParserInput = None
|
||||
self.yield_eof = yield_eof
|
||||
|
||||
def __eq__(self, other):
|
||||
@@ -80,6 +75,74 @@ class BaseParser:
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
||||
def log_result(self, context, source, ret):
|
||||
pass
|
||||
# if not self.log.isEnabledFor(logging.DEBUG):
|
||||
# return
|
||||
#
|
||||
# if ret.status:
|
||||
# value = context.return_value_to_str(ret)
|
||||
# context.log(f"Recognized '{source}' as {value}", self.name)
|
||||
# else:
|
||||
# context.log(f"Failed to recognize '{source}'", self.name)
|
||||
|
||||
def log_multiple_results(self, context, source, list_of_ret):
|
||||
pass
|
||||
# if not self.log.isEnabledFor(logging.DEBUG):
|
||||
# return
|
||||
#
|
||||
# context.log(f"Recognized '{source}' as multiple concepts", self.name)
|
||||
# for r in list_of_ret:
|
||||
# value = context.return_value_to_str(r)
|
||||
# context.log(f" Recognized '{value}'", self.name)
|
||||
|
||||
def get_return_value_body(self, sheerka, source, parsed, try_parse, errors):
|
||||
"""
|
||||
All parsers must return their result in a standard way
|
||||
:param sheerka:
|
||||
:param source:
|
||||
:param parsed:
|
||||
:param try_parse:
|
||||
:param errors:
|
||||
:return:
|
||||
"""
|
||||
if len(errors) == 1 and isinstance(errors[0], Concept):
|
||||
return errors[0]
|
||||
|
||||
if len(errors):
|
||||
if parsed is None:
|
||||
return sheerka.new(BuiltinConcepts.NOT_FOR_ME,
|
||||
body=source,
|
||||
reason=errors)
|
||||
else:
|
||||
return sheerka.new(BuiltinConcepts.ERROR,
|
||||
body=errors)
|
||||
|
||||
return sheerka.new(BuiltinConcepts.PARSER_RESULT,
|
||||
parser=self,
|
||||
source=source,
|
||||
body=parsed,
|
||||
try_parsed=try_parse)
|
||||
|
||||
@staticmethod
|
||||
def get_name(name):
|
||||
return BaseParser.PREFIX + name
|
||||
|
||||
|
||||
class BaseParserInputParser(BaseParser):
|
||||
"""
|
||||
Base parser for stateful parser where context, parser input, and error sink are part of the class
|
||||
"""
|
||||
|
||||
def __init__(self, name, priority: int, enabled=True, yield_eof=False):
|
||||
super(BaseParserInputParser, self).__init__(name, priority, enabled, yield_eof)
|
||||
|
||||
self.error_sink = []
|
||||
self.context: ExecutionContext = None
|
||||
self.sheerka = None
|
||||
self.parser_input: ParserInput = None
|
||||
self.yield_eof = yield_eof
|
||||
|
||||
def reset_parser(self, context, parser_input: ParserInput):
|
||||
self.context = context
|
||||
self.sheerka = context.sheerka
|
||||
@@ -106,54 +169,6 @@ class BaseParser:
|
||||
def has_error(self):
|
||||
return len(self.error_sink) > 0
|
||||
|
||||
def log_result(self, context, source, ret):
|
||||
pass
|
||||
# if not self.log.isEnabledFor(logging.DEBUG):
|
||||
# return
|
||||
#
|
||||
# if ret.status:
|
||||
# value = context.return_value_to_str(ret)
|
||||
# context.log(f"Recognized '{source}' as {value}", self.name)
|
||||
# else:
|
||||
# context.log(f"Failed to recognize '{source}'", self.name)
|
||||
|
||||
def log_multiple_results(self, context, source, list_of_ret):
|
||||
pass
|
||||
# if not self.log.isEnabledFor(logging.DEBUG):
|
||||
# return
|
||||
#
|
||||
# context.log(f"Recognized '{source}' as multiple concepts", self.name)
|
||||
# for r in list_of_ret:
|
||||
# value = context.return_value_to_str(r)
|
||||
# context.log(f" Recognized '{value}'", self.name)
|
||||
|
||||
def get_return_value_body(self, sheerka, source, parsed, try_parse):
|
||||
"""
|
||||
All parsers must return their result in a standard way
|
||||
:param sheerka:
|
||||
:param source:
|
||||
:param parsed:
|
||||
:param try_parse:
|
||||
:return:
|
||||
"""
|
||||
if len(self.error_sink) == 1 and isinstance(self.error_sink[0], Concept):
|
||||
return self.error_sink[0]
|
||||
|
||||
if self.has_error:
|
||||
if parsed is None:
|
||||
return sheerka.new(BuiltinConcepts.NOT_FOR_ME,
|
||||
body=source,
|
||||
reason=self.error_sink)
|
||||
else:
|
||||
return sheerka.new(BuiltinConcepts.ERROR,
|
||||
body=self.error_sink)
|
||||
|
||||
return sheerka.new(BuiltinConcepts.PARSER_RESULT,
|
||||
parser=self,
|
||||
source=source,
|
||||
body=parsed,
|
||||
try_parsed=try_parse)
|
||||
|
||||
@staticmethod
|
||||
def get_input_as_lexer_nodes(parser_input, expected_parser=None):
|
||||
"""
|
||||
@@ -229,12 +244,34 @@ class BaseParser:
|
||||
|
||||
return list_a
|
||||
|
||||
@staticmethod
|
||||
def get_name(name):
|
||||
return BaseParser.PREFIX + name
|
||||
|
||||
|
||||
class BaseExprParser(BaseParser):
|
||||
|
||||
def parse_input(self):
|
||||
def parse_input(self, context, parser_input, error_sink):
|
||||
raise NotImplementedError
|
||||
|
||||
def reset_parser_input(self, parser_input: ParserInput, error_sink):
|
||||
try:
|
||||
error_sink.clear()
|
||||
parser_input.reset(self.yield_eof)
|
||||
except LexerError as e:
|
||||
error_sink.add_error(e)
|
||||
return False
|
||||
|
||||
parser_input.next_token()
|
||||
return True
|
||||
|
||||
|
||||
class ErrorSink:
|
||||
def __init__(self):
|
||||
self.sink = []
|
||||
|
||||
def add_error(self, error):
|
||||
self.sink.append(error)
|
||||
|
||||
def clear(self):
|
||||
self.sink.clear()
|
||||
|
||||
@property
|
||||
def has_error(self):
|
||||
return len(self.sink) > 0
|
||||
|
||||
Reference in New Issue
Block a user