@@ -1426,6 +1426,8 @@ where
14261426 ) ( input)
14271427}
14281428
1429+ ///
1430+
14291431/// Recognizes a floating point number in text format and returns the integer, fraction and exponent parts of the input data
14301432///
14311433/// *Complete version*: Can parse until the end of input.
@@ -1517,24 +1519,35 @@ where
15171519 Ok ( ( i, ( sign, integer, fraction, exp) ) )
15181520}
15191521
1522+ /// Case-insensitive comparison of digits. Only works if `y` is only ASCII letters.
1523+ #[ inline]
1524+ fn case_insensitive_cmp ( x : & [ u8 ] , y : & [ u8 ] ) -> bool {
1525+ let d = ( x. iter ( ) . zip ( y. iter ( ) ) ) . fold ( 0 , |d, ( xi, yi) | d | xi ^ yi) ;
1526+ // This uses the trick that 'a' - 'A' == 0x20, and this is true
1527+ // for all characters, so as long as `yi` is a valid ASCII letter,
1528+ // `xi ^ yi` can only be 0 or 0x20.
1529+ d == 0 || d == 32
1530+ }
1531+
15201532/// Recognizes floating point number in text format and returns a f32.
15211533///
1522- /// *Complete version*: Can parse until the end of input.
1534+ /// *Complete version*: Can parse until the end of input. This only handles
1535+ /// finite (non-special floats).
15231536/// ```rust
15241537/// # use nom::{Err, error::ErrorKind, Needed};
15251538/// # use nom::Needed::Size;
1526- /// use nom::number::complete::float ;
1539+ /// use nom::number::complete::float_finite ;
15271540///
15281541/// let parser = |s| {
1529- /// float (s)
1542+ /// float_finite (s)
15301543/// };
15311544///
15321545/// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
15331546/// assert_eq!(parser("123E-02"), Ok(("", 1.23)));
15341547/// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
15351548/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
15361549/// ```
1537- pub fn float < T , E : ParseError < T > > ( input : T ) -> IResult < T , f32 , E >
1550+ pub fn float_finite < T , E : ParseError < T > > ( input : T ) -> IResult < T , f32 , E >
15381551where
15391552 T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
15401553 T : Clone + Offset ,
@@ -1560,6 +1573,42 @@ where
15601573 Ok ( ( i, float) )
15611574}
15621575
1576+ /// Recognizes floating point number in text format and returns a f32.
1577+ /// This only handles non-finite (special) values.
1578+ pub fn float_nonfinite < T , E : ParseError < T > > ( input : T ) -> IResult < T , f32 , E >
1579+ where
1580+ T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
1581+ T : Clone + Offset ,
1582+ T : InputIter + InputLength + InputTake ,
1583+ <T as InputIter >:: Item : AsChar + Copy ,
1584+ <T as InputIter >:: IterElem : Clone ,
1585+ T : InputTakeAtPosition ,
1586+ <T as InputTakeAtPosition >:: Item : AsChar ,
1587+ T : AsBytes ,
1588+ T : for < ' a > Compare < & ' a [ u8 ] > ,
1589+ {
1590+ let ( i, sign) = sign ( input. clone ( ) ) ?;
1591+ let ( mut float, count) = if i. input_len ( ) >= 3 {
1592+ if case_insensitive_cmp ( i. as_bytes ( ) , b"nan" ) {
1593+ ( f32:: NAN , 3 )
1594+ } else if i. input_len ( ) >= 8 && case_insensitive_cmp ( i. as_bytes ( ) , b"infinity" ) {
1595+ ( f32:: INFINITY , 8 )
1596+ } else if case_insensitive_cmp ( i. as_bytes ( ) , b"inf" ) {
1597+ ( f32:: INFINITY , 3 )
1598+ } else {
1599+ return Err ( Err :: Error ( E :: from_error_kind ( input, ErrorKind :: Float ) ) ) ;
1600+ }
1601+ } else {
1602+ return Err ( Err :: Error ( E :: from_error_kind ( input, ErrorKind :: Float ) ) ) ;
1603+ } ;
1604+
1605+ if !sign {
1606+ float = -float;
1607+ }
1608+
1609+ Ok ( ( i. slice ( count..) , float) )
1610+ }
1611+
15631612/// Recognizes floating point number in text format and returns a f32.
15641613///
15651614/// *Complete version*: Can parse until the end of input.
@@ -1577,7 +1626,44 @@ where
15771626/// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
15781627/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
15791628/// ```
1580- pub fn double < T , E : ParseError < T > > ( input : T ) -> IResult < T , f64 , E >
1629+ pub fn float < T , E : ParseError < T > > ( input : T ) -> IResult < T , f32 , E >
1630+ where
1631+ T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
1632+ T : Clone + Offset ,
1633+ T : InputIter + InputLength + InputTake ,
1634+ <T as InputIter >:: Item : AsChar + Copy ,
1635+ <T as InputIter >:: IterElem : Clone ,
1636+ T : InputTakeAtPosition ,
1637+ <T as InputTakeAtPosition >:: Item : AsChar ,
1638+ T : AsBytes ,
1639+ T : for < ' a > Compare < & ' a [ u8 ] > ,
1640+ {
1641+ if let Ok ( ( i, float) ) = float_finite :: < T , E > ( input. clone ( ) ) {
1642+ Ok ( ( i, float) )
1643+ } else {
1644+ float_nonfinite :: < T , E > ( input)
1645+ }
1646+ }
1647+
1648+ /// Recognizes floating point number in text format and returns a f64.
1649+ ///
1650+ /// *Complete version*: Can parse until the end of input. This only handles
1651+ /// finite (non-special floats).
1652+ /// ```rust
1653+ /// # use nom::{Err, error::ErrorKind, Needed};
1654+ /// # use nom::Needed::Size;
1655+ /// use nom::number::complete::double_finite;
1656+ ///
1657+ /// let parser = |s| {
1658+ /// double_finite(s)
1659+ /// };
1660+ ///
1661+ /// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
1662+ /// assert_eq!(parser("123E-02"), Ok(("", 1.23)));
1663+ /// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
1664+ /// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
1665+ /// ```
1666+ pub fn double_finite < T , E : ParseError < T > > ( input : T ) -> IResult < T , f64 , E >
15811667where
15821668 T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
15831669 T : Clone + Offset ,
@@ -1603,6 +1689,78 @@ where
16031689 Ok ( ( i, float) )
16041690}
16051691
1692+ /// Recognizes floating point number in text format and returns a f64.
1693+ /// This only handles non-finite (special) values.
1694+ pub fn double_nonfinite < T , E : ParseError < T > > ( input : T ) -> IResult < T , f64 , E >
1695+ where
1696+ T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
1697+ T : Clone + Offset ,
1698+ T : InputIter + InputLength + InputTake ,
1699+ <T as InputIter >:: Item : AsChar + Copy ,
1700+ <T as InputIter >:: IterElem : Clone ,
1701+ T : InputTakeAtPosition ,
1702+ <T as InputTakeAtPosition >:: Item : AsChar ,
1703+ T : AsBytes ,
1704+ T : for < ' a > Compare < & ' a [ u8 ] > ,
1705+ {
1706+ let ( i, sign) = sign ( input. clone ( ) ) ?;
1707+ let ( mut double, count) = if i. input_len ( ) >= 3 {
1708+ if case_insensitive_cmp ( i. as_bytes ( ) , b"nan" ) {
1709+ ( f64:: NAN , 3 )
1710+ } else if i. input_len ( ) >= 8 && case_insensitive_cmp ( i. as_bytes ( ) , b"infinity" ) {
1711+ ( f64:: INFINITY , 8 )
1712+ } else if case_insensitive_cmp ( i. as_bytes ( ) , b"inf" ) {
1713+ ( f64:: INFINITY , 3 )
1714+ } else {
1715+ return Err ( Err :: Error ( E :: from_error_kind ( input, ErrorKind :: Float ) ) ) ;
1716+ }
1717+ } else {
1718+ return Err ( Err :: Error ( E :: from_error_kind ( input, ErrorKind :: Float ) ) ) ;
1719+ } ;
1720+
1721+ if !sign {
1722+ double = -double;
1723+ }
1724+
1725+ Ok ( ( i. slice ( count..) , double) )
1726+ }
1727+
1728+ /// Recognizes floating point number in text format and returns a f64.
1729+ ///
1730+ /// *Complete version*: Can parse until the end of input.
1731+ /// ```rust
1732+ /// # use nom::{Err, error::ErrorKind, Needed};
1733+ /// # use nom::Needed::Size;
1734+ /// use nom::number::complete::double;
1735+ ///
1736+ /// let parser = |s| {
1737+ /// double(s)
1738+ /// };
1739+ ///
1740+ /// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
1741+ /// assert_eq!(parser("123E-02"), Ok(("", 1.23)));
1742+ /// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
1743+ /// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
1744+ /// ```
1745+ pub fn double < T , E : ParseError < T > > ( input : T ) -> IResult < T , f64 , E >
1746+ where
1747+ T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
1748+ T : Clone + Offset ,
1749+ T : InputIter + InputLength + InputTake ,
1750+ <T as InputIter >:: Item : AsChar + Copy ,
1751+ <T as InputIter >:: IterElem : Clone ,
1752+ T : InputTakeAtPosition ,
1753+ <T as InputTakeAtPosition >:: Item : AsChar ,
1754+ T : AsBytes ,
1755+ T : for < ' a > Compare < & ' a [ u8 ] > ,
1756+ {
1757+ match double_finite :: < T , E > ( input. clone ( ) ) {
1758+ Ok ( ( i, double) ) => Ok ( ( i, double) ) ,
1759+ Err ( Err :: Incomplete ( e) ) => Err ( Err :: Incomplete ( e) ) ,
1760+ _ => double_nonfinite :: < T , E > ( input) ,
1761+ }
1762+ }
1763+
16061764#[ cfg( test) ]
16071765mod tests {
16081766 use super :: * ;
@@ -1618,6 +1776,23 @@ mod tests {
16181776 } ;
16191777 ) ;
16201778
1779+ // Need more complex logic, since NaN != NaN.
1780+ macro_rules! assert_float_eq {
1781+ ( $left: expr, $right: expr) => {
1782+ let left: $crate:: IResult <_, _, ( _, ErrorKind ) > = $left;
1783+ let right: $crate:: IResult <_, _, ( _, ErrorKind ) > = $right;
1784+ if let Ok ( ( _, float) ) = right {
1785+ if float. is_nan( ) {
1786+ assert!( left. unwrap( ) . 1 . is_nan( ) ) ;
1787+ } else {
1788+ assert_eq!( left, right) ;
1789+ }
1790+ } else {
1791+ assert_eq!( left, right) ;
1792+ }
1793+ } ;
1794+ }
1795+
16211796 #[ test]
16221797 fn i8_tests ( ) {
16231798 assert_parse ! ( i8 ( & [ 0x00 ] [ ..] ) , Ok ( ( & b"" [ ..] , 0 ) ) ) ;
@@ -1942,6 +2117,8 @@ mod tests {
19422117 "12.34" ,
19432118 "-1.234E-12" ,
19442119 "-1.234e-12" ,
2120+ "NaN" ,
2121+ "inf" ,
19452122 ] ;
19462123
19472124 for test in test_cases. drain ( ..) {
@@ -1951,13 +2128,15 @@ mod tests {
19512128 println ! ( "now parsing: {} -> {}" , test, expected32) ;
19522129
19532130 let larger = format ! ( "{}" , test) ;
1954- assert_parse ! ( recognize_float( & larger[ ..] ) , Ok ( ( "" , test) ) ) ;
2131+ if expected32. is_finite ( ) {
2132+ assert_parse ! ( recognize_float( & larger[ ..] ) , Ok ( ( "" , test) ) ) ;
2133+ }
19552134
1956- assert_parse ! ( float( larger. as_bytes( ) ) , Ok ( ( & b"" [ ..] , expected32) ) ) ;
1957- assert_parse ! ( float( & larger[ ..] ) , Ok ( ( "" , expected32) ) ) ;
2135+ assert_float_eq ! ( float( larger. as_bytes( ) ) , Ok ( ( & b"" [ ..] , expected32) ) ) ;
2136+ assert_float_eq ! ( float( & larger[ ..] ) , Ok ( ( "" , expected32) ) ) ;
19582137
1959- assert_parse ! ( double( larger. as_bytes( ) ) , Ok ( ( & b"" [ ..] , expected64) ) ) ;
1960- assert_parse ! ( double( & larger[ ..] ) , Ok ( ( "" , expected64) ) ) ;
2138+ assert_float_eq ! ( double( larger. as_bytes( ) ) , Ok ( ( & b"" [ ..] , expected64) ) ) ;
2139+ assert_float_eq ! ( double( & larger[ ..] ) , Ok ( ( "" , expected64) ) ) ;
19612140 }
19622141
19632142 let remaining_exponent = "-1.234E-" ;
@@ -2051,8 +2230,8 @@ mod tests {
20512230 }
20522231
20532232 fn parse_f64 ( i : & str ) -> IResult < & str , f64 , ( ) > {
2054- match recognize_float ( i) {
2055- Err ( e ) => Err ( e ) ,
2233+ match recognize_float :: < _ , ( ) > ( i) {
2234+ Err ( _ ) => Err ( Err :: Error ( ( ) ) ) ,
20562235 Ok ( ( i, s) ) => {
20572236 if s. is_empty ( ) {
20582237 return Err ( Err :: Error ( ( ) ) ) ;
0 commit comments