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