-
Notifications
You must be signed in to change notification settings - Fork 95
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
parse_lazy
has imprecise semantics
#95
Comments
Ouch, that is a case I failed to consider :(. An idea, if we add a method on |
That wouldn't work for parsers that can return both |
I like the idea of making Then, in this case |
Rather, pub enum LazyResult<T, E> {
ConsumedOk(T),
EmptyOk(T),
ConsumedErr(E),
EmptyErr(E, bool),
} Where |
Could you give an example how that wont work? While I believe your idea might work it would be a breaking change which is unfortunate. |
I mean, it would work, just not in the way that you described. By default all parsers would have to claim Assume a sequencing parser returns EmptyErr. If the sequencing parser's first child says it can return EmptyOk, we have no idea whether it was the first or the second child which caused the error, because either
|
Yep, that's right, it wasn't very thought through idea by me :). So basically we need some extra state somewhere to say what parser caused the error since parsers returning |
A fix for this is coming in #105. It turned out to have a lot more edge cases than I initially had thought of but I am pretty sure the approach is sound. Only drawback of it is that it can result in slowdowns in some uses of parsers returning |
So on attempting to fix a couple of other parser combinators' behaviours on error, I've come to realise that
parse_lazy
doesn't have the right semantics to correctly support what we want.Let's look at a motivating example.
Here we sequentially chain two parsers, the first of which returns
EmptyOk
, and the second returnsEmptyErr
. Now this combined tuple parser will returnEmptyErr
, meaning "no input was consumed, and one of my child parsers failed". However due to the semantics ofparse_lazy
, this will also imply "the first of my child parsers failed". Hence, whenadd_error
is called the message "not expected" will be added, which is clearly wrong.What's the fix?
parse_lazy
should not conflate "no input was consumed" with "first parser failed." So it seems like we have two options:Make
parse_lazy
semantics tighter. This will probably entail returning a separate flag "was actually lazy", which becomes the thing that specifies whetheradd_error
should be called or not. (One thing which I'm not sure about in this scenario is whether the Consumed flag is still useful or not? Is it currently important anywhere other than for determining laziness?)Keep the semantics of
parse_lazy
but rewrite some current parsers so they are not lazy. This loses us some amount of speed. Notably thetuple
andthen
combinators will have to become non-lazy.The text was updated successfully, but these errors were encountered: