1 /*============================================================================= 2 Copyright (c) 1998-2003 Joel de Guzman 3 Copyright (c) 2001-2003 Hartmut Kaiser 4 http://spirit.sourceforge.net/ 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 #ifndef BOOST_SPIRIT_NUMERICS_HPP 10 #define BOOST_SPIRIT_NUMERICS_HPP 11 12 #include <boost/config.hpp> 13 #include <boost/spirit/home/classic/namespace.hpp> 14 #include <boost/spirit/home/classic/core/parser.hpp> 15 #include <boost/spirit/home/classic/core/composite/directives.hpp> 16 17 #include <boost/spirit/home/classic/core/primitives/numerics_fwd.hpp> 18 #include <boost/spirit/home/classic/core/primitives/impl/numerics.ipp> 19 20 namespace boost { namespace spirit { 21 22 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 23 24 /////////////////////////////////////////////////////////////////////////// 25 // 26 // uint_parser class 27 // 28 /////////////////////////////////////////////////////////////////////////// 29 template < 30 typename T, 31 int Radix, 32 unsigned MinDigits, 33 int MaxDigits 34 > 35 struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> > 36 { 37 typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t; 38 39 template <typename ScannerT> 40 struct result 41 { 42 typedef typename match_result<ScannerT, T>::type type; 43 }; 44 45 template <typename ScannerT> 46 typename parser_result<self_t, ScannerT>::type parseboost::spirit::uint_parser47 parse(ScannerT const& scan) const 48 { 49 typedef impl::uint_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t; 50 typedef typename parser_result<impl_t, ScannerT>::type result_t; 51 return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan); 52 } 53 }; 54 55 /////////////////////////////////////////////////////////////////////////// 56 // 57 // int_parser class 58 // 59 /////////////////////////////////////////////////////////////////////////// 60 template < 61 typename T, 62 int Radix, 63 unsigned MinDigits, 64 int MaxDigits 65 > 66 struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> > 67 { 68 typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t; 69 70 template <typename ScannerT> 71 struct result 72 { 73 typedef typename match_result<ScannerT, T>::type type; 74 }; 75 76 template <typename ScannerT> 77 typename parser_result<self_t, ScannerT>::type parseboost::spirit::int_parser78 parse(ScannerT const& scan) const 79 { 80 typedef impl::int_parser_impl<T, Radix, MinDigits, MaxDigits> impl_t; 81 typedef typename parser_result<impl_t, ScannerT>::type result_t; 82 return impl::contiguous_parser_parse<result_t>(impl_t(), scan, scan); 83 } 84 }; 85 86 /////////////////////////////////////////////////////////////////////////// 87 // 88 // uint_parser/int_parser instantiations 89 // 90 /////////////////////////////////////////////////////////////////////////// 91 int_parser<int> const 92 int_p = int_parser<int>(); 93 94 uint_parser<unsigned> const 95 uint_p = uint_parser<unsigned>(); 96 97 uint_parser<unsigned, 2> const 98 bin_p = uint_parser<unsigned, 2>(); 99 100 uint_parser<unsigned, 8> const 101 oct_p = uint_parser<unsigned, 8>(); 102 103 uint_parser<unsigned, 16> const 104 hex_p = uint_parser<unsigned, 16>(); 105 106 /////////////////////////////////////////////////////////////////////////// 107 // 108 // sign_parser class 109 // 110 /////////////////////////////////////////////////////////////////////////// 111 namespace impl 112 { 113 // Utility to extract the prefix sign ('-' | '+') 114 template <typename ScannerT> 115 bool extract_sign(ScannerT const& scan, std::size_t& count); 116 } 117 118 struct sign_parser : public parser<sign_parser> 119 { 120 typedef sign_parser self_t; 121 122 template <typename ScannerT> 123 struct result 124 { 125 typedef typename match_result<ScannerT, bool>::type type; 126 }; 127 sign_parserboost::spirit::sign_parser128 sign_parser() {} 129 130 template <typename ScannerT> 131 typename parser_result<self_t, ScannerT>::type parseboost::spirit::sign_parser132 parse(ScannerT const& scan) const 133 { 134 if (!scan.at_end()) 135 { 136 std::size_t length; 137 typename ScannerT::iterator_t save(scan.first); 138 bool neg = impl::extract_sign(scan, length); 139 if (length) 140 return scan.create_match(1, neg, save, scan.first); 141 } 142 return scan.no_match(); 143 } 144 }; 145 146 sign_parser const sign_p = sign_parser(); 147 148 /////////////////////////////////////////////////////////////////////////// 149 // 150 // default real number policies 151 // 152 /////////////////////////////////////////////////////////////////////////// 153 template <typename T> 154 struct ureal_parser_policies 155 { 156 // trailing dot policy suggested suggested by Gustavo Guerra 157 BOOST_STATIC_CONSTANT(bool, allow_leading_dot = true); 158 BOOST_STATIC_CONSTANT(bool, allow_trailing_dot = true); 159 BOOST_STATIC_CONSTANT(bool, expect_dot = false); 160 161 typedef uint_parser<T, 10, 1, -1> uint_parser_t; 162 typedef int_parser<T, 10, 1, -1> int_parser_t; 163 164 template <typename ScannerT> 165 static typename match_result<ScannerT, nil_t>::type parse_signboost::spirit::ureal_parser_policies166 parse_sign(ScannerT& scan) 167 { 168 return scan.no_match(); 169 } 170 171 template <typename ScannerT> 172 static typename parser_result<uint_parser_t, ScannerT>::type parse_nboost::spirit::ureal_parser_policies173 parse_n(ScannerT& scan) 174 { 175 return uint_parser_t().parse(scan); 176 } 177 178 template <typename ScannerT> 179 static typename parser_result<chlit<>, ScannerT>::type parse_dotboost::spirit::ureal_parser_policies180 parse_dot(ScannerT& scan) 181 { 182 return ch_p('.').parse(scan); 183 } 184 185 template <typename ScannerT> 186 static typename parser_result<uint_parser_t, ScannerT>::type parse_frac_nboost::spirit::ureal_parser_policies187 parse_frac_n(ScannerT& scan) 188 { 189 return uint_parser_t().parse(scan); 190 } 191 192 template <typename ScannerT> 193 static typename parser_result<chlit<>, ScannerT>::type parse_expboost::spirit::ureal_parser_policies194 parse_exp(ScannerT& scan) 195 { 196 return as_lower_d['e'].parse(scan); 197 } 198 199 template <typename ScannerT> 200 static typename parser_result<int_parser_t, ScannerT>::type parse_exp_nboost::spirit::ureal_parser_policies201 parse_exp_n(ScannerT& scan) 202 { 203 return int_parser_t().parse(scan); 204 } 205 }; 206 207 template <typename T> 208 struct real_parser_policies : public ureal_parser_policies<T> 209 { 210 template <typename ScannerT> 211 static typename parser_result<sign_parser, ScannerT>::type parse_signboost::spirit::real_parser_policies212 parse_sign(ScannerT& scan) 213 { 214 return sign_p.parse(scan); 215 } 216 }; 217 218 /////////////////////////////////////////////////////////////////////////// 219 // 220 // real_parser class 221 // 222 /////////////////////////////////////////////////////////////////////////// 223 template < 224 typename T, 225 typename RealPoliciesT 226 > 227 struct real_parser 228 : public parser<real_parser<T, RealPoliciesT> > 229 { 230 typedef real_parser<T, RealPoliciesT> self_t; 231 232 template <typename ScannerT> 233 struct result 234 { 235 typedef typename match_result<ScannerT, T>::type type; 236 }; 237 real_parserboost::spirit::real_parser238 real_parser() {} 239 240 template <typename ScannerT> 241 typename parser_result<self_t, ScannerT>::type parseboost::spirit::real_parser242 parse(ScannerT const& scan) const 243 { 244 typedef typename parser_result<self_t, ScannerT>::type result_t; 245 return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan); 246 } 247 }; 248 249 /////////////////////////////////////////////////////////////////////////// 250 // 251 // real_parser instantiations 252 // 253 /////////////////////////////////////////////////////////////////////////// 254 real_parser<double, ureal_parser_policies<double> > const 255 ureal_p = real_parser<double, ureal_parser_policies<double> >(); 256 257 real_parser<double, real_parser_policies<double> > const 258 real_p = real_parser<double, real_parser_policies<double> >(); 259 260 /////////////////////////////////////////////////////////////////////////// 261 // 262 // strict reals (do not allow plain integers (no decimal point)) 263 // 264 /////////////////////////////////////////////////////////////////////////// 265 template <typename T> 266 struct strict_ureal_parser_policies : public ureal_parser_policies<T> 267 { 268 BOOST_STATIC_CONSTANT(bool, expect_dot = true); 269 }; 270 271 template <typename T> 272 struct strict_real_parser_policies : public real_parser_policies<T> 273 { 274 BOOST_STATIC_CONSTANT(bool, expect_dot = true); 275 }; 276 277 real_parser<double, strict_ureal_parser_policies<double> > const 278 strict_ureal_p 279 = real_parser<double, strict_ureal_parser_policies<double> >(); 280 281 real_parser<double, strict_real_parser_policies<double> > const 282 strict_real_p 283 = real_parser<double, strict_real_parser_policies<double> >(); 284 285 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 286 287 }} // namespace BOOST_SPIRIT_CLASSIC_NS 288 289 #endif 290