disco
disco copied to clipboard
Add parse recovery to parser
I.e. add ability for parser to skip to the next thing when parsing fails, so we can generate multiple parse errors instead of just failing on the first one. Megaparsec has recover
combinator.
See https://web.archive.org/web/20190503013724/https://markkarpov.com/megaparsec/fun-with-the-recovery-feature.html . Instead of many parseTopLevel
, use something like from that example, e.g. recover = manyTill anySingle eol
or something like that. The question is what to do after that point if there are any failures. Can we re-throw a parser error that somehow contains all the errors? Or do we have to do something more manual? Maybe something with custom error type could work: http://hackage.haskell.org/package/megaparsec-6.5.0/docs/Text-Megaparsec-Error.html
This would still be a nice idea, but after using Disco to teach I no longer think this is so critical. In fact it might be kind of overwhelming to see lots of parse errors. Type errors are much more critical.
See here for how to do this with Megaparsec >= 8: https://markkarpov.com/tutorial/megaparsec.html#reporting-multiple-parse-errors . We can registerParseError
to emit a delayed parse error. Seems like this should now not be too bad.
Hmm, seems like this might actually be tricky, since we use indentation and allow definitions with multiple lines. When I tried adding recovery in what seems like a straightforward way, I tried running it on
f : N
f = 3 +
g : Z
g = -7
but it yielded a parse error on the beginning of the g : Z
line, saying that it expected something indented. It seems like by the time we realize that the definition of f
does not parse, it's already too late to recover, or something.