[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Help with an LPEG Grammar
- From: Peter Cawley <lua@...>
- Date: Fri, 19 Jun 2009 22:10:04 +0100
Perhaps something like the following?
local input = [[
%[ one
%[ two ]%
%[ three
%[ four ]%
five ]%
six ]%
]]
local lpeg = require "lpeg"
local C, Ct, P, R, S, V = lpeg.C, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.V
local grammar = P { "entity";
whitespace = S" \t\r\n"^0,
open = P"%[",
close = P"]%",
name = C(R("az", "AZ", "__")^1),
item = (V"name" + V"entity") * V"whitespace",
entity = V"whitespace" * Ct(V"open" * V"whitespace" * V"item"^0 * V"close"),
}
local t = grammar:match(input)
local function print_a(t)
io.write"{"
for i, v in ipairs(t) do
if type(v) == "table" then
print_a(v)
else
io.write(("%q"):format(v))
end
if t[i + 1] then
io.write", "
end
end
io.write"}"
end
print_a(t) --> {"one", {"two"}, {"three", {"four"}, "five"}, "six"}
2009/6/19 Luís Eduardo Jason Santos <jasonsantos@gmail.com>:
> Hi,
>
> I know this is probably a trivial problem for you, people, but I was hoping
> you could provide me some advice regarding this problem I am facing while
> building an LPEG Grammar.
>
> I am trying to create a parser that reads a recursive pattern and builds a
> tree with each capture.
>
> Given the example:
>
> s = [[
> %[ one
> %[ two ]%
> %[ three
> %[ four ]%
> five ]%
> six ]%
>
> ]]
>
> I would like to get a response 't' where
>
> t = { "one", {"two"}, {"three", {"four"}, "five"}, "six" }
>
>
> I have written a simple grammar to experiment with the problem, but I
> couldn't think of a way to solve it.
>
>
> require'luarocks.require'
> require'lpeg'
>
> local SPACE = lpeg.S" \t\n\f"
> local OPEN = lpeg.P"%["
> local CLOSE = lpeg.P"]%"
> local ITEM, SIMPLEITEM, NONITEM, CONTENT = lpeg.V'ITEM', lpeg.V'SIMPLEITEM',
> lpeg.V'NONITEM', lpeg.V'CONTENT'
>
> local item = function(content)
> print('>', content)
> -- TODO: ??
> end
>
> local simpleitem = function(content)
> print('>', content)
> -- TODO: ??
> end
>
> local PATT = {
> CONTENT,
> ITEM = OPEN * lpeg.C(CONTENT) * CLOSE,
> SIMPLEITEM = OPEN * lpeg.C(NONITEM^0) * CLOSE,
> NONITEM = 1-(OPEN + CLOSE),
> CONTENT = (SPACE + SIMPLEITEM / simpleitem + ITEM / item + NONITEM)^1
> }
>
> lpeg.match(PATT, s)
>
>
> I wonder if the answer is at some feature of LPEG that I am not quite
> familiar with yet (like folding captures). I have tried that one, but It
> didn't seemed quite right for the job (since I would probablly have to add
> some constant captures and make a 'switch' inside the function to infer my
> position on the grammar).
>
> Can anyone throw me a bone?
>
> Att.
> Luís Eduardo Jason Santos
>
>