• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2002-2015 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 //  [ JDG May 12, 2015 ]    spirit X3
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16 
17 #include <boost/config/warning_disable.hpp>
18 #include <boost/spirit/home/x3.hpp>
19 #include <iostream>
20 #include <string>
21 
22 namespace client
23 {
24     namespace x3 = boost::spirit::x3;
25     namespace ascii = boost::spirit::x3::ascii;
26 
27     using x3::double_;
28     using ascii::space;
29     using x3::_attr;
30 
31     ///////////////////////////////////////////////////////////////////////////
32     //  Our adder
33     ///////////////////////////////////////////////////////////////////////////
34 
35     template <typename Iterator>
adder(Iterator first,Iterator last,double & n)36     bool adder(Iterator first, Iterator last, double& n)
37     {
38         auto assign = [&](auto& ctx){ n = _attr(ctx); };
39         auto add = [&](auto& ctx){ n += _attr(ctx); };
40 
41         bool r = x3::phrase_parse(first, last,
42 
43             //  Begin grammar
44             (
45                 double_[assign] >> *(',' >> double_[add])
46             )
47             ,
48             //  End grammar
49 
50             space);
51 
52         if (first != last) // fail if we did not get a full match
53             return false;
54         return r;
55     }
56 }
57 
58 ////////////////////////////////////////////////////////////////////////////
59 //  Main program
60 ////////////////////////////////////////////////////////////////////////////
61 int
main()62 main()
63 {
64     std::cout << "/////////////////////////////////////////////////////////\n\n";
65     std::cout << "\t\tA parser for summing a list of numbers...\n\n";
66     std::cout << "/////////////////////////////////////////////////////////\n\n";
67 
68     std::cout << "Give me a comma separated list of numbers.\n";
69     std::cout << "The numbers are added using Phoenix.\n";
70     std::cout << "Type [q or Q] to quit\n\n";
71 
72     std::string str;
73     while (getline(std::cin, str))
74     {
75         if (str.empty() || str[0] == 'q' || str[0] == 'Q')
76             break;
77 
78         double n;
79         if (client::adder(str.begin(), str.end(), n))
80         {
81             std::cout << "-------------------------\n";
82             std::cout << "Parsing succeeded\n";
83             std::cout << str << " Parses OK: " << std::endl;
84 
85             std::cout << "sum = " << n;
86             std::cout << "\n-------------------------\n";
87         }
88         else
89         {
90             std::cout << "-------------------------\n";
91             std::cout << "Parsing failed\n";
92             std::cout << "-------------------------\n";
93         }
94     }
95 
96     std::cout << "Bye... :-) \n\n";
97     return 0;
98 }
99