1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2001-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
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
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>
17 #include <boost/spirit/home/classic/core/primitives/numerics_fwd.hpp>
18 #include <boost/spirit/home/classic/core/primitives/impl/numerics.ipp>
20 namespace boost { namespace spirit {
22 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
24 ///////////////////////////////////////////////////////////////////////////
28 ///////////////////////////////////////////////////////////////////////////
35 struct uint_parser : parser<uint_parser<T, Radix, MinDigits, MaxDigits> >
37 typedef uint_parser<T, Radix, MinDigits, MaxDigits> self_t;
39 template <typename ScannerT>
42 typedef typename match_result<ScannerT, T>::type type;
45 template <typename ScannerT>
46 typename parser_result<self_t, ScannerT>::type
47 parse(ScannerT const& scan) const
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);
55 ///////////////////////////////////////////////////////////////////////////
59 ///////////////////////////////////////////////////////////////////////////
66 struct int_parser : parser<int_parser<T, Radix, MinDigits, MaxDigits> >
68 typedef int_parser<T, Radix, MinDigits, MaxDigits> self_t;
70 template <typename ScannerT>
73 typedef typename match_result<ScannerT, T>::type type;
76 template <typename ScannerT>
77 typename parser_result<self_t, ScannerT>::type
78 parse(ScannerT const& scan) const
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);
86 ///////////////////////////////////////////////////////////////////////////
88 // uint_parser/int_parser instantiations
90 ///////////////////////////////////////////////////////////////////////////
92 int_p = int_parser<int>();
94 uint_parser<unsigned> const
95 uint_p = uint_parser<unsigned>();
97 uint_parser<unsigned, 2> const
98 bin_p = uint_parser<unsigned, 2>();
100 uint_parser<unsigned, 8> const
101 oct_p = uint_parser<unsigned, 8>();
103 uint_parser<unsigned, 16> const
104 hex_p = uint_parser<unsigned, 16>();
106 ///////////////////////////////////////////////////////////////////////////
110 ///////////////////////////////////////////////////////////////////////////
113 // Utility to extract the prefix sign ('-' | '+')
114 template <typename ScannerT>
115 bool extract_sign(ScannerT const& scan, std::size_t& count);
118 struct sign_parser : public parser<sign_parser>
120 typedef sign_parser self_t;
122 template <typename ScannerT>
125 typedef typename match_result<ScannerT, bool>::type type;
130 template <typename ScannerT>
131 typename parser_result<self_t, ScannerT>::type
132 parse(ScannerT const& scan) const
137 typename ScannerT::iterator_t save(scan.first);
138 bool neg = impl::extract_sign(scan, length);
140 return scan.create_match(1, neg, save, scan.first);
142 return scan.no_match();
146 sign_parser const sign_p = sign_parser();
148 ///////////////////////////////////////////////////////////////////////////
150 // default real number policies
152 ///////////////////////////////////////////////////////////////////////////
153 template <typename T>
154 struct ureal_parser_policies
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);
161 typedef uint_parser<T, 10, 1, -1> uint_parser_t;
162 typedef int_parser<T, 10, 1, -1> int_parser_t;
164 template <typename ScannerT>
165 static typename match_result<ScannerT, nil_t>::type
166 parse_sign(ScannerT& scan)
168 return scan.no_match();
171 template <typename ScannerT>
172 static typename parser_result<uint_parser_t, ScannerT>::type
173 parse_n(ScannerT& scan)
175 return uint_parser_t().parse(scan);
178 template <typename ScannerT>
179 static typename parser_result<chlit<>, ScannerT>::type
180 parse_dot(ScannerT& scan)
182 return ch_p('.').parse(scan);
185 template <typename ScannerT>
186 static typename parser_result<uint_parser_t, ScannerT>::type
187 parse_frac_n(ScannerT& scan)
189 return uint_parser_t().parse(scan);
192 template <typename ScannerT>
193 static typename parser_result<chlit<>, ScannerT>::type
194 parse_exp(ScannerT& scan)
196 return as_lower_d['e'].parse(scan);
199 template <typename ScannerT>
200 static typename parser_result<int_parser_t, ScannerT>::type
201 parse_exp_n(ScannerT& scan)
203 return int_parser_t().parse(scan);
207 template <typename T>
208 struct real_parser_policies : public ureal_parser_policies<T>
210 template <typename ScannerT>
211 static typename parser_result<sign_parser, ScannerT>::type
212 parse_sign(ScannerT& scan)
214 return sign_p.parse(scan);
218 ///////////////////////////////////////////////////////////////////////////
222 ///////////////////////////////////////////////////////////////////////////
225 typename RealPoliciesT
228 : public parser<real_parser<T, RealPoliciesT> >
230 typedef real_parser<T, RealPoliciesT> self_t;
232 template <typename ScannerT>
235 typedef typename match_result<ScannerT, T>::type type;
240 template <typename ScannerT>
241 typename parser_result<self_t, ScannerT>::type
242 parse(ScannerT const& scan) const
244 typedef typename parser_result<self_t, ScannerT>::type result_t;
245 return impl::real_parser_impl<result_t, T, RealPoliciesT>::parse(scan);
249 ///////////////////////////////////////////////////////////////////////////
251 // real_parser instantiations
253 ///////////////////////////////////////////////////////////////////////////
254 real_parser<double, ureal_parser_policies<double> > const
255 ureal_p = real_parser<double, ureal_parser_policies<double> >();
257 real_parser<double, real_parser_policies<double> > const
258 real_p = real_parser<double, real_parser_policies<double> >();
260 ///////////////////////////////////////////////////////////////////////////
262 // strict reals (do not allow plain integers (no decimal point))
264 ///////////////////////////////////////////////////////////////////////////
265 template <typename T>
266 struct strict_ureal_parser_policies : public ureal_parser_policies<T>
268 BOOST_STATIC_CONSTANT(bool, expect_dot = true);
271 template <typename T>
272 struct strict_real_parser_policies : public real_parser_policies<T>
274 BOOST_STATIC_CONSTANT(bool, expect_dot = true);
277 real_parser<double, strict_ureal_parser_policies<double> > const
279 = real_parser<double, strict_ureal_parser_policies<double> >();
281 real_parser<double, strict_real_parser_policies<double> > const
283 = real_parser<double, strict_real_parser_policies<double> >();
285 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
287 }} // namespace BOOST_SPIRIT_CLASSIC_NS