lua-users home
lua-l archive

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

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
>> Whereas:
>> 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...

Patrick Donnelly