1 | /*============================================================================= |
---|
2 | Copyright (c) 2001-2003 Joel de Guzman |
---|
3 | Copyright (c) 2001-2003 Hartmut Kaiser |
---|
4 | http://spirit.sourceforge.net/ |
---|
5 | |
---|
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 | #include <boost/spirit/core.hpp> |
---|
11 | #include <boost/spirit/actor/assign_actor.hpp> |
---|
12 | #include <iostream> |
---|
13 | #include <assert.h> |
---|
14 | |
---|
15 | using namespace std; |
---|
16 | using namespace boost::spirit; |
---|
17 | |
---|
18 | template <typename T> |
---|
19 | struct ts_real_parser_policies : public ureal_parser_policies<T> |
---|
20 | { |
---|
21 | // These policies can be used to parse thousand separated |
---|
22 | // numbers with at most 2 decimal digits after the decimal |
---|
23 | // point. e.g. 123,456,789.01 |
---|
24 | |
---|
25 | typedef uint_parser<int, 10, 1, 2> uint2_t; |
---|
26 | typedef uint_parser<T, 10, 1, -1> uint_parser_t; |
---|
27 | typedef int_parser<int, 10, 1, -1> int_parser_t; |
---|
28 | |
---|
29 | ////////////////////////////////// 2 decimal places Max |
---|
30 | template <typename ScannerT> |
---|
31 | static typename parser_result<uint2_t, ScannerT>::type |
---|
32 | parse_frac_n(ScannerT& scan) |
---|
33 | { return uint2_t().parse(scan); } |
---|
34 | |
---|
35 | ////////////////////////////////// No exponent |
---|
36 | template <typename ScannerT> |
---|
37 | static typename parser_result<chlit<>, ScannerT>::type |
---|
38 | parse_exp(ScannerT& scan) |
---|
39 | { return scan.no_match(); } |
---|
40 | |
---|
41 | ////////////////////////////////// No exponent |
---|
42 | template <typename ScannerT> |
---|
43 | static typename parser_result<int_parser_t, ScannerT>::type |
---|
44 | parse_exp_n(ScannerT& scan) |
---|
45 | { return scan.no_match(); } |
---|
46 | |
---|
47 | ////////////////////////////////// Thousands separated numbers |
---|
48 | template <typename ScannerT> |
---|
49 | static typename parser_result<uint_parser_t, ScannerT>::type |
---|
50 | parse_n(ScannerT& scan) |
---|
51 | { |
---|
52 | typedef typename parser_result<uint_parser_t, ScannerT>::type RT; |
---|
53 | static uint_parser<unsigned, 10, 1, 3> uint3_p; |
---|
54 | static uint_parser<unsigned, 10, 3, 3> uint3_3_p; |
---|
55 | |
---|
56 | if (RT hit = uint3_p.parse(scan)) |
---|
57 | { |
---|
58 | T n; |
---|
59 | typedef typename ScannerT::iterator_t iterator_t; |
---|
60 | iterator_t save = scan.first; |
---|
61 | while (match<> next = (',' >> uint3_3_p[assign_a(n)]).parse(scan)) |
---|
62 | { |
---|
63 | hit.value((hit.value() * 1000) + n); |
---|
64 | scan.concat_match(hit, next); |
---|
65 | save = scan.first; |
---|
66 | } |
---|
67 | scan.first = save; |
---|
68 | return hit; |
---|
69 | } |
---|
70 | return scan.no_match(); |
---|
71 | } |
---|
72 | }; |
---|
73 | |
---|
74 | real_parser<double, ts_real_parser_policies<double> > const |
---|
75 | ts_real_p = real_parser<double, ts_real_parser_policies<double> >(); |
---|
76 | |
---|
77 | template <typename T> |
---|
78 | struct no_trailing_dot : public real_parser_policies<T> |
---|
79 | { |
---|
80 | static const bool allow_trailing_dot = false; |
---|
81 | }; |
---|
82 | |
---|
83 | real_parser<double, no_trailing_dot<double> > const |
---|
84 | notrdot_real_p = real_parser<double, no_trailing_dot<double> >(); |
---|
85 | |
---|
86 | template <typename T> |
---|
87 | struct no_leading_dot : public real_parser_policies<T> |
---|
88 | { |
---|
89 | static const bool allow_leading_dot = false; |
---|
90 | }; |
---|
91 | |
---|
92 | real_parser<double, no_leading_dot<double> > const |
---|
93 | nolddot_real_p = real_parser<double, no_leading_dot<double> >(); |
---|
94 | |
---|
95 | /////////////////////////////////////////////////////////////////////////////// |
---|
96 | int |
---|
97 | main() |
---|
98 | { |
---|
99 | cout << "/////////////////////////////////////////////////////////\n\n"; |
---|
100 | cout << "\t\tNumeric tests...\n\n"; |
---|
101 | cout << "/////////////////////////////////////////////////////////\n\n"; |
---|
102 | |
---|
103 | // *** The following assumes 32 bit integers. Modify these constant |
---|
104 | // *** strings when appropriate. BEWARE PLATFORM DEPENDENT! |
---|
105 | |
---|
106 | char const* max_unsigned = "4294967295"; |
---|
107 | char const* unsigned_overflow = "4294967296"; |
---|
108 | char const* max_int = "2147483647"; |
---|
109 | char const* int_overflow = "2147483648"; |
---|
110 | char const* min_int = "-2147483648"; |
---|
111 | char const* int_underflow = "-2147483649"; |
---|
112 | char const* max_binary = "11111111111111111111111111111111"; |
---|
113 | char const* binary_overflow = "100000000000000000000000000000000"; |
---|
114 | char const* max_octal = "77777777777"; |
---|
115 | char const* octal_overflow = "100000000000"; |
---|
116 | char const* max_hex = "FFFFFFFF"; |
---|
117 | char const* hex_overflow = "100000000"; |
---|
118 | |
---|
119 | #ifdef BOOST_HAS_LONG_LONG |
---|
120 | |
---|
121 | char const* max_long_long = "9223372036854775807"; |
---|
122 | char const* long_long_overflow = "9223372036854775808"; |
---|
123 | char const* min_long_long = "-9223372036854775808"; |
---|
124 | char const* long_long_underflow = "-9223372036854775809"; |
---|
125 | |
---|
126 | #endif |
---|
127 | |
---|
128 | // BEGIN TESTS... |
---|
129 | |
---|
130 | unsigned u; |
---|
131 | |
---|
132 | // unsigned integer |
---|
133 | |
---|
134 | parse("123456", uint_p[assign_a(u)]); |
---|
135 | assert(u == 123456); |
---|
136 | |
---|
137 | parse(max_unsigned, uint_p[assign_a(u)]); |
---|
138 | assert(u == UINT_MAX); |
---|
139 | |
---|
140 | assert(!parse(unsigned_overflow, uint_p).full); |
---|
141 | |
---|
142 | // signed integer |
---|
143 | |
---|
144 | int i; |
---|
145 | |
---|
146 | parse("123456", int_p[assign_a(i)]); |
---|
147 | assert(i == 123456); |
---|
148 | |
---|
149 | parse("-123456", int_p[assign_a(i)]); |
---|
150 | assert(i == -123456); |
---|
151 | |
---|
152 | parse(max_int, int_p[assign_a(i)]); |
---|
153 | assert(i == INT_MAX); |
---|
154 | |
---|
155 | parse(min_int, int_p[assign_a(i)]); |
---|
156 | assert(i == INT_MIN); |
---|
157 | |
---|
158 | assert(!parse(int_overflow, int_p).full); |
---|
159 | assert(!parse(int_underflow, int_p).full); |
---|
160 | |
---|
161 | assert(!parse("-", int_p).hit); |
---|
162 | |
---|
163 | // binary |
---|
164 | |
---|
165 | parse("11111110", bin_p[assign_a(u)]); |
---|
166 | assert(u == 0xFE); |
---|
167 | |
---|
168 | parse(max_binary, bin_p[assign_a(u)]); |
---|
169 | assert(u == UINT_MAX); |
---|
170 | |
---|
171 | assert(!parse(binary_overflow, bin_p).full); |
---|
172 | |
---|
173 | // octal |
---|
174 | |
---|
175 | parse("12545674515", oct_p[assign_a(u)]); |
---|
176 | assert(u == 012545674515); |
---|
177 | |
---|
178 | parse(max_octal, oct_p[assign_a(u)]); |
---|
179 | assert(u == UINT_MAX); |
---|
180 | |
---|
181 | assert(!parse(octal_overflow, oct_p).full); |
---|
182 | |
---|
183 | // hex |
---|
184 | |
---|
185 | parse("95BC8DF", hex_p[assign_a(u)]); |
---|
186 | assert(u == 0x95BC8DF); |
---|
187 | |
---|
188 | parse("abcdef12", hex_p[assign_a(u)]); |
---|
189 | assert(u == 0xabcdef12); |
---|
190 | |
---|
191 | parse(max_hex, hex_p[assign_a(u)]); |
---|
192 | assert(u == UINT_MAX); |
---|
193 | |
---|
194 | assert(!parse(hex_overflow, hex_p).full); |
---|
195 | |
---|
196 | // limited fieldwidth |
---|
197 | |
---|
198 | uint_parser<unsigned, 10, 1, 3> uint3_p; |
---|
199 | parse("123456", uint3_p[assign_a(u)]); |
---|
200 | assert(u == 123); |
---|
201 | |
---|
202 | uint_parser<unsigned, 10, 1, 4> uint4_p; |
---|
203 | parse("123456", uint4_p[assign_a(u)]); |
---|
204 | assert(u == 1234); |
---|
205 | |
---|
206 | uint_parser<unsigned, 10, 3, 3> uint3_3_p; |
---|
207 | |
---|
208 | // thousand separated numbers |
---|
209 | |
---|
210 | #define r (uint3_p >> *(',' >> uint3_3_p)) |
---|
211 | |
---|
212 | assert(parse("1,234,567,890", r).full); // OK |
---|
213 | assert(parse("12,345,678,900", r).full); // OK |
---|
214 | assert(parse("123,456,789,000", r).full); // OK |
---|
215 | assert(!parse("1000,234,567,890", r).full); // Bad |
---|
216 | assert(!parse("1,234,56,890", r).full); // Bad |
---|
217 | assert(!parse("1,66", r).full); // Bad |
---|
218 | |
---|
219 | // long long |
---|
220 | |
---|
221 | #ifdef BOOST_HAS_LONG_LONG |
---|
222 | |
---|
223 | // Some compilers have long long, but don't define the |
---|
224 | // LONG_LONG_MIN and LONG_LONG_MAX macros in limits.h. This |
---|
225 | // assumes that long long is 64 bits. |
---|
226 | #if !defined(LONG_LONG_MIN) && !defined(LONG_LONG_MAX) \ |
---|
227 | && !defined(ULONG_LONG_MAX) |
---|
228 | #define ULONG_LONG_MAX 0xffffffffffffffffLLU |
---|
229 | #define LONG_LONG_MAX 0x7fffffffffffffffLL |
---|
230 | #define LONG_LONG_MIN (-LONG_LONG_MAX - 1) |
---|
231 | #endif |
---|
232 | |
---|
233 | ::boost::long_long_type ll; |
---|
234 | int_parser< ::boost::long_long_type> long_long_p; |
---|
235 | |
---|
236 | parse("1234567890123456789", long_long_p[assign_a(ll)]); |
---|
237 | assert(ll == 1234567890123456789LL); |
---|
238 | |
---|
239 | parse("-1234567890123456789", long_long_p[assign_a(ll)]); |
---|
240 | assert(ll == -1234567890123456789LL); |
---|
241 | |
---|
242 | parse(max_long_long, long_long_p[assign_a(ll)]); |
---|
243 | assert(ll == LONG_LONG_MAX); |
---|
244 | |
---|
245 | parse(min_long_long, long_long_p[assign_a(ll)]); |
---|
246 | assert(ll == LONG_LONG_MIN); |
---|
247 | |
---|
248 | #if defined(__GNUG__) && (__GNUG__ == 3) && (__GNUC_MINOR__ < 3) \ |
---|
249 | && !defined(__EDG__) |
---|
250 | // gcc 3.2.3 crashes on parse(long_long_overflow, long_long_p) |
---|
251 | // wrapping long_long_p into a rule avoids the crash |
---|
252 | rule<> gcc_3_2_3_long_long_r = long_long_p; |
---|
253 | assert(!parse(long_long_overflow, gcc_3_2_3_long_long_r).full); |
---|
254 | assert(!parse(long_long_underflow, gcc_3_2_3_long_long_r).full); |
---|
255 | #else |
---|
256 | assert(!parse(long_long_overflow, long_long_p).full); |
---|
257 | assert(!parse(long_long_underflow, long_long_p).full); |
---|
258 | #endif |
---|
259 | |
---|
260 | #endif |
---|
261 | |
---|
262 | // real numbers |
---|
263 | |
---|
264 | double d; |
---|
265 | |
---|
266 | assert(parse("1234", ureal_p[assign_a(d)]).full && d == 1234); // Good. |
---|
267 | assert(parse("1.2e3", ureal_p[assign_a(d)]).full && d == 1.2e3); // Good. |
---|
268 | assert(parse("1.2e-3", ureal_p[assign_a(d)]).full && d == 1.2e-3); // Good. |
---|
269 | assert(parse("1.e2", ureal_p[assign_a(d)]).full && d == 1.e2); // Good. |
---|
270 | assert(parse(".2e3", ureal_p[assign_a(d)]).full && d == .2e3); // Good. |
---|
271 | assert(parse("2e3", ureal_p[assign_a(d)]).full && d == 2e3); // Good. No fraction |
---|
272 | assert(!parse("e3", ureal_p).full); // Bad! No number |
---|
273 | assert(!parse("-1.2e3", ureal_p).full); // Bad! Negative number |
---|
274 | assert(!parse("+1.2e3", ureal_p).full); // Bad! Positive sign |
---|
275 | assert(!parse("1.2e", ureal_p).full); // Bad! No exponent |
---|
276 | assert(!parse("-.3", ureal_p).full); // Bad! Negative |
---|
277 | |
---|
278 | assert(parse("-1234", real_p[assign_a(d)]).full && d == -1234); // Good. |
---|
279 | assert(parse("-1.2e3", real_p[assign_a(d)]).full && d == -1.2e3); // Good. |
---|
280 | assert(parse("+1.2e3", real_p[assign_a(d)]).full && d == 1.2e3); // Good. |
---|
281 | assert(parse("-0.1", real_p[assign_a(d)]).full && d == -0.1); // Good. |
---|
282 | assert(parse("-1.2e-3", real_p[assign_a(d)]).full && d == -1.2e-3); // Good. |
---|
283 | assert(parse("-1.e2", real_p[assign_a(d)]).full && d == -1.e2); // Good. |
---|
284 | assert(parse("-.2e3", real_p[assign_a(d)]).full && d == -.2e3); // Good. |
---|
285 | assert(parse("-2e3", real_p[assign_a(d)]).full && d == -2e3); // Good. No fraction |
---|
286 | assert(!parse("-e3", real_p).full); // Bad! No number |
---|
287 | assert(!parse("-1.2e", real_p).full); // Bad! No exponent |
---|
288 | |
---|
289 | assert(!parse("1234", strict_ureal_p[assign_a(d)]).full); // Bad. Strict real |
---|
290 | assert(parse("1.2", strict_ureal_p[assign_a(d)]).full && d == 1.2); // Good. |
---|
291 | assert(!parse("-1234", strict_real_p[assign_a(d)]).full); // Bad. Strict real |
---|
292 | assert(parse("123.", strict_real_p[assign_a(d)]).full && d == 123); // Good. |
---|
293 | assert(parse("3.E6", strict_real_p[assign_a(d)]).full && d == 3e6); // Good. |
---|
294 | |
---|
295 | assert(!parse("1234.", notrdot_real_p[assign_a(d)]).full); // Bad trailing dot |
---|
296 | assert(!parse(".1234", nolddot_real_p[assign_a(d)]).full); // Bad leading dot |
---|
297 | |
---|
298 | // Special thousands separated numbers |
---|
299 | |
---|
300 | assert(parse("123,456,789.01", ts_real_p[assign_a(d)]).full && d == 123456789.01); // Good. |
---|
301 | assert(parse("12,345,678.90", ts_real_p[assign_a(d)]).full && d == 12345678.90); // Good. |
---|
302 | assert(parse("1,234,567.89", ts_real_p[assign_a(d)]).full && d == 1234567.89); // Good. |
---|
303 | assert(!parse("1234,567,890", ts_real_p).full); // Bad. |
---|
304 | assert(!parse("1,234,5678,9", ts_real_p).full); // Bad. |
---|
305 | assert(!parse("1,234,567.89e6", ts_real_p).full); // Bad. |
---|
306 | assert(!parse("1,66", ts_real_p).full); // Bad. |
---|
307 | |
---|
308 | // END TESTS. |
---|
309 | |
---|
310 | ///////////////////////////////////////////////////////////////// |
---|
311 | cout << "success!\n"; |
---|
312 | return 0; |
---|
313 | } |
---|