Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Denis Lisov
@tanriol
@oddcoder I'd really recommend if you're new to nom to start with Nom 5 and without macros (at least without named!)
Graeme Ferguson
@gqo

Hi there, I'm new to nom and as an learning experiment I've been trying to make a simplified JSON (just arrays of strings and string key:val pairs) parser using nom5. However, I've reached a point where I'm trying to parse the right side of a key:val pair wherein val could be an array or a quote delimited string.

I'm trying to do something like this:

fn parse_quotes(input: &str) -> IResult<&str, &str> { ... }
fn parse_array(input: &str) -> IResult<&str, Vec<&str>> { ... }

fn parse_value(input: &str) -> IResult<&str, _> {
    alt((
        parse_quotes, 
        parse_array
    ))(input)
}

My problem here is, as parse_quotes and parse_array return different types, I'm not sure how to handle combining/branching them in alt or even if I should do that in the first place. I'd appreciate any pointers!

I was hoping to avoid creating an Enum until I got most of the text parsing done in this silly example but maybe that would solve my issue
Nathan Ringo
@remexre
If I'm using the function-based API, how do I do eof!()?
Denis Lisov
@tanriol
For example, you can explicitly check whether the tail is empty.
Alexander Ekdahl
@AlexanderEkdahl

Hi, I'm running into an issue parsing bits. From what I can see the example at https://docs.rs/nom/5.0.1/nom/bits/fn.bits.html does not work. First of all the function should be bits and not take_bits but more elusively I get the following compile error:

error[E0283]: type annotations required: cannot resolve `_: nom::error::ParseError<(&[u8], usize)>`

    bits::bits(bits::complete::take(4usize))(input)
    ^^^^^^^^^^

   pub fn bits<I, O, E1: ParseError<(I, usize)>+ErrorConvert<E2>, E2: ParseError<I>, P>(parser: P) -> impl Fn(I) -> IResult<I, O, E2>
                         ---------------------- required by this bound in `nom::bits::bits`

Not sure how to proceed or how to explicitly give it the required type annotation.

Denis Lisov
@tanriol
Should work with bits::complete::take::<_, _, _, (_, _)>. Yes, the required annotations here are not nice :-(
Alexander Ekdahl
@AlexanderEkdahl
@tanriol Thank you! That worked.
I will update the example in the documentation
Alexander Ekdahl
@AlexanderEkdahl
Created a PR: Geal/nom#1071
Open to suggestions for how the example can be improved
Mathias Ottosson
@ottosson

I would like to parse a separated list that can have white spaces before and after the separators like [0 , 1 , 2]

I've got this working, but it only accounts for whitespaces after the separator:
separated_list(preceded(char(','), multispace0), float)
How can I make it work with white spaces on both sides?

Johan Segolsson
@phaero
how come the first escape_transform works while the other hangs?
fn parser(i: &str) -> IResult<&str, String> {
    // Works
    escaped_transform(is_not("\\"), '\\', escape)(i)

    // Hangs
    //escaped_transform(take_while(|c| c != '\\'), '\\', escape)(i)
}

fn escape(i: &str) -> IResult<&str, &str> {
    alt((
        map(tag("\\"), |_| "\\"),
        map(tag("\""), |_| "\""),
        map(tag("n"), |_| "\n"),
    ))(i)
}
Johan Segolsson
@phaero
if anyone is wondering, the answer to my question is to user take_while1 instead of take_while. I'm guessing it has to do with that it will succeed even with an empty match. I would have expected that it would fail when there is no more input however...
Alistair A. Israel
@aisrael

Any examples on how to use nom::branch::alt when combining parsers with different (map-ped) outputs?

Specifically, I have two sub-parsers, e.g. parse_int that returns (&str, i64) and parse_alpha that returns (&str, &str). How would one construct an alt(parse_int, parse_alpha) given that both sub-parsers have different return types?

Johan Segolsson
@phaero
@aisrael I think parsers in alt needs to return the same type for it to work, the easiest way would probably be if each returns the same enum with different values
Alistair A. Israel
@aisrael
@phaero I get that. But I'm really trying to write a parser for a DSL and am trying to design the language and the AST model and figure out nom (and Rust) while am it so everything's kinda all up in the air. Right now am experimenting with e.g. impl From<IntegerLiteral> for Expression and impl From<Identifier> for Expression and alt(parse_integer_literal, parse_identifier) and so on...
stedingan
@stedingan
hello can somebody please help me understand num better? what is the code doing? why am i getting an error? https://paste.xinu.at/B5HM/
stedingan
@stedingan
shouldn't this little code snippet work and give the back the lenght found as u16?
Denis Lisov
@tanriol
Your paste is not found :-(
stedingan
@stedingan
oh yeah i'm sorry. but i figured it out :)
and i think i'm getting a better grasp of nom too
stedingan
@stedingan
can somebody help me understand? https://paste.xinu.at/US9/ how does the be_u16() work? seems like i'm using it the wrong way
Denis Lisov
@tanriol
These parsers work with binary data and numbers in binary representation, not text.
stedingan
@stedingan
hmm, so i probably can just use the 00 as string
something like take_till(is_alphabetic)
stedingan
@stedingan
hmm, can somebody explain to me what is the difference between map_res!() and map_res()?
stedingan
@stedingan
Denis Lisov
@tanriol
Macros are considered deprecated in nom 5 series, so functions are the way forward.
Otavio Salvador
@otavio
Hello all. We have a small text protocol that we'd like to add support using nom. However, we need to have deserialize and serialize it. Does nom has support for it?
stedingan
@stedingan
do i need to write my own function to eat whitespaces? or is there already a function defined in nom?
Denis Lisov
@tanriol
@otavio nom does not support serialization (but you may want to look at cookie-factory for that). nom does not generate parsers from your structures if you need that for serialization.
@stedingan No built-in, AFAIK. May be a good idea for a pull request :-)
Marin
@p1-mmr
Hello, I would like to know if there is a way to handle implicit padding for word-alignment when reading data with nom macros? For example, I have a length and a value field in a given protocol, and the protocol requires me to read the length field, then if the value is 7-bytes long, to read 7 bytes of data for the data field then to read 1 extra byte of padding to have the protocol cursor 4-byte aligned, is there a standard way to implement that with macros?
Denis Lisov
@tanriol
Macros are not the standard way of reading data in nom these days :-)
Marin
@p1-mmr
Oh, what is the newer way then?
Denis Lisov
@tanriol
Plain functions, see the 5.0 announcement blog post.
I'm pretty sure that a "aligned read" wrapper can be written without much trouble. Nothing built-in, however.
Mathias Ottosson
@ottosson
@tanriol Am I misunderstanding something or why can't @stedingan use the built in multispace0-parser?
Denis Lisov
@tanriol
@ottosson Correct, I'd failed my search roll :-) however I'd note that this one eats a specific set of ASCII whitespace, not all the Unicode spaces.
This may be or not be what @stedingan wants :-)
Mathias Ottosson
@ottosson
Ah! Then I guess rolling his own is the way to go :)
Mathias Ottosson
@ottosson
The amount of pull requests for nom are starting to grow a bit. When will someone start accepting them? I'd love to see nom being actively developed, but at the same time I understand if Geoffroy is busy with other things or whatever. Maybe it would be a good idea to have more people being able to accept PRs?
Roman Valls Guimera
@brainstorm
@stedingan @tanriol I wonder what factor() does in https://github.com/Geal/nom/blob/master/doc/making_a_new_parser_from_scratch.md#testing-the-parsers if it doesn't eat whitespaces... wish I could see where that snippet was taken from.
Marin
@p1-mmr

