Skip to content
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

Add a many_till combinator #176

Closed
mwobat opened this issue Jul 23, 2022 · 5 comments
Closed

Add a many_till combinator #176

mwobat opened this issue Jul 23, 2022 · 5 comments

Comments

@mwobat
Copy link

mwobat commented Jul 23, 2022

I propose a combinator that repeats the first parser until the second one matches.

nom has an equivalent combinator:
https://docs.rs/nom/7.1.1/nom/multi/fn.many_till.html

The output type would be (Vec<A>, B),
A and B being the output types of the given parsers.

@Zij-IT
Copy link
Contributor

Zij-IT commented Jul 31, 2022

I may be misunderstanding you, but wouldn't such a combinator be the equivalent of:

just(A).repeated().then(just(B))

You can see this being used in Zesterer's foo implementation.

@mwobat
Copy link
Author

mwobat commented Aug 1, 2022

I may be misunderstanding you, but wouldn't such a combinator be the equivalent of:

just(A).repeated().then(just(B))

I should've explained more clearly.

The docs for nom::multi::many_till say:

Applies the parser f until the parser g produces a result.

I guess the description for the parser you suggested would be:
Applies the Parser f any number of times,
then applies the parser g.

So while the many_till parser applies f lazily, your one applies it eagerly.
I think you can use these two parsers interchangeably,
until you have a case where f and g could parse the same input.
Then the many_till parser would parse g, and your one would parse f.

If I'm not mistaken, it looks like the examples in the nom docs and for the foo implementation
are just such cases where you could use your parser as well.

@zesterer
Copy link
Owner

So really, you want something like

a.and_is(b.not()).repeated().then(b)?

i.e: lazily consume a, provided it doesn't match b, and then consume a b?

@mwobat
Copy link
Author

mwobat commented Aug 21, 2022

Yes, exactly 🙂

@zesterer
Copy link
Owner

Right. In that case, I'll probably close this in favour of #181 because it contains a little more discussion about these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants