Strange trace during `cache_left_rec`
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?
Why is parent matching smaller than child matching? (rule add)
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.
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