[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: [LPeg] How can I make a recursive pattern?
- From: "Soni L." <fakedme@...>
- Date: Wed, 27 Jul 2016 11:27:35 -0300
Sean Conner's incomplete solution uses lpeg.Carg(1) which doesn't work
recursively.
This is what I'm trying to parse: https://github.com/SoniEx2/MDXML
This is what I currently have:
----------------------------------
--[[
EOF/newlines/whitespace/inline comments
--]]
local eof = lpeg.P(-1)
local nl = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n" + eof -- \r
for winblows compat
local ws = lpeg.S(" \t") + nl - nl * nl
local inlineComment = lpeg.P("`") * (1 - (lpeg.S("`\n"))) ^ 0 *
lpeg.P("`")
local wsc = ws + inlineComment -- comments count as whitespace
--[[
Escape sequences
--]]
local backslashEscaped
= lpeg.P("\\ ") / " " -- escaped spaces
+ lpeg.P("\\\\") / "\\" -- escaped escape character
+ lpeg.P("\\#") / "#"
+ lpeg.P("\\>") / ">"
+ lpeg.P("\\`") / "`"
+ lpeg.P("\\n") -- \\n newlines count as backslash escaped
+ lpeg.P("\\") * lpeg.P(function(_, i)
error("Unknown backslash escape at position " .. i)
end)
local content = lpeg.Cs((wsc / " " + (backslashEscaped + 1 -
nl*nl))^0) * nl * nl
--[[
Process tag/attribute/value/etc
(the `c` in the argument names means "captured")
--]]
local tag = lpeg.P"#" * lpeg.C((1 - nl)^1) * nl / function(ctag)
return content:match(ctag)
end
local attribute = lpeg.P"##" * lpeg.C((1 - nl)^1) * nl /
function(cattribute)
return content:match(cattribute)
end
local value = lpeg.P"###" * lpeg.C((1 - nl)^1) * nl / function(cvalue)
return content:match(cvalue)
end
local tagns = lpeg.P"####" * lpeg.C((1 - nl)^1) * nl / function(ctagns)
return content:match(ctagns)
end
local attrns = lpeg.P"#####" * lpeg.C((1 - nl)^1) * nl /
function(cattrns)
return content:match(cattrns)
end
--[[
Recursive grammar.
--]]
local doc = lpeg.P { lpeg.V"entry",
entry = ((lpeg.Carg(1) * lpeg.C(tag))
/ function(t,tag)
local x = { [0] = tag }
table.insert(t,x)
return t
end
* (
(lpeg.Carg(1) * lpeg.C(tagns))
/ function (t, ns)
local x = t[#t]
local tag = x[0]
x[0] = {tag=tag, ns=ns}
end
)^0
* (
(lpeg.Carg(1) * lpeg.C(attribute) * lpeg.C(value))
/ function(t,a,v)
local x = t[#t]
x[a] = v
return t
end
)^0
* (
(lpeg.Carg(1) * lpeg.C(content))
/ function(t,c)
local x = t[#t]
table.insert(x,c)
return t
end
)^0)
}
----------------------------------
--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.