• Subject: Re: lpeg.Cb bug (?) with repeated evaluation of group capture pattern
• From: Roberto Ierusalimschy <roberto@...>
• Date: Thu, 15 Sep 2016 08:54:31 -0300

```> I think there is certainly an implied and necessary ordering to
> capture evalutation (in some cases). There is only one reasonable way
> to evaluate the captures in this pattern (p2):
>
> local function a(a) return a end
> local function aa(a) return a..a end
> local p1 = C "a" / a
> local p2 = p1 / aa
>
> The captures produced by p2 cannot be known without evaluating aa,
> which cannot be evaluated without evaluating p1, etc. Even if the
> to evaluate the captures, do you? :)

For what is worth, Lua could use lazy evaluation, with the function 'a'
being called only when the parameter 'a' is used inside 'aa', or even
being called twice, for each use of the parameter (and not being called
at all if 'aa' did not use that parameter). Anyway, my point is not that
there isn't an order, but that you should not depend on it. (Of course,
the real order must be one that ensures a correct result regarding the
flow of captures. The problem comes from side effects.)

As a more realistic example, consider the following:

local function a(a) return a end
local p1 = C "a" / a
local p2 = p1 / 0

The specification says nothing about whether 'a' will be called or not.
The only garantee is that 'p2' will return no captures.

> I think it's necessary that Cb also implies an ordering. One of LPeg's
> most compelling features is building up a data structure as you match
> through capture manipulation. However, if you can't reference an
> earlier table capture (or any Lua value produced from a capture!),
> that seems to artifically limit LPeg's ability to process complex
> cyclic grammars. (When I say cyclic grammar I mean one in which
> patterns may depend on any open capture.)

Your initial question shows that Cb does not imply an order. The pattern
being refered could be evaluated only once, when it matched; it could be
evaluated even earlier, in a failed attempt; it could be re-evaluated
when Cb needs its value (as it does in the current implementation).
Again, any real order must ensure correctness, that is, it must ensure
that Cb gets the resulting values from what it is refering.
Except for that, anything is allowed.

-- Roberto

```