nom
nom copied to clipboard
is there a "skip" or "drop", like "take"?
Hi there, Firstly, thank you so much for nom, it is a true pleasure to use. We use it regularly in production and it has been rock solid, and a real joy to develop with. Hopefully I will be able to open-source a parser we have written soon.
I have no issue to report, just a question:
I am wondering if there is a combinator that is similar to take, but drops/discards/skips the given number of bytes rather than returning them. Saying this another way, is there something like:
let s = skip(2usize)(s)?;
that simply returns the input with a certain number of prefix bytes removed, as opposed to using take like so:
let (s, _skipped_bytes) = take(2usize)(s)?;
I certainly can make a function that does this, I'm just curious if such a thing exists as a primitive in nom. I have searched the documentation and the source and so far not been able to find anything, but I may have missed it. Thank you!
Hello! any updates?)
Since take can provide the same functionality at the same performance (I presume), I'm curious what your motivation is. Is it to make the code more declarative / read as a grammar?
I created PR: https://github.com/Geal/nom/pull/1566/files
I'm trying to learn rust, and for the project I decided on, I need a parser and decided on nom. I literally just started looking at this library 10 minutes ago, and I was looking for "skip". Since @ikrivosheev didn't provide a reasoning, I thought I'd provide mine.
My experience comes from nimble_parsec which, being Elixir, uses chaining heavily. It's a small thing, but I was just after the same type of streamlined code. You can see they have an ignore which will ignore the output of any combinator, so it wouldn't quite be skip(3) like take(3) but more generally, skip(take(3))(s).
Again, in my case, it was just about removing the unnecessary extra let (s, _) = ...., which I think decreases the readability of the code.
My parse has a lot of places where it reads up to a pattern (like, a single character that can be ignored), skips the character, then keeps going. I can write my own function that does this, but first I thought there might be something built-in, which is how I saw this issue.
(I'm not suggesting that what's idiomatic in Elixir would make sense or belongs in Rust. Obviously, I need to adapt to the Rust-way.)
@karlseguin
Again, in my case, it was just about removing the unnecessary extra
let (s, _) = ...., which I think decreases the readability of the code.
Except skip would just change the output type to () at best and you would still have let (s, ()) = ... which isn't much different.
That said, I feel like a generic combinator is better than specialized versions of each function. combine does this with Parser::skip while chumsky does Parser::ignored. As @Xiretza points out in #1566, we already do have value((), p) and proposes void(p).