From 7545e153d43dd652cbb863d946d27ad046999870 Mon Sep 17 00:00:00 2001 From: Anton Lydike Date: Tue, 2 Jul 2024 18:25:47 +0100 Subject: [PATCH] fix CHECK-NEXT to consume as few matches as possible --- README.md | 1 + filecheck/compiler.py | 2 -- filecheck/finput.py | 17 ++++++++++++----- filecheck/matcher.py | 4 ++-- tests/filecheck/simple.test | 6 ++++++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1dc0828..d4ce483 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ There are some features that are left out for now (e.g. [pseudo-numeric variable - [ ] MLIR/xDSL integration tests - **UX:** - [ ] Good error messages: I have some error messages, but could be a lot better + - [ ] Error messages for malformed regexes - **Infrastructure:** - [X] Formatting: black - [X] Pyright: Almost passes rn diff --git a/filecheck/compiler.py b/filecheck/compiler.py index f05f5fa..2aa9419 100644 --- a/filecheck/compiler.py +++ b/filecheck/compiler.py @@ -22,8 +22,6 @@ def compile_uops( expr: list[str] = [] if check.name == "NEXT": expr.append(r"\n?[^\n]*") - elif check.name == "SAME": - expr.append("[^\n]*") elif check.name == "EMPTY": return CHECK_EMPTY_EXPR, dict() diff --git a/filecheck/finput.py b/filecheck/finput.py index 2fcd686..3812e6f 100644 --- a/filecheck/finput.py +++ b/filecheck/finput.py @@ -61,15 +61,22 @@ def match(self, pattern: re.Pattern[str]) -> re.Match[str] | None: """ Match (exactly from the current position) """ - print(f"matching on {pattern}") + print(f"matching on r{repr(pattern.pattern)}") return pattern.match(self.content, pos=self.pos) - def find(self, pattern: re.Pattern[str]) -> re.Match[str] | None: + def find( + self, pattern: re.Pattern[str], this_line: bool = False + ) -> re.Match[str] | None: """ Find the first occurance of a pattern, might be far away. + + If this_line is given, match only until the next newline. """ - print(f'searching for r"{pattern.pattern}"') - return pattern.search(self.content, pos=self.pos) + print(f"searching for r{repr(pattern.pattern)}") + endpos = self.content.find("\n", self.pos) if this_line else -1 + if endpos == -1: + endpos = sys.maxsize + return pattern.search(self.content, pos=self.pos, endpos=endpos) def find_between( self, pattern: re.Pattern[str], start: int, end: int @@ -77,7 +84,7 @@ def find_between( """ Find the first occurance of a pattern, might be far away. """ - print(f"searching for {pattern} in input[{start}:{end}]") + print(f"searching for r{repr(pattern.pattern)} in input[{start}:{end}]") return pattern.search(self.content, pos=start, endpos=end) def print_line_with_current_pos(self, pos_override: int | None = None): diff --git a/filecheck/matcher.py b/filecheck/matcher.py index 1baf8ed..f4fd6ab 100644 --- a/filecheck/matcher.py +++ b/filecheck/matcher.py @@ -60,7 +60,7 @@ def run(self) -> int: "NOT": self.enqueue_not, "EMPTY": self.check_empty, "NEXT": self.match_immediately, - "SAME": self.match_immediately, + "SAME": self.match_eventually, "LABEL": self.check_label, "CHECK": self.match_eventually, } @@ -204,7 +204,7 @@ def match_eventually(self, op: CheckOp): Uses file.find """ pattern, repl = compile_uops(op, self.ctx.live_variables, self.opts) - if match := self.file.find(pattern): + if match := self.file.find(pattern, op.name == "SAME"): print( f"matched: {op.check_line_repr()}, groups={match.groups()} mapping to {repl}" ) diff --git a/tests/filecheck/simple.test b/tests/filecheck/simple.test index 26abf42..0282f4a 100644 --- a/tests/filecheck/simple.test +++ b/tests/filecheck/simple.test @@ -17,3 +17,9 @@ SOME B C // CHECK-NOT: 404 suffix + +test A val1 val2 val1 val2 val1 +// CHECK: test A +// CHECK-SAME: val2 +// CHECK-SAME: val1 +// CHECK-SAME: val2