0

Nom has an example of parsing a floating point number:

named!(unsigned_float <f32>, map_res!(
  map_res!(
    recognize!(
      alt!(
        delimited!(digit, tag!("."), opt!(complete!(digit))) |
        delimited!(opt!(digit), tag!("."), digit)
      )
    ),
    str::from_utf8
  ),
  FromStr::from_str
));

I want to extend this example to also support parsing "123" to 123.0. I've tried something like this with no luck:

named!(unsigned_float_v1 <f32>,
    map_res!(
        map_res!(
            alt!(
                recognize!(
                    alt!(
                        delimited!(digit, tag!("."), opt!(complete!(digit))) |
                        delimited!(opt!(digit), tag!("."), digit)
                    )
                ) |
                ws!(digit)
            ),
            str::from_utf8
        ),
        FromStr::from_str
    )
);

named!(unsigned_float_v2 <f32>,
    map_res!(
        map_res!(
            recognize!(
                alt!(
                    delimited!(digit, tag!("."), opt!(complete!(digit))) |
                    delimited!(opt!(digit), tag!("."), digit) |
                    digit
                )
            ),
            str::from_utf8
        ),
        FromStr::from_str
    )
);
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
mitnk
  • 3,127
  • 2
  • 21
  • 28

1 Answers1

1

You need to wrap the tag!(".") with complete! too, as follows:

named!(unsigned_float_v2 <f32>,
    map_res!(
        map_res!(
            recognize!(
                alt!(
                    delimited!(digit, complete!(tag!(".")), opt!(complete!(digit))) |
                    delimited!(opt!(digit), complete!(tag!("."), digit) |
                    digit
                )
            ),
            str::from_utf8
        ),
        FromStr::from_str
    )
);

If the input is 123, the tag! would return Incomplete because it cannot decide if the next input is a .

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Géal
  • 1,482
  • 11
  • 13