4

I have a somewhat techinical question about the inner workings of (Mega)Parsec, the informal context of which is:

What is the idea governing the accumulation/propagation of error messages through continuations in Parsec?

Specifically: Consider the mplus operation making ParsecT an instance of MonadPlus. (source) mplus m n takes, as input, a string s to parse and continuations cok, cerr, eok, and eerr to follow based on the result of the parse.

First parse s with m:

  • If the parse succeeds and consumes (respectively, does not consume) part of s, follow the cok (respectively, eok) continuation.
  • If the parse of s with m fails while consuming part of s, follow the cerr continuation.
  • Suppose the parse of s with m fails without consuming anything; let err be the parse error associated with this failure. We then try parsing s with n, and choose a continuation accordingly:
    • If the parse of s with n succeeds while consuming input, follow the cok continuation.
    • If the parse of s with n fails while consuming input, follow the cerr continuation.
    • If the parse of s with n succeeds without consuming input, follow a continuation neok derived from eok: neok y s' err' = eok y s' (mergeError err err')
    • If the parse of s with n fails without consuming input, follow a continuation neerr derived from eerr: neerr y s' err' = eerr (mergeError err err')

My question is:

Why do we merge errors when following an 'empty' continuation and not when following a 'consumed' continuation, thereby forgetting about all previous errors?

This must be a design decision, but I can't figure out the reasoning behind it. Is there, perhaps, a simple example that would clarify this?

fmg
  • 813
  • 8
  • 18
  • I think this is meant to achieve the effect of reporting all errors iff none of the attempted parsers succeeded; but if at least one succeeded, the errors from all unsuccessful parsers ought to be swallowed. – Fyodor Soikin Apr 16 '18 at 15:49
  • @FyodorSoikin Then why does `cok` even take a `ParseError` argument? – fmg Apr 16 '18 at 15:53
  • https://stackoverflow.com/questions/39057940/why-doesnt-parsec-backtrack-when-one-part-of-the-parser-succeeds-and-the-rest-f – leftaroundabout Apr 16 '18 at 16:33
  • @leftaroundabout Would you be able to guide me a little? What part of the referenced post is addressing what? – fmg Apr 16 '18 at 17:04
  • @fmg it takes that argument, because its signature is dictated by the `ParsecT` constructor. – Fyodor Soikin Apr 16 '18 at 17:18
  • @FyodorSoikin I meant, why is the ParsecT type defined in this way, i.e., with cok taking a ParseError argument that never seems to be used nontrivially. – fmg Apr 16 '18 at 17:25
  • Because it's not in every case that you want up swallow these errors. – Fyodor Soikin Apr 16 '18 at 18:45
  • @FyodorSoikin Would you mind suggesting an example where you don't want these elements swallowed when passing through `cok`? Are there any such in the `Parsec` codebase, that you know of? – fmg Apr 16 '18 at 20:02

0 Answers0