|
On 08/04/2019 03.07, Sean Conner wrote:
It was thus said that the Great nobody once stated:-- wrap pattern with enter/leave (pattern simplified to "foo" here) -- leave should always ping once (on success or by backtracking) p = (enter + leave) * C"foo" * leaveFor p:match("bar"), the enter rule will *always* match, because it matches the empty string; leave will never be called at all. So depth becomes 1. Then the rule C"foo" is attempted, and since it fails, the entire match fails at that point, so leave (which is an "and this pattern") is never called. To properly keep track of level, you might have to do: p = C"foo" * enter * rest_of_foo * leave If you do: p = enter * C"foo" * rest_of_foo * leave + leave
Oh, right. As a sub-pattern, (enter+leave) succeeded via the first branch, and there's no backtracking *into* that sub-pattern – that was my misconception. So the correct thing is
p = enter * (C"foo" * leave + leave) or (de-simplified a bit) p = enter * (C"foo" * leave + fail_hard) and things work as expected now.That still left me wondering about those huge negative numbers in the debug output. Digging further, they seem to be produced by any failing match, even by something as simple as
require"lpeg".P"x":match""and looking at the source reveals that the PC is computed by pointer difference to the pcode base address, but `giveup` is actually a
static const Instruction giveup = {{IGiveup, 0, 0}}; i.e. located in a completely different place, hence the big difference. So all is well – thanks for the help! -- nobody