4 ms·
> For a user-facing tool, parse errors should be recoverable and the parser should be able to keep going to collect multiple errors. I don't necessarily agree
by repiret 8y ago
> For a user-facing tool, parse errors should be recoverable and the parser should be able to keep going to collect multiple errors.
I don't necessarily agree with that assertion. I need to fix syntax errors one at a time anyway, and very often the parser recovers incorrectly and a single missing parenthesis gives hundreds of errors. Depending on the tooling, later errors can obscure earlier ones, but later errors are more likely to just be a result of the parser recovering incorrectly.
A lot of academic work has gone into making recoverable parsers, but a lot of that work originated from when compilers were much much slower. Remember there was a time when compiling meant taking your stack of punch cards down to the computer room, and checking on the results the next morning. The largest C++ file in my corner of the project I work on is about a quarter megabyte, and builds in 2 seconds on my aging desktop. Of course most of that time is compiling and not parsing. I intentionally added a parse error on its last line, and the compiler only spent 800ms to find it. Most languages parse faster than C++, and most source files are smaller. Waiting 800ms to get to the next syntax error isn't that bad, and it sure beats a screenful of false syntax errors resulting from incorrect parser recovery.
Tooling matters though. Good tooling means that rather than having to search a scollback buffer for the errors that matter, you editor has just jumped to some highlighted lines. But good tooling also means that as soon as you fix one syntax error, the parse results are updated. So it doesn't matter if the one error you fixed is the only one, or the tip of an iceberg.
- Arnavion 8y agoCompilers are not the only tools worth considering. Language services are also important, and language services see most use when the code is half-written and malformed. func foo() { b func bar() { } `foo` is still in the process of being written and the user has invoked auto-completion after typing `b`. It's good if the parser can recover and parse the `bar` function so that the language service can suggest `bar` there.
- hinkley 8y agoAs I sit in my fancy editor typing away code fragments I am often struck by the notion that my productivity would improve if the analyzer remembered something about the last clean parse of the file. If you parsed the file as a diff against the last known good state you should be able reason a lot more about what’s going on. Especially if the programmer has a habit of writing code incrementally.
- hinkley 8y agoInstead, what my editor does is autocomplete code blocks or statements in order to keep the parse tree consistent. But my editing style causes it to constantly jam me up when I’m trying to change string construction, Boolean logic, function calls or function chaining.
- userbinator 8y agoI am reminded of Knuth's famous TeX, which goes into an interactive mode when it encounters an error, asking the user what to do next; options include inserting extra tokens before the unexpected one, trying to recover and continuing to process the input, aborting, or even opening the editor so you can edit it in-place. I don't know of any other compiler which does this.
- andrewflnr 8y agoI don't think you actually disagree with the author. I think they would basically agree with everything you wrote and just add on, "therefore write your parser so it actually does recover correctly." Which is what most of the post boils down to.