Refactored parsers to introduce priority
This commit is contained in:
+65
-25
@@ -211,42 +211,82 @@ class Sheerka(Concept):
|
||||
|
||||
def _call_parsers(self, execution_context, return_values, logger=None):
|
||||
|
||||
result = []
|
||||
# return_values must be a list
|
||||
if not isinstance(return_values, list):
|
||||
return_values = [return_values]
|
||||
|
||||
for return_value in return_values:
|
||||
# make sure we only parse user input
|
||||
if not return_value.status or not self.isinstance(return_value.body, BuiltinConcepts.USER_INPUT):
|
||||
result.append(return_value)
|
||||
continue
|
||||
# first make the distinguish between what is for the parsers and what is not
|
||||
result = []
|
||||
to_process = []
|
||||
for r in return_values:
|
||||
if not r.status or not self.isinstance(r.body, BuiltinConcepts.USER_INPUT):
|
||||
result.append(r)
|
||||
else:
|
||||
to_process.append(r)
|
||||
|
||||
to_parse = return_value.body.body # get the underlying text
|
||||
if not to_process:
|
||||
return result
|
||||
|
||||
if self.log.isEnabledFor(logging.DEBUG):
|
||||
debug_text = "'" + to_parse + "'" if isinstance(to_parse, str) \
|
||||
else "'" + BaseParser.get_text_from_tokens(to_parse) + "' as tokens"
|
||||
execution_context.log(logger or self.log, f"Parsing {debug_text}")
|
||||
# keep track of the originals user inputs, as they need to be removed at the end
|
||||
user_inputs = to_process[:]
|
||||
|
||||
for parser in self.parsers.values():
|
||||
p = parser(sheerka=self)
|
||||
if logger:
|
||||
p.log = logger
|
||||
# group the parsers by priorities
|
||||
instantiated_parsers = [parser(sheerka=self) for parser in self.parsers.values()]
|
||||
grouped_parsers = {}
|
||||
for parser in [p for p in instantiated_parsers if p.enabled]:
|
||||
if logger:
|
||||
parser.log = logger
|
||||
grouped_parsers.setdefault(parser.priority, []).append(parser)
|
||||
sorted_priorities = sorted(grouped_parsers.keys(), reverse=True)
|
||||
|
||||
with execution_context.push(desc=f"Parsing using {p.name}") as sub_context:
|
||||
res = p.parse(sub_context, to_parse)
|
||||
stop_processing = False
|
||||
for priority in sorted_priorities:
|
||||
inputs_for_this_group = to_process[:]
|
||||
|
||||
if hasattr(res, "__iter__"):
|
||||
for r in res:
|
||||
r.parents = [return_value]
|
||||
result.append(r)
|
||||
else:
|
||||
res.parents = [return_value]
|
||||
result.append(res)
|
||||
for parser in grouped_parsers[priority]:
|
||||
|
||||
sub_context.add_values(return_values=res)
|
||||
return_value_success_found = False
|
||||
for return_value in inputs_for_this_group:
|
||||
|
||||
to_parse = return_value.body.body \
|
||||
if self.isinstance(return_value.body, BuiltinConcepts.USER_INPUT) \
|
||||
else return_value.body
|
||||
|
||||
# if self.log.isEnabledFor(logging.DEBUG):
|
||||
# debug_text = "'" + to_parse + "'" if isinstance(to_parse, str) \
|
||||
# else "'" + BaseParser.get_text_from_tokens(to_parse) + "' as tokens"
|
||||
# execution_context.log(logger or self.log, f"Parsing {debug_text}")
|
||||
|
||||
with execution_context.push(desc=f"Parsing using {parser.name}") as sub_context:
|
||||
res = parser.parse(sub_context, to_parse)
|
||||
if res is not None:
|
||||
if hasattr(res, "__iter__"):
|
||||
for r in res:
|
||||
if r is None:
|
||||
continue
|
||||
r.parents = [return_value]
|
||||
result.append(r)
|
||||
if self.isinstance(r.body, BuiltinConcepts.PARSER_RESULT):
|
||||
to_process.append(r)
|
||||
if r.status:
|
||||
return_value_success_found = True
|
||||
|
||||
else:
|
||||
res.parents = [return_value]
|
||||
result.append(res)
|
||||
if self.isinstance(res.body, BuiltinConcepts.PARSER_RESULT):
|
||||
to_process.append(res)
|
||||
if res.status:
|
||||
return_value_success_found = True
|
||||
|
||||
if return_value_success_found:
|
||||
stop_processing = True
|
||||
break # Stop the other return_values (but not the other parsers with the same priority)
|
||||
|
||||
if stop_processing:
|
||||
break # Do not try the other priorities if a match is found
|
||||
|
||||
result = core.utils.remove_list_from_list(result, user_inputs)
|
||||
return result
|
||||
|
||||
def _call_evaluators(self, execution_context, return_values, process_step, evaluation_context=None, logger=None):
|
||||
|
||||
Reference in New Issue
Block a user