Skip to content

Commit

Permalink
fix float parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
sthiele committed Jun 2, 2020
1 parent 51ca9ba commit 45e0ad6
Showing 1 changed file with 66 additions and 3 deletions.
69 changes: 66 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use nom::{
character::complete::{char, one_of, space0, space1},
combinator::{map_res, opt},
multi::{many0, separated_list},
number::complete::double,
};
pub use nom::{
error::{convert_error, ParseError, VerboseError},
Expand Down Expand Up @@ -1436,6 +1435,21 @@ fn test_constraint_item() {
);
assert_eq!(
constraint_item::<VerboseError<&str>>("constraint array_var_int_element(INT01, w, 2);"),
Ok((
"",
ConstraintItem {
id: "array_var_int_element".to_string(),
exprs: vec![
Expr::VarParIdentifier("INT01".to_string()),
Expr::VarParIdentifier("w".to_string()),
Expr::Int(2)
],
annos: vec![]
}
))
);
assert_eq!(
constraint_item::<VerboseError<&str>>("constraint array_var_int_element(INT01, w, 2.0);"),
Ok((
"",
ConstraintItem {
Expand Down Expand Up @@ -1465,7 +1479,7 @@ fn test_constraint_item_2() {
IntExpr::VarParIdentifier("INT01".to_string()),
IntExpr::VarParIdentifier("p".to_string())
]),
Expr::Float(-3.0)
Expr::Int(-3)
],
annos: vec![]
}
Expand Down Expand Up @@ -1958,6 +1972,8 @@ fn is_dec_digit(c: char) -> bool {
#[test]
fn test_float() {
use nom::error::VerboseError;
//TODO should return error
// float_literal::<VerboseError<&str>>("5")
assert_eq!(
float_literal::<VerboseError<&str>>("023.21"),
Ok(("", 023.21))
Expand All @@ -1979,6 +1995,53 @@ fn test_float() {
}
fn float_literal<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, f64, E> {
let (input, _) = space0(input)?;
let (input, f) = double(input)?;
let (input, f) = fz_float(input)?;
Ok((input, f))
}

fn fz_float<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, f64, E> {
let (input, f) = alt((fz_float1, fz_float2))(input)?;
let f2 = f.parse::<f64>().unwrap();
Ok((input, f2))
}

fn fz_float1<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, String, E> {
let (input, sign) = opt(char('-'))(input)?;
let (input, a) = take_while1(is_dec_digit)(input)?;
let (input, _) = char('.')(input)?;
let (input, b) = take_while1(is_dec_digit)(input)?;
let (input, rest) = opt(bpart)(input)?;
if let Some(s) = sign {
if let Some(rest) = rest {
Ok((input, format!("{}{}.{}{}", s, a, b, rest)))
} else {
Ok((input, format!("{}{}.{}", s, a, b)))
}
} else {
if let Some(rest) = rest {
Ok((input, format!("{}.{}{}", a, b, rest)))
} else {
Ok((input, format!("{}.{}", a, b)))
}
}
}
fn fz_float2<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, String, E> {
let (input, sign) = opt(char('-'))(input)?;
let (input, digits) = take_while1(is_dec_digit)(input)?;
let (input, rest) = bpart(input)?;
if let Some(sign) = sign {
Ok((input, format!("{}{}{}", sign, digits, rest)))
} else {
Ok((input, format!("{}{}", digits, rest)))
}
}
fn bpart<'a, E: ParseError<&'a str>>(input: &'a str) -> IResult<&'a str, String, E> {
let (input, e) = alt((tag("e"), tag("E")))(input)?;
let (input, sign) = opt(alt((tag("-"), tag("+"))))(input)?;
let (input, digits) = take_while1(is_dec_digit)(input)?;
if let Some(sign) = sign {
Ok((input, format!("{}{}{}", e, sign, digits)))
} else {
Ok((input, format!("{}{}", e, digits)))
}
}

0 comments on commit 45e0ad6

Please sign in to comment.