Line data Source code
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
47 : 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
78 0 : 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 0 : 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 :
128 : sign_parser() {}
129 :
130 : template <typename ScannerT>
131 : typename parser_result<self_t, ScannerT>::type
132 : 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
166 : 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
173 : 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
180 : 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
187 : 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
194 : 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
201 : 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
212 : 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 :
238 : real_parser() {}
239 :
240 : template <typename ScannerT>
241 : typename parser_result<self_t, ScannerT>::type
242 : 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
|