Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/spirit/example/fundamental/thousand_separated.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 4.6 KB
Line 
1/*=============================================================================
2    Copyright (c) 2002-2003 Joel de Guzman
3    http://spirit.sourceforge.net/
4
5    Use, modification and distribution is subject to the Boost Software
6    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7    http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9///////////////////////////////////////////////////////////////////////////////
10//
11//  A parser for a real number parser that parses thousands separated numbers
12//  with at most two decimal places and no exponent. This is discussed in the
13//  "Numerics" chapter in the Spirit User's Guide.
14//
15//  [ JDG 12/16/2003 ]
16//
17///////////////////////////////////////////////////////////////////////////////
18#include <boost/spirit/core.hpp>
19#include <boost/spirit/actor/assign_actor.hpp>
20#include <iostream>
21#include <string>
22
23///////////////////////////////////////////////////////////////////////////////
24using namespace std;
25using namespace boost::spirit;
26
27template <typename T>
28struct ts_real_parser_policies : public ureal_parser_policies<T>
29{
30    //  These policies can be used to parse thousand separated
31    //  numbers with at most 2 decimal digits after the decimal
32    //  point. e.g. 123,456,789.01
33
34    typedef uint_parser<int, 10, 1, 2>  uint2_t;
35    typedef uint_parser<T, 10, 1, -1>   uint_parser_t;
36    typedef int_parser<int, 10, 1, -1>  int_parser_t;
37
38    //////////////////////////////////  2 decimal places Max
39    template <typename ScannerT>
40    static typename parser_result<uint2_t, ScannerT>::type
41    parse_frac_n(ScannerT& scan)
42    { return uint2_t().parse(scan); }
43
44    //////////////////////////////////  No exponent
45    template <typename ScannerT>
46    static typename parser_result<chlit<>, ScannerT>::type
47    parse_exp(ScannerT& scan)
48    { return scan.no_match(); }
49
50    //////////////////////////////////  No exponent
51    template <typename ScannerT>
52    static typename parser_result<int_parser_t, ScannerT>::type
53    parse_exp_n(ScannerT& scan)
54    { return scan.no_match(); }
55
56    //////////////////////////////////  Thousands separated numbers
57    template <typename ScannerT>
58    static typename parser_result<uint_parser_t, ScannerT>::type
59    parse_n(ScannerT& scan)
60    {
61        typedef typename parser_result<uint_parser_t, ScannerT>::type RT;
62        static uint_parser<unsigned, 10, 1, 3> uint3_p;
63        static uint_parser<unsigned, 10, 3, 3> uint3_3_p;
64        if (RT hit = uint3_p.parse(scan))
65        {
66            T n;
67            typedef typename ScannerT::iterator_t iterator_t;
68            iterator_t save = scan.first;
69            while (match<> next = (',' >> uint3_3_p[assign_a(n)]).parse(scan))
70            {
71                hit.value((hit.value() * 1000) + n);
72                scan.concat_match(hit, next);
73                save = scan.first;
74            }
75            scan.first = save;
76            return hit;
77
78            // Note: On erroneous input such as "123,45", the result should
79            // be a partial match "123". 'save' is used to makes sure that
80            // the scanner position is placed at the last *valid* parse
81            // position.
82        }
83        return scan.no_match();
84    }
85};
86
87real_parser<double, ts_real_parser_policies<double> > const
88    ts_real_p = real_parser<double, ts_real_parser_policies<double> >();
89
90////////////////////////////////////////////////////////////////////////////
91//
92//  Main program
93//
94////////////////////////////////////////////////////////////////////////////
95int
96main()
97{
98    cout << "/////////////////////////////////////////////////////////\n\n";
99    cout << "\t\tA real number parser that parses thousands separated\n";
100    cout << "\t\tnumbers with at most two decimal places and no exponent...\n\n";
101    cout << "/////////////////////////////////////////////////////////\n\n";
102
103    cout << "Give me a number.\n";
104    cout << "Type [q or Q] to quit\n\n";
105
106    string str;
107    double n;
108    while (getline(cin, str))
109    {
110        if (str.empty() || str[0] == 'q' || str[0] == 'Q')
111            break;
112
113        if (parse(str.c_str(), ts_real_p[assign_a(n)]).full)
114        {
115            cout << "-------------------------\n";
116            cout << "Parsing succeeded\n";
117            cout << str << " Parses OK: " << endl;
118            cout << "n=" << n << endl;
119            cout << "-------------------------\n";
120        }
121        else
122        {
123            cout << "-------------------------\n";
124            cout << "Parsing failed\n";
125            cout << "-------------------------\n";
126        }
127    }
128
129    cout << "Bye... :-) \n\n";
130    return 0;
131}
132
133
Note: See TracBrowser for help on using the repository browser.