Hello!

It seems that certain combinator functions, such as take, don't have a prototype that would let using these with the ? operator in a function which returns IResult<I, O, E> with E being the default of E=(I,ErrorKind) (as in pub type IResult<I, O, E=(I,ErrorKind)> = Result<(I, O), Err<E>>; defined here https://docs.rs/nom/5.0.0/src/nom/internal.rs.html ):

error[E0277]: the trait bound `(&[u8], nom::error::ErrorKind): nom::error::ParseError<(_, usize)>` is not satisfied
  --> src/main.rs:83:16
   |
83 |     let data = take(length - header_size)(input)?;
   |                ^^^^ the trait `nom::error::ParseError<(_, usize)>` is not implemented for `(&[u8], nom::error::ErrorKind)`
   | 
  ::: /home/marin/.cargo/registry/src/github.com-1ecc6299db9ec823/nom-5.0.1/src/bits/complete.rs:10:25
   |
10 | pub fn take<I, O, C, E: ParseError<(I, usize)>>(count: C) -> impl Fn((I, usize)) -> IResult<(I, usize), O, E>
   |                         ---------------------- required by this bound in `nom::complete::take`
   |
   = help: the following implementations were found:
             <(I, nom::error::ErrorKind) as nom::error::ParseError<I>>

I would like to know whether there is a way to have a function returning an IResult where the IResult could be an IResult::Err originating from any of the built-in combinators of nom, or if the use of the ? operator with nom is discouraged currently?

Denis Lisov
@tanriol
As the error message mentions ParseError<(_, usize)>, it looks like you're mixing byte-level and bit-level parsers. This is known to be tricky in terms of errors :-(
Marin
@p1-mmr
Oh, maybe that there are different take combinators and that I imported the wrong one (bit-level instead of byte-level) due to asterisk imports?
Marin
@p1-mmr
Ok then, I modified the import of nom::complete::* into nom::bytes::complete::*. I would also like to know whether there would be a way to mix returning VerboseError errors from my own parsers, with the tuple results that seem to be the standard way to return errors from byte-based parsers with nom, or if again a function can't return both kind of errors and would recommend using match { } constructs instead of the ? operator?
Maybe stringifiyng tuple-based error items into VerboseError vector items before returning?
Marin
@p1-mmr
Ok, the built-in byte-based combinators just return into in with explictly specifying E=VerboseError<&[u8]> in the return types of my functions