lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi Roberto,

On Mon, Aug 21, 2023, 2:00 PM Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
> Anyway, in the code below the tests C1..C3 and D1..D4 are based in
> your examples. In the block D1..D4 only D4 yields an error, and that
> makes sense to me - but in the block C1..C3 the tests C1 and C3 yield
> errors but C2 does not. Is this behavior of C1..C3 something that is
> explained in the documentation? How? I admit that I'm still struggling
> with some terms, sorry...
>
> The code:
>
>   [...]
>
>   (Cb"c"      )     :pm()                   -- C1
>   (Cb"c":Cg"c")     :pm()                   -- C2
>   (Cb"c":Cg"c"):Ct():pm()                   -- C3

C2 is really subtle. I first thought that was a bug :-)

All three cases are wrong. In C2, however, as the back reference is
inside a named group, the named group just throws away its inner
capture, without evaluating it. The manual allows that:

  "Usually, LPeg does not specify when (and if) it evaluates its captures."

As the back reference is not evaluated, no error is raised. (Again, this
highlights that captures are computations; it is hard to express them
statically...)

You know documentation is of high quality when the author consults it to justify program behavior. :)

I would request that the manual be enhanced with:

  "Usually, LPeg does not specify if, when, or how many times it evaluates its captures."

It bit me long ago that Cb may reevaluate Ct. I.e.:

Cg(Ct(), "foo") * Cb("foo")

May produce one or two unique tables. An example in the manual like the above would be very useful to communicate that I think.

Please forgive terseness and possibly buggy example code as I'm on my phone.

Patrick