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 // This sample demontrates a parser for a comma separated list of identifiers
12 // This is a variation of stuff_vector.cpp.
13 // This is discussed in the "Phoenix" chapter in the Spirit User's Guide.
14 //
15 // [ JDG 1/12/2004 ]
16 //
17 ///////////////////////////////////////////////////////////////////////////////
18 #include <boost/spirit/include/classic_core.hpp>
19 #include <boost/spirit/include/classic_operators.hpp>
20 #include <boost/spirit/include/phoenix1_functions.hpp>
21 #include <boost/spirit/include/phoenix1_primitives.hpp>
22 #include <boost/spirit/include/phoenix1_casts.hpp>
23 #include <iostream>
24 #include <string>
25
26 ///////////////////////////////////////////////////////////////////////////////
27 using namespace std;
28 using namespace BOOST_SPIRIT_CLASSIC_NS;
29 using namespace phoenix;
30
31 ///////////////////////////////////////////////////////////////////////////////
32 //
33 // Our comma separated list parser
34 //
35 ///////////////////////////////////////////////////////////////////////////////
36 struct push_back_impl
37 {
38 template <typename Container, typename Item>
39 struct result
40 {
41 typedef void type;
42 };
43
44 template <typename Container, typename Item>
operator ()push_back_impl45 void operator()(Container& c, Item const& item) const
46 {
47 c.push_back(item);
48 }
49 };
50
51 function<push_back_impl> const push_back = push_back_impl();
52
53 bool
parse_identifiers(char const * str,vector<std::string> & v)54 parse_identifiers(char const* str, vector<std::string>& v)
55 {
56 return parse(str,
57
58 // Begin grammar
59 (
60 (+alpha_p)
61 [
62 push_back(var(v), construct_<std::string>(arg1, arg2))
63 ]
64 >>
65 *(',' >>
66 (+alpha_p)
67 [
68 push_back(var(v), construct_<std::string>(arg1, arg2))
69 ]
70 )
71 )
72 ,
73 // End grammar
74
75 space_p).full;
76 }
77
78 ////////////////////////////////////////////////////////////////////////////
79 //
80 // Main program
81 //
82 ////////////////////////////////////////////////////////////////////////////
83 int
main()84 main()
85 {
86 cout << "/////////////////////////////////////////////////////////\n\n";
87 cout << "\t\tA comma separated list parser for Spirit...\n\n";
88 cout << "/////////////////////////////////////////////////////////\n\n";
89
90 cout << "Give me a comma separated list of identifiers.\n";
91 cout << "An identifier is comprised of one or more alphabetic characters.\n";
92 cout << "The identifiers will be inserted in a vector of numbers\n";
93 cout << "Type [q or Q] to quit\n\n";
94
95 string str;
96 while (getline(cin, str))
97 {
98 if (str.empty() || str[0] == 'q' || str[0] == 'Q')
99 break;
100
101 vector<std::string> v;
102 if (parse_identifiers(str.c_str(), v))
103 {
104 cout << "-------------------------\n";
105 cout << "Parsing succeeded\n";
106 cout << str << " Parses OK: " << endl;
107
108 for (vector<std::string>::size_type i = 0; i < v.size(); ++i)
109 cout << i << ": " << v[i] << endl;
110
111 cout << "-------------------------\n";
112 }
113 else
114 {
115 cout << "-------------------------\n";
116 cout << "Parsing failed\n";
117 cout << "-------------------------\n";
118 }
119 }
120
121 cout << "Bye... :-) \n\n";
122 return 0;
123 }
124
125
126