[red-knot] Hand-written MDTest parser (#15926)

## Summary

Replaces our existing Markdown test parser with a fully hand-written
parser. I tried to fix this bug using the old approach and kept running
into problems. Eventually this seemed like the easier way. It's more
code (+50 lines, excluding the new test), but I hope it's relatively
straightforward to understand, compared to the complex interplay between
the byte-stream-manipulation and regex-parsing that we had before.

I did not really focus on performance, as the parsing time does not
dominate the test execution time, but this seems to be slightly faster
than what we had before (executing all MD tests; debug):

| Command | Mean [s] | Min [s] | Max [s] | Relative |
|:---|---:|---:|---:|---:|
| this branch | 2.775 ± 0.072 | 2.690 | 2.877 | 1.00 |
| `main` | 2.921 ± 0.034 | 2.865 | 2.967 | 1.05 ± 0.03 |

closes #15923

## Test Plan

One new regression test.
This commit is contained in:
David Peter 2025-02-04 14:01:53 +01:00 committed by GitHub
parent 15dd3b5ebd
commit 9a33924a65
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 207 additions and 95 deletions

View file

@ -92,6 +92,18 @@ impl<'a> Cursor<'a> {
}
}
/// Eats the next two characters if they are `c1` and `c2`. Does not
/// consume any input otherwise, even if the first character matches.
pub fn eat_char2(&mut self, c1: char, c2: char) -> bool {
if self.first() == c1 && self.second() == c2 {
self.bump();
self.bump();
true
} else {
false
}
}
pub fn eat_char_back(&mut self, c: char) -> bool {
if self.last() == c {
self.bump_back();