winnow-rs / winnow

Making parsing a breeze
https://docs.rs/winnow
Other
525 stars 40 forks source link

Names of `take_until` and `take_till` don't distinguish them #487

Open epage opened 7 months ago

epage commented 7 months ago

From #485

One example is take_till vs take_until. Semantically that means the same thing, and their descriptions on the doc's list of combinators, seem to say the same thing just with different words.

See also #95

epage commented 7 months ago

See also rust-bakery/nom#968

yyy33 commented 1 month ago

Why take_till and take_untill are not the same as repeat_till, which receives a Parser as a termination condition, I think take_till and take_untill could be the same way

epage commented 1 month ago

repeat_till().take() can fill that same role while these functions fill a more specialized, optimized role.

yyy33 commented 1 month ago

repeat_till().take() can fill that same role while these functions fill a more specialized, optimized role.

repeat_till(any, terminator).take(),Am I understanding you correctly?

epage commented 1 month ago

Yes

yyy33 commented 1 month ago

I've been thinking about your reply for a long time and have been reading the winnow code lately. And I've been comparing winnow's api to regular expressions. I found repeat_till to be the functional equivalent of a superset, t similar to the repeat syntax in regular expressions. And take_while,take_till and so on is a subset of it, some operations repeat_till can do, but it might be faster to use take,take_while? So I'm wondering if it's necessary to just keep repeat_till, and then use specializations for take,take_while and such?

epage commented 1 month ago

If you know of a way to to get the performance benefits of take_while with repeat and take_until / take_till with repeat_till,. then I would be open to considering it. For myself, I don't see a good way of doing that. I also suspect users might prefer specialized methods for easier discovery, better examples for specializing on their own, and compile-time guarantees that they are getting better performance.

yyy33 commented 1 month ago

What I'm wondering is why winnow::combinator::Repeat parses to an Accumulate instead of <I as Stream>::Slice, and if winnow::combinator::Repeatreturns a Slice, wouldn't that be as fast as take_while? while. Define a collectmethod for winnow::combinator::Repeatthat returns Accumulate

epage commented 1 month ago

That depends on how expensive your error type is and how much the optimizer can do as looping over parsers has more overhead.

That also leaves out one of the take_*s as it applies simd optimizations.