Commit ea695bb6 authored by Eckhart Arnold's avatar Eckhart Arnold
Browse files

parse.py: reentry_point() refactored

parent 16f61378
...@@ -3142,7 +3142,7 @@ class EBNFCompiler(Compiler): ...@@ -3142,7 +3142,7 @@ class EBNFCompiler(Compiler):
nd = self.rules[rule.s][0].children[1] nd = self.rules[rule.s][0].children[1]
refined = self.gen_search_rule(nd) refined = self.gen_search_rule(nd)
except IndexError: except IndexError:
nd = self.tree nd = self.tree # TODO: Allow arbitrary parsers, here
refined = "" refined = ""
except KeyError: except KeyError:
# rule represents a procedure name # rule represents a procedure name
......
...@@ -177,7 +177,7 @@ class ParserError(Exception): ...@@ -177,7 +177,7 @@ class ParserError(Exception):
return pe return pe
PatternMatchType = Union[RxPatternType, str, Callable] PatternMatchType = Union[RxPatternType, str, Callable, 'Parser']
ErrorMessagesType = List[Tuple[PatternMatchType, str]] ErrorMessagesType = List[Tuple[PatternMatchType, str]]
ResumeList = List[PatternMatchType] # list of strings or regular expressions ResumeList = List[PatternMatchType] # list of strings or regular expressions
ReentryPointAlgorithm = Callable[[StringView, int, int], Tuple[int, int]] ReentryPointAlgorithm = Callable[[StringView, int, int], Tuple[int, int]]
...@@ -228,6 +228,7 @@ def reentry_point(rest: StringView, ...@@ -228,6 +228,7 @@ def reentry_point(rest: StringView,
""" """
upper_limit = len(rest) + 1 upper_limit = len(rest) + 1
closest_match = upper_limit closest_match = upper_limit
skip_node = None
comments = None # type: Optional[Iterator] comments = None # type: Optional[Iterator]
if search_window < 0: if search_window < 0:
search_window = len(rest) search_window = len(rest)
...@@ -299,19 +300,30 @@ def reentry_point(rest: StringView, ...@@ -299,19 +300,30 @@ def reentry_point(rest: StringView,
# find closest match # find closest match
for rule in rules: for rule in rules:
comments = rest.finditer(comment_regex) comments = rest.finditer(comment_regex)
if callable(rule): if isinstance(rule, Parser):
search_func = algorithm_search _node, _text = cast(Parser, rule)(rest)
elif isinstance(rule, str): if _node:
search_func = str_search pos = len(rest) - len(_text)
if pos < closest_match:
closest_match = pos
skip_node = _node
else: else:
search_func = rx_search if callable(rule):
pos = entry_point(search_func, rule) search_func = algorithm_search
closest_match = min(pos, closest_match) elif isinstance(rule, str):
search_func = str_search
else:
search_func = rx_search
pos = entry_point(search_func, rule)
if pos < closest_match:
skip_node = None
closest_match = pos
# in case no rule matched return -1 # in case no rule matched return -1
if closest_match == upper_limit: if closest_match == upper_limit:
closest_match = -1 closest_match = -1
skip_node = Node(ZOMBIE_TAG, rest[:max(closest_match,0)]) if skip_node is None:
skip_node = Node(ZOMBIE_TAG, rest[:max(closest_match,0)])
return closest_match, skip_node return closest_match, skip_node
...@@ -2760,7 +2772,7 @@ class MandatoryNary(NaryParser): ...@@ -2760,7 +2772,7 @@ class MandatoryNary(NaryParser):
failed_on_lookahead: bool, failed_on_lookahead: bool,
expected: str, expected: str,
reloc: int, reloc: int,
err_node: Node) -> Tuple[Error, Node, StringView]: err_node: Node) -> Tuple[Error, StringView]:
""" """
Chooses the right error message in case of a mandatory violation and Chooses the right error message in case of a mandatory violation and
returns an error with this message, an error node, to which the error returns an error with this message, an error node, to which the error
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment