[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: lpeg.Cb bug (?) with repeated evaluation of group capture pattern
- From: Patrick Donnelly <batrick@...>
- Date: Wed, 14 Sep 2016 18:11:08 -0400
On Wed, Sep 14, 2016 at 3:27 PM, Roberto Ierusalimschy
<roberto@inf.puc-rio.br> 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