[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lpeg: a question about function captures and named captures
- From: Sean Conner <sean@...>
- Date: Wed, 12 Apr 2023 16:06:57 -0400
It was thus said that the Great Eduardo Ochs once stated:
> Hi list,
>
> if anyone wants a short version of my question, here it is...
> when we use function captures in lpeg - i.e., this thing,
>
> http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html#cap-func
>
> the "f" in patt/f receives "numbered captures" and returns "numbered
> captures".
It actually returns captures:
> lpeg = require "lpeg"
> number = lpeg.R"09"^1 / tonumber
> x = number:match "123"
> print(type(x),x)
number 123
The "numbered captures" are a result of using lpeg.Ct().
> Is there a way to write something similar to that returns
> named captures?
Not directly, no.
> Now here is a clearer version of that question, with code. In the code
> below PP is my favorite pretty-printing functions.
> ...
>
> Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> > require "lpeg"
> > B,C,P,R,S,V = lpeg.B,lpeg.C,lpeg.P,lpeg.R,lpeg.S,lpeg.V
> > Cb,Cc,Cf,Cg = lpeg.Cb,lpeg.Cc,lpeg.Cf,lpeg.Cg
> > Cp,Cs,Ct = lpeg.Cp,lpeg.Cs,lpeg.Ct
> > Carg,Cmt = lpeg.Carg,lpeg.Cmt
> >
> > lpeg.ptmatch = function (pat, str) PP(pat:Ct():match(str)) end
> >
> > PP {a="b", 10, 20}
> {1=10, 2=20, "a"="b"}
> >
> > f = function (a,b) return a..b,b..a end
> >
> > (Cc"a" * Cc"b") :ptmatch("ccc")
> {1="a", 2="b"}
> > (Cc"a" * Cc"b" / f) :ptmatch("ccc")
> {1="ab", 2="ba"}
> > (Cc"a" * Cc"b" / f):Cg"c" :ptmatch("ccc")
> {"c"="ab"}
> > (Cc"a" * Cc"b" / f):Cg(3) :ptmatch("ccc")
> {3="ab"}
> >
>
> How do I modify the ".../f" above to make it put the first result of f
> into :Cg"c" and the second result into :Cg"d"?
If I understand your question correctly, for
Cc'a' * Cc'b' / f
you want the first result of f() to go into a field named 'c', and the
second result of f() to go into a field named 'd'. Yes, that isn't going to
work. You can change f() to be:
function f(a,b) return { c = a .. b , d = b .. a } end
And then this line:
(Cc"a" * Cc"b" / f):Cg"c" :ptmatch("ccc")
returns:
{ c = { c = "ab" , d = "ba" } }
You could do:
local pattern = (Ct"" * Cc'a' * Cc'b')
/ function(t,a,b)
t.c = a .. b
t.d = b .. a
return t
end
PP(pattern:match "")
and get a table with:
{ c = "ab" , d = "ba" }
Personally, I tend to just use Cg() for all my named capture needs.
-spc