Search code examples
rustparser-combinators

Recognize floating point from input with nom


I'm trying to use nom to parse a text based protocol. This protocol can have floating point values in it of the form:

[-]digit+[.digit+]

Examples of which are:

  • -10.0
  • 10.0
  • 10

The nom parser I've built to recognize this is... not pretty. It also doesn't quite typecheck. What I've got so far:

named!(float_prs <&[u8], f64>,
       alt!(
           take_while!(nom::is_digit) => {|x| FromStr::from_str(std::str::from_utf8(x).unwrap()).unwrap()} |
           recognize!(chain!(
               take_while!(nom::is_digit) ~
                   tag!(".") ~
                   take_while!(nom::is_digit),
               || {})
           ) => {|x: &[u8]| FromStr::from_str(std::str::from_utf8(x).unwrap()).unwrap() }
       )
);

The first alternative parser recognizes digit+, the second is an attempt to recognize digit+.digit+ but

<nom macros>:5:38: 5:62 error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282]
<nom macros>:5 let index = ( $ i ) . offset ( i ) ; $ crate:: IResult:: Done (

Recognizing -digit etc is not addressed in the above. There's a significant amount of duplication and the intent is very much obscured. Is there a better way to parse [-]digit+[.digit+] that I'm not seeing?


Solution

  • Nom 2.1 now has float parser helper functions; you should no longer need to do this manually:

    This was added on Jan 27th.