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
Rewind parser #33
Rewind parser #33
Conversation
Hi, thanks for the PR! Just so I can get a few things straight about exactly what problems you encountered:
This doesn't look like a pattern that should fail, unless The PR seems like the parse succeeds on valid input, but reverts to the start of this input. Is this the intended behaviour? |
@zesterer Thanks for the review.
I forgot to write that the
Yes, this is intended. Certainly, It looks like it could be a success, and the introduced parser is unnecessary. |
src/combinator.rs
Outdated
#[test] | ||
// TODO: this fails | ||
fn reproduce_repeated_with_infix() { | ||
let a = just::<_, Simple<char>>('a'); | ||
let parser = a | ||
.clone() | ||
.repeated() | ||
.then(a.clone().then_ignore(just('-')).then(a)) | ||
.then_ignore(end()); | ||
|
||
assert_eq!(parser.parse("aaa-a"), Ok((vec!['a', 'a'], ('a', 'a')))); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added that reproduces the condition I met and I want to solve.
What I'm worried about is the extent to which this combinator generalises and the ergonomics of it. For me, it took me quite a while to understand exactly what the code in your example was actually doing. I think it's probably the case that this case of overzealous parsing is only hit when a parser consumes too much of the input to the right of its intended pattern. If this is the case, may I recommend a rename to
|
I had a little survey on this, the I roughly agree the lookahead API I suggested is difficult to understand. How about Also, How about |
We already have |
/// Parse something and then rewind the state so that it only looks ahead and does not consume input. | ||
/// Chumsky's parsers are always rewind the state when they fail. | ||
/// But this combinator makes a parsers to rewind the state whether it succeeds or fails. | ||
/// A typical use-case of this is that you want to parse something which is not followed by something else. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// # use chumsky::prelude::*; | ||
/// let just_numbers = text::digits::<_, Simple<char>>(10) | ||
/// .padded() | ||
/// .then_ignore(none_of("+-*/".chars()).rewind()) | ||
/// .separated_by(just(',')); | ||
/// // 3 is not parsed because it's followed by '+'. | ||
/// assert_eq!(just_numbers.parse("1, 2, 3 + 4"), Ok(vec!["1".to_string(), "2".to_string()])); | ||
/// ``` | ||
fn rewind(self) -> Rewind<Self> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed it to rewind
, and made the documentation slightly better.
src/combinator.rs
Outdated
|
||
#[test] | ||
// TODO: this fails | ||
fn reproduce_repeated_with_infix() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need a #[should_fail]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but I deleted the test in my latest commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently not.
Thanks for your work on this PR! |
Thank you! This makes my programming language more powerful 💪 |
Hi, continuously I perfectly enjoying parsing with this amazing crate. Today I introduce
lookahead
combinator.I don't believe that this should be merged, but this is a little bit convenience for some case. Also, I am not confident on the naming and design of this new combinator.
Motivation
I want to parse something like this;
with
But this fails at
-
.So I introduce
lookahead
and change the parser like below.Compare to other designs
I choose the one I think it's most fits to chumsky's APIs.
word.lookahead(none_of("-".chars()))
This is like very natural, but always ignores the outputs of the lookahead parser.
In some case, we may want not to ignore, such as infix attribute syntax that have influence to the both side.
word.then_ignore(lookahead(none_of("-".chars())))
This is also natural, and allows us to choose whether ignore the output or not.
However, this is odd in chumsky's conventions.