11//! Parsers recognizing numbers, complete input version
22
3+ use core:: { f32, f64} ;
34use crate :: branch:: alt;
45use crate :: bytes:: complete:: tag;
56use crate :: character:: complete:: { char, digit1, sign} ;
@@ -1426,6 +1427,8 @@ where
14261427 ) ( input)
14271428}
14281429
1430+ ///
1431+
14291432/// Recognizes a floating point number in text format and returns the integer, fraction and exponent parts of the input data
14301433///
14311434/// *Complete version*: Can parse until the end of input.
@@ -1517,24 +1520,35 @@ where
15171520 Ok ( ( i, ( sign, integer, fraction, exp) ) )
15181521}
15191522
1523+ /// Case-insensitive comparison of digits. Only works if `y` is only ASCII letters.
1524+ #[ inline]
1525+ fn case_insensitive_cmp ( x : & [ u8 ] , y : & [ u8 ] ) -> bool {
1526+ let d = ( x. iter ( ) . zip ( y. iter ( ) ) ) . fold ( 0 , |d, ( xi, yi) | d | xi ^ yi) ;
1527+ // This uses the trick that 'a' - 'A' == 0x20, and this is true
1528+ // for all characters, so as long as `yi` is a valid ASCII letter,
1529+ // `xi ^ yi` can only be 0 or 0x20.
1530+ d == 0 || d == 32
1531+ }
1532+
15201533/// Recognizes floating point number in text format and returns a f32.
15211534///
1522- /// *Complete version*: Can parse until the end of input.
1535+ /// *Complete version*: Can parse until the end of input. This only handles
1536+ /// finite (non-special floats).
15231537/// ```rust
15241538/// # use nom::{Err, error::ErrorKind, Needed};
15251539/// # use nom::Needed::Size;
1526- /// use nom::number::complete::float ;
1540+ /// use nom::number::complete::float_finite ;
15271541///
15281542/// let parser = |s| {
1529- /// float (s)
1543+ /// float_finite (s)
15301544/// };
15311545///
15321546/// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
15331547/// assert_eq!(parser("123E-02"), Ok(("", 1.23)));
15341548/// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
15351549/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
15361550/// ```
1537- pub fn float < T , E : ParseError < T > > ( input : T ) -> IResult < T , f32 , E >
1551+ pub fn float_finite < T , E : ParseError < T > > ( input : T ) -> IResult < T , f32 , E >
15381552where
15391553 T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
15401554 T : Clone + Offset ,
@@ -1560,6 +1574,42 @@ where
15601574 Ok ( ( i, float) )
15611575}
15621576
1577+ /// Recognizes floating point number in text format and returns a f32.
1578+ /// This only handles non-finite (special) values.
1579+ pub fn float_nonfinite < T , E : ParseError < T > > ( input : T ) -> IResult < T , f32 , E >
1580+ where
1581+ T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
1582+ T : Clone + Offset ,
1583+ T : InputIter + InputLength + InputTake ,
1584+ <T as InputIter >:: Item : AsChar + Copy ,
1585+ <T as InputIter >:: IterElem : Clone ,
1586+ T : InputTakeAtPosition ,
1587+ <T as InputTakeAtPosition >:: Item : AsChar ,
1588+ T : AsBytes ,
1589+ T : for < ' a > Compare < & ' a [ u8 ] > ,
1590+ {
1591+ let ( i, sign) = sign ( input. clone ( ) ) ?;
1592+ let ( mut float, count) = if i. input_len ( ) >= 3 {
1593+ if case_insensitive_cmp ( i. as_bytes ( ) , b"nan" ) {
1594+ ( f32:: NAN , 3 )
1595+ } else if i. input_len ( ) >= 8 && case_insensitive_cmp ( i. as_bytes ( ) , b"infinity" ) {
1596+ ( f32:: INFINITY , 8 )
1597+ } else if case_insensitive_cmp ( i. as_bytes ( ) , b"inf" ) {
1598+ ( f32:: INFINITY , 3 )
1599+ } else {
1600+ return Err ( Err :: Error ( E :: from_error_kind ( input, ErrorKind :: Float ) ) ) ;
1601+ }
1602+ } else {
1603+ return Err ( Err :: Error ( E :: from_error_kind ( input, ErrorKind :: Float ) ) ) ;
1604+ } ;
1605+
1606+ if !sign {
1607+ float = -float;
1608+ }
1609+
1610+ Ok ( ( i. slice ( count..) , float) )
1611+ }
1612+
15631613/// Recognizes floating point number in text format and returns a f32.
15641614///
15651615/// *Complete version*: Can parse until the end of input.
@@ -1577,7 +1627,44 @@ where
15771627/// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
15781628/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
15791629/// ```
1580- pub fn double < T , E : ParseError < T > > ( input : T ) -> IResult < T , f64 , E >
1630+ pub fn float < T , E : ParseError < T > > ( input : T ) -> IResult < T , f32 , E >
1631+ where
1632+ T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
1633+ T : Clone + Offset ,
1634+ T : InputIter + InputLength + InputTake ,
1635+ <T as InputIter >:: Item : AsChar + Copy ,
1636+ <T as InputIter >:: IterElem : Clone ,
1637+ T : InputTakeAtPosition ,
1638+ <T as InputTakeAtPosition >:: Item : AsChar ,
1639+ T : AsBytes ,
1640+ T : for < ' a > Compare < & ' a [ u8 ] > ,
1641+ {
1642+ if let Ok ( ( i, float) ) = float_finite :: < T , E > ( input. clone ( ) ) {
1643+ Ok ( ( i, float) )
1644+ } else {
1645+ float_nonfinite :: < T , E > ( input)
1646+ }
1647+ }
1648+
1649+ /// Recognizes floating point number in text format and returns a f64.
1650+ ///
1651+ /// *Complete version*: Can parse until the end of input. This only handles
1652+ /// finite (non-special floats).
1653+ /// ```rust
1654+ /// # use nom::{Err, error::ErrorKind, Needed};
1655+ /// # use nom::Needed::Size;
1656+ /// use nom::number::complete::double_finite;
1657+ ///
1658+ /// let parser = |s| {
1659+ /// double_finite(s)
1660+ /// };
1661+ ///
1662+ /// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
1663+ /// assert_eq!(parser("123E-02"), Ok(("", 1.23)));
1664+ /// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
1665+ /// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
1666+ /// ```
1667+ pub fn double_finite < T , E : ParseError < T > > ( input : T ) -> IResult < T , f64 , E >
15811668where
15821669 T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
15831670 T : Clone + Offset ,
@@ -1603,6 +1690,78 @@ where
16031690 Ok ( ( i, float) )
16041691}
16051692
1693+ /// Recognizes floating point number in text format and returns a f64.
1694+ /// This only handles non-finite (special) values.
1695+ pub fn double_nonfinite < T , E : ParseError < T > > ( input : T ) -> IResult < T , f64 , E >
1696+ where
1697+ T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
1698+ T : Clone + Offset ,
1699+ T : InputIter + InputLength + InputTake ,
1700+ <T as InputIter >:: Item : AsChar + Copy ,
1701+ <T as InputIter >:: IterElem : Clone ,
1702+ T : InputTakeAtPosition ,
1703+ <T as InputTakeAtPosition >:: Item : AsChar ,
1704+ T : AsBytes ,
1705+ T : for < ' a > Compare < & ' a [ u8 ] > ,
1706+ {
1707+ let ( i, sign) = sign ( input. clone ( ) ) ?;
1708+ let ( mut double, count) = if i. input_len ( ) >= 3 {
1709+ if case_insensitive_cmp ( i. as_bytes ( ) , b"nan" ) {
1710+ ( f64:: NAN , 3 )
1711+ } else if i. input_len ( ) >= 8 && case_insensitive_cmp ( i. as_bytes ( ) , b"infinity" ) {
1712+ ( f64:: INFINITY , 8 )
1713+ } else if case_insensitive_cmp ( i. as_bytes ( ) , b"inf" ) {
1714+ ( f64:: INFINITY , 3 )
1715+ } else {
1716+ return Err ( Err :: Error ( E :: from_error_kind ( input, ErrorKind :: Float ) ) ) ;
1717+ }
1718+ } else {
1719+ return Err ( Err :: Error ( E :: from_error_kind ( input, ErrorKind :: Float ) ) ) ;
1720+ } ;
1721+
1722+ if !sign {
1723+ double = -double;
1724+ }
1725+
1726+ Ok ( ( i. slice ( count..) , double) )
1727+ }
1728+
1729+ /// Recognizes floating point number in text format and returns a f64.
1730+ ///
1731+ /// *Complete version*: Can parse until the end of input.
1732+ /// ```rust
1733+ /// # use nom::{Err, error::ErrorKind, Needed};
1734+ /// # use nom::Needed::Size;
1735+ /// use nom::number::complete::double;
1736+ ///
1737+ /// let parser = |s| {
1738+ /// double(s)
1739+ /// };
1740+ ///
1741+ /// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
1742+ /// assert_eq!(parser("123E-02"), Ok(("", 1.23)));
1743+ /// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
1744+ /// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
1745+ /// ```
1746+ pub fn double < T , E : ParseError < T > > ( input : T ) -> IResult < T , f64 , E >
1747+ where
1748+ T : Slice < RangeFrom < usize > > + Slice < RangeTo < usize > > + Slice < Range < usize > > ,
1749+ T : Clone + Offset ,
1750+ T : InputIter + InputLength + InputTake ,
1751+ <T as InputIter >:: Item : AsChar + Copy ,
1752+ <T as InputIter >:: IterElem : Clone ,
1753+ T : InputTakeAtPosition ,
1754+ <T as InputTakeAtPosition >:: Item : AsChar ,
1755+ T : AsBytes ,
1756+ T : for < ' a > Compare < & ' a [ u8 ] > ,
1757+ {
1758+ match double_finite :: < T , E > ( input. clone ( ) ) {
1759+ Ok ( ( i, double) ) => Ok ( ( i, double) ) ,
1760+ Err ( Err :: Incomplete ( e) ) => Err ( Err :: Incomplete ( e) ) ,
1761+ _ => double_nonfinite :: < T , E > ( input) ,
1762+ }
1763+ }
1764+
16061765#[ cfg( test) ]
16071766mod tests {
16081767 use super :: * ;
@@ -1618,6 +1777,23 @@ mod tests {
16181777 } ;
16191778 ) ;
16201779
1780+ // Need more complex logic, since NaN != NaN.
1781+ macro_rules! assert_float_eq {
1782+ ( $left: expr, $right: expr) => {
1783+ let left: $crate:: IResult <_, _, ( _, ErrorKind ) > = $left;
1784+ let right: $crate:: IResult <_, _, ( _, ErrorKind ) > = $right;
1785+ if let Ok ( ( _, float) ) = right {
1786+ if float. is_nan( ) {
1787+ assert!( left. unwrap( ) . 1 . is_nan( ) ) ;
1788+ } else {
1789+ assert_eq!( left, right) ;
1790+ }
1791+ } else {
1792+ assert_eq!( left, right) ;
1793+ }
1794+ } ;
1795+ }
1796+
16211797 #[ test]
16221798 fn i8_tests ( ) {
16231799 assert_parse ! ( i8 ( & [ 0x00 ] [ ..] ) , Ok ( ( & b"" [ ..] , 0 ) ) ) ;
@@ -1942,6 +2118,8 @@ mod tests {
19422118 "12.34" ,
19432119 "-1.234E-12" ,
19442120 "-1.234e-12" ,
2121+ "NaN" ,
2122+ "inf" ,
19452123 ] ;
19462124
19472125 for test in test_cases. drain ( ..) {
@@ -1951,13 +2129,15 @@ mod tests {
19512129 println ! ( "now parsing: {} -> {}" , test, expected32) ;
19522130
19532131 let larger = format ! ( "{}" , test) ;
1954- assert_parse ! ( recognize_float( & larger[ ..] ) , Ok ( ( "" , test) ) ) ;
2132+ if expected32. is_finite ( ) {
2133+ assert_parse ! ( recognize_float( & larger[ ..] ) , Ok ( ( "" , test) ) ) ;
2134+ }
19552135
1956- assert_parse ! ( float( larger. as_bytes( ) ) , Ok ( ( & b"" [ ..] , expected32) ) ) ;
1957- assert_parse ! ( float( & larger[ ..] ) , Ok ( ( "" , expected32) ) ) ;
2136+ assert_float_eq ! ( float( larger. as_bytes( ) ) , Ok ( ( & b"" [ ..] , expected32) ) ) ;
2137+ assert_float_eq ! ( float( & larger[ ..] ) , Ok ( ( "" , expected32) ) ) ;
19582138
1959- assert_parse ! ( double( larger. as_bytes( ) ) , Ok ( ( & b"" [ ..] , expected64) ) ) ;
1960- assert_parse ! ( double( & larger[ ..] ) , Ok ( ( "" , expected64) ) ) ;
2139+ assert_float_eq ! ( double( larger. as_bytes( ) ) , Ok ( ( & b"" [ ..] , expected64) ) ) ;
2140+ assert_float_eq ! ( double( & larger[ ..] ) , Ok ( ( "" , expected64) ) ) ;
19612141 }
19622142
19632143 let remaining_exponent = "-1.234E-" ;
@@ -2051,8 +2231,8 @@ mod tests {
20512231 }
20522232
20532233 fn parse_f64 ( i : & str ) -> IResult < & str , f64 , ( ) > {
2054- match recognize_float ( i) {
2055- Err ( e ) => Err ( e ) ,
2234+ match recognize_float :: < _ , ( ) > ( i) {
2235+ Err ( _ ) => Err ( Err :: Error ( ( ) ) ) ,
20562236 Ok ( ( i, s) ) => {
20572237 if s. is_empty ( ) {
20582238 return Err ( Err :: Error ( ( ) ) ) ;
0 commit comments