chumsky
chumsky copied to clipboard
Add a `many_till` combinator
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.
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.
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 parserg
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.
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
?
Yes, exactly 🙂
Right. In that case, I'll probably close this in favour of #181 because it contains a little more discussion about these.