rust-peg icon indicating copy to clipboard operation
rust-peg copied to clipboard

Strange trace during `cache_left_rec`

Open A4-Tacks opened this issue 7 months ago • 2 comments

peg::parser!(grammar p() for str {
    rule pack(p: rule<()>) -> ()
        = p() {}
    rule number() = ['0'..='9']+
    rule atom() -> () = n:$(number()) {}
    #[cache_left_rec]
    rule add() -> ()
        = add() "+" atom()
        / atom()
    rule cmp() -> ()
        = add() "<" add()
        / add()
    rule equalty() -> ()
        = pack(<cmp() "=" cmp()>) // pack Failed, but equality Matched
        / cmp()
    pub rule top() = equalty()
});

fn main() {
    let _ = dbg!(p::top("1+2<3"));
}

trace output:

[PEG_TRACE] Attempting to match rule `equalty` at 1:1
[PEG_TRACE] Attempting to match rule `pack` at 1:1
...
[PEG_TRACE] Failed to match rule `pack` at 1:1
[PEG_TRACE] Attempting to match rule `cmp` at 1:1
[PEG_TRACE] Cached match of rule add at 1:1
[PEG_TRACE] Cached match of rule add at 1:5
[PEG_TRACE] Matched rule `cmp` at 1:1 to 1:6
[PEG_TRACE] Matched rule `equalty` at 1:1 to 1:6

Why did the pack fail but equalty succeeded?

Image

Why is parent matching smaller than child matching? (rule add)

A4-Tacks avatar May 20 '25 16:05 A4-Tacks

Matching pack with the closure passed to it would require matching "=", which is not in the string used in the tests. However, it does match as far as the first cmp() in the closure, and in doing so, tries add() in all the positions of the final match. Those are then cached so when cmp() is tried again in equality()'s alternate, the cached matches of add() are returned. The trick of cache_left_rec is that when add() calls itself recursively, it temporarily makes the cache return a failure of add() to force it to try atom() instead of recursing infinitely.

Not quite sure what you're asking, but hopefully that explains it.

kevinmehall avatar May 20 '25 17:05 kevinmehall

In previous practice, the content between paired Attempting and Failed was always discarded, but this experience seems to no longer be valid after using catch_left_rec

Try to find an effective way to correctly parse discarded results

A4-Tacks avatar May 20 '25 22:05 A4-Tacks