luaparse
luaparse copied to clipboard
Tolerant error handling
Implement a mode where errors are stored instead of thrown. Necessary recovery functions should be exposed so that users can hook into it.
I don't think the parser itself should include recovery functionality but should definitely have an example available.
This would be great for syntax highlighting, autocompletion, getting a list of definitions and even better static analysis (letting you get many errors in a single run)...
What would need to be changed in order to support this?
I'm sorry, are there any news on this? Somewhere where help is needed or a way to start working on this?
To my knowledge, unless @oxyc is sitting in a cave and secretly crafting a solution, this isn't being worked on currently. As the cliché goes, patches are welcome.
I think simply slapping some try-catch blocks in a few strategic places (where the catch block puts the syntax error in some array and then just swallows the exception) could give us a rudimentary solution. But that would hardcode some policy decisions about interpreting non-well-formed code into the parser. I'm not sure what design @oxyc had in mind when he filed this issue.
(And while we're doing this, I'd change the SyntaxError
to a dedicated exception type.)
Yeah I've given a a few shots at implementations but couldn't really come up with anything that was useful. At the moment I don't have access to the code I experimented with and it was a while ago so not certain what I tried.
I at least wrapped lex()
within next()
in a try-catch and then attempted to move on from errors. Also had several recovery conditions in the individual parse functions but it just turned into a mess. I think I would have to read up on strategies if I were to implement it. But yes, patches are definitely welcome hehe.
Acorns loose parser would be a something to look at. https://github.com/ternjs/acorn/tree/master/src/loose
When parse errors are made recoverable, it seems it shouldn't be too hard to go the whole way and introduce warning lints as well, or at least a mechanism for such lints to be easily plugged in.
Some warnings to consider:
- Core language pitfalls
- [ ] Referencing a global variable, unless specifically whitelisted
- [ ] Attempting to index a non-string literal (in 5.0 string literals were errors as well)
- [ ] Leading zeroes in number literals (which may be mistaken for octal; thank you, ~~C~~ B).
- [ ] Likewise, decimal string escapes in in Lua 5.2+ (in 5.1 there are no hexadecimal escapes, so…)
- [ ]
...
in the top-level chunk (mentioned in #74) - [ ] Implicit clipping of varargs, as in
f(..., a)
or{ ..., a }
- [ ]
{ ... }
should probably bearg
(5.1 withLUA_COMPAT_VARARG
, unless at the top level),{ n = select('#', ...), ... }
(5.1 generally) ortable.pack(...)
(5.2) instead- [ ]
for a, b in ipairs { ... } do --[[ ... ]] end
should be, depending on version:- 5.1:
do local _ = { ... } for a = 1, select('#', ...) do local b = _[a] --[[ ... ]] end end
- 5.2+:
do local _ = table.pack(...) for a = 1, _.n do local b = _[a] --[[ ... ]] end end
- 5.1:
- [ ]
- Library function pitfalls
- [ ] No
mode
argument in aload
call - [ ] Implicit clipping of multiple return values, as in
f(table.unpack(a), b)
or{ table.unpack(a), b }
- [ ] No
- Compatibility hazards (deprecations and breaking changes)
- [ ] Calling any deprecated library function
- [ ] Unrecognised escape sequences (falls back to the respective escaped character in 5.1, error in 5.2+)
- [ ] In Lua 5.1, declaring a variable named
_ENV
(forward compat hazard against 5.2+) - [ ] In Lua 5.1, accessing varargs via
arg
and/or declaring a variable namedarg
(https://stackoverflow.com/a/18679249)