-
Notifications
You must be signed in to change notification settings - Fork 23
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
Bug in attempt
?
#15
Comments
The docstring is technically right, but I agree that it's a bit jarring at first.
The first run works because it just parses Hello. The second run fails because the first one consumes and parses the H just fine, Wrapping the hello parser in an attempt lets you ignore the fact that it |
Why does choice consume anything if it doesn’t match? I would have expected some kind of backtracking. In the second example it can match the |
And I am still not sure why |
I'll leave this for @youngnh to answer since I'm still a bit shaky on this.
Okay, first,
Basically, if the parser you give to So:
First case:
Matches fine, returns result. All good. Next:
The
The
The
The |
Okay good, thanks for the clarification. It was What is the difference between these two? (run (either (char \x) (char \y)) "y") (run (either (attempt (char \x)) (char \y)) "y") So, |
Okay, after rewatching the talk to refresh my memory of the internals, I think
In that example, hello effectively returned "error, and I consumed a value". Okay, now in your last example:
This first tries the If you chained two characters together and the first one matched but the second But because
The Back to my example:
Now
Because this is parsing more than one thing at a time, and consumes/parses each Now, with all that said, I think it would be a lot more intuitive to use if |
Yes agreed, if it automatically wrapped its args, then it would give the backtracking effect. |
Backtracking is a common request and common source of confusion. The Parsatron doesn't do it by default because Haskell's parsec doesn't do it and this lib started out as a straight port. As things currently stand, users have to manually implement backtracking using parsers like There is something natural that matches people's expectations about backtracking. Its the way that new users of the library expect things to work, so there is an argument there that The Parsatron should implement it and people's programs will work as they want them to without muss or fuss. At the same time backtracking can incur very high costs in the case of long parse paths that fail close to the end, in highly branched parsers, or in parsers that attempt a match multiple times (like Right now, I think I'm leaning towards creating a second namespace in The Parsatron with backtracking equivalents of the functions in the current namespace. So that users may switch between implementations simply by changing the |
Maybe this is the right way to approach this. A new NS that can be used for testing. People could use the more comfortable one and see how it works out, and in case something is not going fast enough, users with more insight can switch back to the more low-levelish implementation. |
I've just run into the backtracking problem myself. I think the issue is that it's natural to expect the combinators to behave opaquely; having one branch of a choice fail but still consume input is very strange. One option is to add something like choice* from #26 to the library; this would make the distinction clear and probably ease this bump for new users. |
From the docstring “A parser that will attempt to parse p, and upon failure never consume any input” it was not clear to me, that
attempt
would throw an Exception.The text was updated successfully, but these errors were encountered: