[parser] Error recovery tests

Based on the blog post "Resilient LL Parsing Tutorial" by Alex Kladov, at
https://matklad.github.io/2023/05/21/resilient-ll-parsing-tutorial.html

Because I was trying to be "simple" in my grammar definition I found
a bug in the grammar class, whoops! :)
This commit is contained in:
John Doty 2024-09-22 08:46:54 -07:00
parent 071cd29d8f
commit bb52ab8da5
2 changed files with 24 additions and 10 deletions

View file

@ -24,17 +24,23 @@ class Tree:
end: int
children: typing.Tuple["Tree | TokenValue", ...]
def format_lines(self, source: str | None = None) -> list[str]:
def format_lines(self, source: str | None = None, *, ignore_error: bool = False) -> list[str]:
lines = []
def format_node(node: Tree | TokenValue, indent: int):
match node:
case Tree(name=name, start=start, end=end, children=children):
if ignore_error and start == end:
return
lines.append((" " * indent) + f"{name or '???'} [{start}, {end})")
for child in children:
format_node(child, indent + 2)
case TokenValue(kind=kind, start=start, end=end):
if ignore_error and start == end:
return
if source is not None:
value = f":'{source[start:end]}'"
else:
@ -44,8 +50,8 @@ class Tree:
format_node(self, 0)
return lines
def format(self, source: str | None = None) -> str:
return "\n".join(self.format_lines(source))
def format(self, source: str | None = None, *, ignore_error: bool = False) -> str:
return "\n".join(self.format_lines(source, ignore_error=ignore_error))
@dataclass