lua-users home
lua-l archive

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


Hi Sean !

Thanks for your patience, really appreciate it.

1     list = lpeg.P {
2                'list',
3                list = lpeg.P'['
4                     * lpeg.Cf(lpeg.Ct"" * lpeg.V"data"^0,function(a,b) table.insert(a,b) return a end)
5                     * lpeg.P']',
6                data = "" * C(number)
7                     + lpeg.V"list"
8        }

In line 4 are you passing lpeg.Ct"" to lpeg.Cf , that is key I think.

I was under the impression this was an anti-pattern, that LPEG operations should be stateless ( you should not maintain local state )

Yes, Cf should be used when you are constructing something that is NOT a table.

I was so confused because this is what I had in mind:


Cn(.....Cf(Cf(Cf(Cf(Cf(C1,C2),C3),C4),C5),C6),....Cn)


If you change the notation to:

T1 -> C1 C2
T2 -> T1 C3
T3 -> T2 C4
T4 -> T3 C5
...........
...........
...........

You can see the algorithm moves linearly like a snake through every capture.

Why is this important ? Errors Handling !

You can terminate the entire algorithm at ANY wrong capture regardless of how deeply its nested.

However it gets problematic when you also nest Cf, since you cannot create LOCAL STATE in your nest ( without passing Ct '')

I was trying really hard to solve the problem using Carg(1) which is the global state.

I was a fool in making such useless assumptions.

best wishes,

Joy

On Mon, Apr 8, 2019 at 12:55 PM Sean Conner <sean@conman.org> wrote:
It was thus said that the Great Sean Conner once stated:
> It was thus said that the Great joy mondal once stated:
> > I tried using lpeg.Cf recursively and its quite convoluted.
> >
> > For parsing thing like this:
> >
> > [[[]]]
>
>   What, exactly are you trying to parse there?  Something like:
>
>       [ 1 2 3 [ 4 5 6 [ 7 8 9 ] 10 11 ] 12 13 ] --?
>
> > Its quite a bit easier with Cmt since I can create an empty table ( state )
> > at the start of the loop. with Cf you are not sure if you at the
> > start,middle or end of the loop.
>
>   I rarely use lpeg.Cf() to fold captures into a table.  I'd rather use
> lpeg.Ct() with a capture pattern inside:
>
>       list = lpeg.P"[" * lpeg.Ct((SPACE * C(number))^0) * lpeg.P"]"
>
> If it's recursive, then an LPEG grammar would be appropriate:
>
>       list = lpeg.P {
>               'list',
>               list = lpeg.P'[' * lpeg.Ct(lpeg.V"data") * lpeg.P']',
>               data = "" * C(number)
>                      + lpeg.V"list"
>       }
>
> This would be enough to parse the example I'm asking about (given an
> appropriate definition for SPACE and number).

  I just reread your message, and perhaps I should present this definition
of list:

        list = lpeg.P {
                'list',
                list = lpeg.P'['
                     * lpeg.Cf(lpeg.Ct"" * lpeg.V"data"^0,function(a,b) table.insert(a,b) return a end)
                     * lpeg.P']',
                data = "" * C(number)
                     + lpeg.V"list"
        }

This uses lpeg.Cf() recursively (it also uses lpeg.Ct(), but only to
generate the table (generated by matching the empty string) used to
accumulate the results.  As you can see, it's a bit longer than just using
lpeg.Ct() around a pattern.

  -spc