Any suggestions for discriminating between a partial parse and an error parse? For example a REPL in which on newline if the parse can never be correct versus a parse that could be made correct with more input.
Re:PEG Parsers
by victorNicollet on Tuesday July 23, 2019 @03:50AM
(#20505153)
This has always struck me as significant effort invested in making a bad user experience only slight less bad: the REPL overloads the meaning of "enter" to mean both "insert a new line" and "execute command", and then attempts to guess what the user meant by tweaking the grammar of the language. Why not distinguish between "insert a new line" and "execute command" as two distinct inputs, and eliminate all ambiguity ?
I haven't used it for that, but I have used it to absorb errors and continue. The error just gets placed into the AST and then a later phase can report on (potentially) many errors, rather than just stopping at the first. YMMV
Re:PEG Parsers
by colanderman on Tuesday July 23, 2019 @12:09AM
(#20504328)
I used this exact same technique for the most recent PEG-based parser I wrote too. Works really well, and integrates well with Prolog (which I was using).
Wait... what is a "cut"? A minimal sample that show how it help with the error messages?
Cut means "if you matched this far, don't consider other options even if the current option fails to parse".
With this grammar:
expr: expr '+' term | term
And this input: 5 +
It will first consider the first alternative (expr '+' term) but will fail to match that branch because it's missing the "term" after the "+". That's fine because there's another alternative to try (term). That alternative doesn't match either, and you'll get the error message from the last alternative that it tried (probably something like "unexpected +").But with this grammar:
expr: expr '+' <cut> term | term
Then with the same input ("5 +") it will consider the first alternative, fail to match, and then fail immediately with the error message from that first alternative (something like "missing term after +").yeah, I get the purposed point of a "cut" but how I put one? Exist a basic sample? (ie: Using a peg parser how define what is a "cut"???)
expr: expr '+' API_call_here? term | termHmm, if you're using a peg parser that doesn't directly support this you can emulate it by choosing between the rhs of the cut and a production that will always match
so
expr : atom (op <cut> expr)*
Would be replaced with expr : atom (op (expr / cut))*
cut : "XXX"?
or perhaps simpler expr : atom (op expr?)*
Either way when you process the expr rule there will be an empty match where the rhs should be, and an appropriate error can be generated
My approach has been to introduce a type of cut operator, such that if you backtrack past a cut operator then it's information is stored, then if the parsee can't proceed it can examine the stored errors and produce hopefully sensible error messages.
For example, if I have a simple rule for an expression
And I insert a cut between the op and the atom... Then that cut (which can be appropriately annotated with human readable error information) will be returned if there is a binary exp with no rhs