1 /*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2001-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
6 Use, modification and distribution is subject to the Boost Software
7 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 http://www.boost.org/LICENSE_1_0.txt)
9 =============================================================================*/
10 #ifndef BOOST_SPIRIT_NUMERICS_HPP
11 #define BOOST_SPIRIT_NUMERICS_HPP
13 #include <boost/config.hpp>
14 #include <boost/spirit/core/parser.hpp>
15 #include <boost/spirit/core/composite/directives.hpp>
17 #include <boost/spirit/core/primitives/numerics_fwd.hpp>
18 #include <boost/spirit/core/primitives/impl/numerics.ipp>
20 namespace boost
{ namespace spirit
22 ///////////////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////////////
33 struct uint_parser
: parser
<uint_parser
<T
, Radix
, MinDigits
, MaxDigits
> >
35 typedef uint_parser
<T
, Radix
, MinDigits
, MaxDigits
> self_t
;
37 template <typename ScannerT
>
40 typedef typename match_result
<ScannerT
, T
>::type type
;
43 template <typename ScannerT
>
44 typename parser_result
<self_t
, ScannerT
>::type
45 parse(ScannerT
const& scan
) const
47 typedef impl::uint_parser_impl
<T
, Radix
, MinDigits
, MaxDigits
> impl_t
;
48 typedef typename parser_result
<impl_t
, ScannerT
>::type result_t
;
49 return impl::contiguous_parser_parse
<result_t
>(impl_t(), scan
, scan
);
53 ///////////////////////////////////////////////////////////////////////////
57 ///////////////////////////////////////////////////////////////////////////
64 struct int_parser
: parser
<int_parser
<T
, Radix
, MinDigits
, MaxDigits
> >
66 typedef int_parser
<T
, Radix
, MinDigits
, MaxDigits
> self_t
;
68 template <typename ScannerT
>
71 typedef typename match_result
<ScannerT
, T
>::type type
;
74 template <typename ScannerT
>
75 typename parser_result
<self_t
, ScannerT
>::type
76 parse(ScannerT
const& scan
) const
78 typedef impl::int_parser_impl
<T
, Radix
, MinDigits
, MaxDigits
> impl_t
;
79 typedef typename parser_result
<impl_t
, ScannerT
>::type result_t
;
80 return impl::contiguous_parser_parse
<result_t
>(impl_t(), scan
, scan
);
84 ///////////////////////////////////////////////////////////////////////////
86 // uint_parser/int_parser instantiations
88 ///////////////////////////////////////////////////////////////////////////
90 int_p
= int_parser
<int>();
92 uint_parser
<unsigned> const
93 uint_p
= uint_parser
<unsigned>();
95 uint_parser
<unsigned, 2> const
96 bin_p
= uint_parser
<unsigned, 2>();
98 uint_parser
<unsigned, 8> const
99 oct_p
= uint_parser
<unsigned, 8>();
101 uint_parser
<unsigned, 16> const
102 hex_p
= uint_parser
<unsigned, 16>();
104 ///////////////////////////////////////////////////////////////////////////
108 ///////////////////////////////////////////////////////////////////////////
111 // Utility to extract the prefix sign ('-' | '+')
112 template <typename ScannerT
>
113 bool extract_sign(ScannerT
const& scan
, std::size_t& count
);
116 struct sign_parser
: public parser
<sign_parser
>
118 typedef sign_parser self_t
;
120 template <typename ScannerT
>
123 typedef typename match_result
<ScannerT
, bool>::type type
;
128 template <typename ScannerT
>
129 typename parser_result
<self_t
, ScannerT
>::type
130 parse(ScannerT
const& scan
) const
135 typename
ScannerT::iterator_t
save(scan
.first
);
136 bool neg
= impl::extract_sign(scan
, length
);
138 return scan
.create_match(1, neg
, save
, scan
.first
);
140 return scan
.no_match();
144 sign_parser
const sign_p
= sign_parser();
146 ///////////////////////////////////////////////////////////////////////////
148 // default real number policies
150 ///////////////////////////////////////////////////////////////////////////
151 template <typename T
>
152 struct ureal_parser_policies
154 // trailing dot policy suggested suggested by Gustavo Guerra
155 BOOST_STATIC_CONSTANT(bool, allow_leading_dot
= true);
156 BOOST_STATIC_CONSTANT(bool, allow_trailing_dot
= true);
157 BOOST_STATIC_CONSTANT(bool, expect_dot
= false);
159 typedef uint_parser
<T
, 10, 1, -1> uint_parser_t
;
160 typedef int_parser
<T
, 10, 1, -1> int_parser_t
;
162 template <typename ScannerT
>
163 static typename match_result
<ScannerT
, nil_t
>::type
164 parse_sign(ScannerT
& scan
)
166 return scan
.no_match();
169 template <typename ScannerT
>
170 static typename parser_result
<uint_parser_t
, ScannerT
>::type
171 parse_n(ScannerT
& scan
)
173 return uint_parser_t().parse(scan
);
176 template <typename ScannerT
>
177 static typename parser_result
<chlit
<>, ScannerT
>::type
178 parse_dot(ScannerT
& scan
)
180 return ch_p('.').parse(scan
);
183 template <typename ScannerT
>
184 static typename parser_result
<uint_parser_t
, ScannerT
>::type
185 parse_frac_n(ScannerT
& scan
)
187 return uint_parser_t().parse(scan
);
190 template <typename ScannerT
>
191 static typename parser_result
<chlit
<>, ScannerT
>::type
192 parse_exp(ScannerT
& scan
)
194 return as_lower_d
['e'].parse(scan
);
197 template <typename ScannerT
>
198 static typename parser_result
<int_parser_t
, ScannerT
>::type
199 parse_exp_n(ScannerT
& scan
)
201 return int_parser_t().parse(scan
);
205 template <typename T
>
206 struct real_parser_policies
: public ureal_parser_policies
<T
>
208 template <typename ScannerT
>
209 static typename parser_result
<sign_parser
, ScannerT
>::type
210 parse_sign(ScannerT
& scan
)
212 return sign_p
.parse(scan
);
216 ///////////////////////////////////////////////////////////////////////////
220 ///////////////////////////////////////////////////////////////////////////
223 typename RealPoliciesT
226 : public parser
<real_parser
<T
, RealPoliciesT
> >
228 typedef real_parser
<T
, RealPoliciesT
> self_t
;
230 template <typename ScannerT
>
233 typedef typename match_result
<ScannerT
, T
>::type type
;
238 template <typename ScannerT
>
239 typename parser_result
<self_t
, ScannerT
>::type
240 parse(ScannerT
const& scan
) const
242 typedef typename parser_result
<self_t
, ScannerT
>::type result_t
;
243 return impl::real_parser_impl
<result_t
, T
, RealPoliciesT
>::parse(scan
);
247 ///////////////////////////////////////////////////////////////////////////
249 // real_parser instantiations
251 ///////////////////////////////////////////////////////////////////////////
252 real_parser
<double, ureal_parser_policies
<double> > const
253 ureal_p
= real_parser
<double, ureal_parser_policies
<double> >();
255 real_parser
<double, real_parser_policies
<double> > const
256 real_p
= real_parser
<double, real_parser_policies
<double> >();
258 ///////////////////////////////////////////////////////////////////////////
260 // strict reals (do not allow plain integers (no decimal point))
262 ///////////////////////////////////////////////////////////////////////////
263 template <typename T
>
264 struct strict_ureal_parser_policies
: public ureal_parser_policies
<T
>
266 BOOST_STATIC_CONSTANT(bool, expect_dot
= true);
269 template <typename T
>
270 struct strict_real_parser_policies
: public real_parser_policies
<T
>
272 BOOST_STATIC_CONSTANT(bool, expect_dot
= true);
275 real_parser
<double, strict_ureal_parser_policies
<double> > const
277 = real_parser
<double, strict_ureal_parser_policies
<double> >();
279 real_parser
<double, strict_real_parser_policies
<double> > const
281 = real_parser
<double, strict_real_parser_policies
<double> >();
283 }} // namespace boost::spirit