Ok, here’s what I’ve come up with. I’m interested in any criticisms you have, as I’m new to LPeg. (I’ve also fleshed it out with different types of atoms: strings, numbers, etc.)
local tokens = {}
local function add_token(t)
tokens[#tokens + 1] = t
t = ('[%d]'):format(#tokens)
return t
end
local function get_token(t)
return tokens[tonumber(t)] or ''
end
local space = lpeg.S(' \t\n\r\v')
local atom_g = lpeg.P{
'atom',
atom = lpeg.Cs(((lpeg.V'str' + lpeg.V'uuid' + lpeg.V'ident' + lpeg.V'num') / add_token + 1)^0),
ident = (lpeg.R('az') + lpeg.S'_')^1,
str = '"' * (1 - lpeg.P('"'))^0 * '"',
num = lpeg.P('-')^-1 * lpeg.R('09')^1 * ('.' * lpeg.R('09')^1)^-1,
uuid_part = (lpeg.R('az') + lpeg.R('09'))^1,
uuid = (lpeg.V'uuid_part' * ('-' * lpeg.V'uuid_part')^1),
}
local ignore_space = lpeg.Cs((space^1 / '' + 1)^0)
local lisp_g = lpeg.P{
'lisp',
token = '[' * (lpeg.R("09")^1 / get_token) * ']',
lisp = '(' * lpeg.Ct((lpeg.V'token' + lpeg.V'lisp')^0) * ')',
}