1 /*=============================================================================
2     Copyright (c) 2002-2010 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 ///////////////////////////////////////////////////////////////////////////////
8 //
9 //  A parser for summing a comma-separated list of numbers using phoenix.
10 //
11 //  [ JDG June 28, 2002 ]   spirit1
12 //  [ JDG March 24, 2007 ]  spirit2
13 //
14 ///////////////////////////////////////////////////////////////////////////////
15 
16 #include <boost/config/warning_disable.hpp>
17 //[tutorial_adder_includes
18 #include <boost/spirit/include/qi.hpp>
19 #include <boost/spirit/include/phoenix_core.hpp>
20 #include <boost/spirit/include/phoenix_operator.hpp>
21 #include <iostream>
22 #include <string>
23 //]
24 
25 namespace client
26 {
27     //[tutorial_adder_using
28     namespace qi = boost::spirit::qi;
29     namespace ascii = boost::spirit::ascii;
30     namespace phoenix = boost::phoenix;
31 
32     using qi::double_;
33     using qi::_1;
34     using ascii::space;
35     using phoenix::ref;
36     //]
37 
38     ///////////////////////////////////////////////////////////////////////////
39     //  Our adder
40     ///////////////////////////////////////////////////////////////////////////
41 
42     //[tutorial_adder
43     template <typename Iterator>
adder(Iterator first,Iterator last,double & n)44     bool adder(Iterator first, Iterator last, double& n)
45     {
46         bool r = qi::phrase_parse(first, last,
47 
48             //  Begin grammar
49             (
50                 double_[ref(n) = _1] >> *(',' >> double_[ref(n) += _1])
51             )
52             ,
53             //  End grammar
54 
55             space);
56 
57         if (first != last) // fail if we did not get a full match
58             return false;
59         return r;
60     }
61     //]
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////
65 //  Main program
66 ////////////////////////////////////////////////////////////////////////////
67 int
main()68 main()
69 {
70     std::cout << "/////////////////////////////////////////////////////////\n\n";
71     std::cout << "\t\tA parser for summing a list of numbers...\n\n";
72     std::cout << "/////////////////////////////////////////////////////////\n\n";
73 
74     std::cout << "Give me a comma separated list of numbers.\n";
75     std::cout << "The numbers are added using Phoenix.\n";
76     std::cout << "Type [q or Q] to quit\n\n";
77 
78     std::string str;
79     while (getline(std::cin, str))
80     {
81         if (str.empty() || str[0] == 'q' || str[0] == 'Q')
82             break;
83 
84         double n;
85         if (client::adder(str.begin(), str.end(), n))
86         {
87             std::cout << "-------------------------\n";
88             std::cout << "Parsing succeeded\n";
89             std::cout << str << " Parses OK: " << std::endl;
90 
91             std::cout << "sum = " << n;
92             std::cout << "\n-------------------------\n";
93         }
94         else
95         {
96             std::cout << "-------------------------\n";
97             std::cout << "Parsing failed\n";
98             std::cout << "-------------------------\n";
99         }
100     }
101 
102     std::cout << "Bye... :-) \n\n";
103     return 0;
104 }
105 
106 
107