diff --git a/src/value/attr_value/parser.rs b/src/value/attr_value/parser.rs index 6ace5c2..ead9cef 100644 --- a/src/value/attr_value/parser.rs +++ b/src/value/attr_value/parser.rs @@ -20,15 +20,10 @@ where delimited(multispace, p, multispace) } -fn parse_num(i: &str) -> IResult<&str, i32, VerboseError<&str>> { - alt(( - map_res(digit1, |s: &str| s.parse::()), - map_res(preceded(tag("-"), digit1), |s: &str| s.parse::().map(|x| -x)), - ))(i) -} - -fn parse_stringlit(i: &str) -> IResult<&str, &str, VerboseError<&str>> { - alt((delimited(tag("'"), take_while(|c| c != '\''), tag("'")), delimited(tag("\""), take_while(|c| c != '"'), tag("\""))))(i) +fn parse_num(i: &str) -> IResult<&str, f64, VerboseError<&str>> { + let (i, neg) = opt(tag("-"))(i)?; + let (i, num): (_, f64) = map_res(take_while(|c: char| c.is_numeric() || c == '.'), |n: &str| n.parse::())(i)?; + Ok((i, if neg.is_some() { -num } else { num })) } fn parse_bool(i: &str) -> IResult<&str, &str, VerboseError<&str>> { @@ -39,6 +34,10 @@ fn parse_literal(i: &str) -> IResult<&str, &str, VerboseError<&str>> { alt((parse_bool, parse_stringlit, recognize(parse_num)))(i) } +fn parse_stringlit(i: &str) -> IResult<&str, &str, VerboseError<&str>> { + alt((delimited(tag("'"), take_while(|c| c != '\''), tag("'")), delimited(tag("\""), take_while(|c| c != '"'), tag("\""))))(i) +} + fn parse_identifier(i: &str) -> IResult<&str, &str, VerboseError<&str>> { verify(recognize(pair(alt((alpha1, tag("_"), tag("-"))), many0(alt((alphanumeric1, tag("_"), tag("-")))))), |x| { !["if", "then", "else"].contains(x) @@ -158,6 +157,7 @@ mod test { use pretty_assertions::assert_eq; #[test] fn test_parser() { + assert_eq!(("", 12.22f64), parse_num("12.22").unwrap()); assert_eq!(AttrValExpr::Literal(AttrVal::from_primitive("12")), AttrValExpr::parse("12").unwrap()); assert_eq!( AttrValExpr::UnaryOp(UnaryOp::Not, box AttrValExpr::Literal(AttrVal::from_primitive("false"))), @@ -171,6 +171,13 @@ mod test { ), AttrValExpr::parse("12 + 2").unwrap() ); + assert_eq!( + AttrValExpr::FunctionCall( + "test".to_string(), + vec![AttrValExpr::Literal(AttrVal::from_primitive("hi")), AttrValExpr::Literal(AttrVal::from_primitive("ho")),] + ), + AttrValExpr::parse("test(\"hi\", \"ho\")").unwrap() + ); assert_eq!( AttrValExpr::UnaryOp( UnaryOp::Not,