[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Luma errors
- From: Tony Finch <dot@...>
- Date: Tue, 12 Apr 2011 09:55:25 +0100
Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
> > > Would you mind explaining how these changes make writing and composing
> > > grammars *much* more convenient?
> >
> > The second change lets the grammar writer refactor a non-terminal to a
> > definition without adding % to all of its uses.
>
> Can't you simply keep the non-terminal as a non-terminal, adding one new
> rule like this?
>
> non-terminal -> %new-definition
I usually use re to define stand-alone rules, since it has nicer syntax
but there are things I can do with stand-alone rules that I can't do with
re, such as folds and argument captures. I can't use a re grammar to
define my low-level non-terminals in one go, since re grammars are
immediately fixed and I can't extract non-terminal definitions from a
compiled parser.
So I use the missing % patch to make it easier to compose re patterns.
The usual way I do this is with this code:
local parse = (function()
-- environment for non-terminals
local env = {}
local function p(pat)
return re.compile(pat, env)
end
setfenv(1,env)
-- then define various non-terminals
CRLF = lpeg.S"\r\n"
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
-- etc.
return env
end)()
parse.ipv4:match(str)
A couple of examples:
http://www-uxsup.csx.cam.ac.uk/~fanf2/hermes/conf/exim/sbin/bogons
http://www-uxsup.csx.cam.ac.uk/~fanf2/misc/geoip/geoip2lua.lua
Tony.
--
f.anthony.n.finch <dot@dotat.at> http://dotat.at/
Hebrides, Bailey, Fair Isle, Faeroes: West backing southwest 5 to 7. Rough or
very rough, occasionally high. Squally showers, rain later. Moderate or good.