-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple Error Messages #139
Comments
Could do both actually: partial results might be desirable to continue working, whereas multiple errors on their own is also good. Would require two extra run loops anyway, because we don't want to ruin the tight loop in the real run function. The major change here is just how these should be reflected in the This might make it non major... |
I would very much love to see a nice parser combinator library with error recovery 🥺 Would it be in scope to produce multiple errors AND a result value? Thinking in the context of a language server. |
So we actually had a Masters project by @DanKirwan that implemented this this year (way harder than we anticipated!). It was able to generate a final result as well as multiple error messages with a manual combinator that can specify how errors might be recovered at a certain point in the parse, with a dummy value to fill for that. In fact, Dan turned an existing parser+compiler written with parsley into a language server for vscode compiling it to scala-js with the new combinators. |
Very exciting! Is this available to view somewhere online? :) |
The language server in question no, that was technically an adapted coursework solution. |
right, thought as much... can you tell me more about the combinator for recovery, though? |
Sure, The combinator Dan introduced basically has this shape: extension [A](p: Parsley[A]) def recoverWith[B >: A](hdl: Parsley[B]): Parsley[B] The idea is that you run This combinator is pretty general, but it can be used to make a bunch of handy recovery strategies and patterns: extension [A](p: Parsley[A])
def panic[B >: A](FOLLOW: Parsley[?], dummy: B) = p.recoverWith(many(item - FOLLOW).as(dummy))
... The |
Is your feature request related to a problem? Please describe.
Occasionally, after having generated one syntax error, it may be possible to resume the parse and generate further syntax errors. As these go on, they may become less and less useful, but this is up for the end-user to appreciate for themselves.
Describe the solution you'd like
It would be nice if Parsley could produce multiple syntax errors from a parser. To accomplish this, recovery points need to be added into parsing flow, to indicate where a catastrophically failed parser could resume from. Such recovery points are places in the grammar that the parse can resume, and must know first predicate of that grammar position. This can be done via a combinator, which marks a specific parser as a continuation point, and tells it the set of characters it may resume from: these are provided explicitly. When a failure occurs, the parse will try and resume afresh from the next recovery point, dropping input until one of the provided character set is reached.
Describe alternatives you've considered
It is possible to establish the first predicate of a parser via static analysis: this, however, would be prohibitively expensive, so a user-directed approach is favourable.
Additional context
Recovery combinators either need to provide dummy values to allow for the parser to continue to construct values, or need to force the parser to run in some cheaper error generating only mode. The former is easier but requires more user annotation, the latter requires extra evaluation semantics for each instruction, which may be annoying to implement.
The text was updated successfully, but these errors were encountered: