• 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 //  This sample demontrates a parser for a comma separated list of numbers.
10 //
11 //  [ JDG May 10, 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 
20 #include <iostream>
21 #include <string>
22 #include <vector>
23 
24 namespace client
25 {
26     namespace x3 = boost::spirit::x3;
27     namespace ascii = boost::spirit::x3::ascii;
28 
29     ///////////////////////////////////////////////////////////////////////////
30     //  Our number list compiler
31     ///////////////////////////////////////////////////////////////////////////
32     template <typename Iterator>
parse_numbers(Iterator first,Iterator last,std::vector<double> & v)33     bool parse_numbers(Iterator first, Iterator last, std::vector<double>& v)
34     {
35         using x3::double_;
36         using x3::phrase_parse;
37         using x3::_attr;
38         using ascii::space;
39 
40         auto push_back = [&](auto& ctx){ v.push_back(_attr(ctx)); };
41 
42         bool r = phrase_parse(first, last,
43 
44             //  Begin grammar
45             (
46                 double_[push_back] >> *(',' >> double_[push_back])
47             )
48             ,
49             //  End grammar
50 
51             space);
52 
53         if (first != last) // fail if we did not get a full match
54             return false;
55         return r;
56     }
57 }
58 
59 ////////////////////////////////////////////////////////////////////////////
60 //  Main program
61 ////////////////////////////////////////////////////////////////////////////
62 int
main()63 main()
64 {
65     std::cout << "/////////////////////////////////////////////////////////\n\n";
66     std::cout << "\t\tA comma separated list parser for Spirit...\n\n";
67     std::cout << "/////////////////////////////////////////////////////////\n\n";
68 
69     std::cout << "Give me a comma separated list of numbers.\n";
70     std::cout << "The numbers will be inserted in a vector of numbers\n";
71     std::cout << "Type [q or Q] to quit\n\n";
72 
73     std::string str;
74     while (getline(std::cin, str))
75     {
76         if (str.empty() || str[0] == 'q' || str[0] == 'Q')
77             break;
78 
79         std::vector<double> v;
80         if (client::parse_numbers(str.begin(), str.end(), v))
81         {
82             std::cout << "-------------------------\n";
83             std::cout << "Parsing succeeded\n";
84             std::cout << str << " Parses OK: " << std::endl;
85 
86             for (std::vector<double>::size_type i = 0; i < v.size(); ++i)
87                 std::cout << i << ": " << v[i] << std::endl;
88 
89             std::cout << "\n-------------------------\n";
90         }
91         else
92         {
93             std::cout << "-------------------------\n";
94             std::cout << "Parsing failed\n";
95             std::cout << "-------------------------\n";
96         }
97     }
98 
99     std::cout << "Bye... :-) \n\n";
100     return 0;
101 }
102