lua-users home
lua-l archive

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

On 14/09/16 07:11 PM, Patrick Donnelly wrote:
On Wed, Sep 14, 2016 at 3:27 PM, Roberto Ierusalimschy
<> wrote:
I found that for some reason LPeg is evaluating a pattern in a group
capture multiple times:

local patt = lpeg.Cg(lpeg.Ct"", "foo") * lpeg.Cb "foo" * lpeg.Cb "foo";
print(patt:match "") --> table: 0x1634280        table: 0x16342c0

(two unique tables!) Or:

local patt = lpeg.P {
     lpeg.Cg(lpeg.V "v", "foo") * lpeg.Cb "foo" * lpeg.Cb "foo";
     v = lpeg.Ct "" / function(...) print(...) return ... end,
print(patt:match "") --> table: 0x233d4a0 \n table: 0x22f0ab0 \n
table: 0x233d4a0        table: 0x22f0ab0


local patt = lpeg.Cg(lpeg.Cmt("", function(s,p) return p, {} end),
"foo") * lpeg.Cb "foo" * lpeg.Cb "foo";
print(patt:match "") --> table: 0x87a950 table: 0x87a950

(one table!)

Is this a bug?
Well, I know it works that way :-)

Except for 'Cmt', captures in LPeg have a functional flavor. LPeg does
not specify in what order it evaluates its captures. It does not specify
even whether it actually will execute a capture. All that matters are
the results from the captures.  (For instance, the manual does not say
that LPeg will not execute captures for failed match attempts; what it
ensures is that those values are not used in its results.)
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
manual avoids talking about this, I don't see another reasonable way
to evaluate the captures, do you? :)

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.)

In any case, I don't really have a horse in this race (except my
contribution to Sean's "Ctab" thread). Maybe time will tell if this is
really needed or not...

This would make error reporting easier.

Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.