Skip to content

Commit 0281cf0

Browse files
committed
Replace LARK with a hand-written parser.
* This is faster and reduces the overhead of `check_shapes` somewhat. * This removes an external dependency of `check_shapes`.
1 parent 3969110 commit 0281cf0

File tree

7 files changed

+575
-595
lines changed

7 files changed

+575
-595
lines changed

check_shapes/check_shapes.lark

Lines changed: 0 additions & 92 deletions
This file was deleted.

check_shapes/docstring.lark

Lines changed: 0 additions & 51 deletions
This file was deleted.

check_shapes/error_contexts.py

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,11 @@
3838
Dict,
3939
Iterator,
4040
List,
41-
Mapping,
4241
Optional,
43-
Sequence,
4442
Tuple,
4543
Union,
4644
)
4745

48-
from lark.exceptions import UnexpectedCharacters, UnexpectedEOF, UnexpectedInput
49-
5046
from .base_types import Shape
5147
from .config import get_enable_function_call_precompute
5248

@@ -563,48 +559,47 @@ class ParserInputContext(ErrorContext, ABC):
563559
"""
564560

565561
text: str
562+
index: int
563+
564+
def print_line(self, builder: MessageBuilder) -> None:
565+
text = self.text
566+
index = self.index
567+
568+
line_start = text.rfind("\n", 0, self.index)
569+
if line_start != -1:
570+
text = text[line_start + 1 :]
571+
index -= line_start + 1
572+
573+
line_end = text.find("\n")
574+
if line_end != -1:
575+
text = text[:line_end]
566576

567-
def print_line(self, builder: MessageBuilder, line: int, column: int) -> None:
568-
if line > 0:
569-
line_content = self.text.split("\n")[line - 1]
570-
builder.add_columned_line("Line:", f'"{line_content}"')
571-
if column > 0:
572-
builder.add_columned_line("", " " * column + "^")
577+
builder.add_columned_line("Line:", f'"{text}"')
578+
builder.add_columned_line("", " " * (index + 1) + "^")
573579

574580

575581
@dataclass(frozen=True)
576-
class LarkUnexpectedInputContext(ParserInputContext):
582+
class UnexpectedInputContext(ParserInputContext):
577583
"""
578-
An error was caused by an `UnexpectedInput` error from `Lark`.
584+
An error was caused by a malformed specification or docstring.
579585
"""
580586

581-
error: UnexpectedInput
582-
terminal_descriptions: Mapping[str, str]
587+
expected: Tuple[str, ...]
588+
is_eof: bool
583589

584590
def print(self, builder: MessageBuilder) -> None:
585-
self.print_line(
586-
builder,
587-
getattr(self.error, "line", -1),
588-
getattr(self.error, "column", -1),
589-
)
590-
591-
expected: Sequence[str] = getattr(self.error, "accepts", [])
592-
if not expected:
593-
expected = getattr(self.error, "expected", [])
594-
expected = sorted(expected)
595-
expected_key = "Expected:" if len(expected) <= 1 else "Expected one of:"
596-
for expected_name in expected:
597-
expected_value = self.terminal_descriptions.get(expected_name, expected_name)
598-
builder.add_columned_line(expected_key, expected_value)
599-
expected_key = ""
591+
self.print_line(builder)
600592

601-
if isinstance(self.error, UnexpectedCharacters):
602-
builder.add_line("Found unexpected character.")
603-
if isinstance(self.error, UnexpectedEOF):
593+
if self.is_eof:
604594
builder.add_line("Found unexpected end of input.")
595+
else:
596+
builder.add_line("Found unexpected character.")
605597

606-
def __hash__(self) -> int:
607-
return hash((self.error, *sorted(self.terminal_descriptions.items())))
598+
expected = sorted(set(self.expected))
599+
expected_key = "Expected:" if len(self.expected) <= 1 else "Expected one of:"
600+
for expected_value in expected:
601+
builder.add_columned_line(expected_key, expected_value)
602+
expected_key = ""
608603

609604

610605
@dataclass(frozen=True)
@@ -613,11 +608,9 @@ class MultipleElementBoolContext(ParserInputContext):
613608
An error was caused by trying to use a multi-element argument specification as a bool.
614609
"""
615610

616-
line: int
617-
column: int
618-
619611
def print(self, builder: MessageBuilder) -> None:
620-
self.print_line(builder, self.line, self.column)
612+
self.print_line(builder)
613+
621614
builder.add_line(
622615
"Argument references that evaluate to multiple values are not supported for boolean"
623616
" expressions."

0 commit comments

Comments
 (0)