[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: A few Wild and Wooly Proposals, while we're here (was Re: Feature request: userdata slice)
- From: William Ahern <william@...>
- Date: Fri, 21 Aug 2015 11:23:33 -0700
On Fri, Aug 21, 2015 at 05:06:52PM +0200, Dirk Laurie wrote:
> 2015-08-21 16:04 GMT+02:00 Coda Highland <chighland@gmail.com>:
>
> > But the thing is, if THAT'S what you want, Lua already has it!
> >
> > ymd_"2015/08/01" is, by Lua's standard parsing rules, equivalent to
> > ymd_("2015/08/01").
>
> I know. But I might not remember if it is ymd or ymd_ or YMD or YMD_
> or date or date_ or whatever. Nicest would be just 2015/08/01 but Lua
> already treats that as something. <2015/08/01> is a good second.
> The same delimiters apply to all user literals, and if they follow a pattern
> well known to the intended user community, there is nothing extra to be
> memorized.
An LPeg grammar to parse Lua source code is so small that there's really no
excuse for not coming to the table having already tested out the idea. Your
proposal might cause all sorts of headaches with the grammar, especially
because < is already a binary operator.
The following is a quick copy+paste from a file I had lying around, which I
wrote when implementing a declarative language for a filtering engine that
permitted embedding arbitrary Lua code as actions. It might not be from the
working copy; I didn't test. Any missing pattern definition, foo, should
just be V"foo".
If you can make your proposal work your case would be much stronger. But I
really can't imagine how user-defined literals could be made much easier.
E.g. L"2015/08/01", where L is a function that traverses your pattern set.
--
-- L U A G R A M M A R
--
-- Lua 5.2 Syntax from http://www.lua.org/manual/5.2/manual.html#9
--
-- Right-recursive refactoring from http://leg.luaforge.net/ with some
-- changes to rely on proper PEG lookahead assertions to resolve prefixexp
-- ambiguities instead of gross hacks.
--
-- -------------------------------------------------------------------------
local endstring = P"]" * Cb("eq") * P"]"
local _longstring = P"[" * Cg(P"="^0, "eq") * P"[" * (P(1) - endstring)^0 * endstring
local longstring = _longstring / function() return end --> discard group/back captures
local escape = P"\\" * P(1)
local doublequote = P'"' * (escape + (P(1) - S('"\n\r\f')))^0 * P'"'
local singlequote = P"'" * (escape + (P(1) - S("'\n\r\f")))^0 * P"'"
local shortstring = doublequote + singlequote
local longcomment = P"--" * longstring
local shortcomment = P"--" * (-P"\n" * P(1))^0 * P"\n"
local comment = longcomment + shortcomment
local whitespace = S" \t\n\r\f"^1
local space = (whitespace + comment)^0
local shebang = P"#!" * (P(1) - P"\n")^0 * P"\n"
local nameprefix = R("AZ", "az") + P"_"
local namesuffix = R("AZ", "az", "09") + P"_"
local function K(word) -- future keyword augmentations
return P(word)
end
local function J(patt, ...) -- join sequences with whitespace breaks
if patt then
-- consuming whitespace upfront also makes lists work
return space * patt * J(...)
else
return P(true)
end
end
local function E(list, terminal) -- generate list of terminal matches
local patt = P(list[1])
for i = 2, #list do
patt = patt + P(list[i])
end
-- exclude prefix matches
return patt * terminal
end
local LuaGrammar = G{ shebang^-1 * V"block",
block = J(stat^0, retstat^-1) * space,
stat = P";"
+ J(varlist, "=", explist)
+ functioncall
+ label
+ K"break"
+ J(K"goto", Name)
+ J(K"do", block, K"end")
+ J(K"while", exp, K"do", block, K"end")
+ J(K"repeat", block, K"until", exp)
+ J(K"if", exp, K"then", block, J(K"elseif", exp, K"then", block)^0, J(K"else", block)^-1, K"end")
+ J(K"for", Name, "=", exp, ",", exp, J(",", exp)^-1, K"do", block, K"end")
+ J(K"for", namelist, K"in", explist, K"do", block, K"end")
+ J(K"function", funcname, funcbody)
+ J(K"local", K"function", Name, funcbody)
+ J(K"local", namelist, J(P"=", explist)^-1),
retstat = J(K"return", explist^-1, P";"^-1),
label = J(P"::", Name, P"::"),
funcname = J(Name, J(P".", Name)^0, J(":" * Name)^-1),
varlist = J(var, J(",", var)^0),
var = prefixexp,
namelist = J(Name, J(P",", Name)^0),
explist = J(exp, J(P",", exp)^0),
simplexp = K"nil"
+ K"false"
+ K"true"
+ Number
+ String
+ P"..."
+ functiondef
+ prefixexp
+ tableconstructor
+ J(unop, simplexp),
prefixexp = J(Name + parenexp, (bracexp + dotexp + argsexp + colonexp)^0),
parenexp = J(P"(", exp, P")"),
bracexp = J(P"[", exp, P"]"),
dotexp = J(P".", Name),
argsexp = args,
colonexp = J(P":", Name, args),
exp = J(simplexp, J(binop, simplexp)^0),
functioncall = prefixexp,
args = J(P"(", explist^-1, P")") + tableconstructor + String,
functiondef = J(K"function", funcbody),
funcbody = J(P"(", parlist^-1, P")", block, K"end"),
parlist = J(namelist, J(P",", P"...")^-1) + P"...",
tableconstructor = J(P"{", fieldlist^-1, P"}"),
fieldlist = J(field, J(fieldsep, field)^0, fieldsep^-1),
field = J(P"[", exp, P"]", P"=", exp)
+ J(Name, "=", exp)
+ exp,
fieldsep = P"," + P";",
binop = P"and" + P"or" + P"~=" + P"==" + P">=" + P"<=" + P">" + P"<"
+ P".." + P"%" + P"^" + P"/" + P"*" + P"-" + P"+",
unop = P"-" + P"not" + P"#",
keyword = E({ -- NOTE: swapped else/elseif from Lua reference manual
"and", "break", "do", "elseif", "else", "end", "false",
"for", "function", "if", "in", "local", "nil", "not",
"or", "repeat", "return", "then", "true", "until", "while"
}, -namesuffix),
Name = (nameprefix * namesuffix^0) - keyword,
String = shortstring + longstring,
Number = R"09"^1 --> FIXME
}
- References:
- Re: Feature request: userdata slice, Dirk Laurie
- Re: Feature request: userdata slice, Dirk Laurie
- Re: Feature request: userdata slice, Tim Hill
- Re: Feature request: userdata slice, William Ahern
- Re: Feature request: userdata slice, Roberto Ierusalimschy
- Re: Feature request: userdata slice, William Ahern
- A few Wild and Wooly Proposals, while we're here (was Re: Feature request: userdata slice), Sean Conner
- Re: A few Wild and Wooly Proposals, while we're here (was Re: Feature request: userdata slice), Dirk Laurie
- Re: A few Wild and Wooly Proposals, while we're here (was Re: Feature request: userdata slice), Coda Highland
- Re: A few Wild and Wooly Proposals, while we're here (was Re: Feature request: userdata slice), Dirk Laurie