e=p[i]
if type(e) == "string" then
if not lx:is_keyword (lx:next(), e) then
- parse_error (lx, "Keyword '%s' expected", e) end
+ parse_error (lx, "A keyword was expected, probably `%s'.", e) end
elseif is_parser (e) then
table.insert (r, e (lx))
else
- gg.parse_error (lx,"Sequence `%s': element #%i is not a string "..
+ gg.parse_error (lx,"Sequence `%s': element #%i is neither a string "..
"nor a parser: %s",
p.name, i, table.tostring(e))
end
-- Check for non-associative operators, and complain if applicable.
-----------------------------------------
elseif p2.assoc=="none" and p2.prec==prec then
- parser_error (lx, "non-associative operator!")
+ parse_error (lx, "non-associative operator!")
-----------------------------------------
-- No infix operator suitable at that precedence
compiler should be prefixed with an option flag, hinting what must be
done with them: take tham as file names to compile, as library names
to load, as parameters passed to the running program... When option
-flags lack, metalua tries to adopt a "Do What I Mean" approach:
+flags are absent, metalua tries to adopt a "Do What I Mean" approach:
- if no code (no library, no literal expression and no file) is
specified, the first flag-less parameter is taken as a file name to
function id_or_literal (lx)
local a = lx:next()
if a.tag~="Id" and a.tag~="String" and a.tag~="Number" then
- gg.parse_error (lx, "Unexpected expr token %s",
- _G.table.tostring (a, 'nohash'))
+ local msg
+ if a.tag=='Eof' then
+ msg = "End of file reached when an expression was expected"
+ elseif a.tag=='Keyword' then
+ msg = "An expression was expected, and `"..a[1]..
+ "' can't start an expression"
+ else
+ msg = "Unexpected expr token " .. _G.table.tostring (a, 'nohash')
+ end
+ gg.parse_error (lx, msg)
end
return a
end
-- That is, without sugar:
return {tag="String", {tag="Index", {tag="Splice", id[1] },
{tag="Number", 1 } } }
- else error ("Identifier expected: "..table.tostring(id)) end
+ else error ("Identifier expected: ".._G.table.tostring(id)) end
end
--------------------------------------------------------------------------------
else
assert (#e > 0)
if #e > 1 then
- gg.parse_error (lx, "comma is not a valid statement separator") end
+ gg.parse_error (lx,
+ "comma is not a valid statement separator; statement can be "..
+ "separated by semicolons, or not separated at all") end
if e[1].tag ~= "Call" and e[1].tag ~= "Invoke" then
- gg.parse_error (lx, "This expression is of type '%s'; "..
- "only function and method calls make valid statements",
- e[1].tag or "<list>")
+ local typename
+ if e[1].tag == 'Id' then typename = "an identifier"
+ elseif e[1].tag == 'Op' then typename = "an arithmetic operation"
+ else typename = "of type '"..(e[1].tag or "<list>".."'" end
+
+ gg.parse_error (lx, "This expression is " .. typename ..
+ "; only function and method call expressions "..
+ "can be used as statements");
end
return e[1]
end