lexi-lambda/megaparsack

Documentation: megaparsack doc confusing regarding backtracking

bobduff opened this issue · 2 comments

(I'm new to racket and to megaparsack. Both look very interesting.
Please let me know if I'm sending this bug report in a wrong way.
I already reported this at racket/issues, but was told to go here.)

I think there are bugs in the megaparsack documentation,
regarding backtracking.

I'm using racket v8.2 on x86_64 linux.

"2.1.2 Backtracking with caution" says:

> (parse-result! (parse-string try-labeled/p "the integer: false"))
string:1:13: parse error
  unexpected: f
  expected: integer

And then says that message is "useless". In fact, that error message
is crystal clear. It then shows how to factor out "the ", and shows
a supposedly better error. But the better message is identical to
the one above.

This leaves me confused about what backtracking in Megaparsack
actually does.

"5.1 Primitives" says:

(or/p parser ...+) → parser?

  parser : parser?

Tries each parser in succession until one either succeeds or consumes
input, at which point its result will be returned as the result of the
overall parse. Parsers that consume input but fail will halt further
parsers from being tried and will simply return an error; if
backtracking is desired, the parser should be wrapped with try/p.

Changed in version 1.5 of package megaparsack-lib: Changed to always
return the first successful result, rather than continuing to try
parsers until one consumes input. The new behavior is more predictable
and more consistent with existing Parsec implementations, though the old
behavior was more consistent with the presentation in the original
paper.

First, it seems strange to document the old behavior first, and then say
it changed. Why not document the behavior of the latest version, and
then say, "This changed in version 1.5 of package megaparsack-lib;
before version 1.5, it did so-and-so..."? (I see that "many+/p" is
documented that way.)

Second, the description of the new behavior is incomplete -- it doesn't
say what happens if all alternatives of "or/p" fail. Does it return
the first successful, but if there is no such, the first unsuccessful
(i.e. the first)? That would explain my confusion about section 2.1.2.

"5.1 Primitives" says:

void/p : (parser/c any/c void?)

A parser that always succeeds and always returns #<void>.

"...and does not consume input", right?

"5 API Reference" is missing "into": "syntax objects" should be
"syntax objects into".

First, it seems strange to document the old behavior first, and then say
it changed. Why not document the behavior of the latest version, and
then say, "This changed in version 1.5 of package megaparsack-lib;
before version 1.5, it did so-and-so..."? (I see that "many+/p" is
documented that way.)

From what I can tell, what is documented first for or/p is the new behaviour: v1.4...v1.5

The note below that seems to be a clarification for the old behaviour that isn't mentioned anywhere, so that section is still definitely confusing.

From what I can tell, what is documented first for or/p is the new behaviour: v1.4...v1.5

Ah, OK, I see how you can read it that way.

The note below that seems to be a clarification for the old behaviour that isn't mentioned anywhere, so that section is still > definitely confusing.

I was confused. ;-)

I guess the stuff in 2.1.2 is obsolete.

Thanks for checking.

  • Bob