[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: LPeg sugars for average users
- From: François Perrad <francois.perrad@...>
- Date: Fri, 16 Dec 2011 18:50:18 +0100
I really love LPeg with its underlaying model and its efficient engine
(virtual parsing machine).
But I am only a casual user (with an old brain). Every 6 months, I
need to use Lpeg and I must re-learn the syntax because I forgot it
since the last time.
Now, I propose a small skin over LPeg which looks like the parser combinators.
The following example from the LPeg documentation (balanced parentheses) :
b = lpeg.P{ "(" * ((1 - lpeg.S"()") + lpeg.V(1))^0 * ")" }
could be rewritten :
b = grammar{ sequence(literal'(', many(choice(except(any(),
set'()'), variable(1))), literal')') }
For a more large example, see
https://github.com/fperrad/lua-CodeGen/commit/0d0253c6072af6679da613caab08f969cefba46a.
I write this mockup as a pure Lua module (see attachment). But a C
version is also possible.
Your feedback is welcome.
Currently, I don't know what to do with this module and I am not happy
with all keywords.
Thanks.
François
local lpeg = require 'lpeg'
local assert = assert
local type = type
local m = {
arg = lpeg.Carg,
backref = lpeg.Cb,
capture = lpeg.C,
constant = lpeg.Cc,
fold = lpeg.Cf,
group = lpeg.Cg,
matchtime = lpeg.Cmt,
position = lpeg.Cp,
range = lpeg.R,
subst = lpeg.Cs,
set = lpeg.S,
table = lpeg.Ct,
variable = lpeg.V,
}
_ENV = nil
function m.any (n)
n = n or 1
assert(type(n) == 'number' and n > 0, "number expected")
return lpeg.P(n)
end
function m.choice (p, ...)
assert(lpeg.type(p) == 'pattern', "pattern expected")
local t = {...}
for i=1, #t do
p = p + t[i]
end
return p
end
function m.empty ()
return lpeg.P(0)
end
function m.except (p, ...)
assert(lpeg.type(p) == 'pattern', "pattern expected")
local t = {...}
for i=1, #t do
p = p - t[i]
end
return p
end
function m.complement (p)
assert(lpeg.type(p) == 'pattern', "pattern expected")
return -p
end
function m.eof ()
return lpeg.P(-1)
end
function m.fail ()
return lpeg.P(false)
end
function m.grammar (t)
assert(type(t) == 'table', "table expected")
return lpeg.P(t)
end
function m.literal (s)
assert(type(s) == 'string', "string expected")
return lpeg.P(s)
end
function m.lookahead (p)
assert(lpeg.type(p) == 'pattern', "pattern expected")
return #p
end
function m.many (p)
assert(lpeg.type(p) == 'pattern', "pattern expected")
return p^0
end
function m.optional (p)
assert(lpeg.type(p) == 'pattern', "pattern expected")
return p^-1
end
function m.sequence (p, ...)
assert(lpeg.type(p) == 'pattern', "pattern expected")
local t = {...}
for i=1, #t do
p = p * t[i]
end
return p
end
function m.some (p)
assert(lpeg.type(p) == 'pattern', "pattern expected")
return p^1
end
function m.replace (p, s)
assert(lpeg.type(p) == 'pattern', "pattern expected")
return p / s
end
function m.succeed ()
return lpeg.P(true)
end
return m