lua-users home
lua-l archive

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


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