[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: intra table reference
- From: Tony Finch <dot@...>
- Date: Mon, 30 Nov 2009 13:11:58 +0000
On Mon, 30 Nov 2009, spir wrote:
>
> Thank you. I think this may be a solution, a kind of table factory.
>
> The use case is to build parsers/grammars as tables of (named) patterns.
> This seems to me rather an obvious solution in Lua. However,
> higher-level patterns need to reference lower-level ones, eg integer =
> OneOrMore(digit).
I do this when writing LPEG grammars.
The basic pattern is below. Sometimes I return the whole pattern
environment, in which case match operations look like
parser.thing:match(str), or I just return the start symbol so match
operations are parser:match(str)
Note this code uses my LPEG patch so % operators are not necessary to
access the pattern environment, and I've also used a pythonic % operator.
local function make_parser()
-- environment for non-terminals
local env = {}
local function p(pat)
return re.compile(pat, env)
end
setfenv(1,env)
-- define grammar here
CRLF = lpeg.S"\r\n"
INL = 1 - CRLF
comment = p[[ "#" INL* CRLF+ ]]
EOL = p[[ CRLF+ comment* / !. ]]
BEGIN = p[[ CRLF* comment* ]]
name = p[[ {[a-z]+} ]]
num = p[[ {[0-9]+} ]] / tonumber
hex = p[[ {[0-9a-fA-F]+} ]] /
function (n) return tonumber(n,16) end
ipv4 = p[[ num "." num "." num "." num ]] /
function (a,b,c,d)
return a * 16777216 + b * 65536 + c * 256 + d
end
ipv6 = p[[ (hex ":")+ ":" ]] /
function (a,b,c,d)
return "%4x:%4x:%4x:%4x::" %
{ a or 0, b or 0, c or 0, d or 0 }
end
asn = p[[ num ("." num)? ]] /
function (a,b)
if b then return a * 65536 + b else return a end
end
-- ... other grammar definitions
return env
end
local parser = make_parser()
Tony.
--
f.anthony.n.finch <dot@dotat.at> http://dotat.at/
GERMAN BIGHT HUMBER: SOUTHWEST 5 TO 7. MODERATE OR ROUGH. SQUALLY SHOWERS.
MODERATE OR GOOD.