1 /*=============================================================================
2 Copyright (c) 2001-2003 Hartmut Kaiser
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 // This sample shows the usage of the list_p utility parser
11 // 1. parsing a simple ',' delimited list w/o item formatting
12 // 2. parsing a CSV list (comma separated values - strings, integers or reals)
13 // 3. parsing a token list (token separated values - strings, integers or
14 // reals)
15 // with an action parser directly attached to the item part of the list_p
16 // generated parser
17
18 #include <string>
19 #include <iostream>
20 #include <cassert>
21 #include <vector>
22
23 #include <boost/spirit/include/classic_core.hpp>
24 #include <boost/spirit/include/classic_confix.hpp>
25 #include <boost/spirit/include/classic_lists.hpp>
26 #include <boost/spirit/include/classic_escape_char.hpp>
27
28 ///////////////////////////////////////////////////////////////////////////////
29 using namespace std;
30 using namespace BOOST_SPIRIT_CLASSIC_NS;
31
32 ///////////////////////////////////////////////////////////////////////////////
33 // actor, attached to the list_p parser
34 class list_actor
35 {
36 public:
list_actor(std::vector<std::string> & vec_)37 list_actor (std::vector<std::string> &vec_) : vec(vec_) {}
38
39 // The following operator() is called by the action parser generated by
40 // attaching this actor to a list_p generated list parser.
41
42 template <typename ActionIterT>
operator ()(ActionIterT const & first,ActionIterT const & last) const43 void operator() (ActionIterT const &first, ActionIterT const &last) const
44 {
45 vec.push_back(std::string(first, last-first));
46 }
47
48 private:
49 std::vector<std::string> &vec;
50 };
51
52 ///////////////////////////////////////////////////////////////////////////////
53 // main entry point
main()54 int main ()
55 {
56 // 1. parsing a simple ',' delimited list w/o item formatting
57 char const* plist_wo_item = "element1,element2,element3";
58 rule<> list_wo_item;
59 std::vector<std::string> vec_list;
60
61 list_wo_item =
62 list_p[push_back_a(vec_list)]
63 ;
64
65 parse_info<> result = parse (plist_wo_item, list_wo_item);
66
67 cout << "-----------------------------------------------------------------"
68 << endl;
69
70 if (result.hit)
71 {
72 cout
73 << "Parsing simple list" << endl
74 << "\t" << plist_wo_item << endl
75 << "Parsed successfully!" << endl << endl;
76
77 cout
78 << "Actor was called " << (int)vec_list.size()
79 << " times: " << endl;
80
81 cout
82 << "Results got from the list parser:" << endl;
83 for (std::vector<std::string>::iterator it = vec_list.begin();
84 it != vec_list.end(); ++it)
85 {
86 cout << *it << endl;
87 }
88 }
89 else
90 {
91 cout << "Failed to parse simple list!" << endl;
92 }
93
94 cout << endl;
95
96 // 2. parsing a CSV list (comma separated values - strings, integers or
97 // reals)
98 char const *plist_csv = "\"string\",\"string with an embedded \\\"\","
99 "12345,0.12345e4,,2";
100 rule<> list_csv, list_csv_item;
101 std::vector<std::string> vec_item;
102
103 vec_list.clear();
104
105 list_csv_item =
106 !(
107 confix_p('\"', *c_escape_ch_p, '\"')
108 | longest_d[real_p | int_p]
109 );
110
111 list_csv =
112 list_p(
113 list_csv_item[push_back_a(vec_item)],
114 ','
115 )[push_back_a(vec_list)]
116 ;
117
118 result = parse (plist_csv, list_csv);
119
120 cout << "-----------------------------------------------------------------"
121 << endl;
122 if (result.hit)
123 {
124 cout
125 << "Parsing CSV list (comma separated values) " << endl
126 << "\t" << plist_csv << endl
127 << "Parsed successfully!" << endl << endl;
128
129 if (result.full)
130 {
131 cout << "Matched " << (int)vec_list.size() <<
132 " list elements (full list): " << endl;
133 }
134 else
135 {
136 cout << "Matched " << (int)vec_list.size() <<
137 " list elements: " << endl;
138 }
139
140 cout << "The list parser matched:" << endl;
141 for (std::vector<std::string>::iterator itl = vec_list.begin();
142 itl != vec_list.end(); ++itl)
143 {
144 cout << *itl << endl;
145 }
146
147 cout << endl << "Item(s) got directly from the item parser:" << endl;
148 for (std::vector<std::string>::iterator it = vec_item.begin();
149 it != vec_item.end(); ++it)
150 {
151 cout << *it << endl;
152 }
153
154 }
155 else
156 {
157 cout << "Failed to parse CSV list!" << endl;
158 }
159
160 cout << endl;
161
162 // 3. parsing a token list (token separated values - strings, integers or
163 // reals) with an action parser directly attached to the item part of the
164 // list_p generated parser
165 char const *plist_csv_direct = "\"string\"<par>\"string with an embedded "
166 "\\\"\"<par>12345<par>0.12345e4";
167 rule<> list_csv_direct, list_csv_direct_item;
168
169 vec_list.clear();
170 vec_item.clear();
171
172 // Note: the list parser is here generated through the list_p.direct()
173 // generator function. This inhibits re-attachment of the item_actor_direct
174 // during parser construction (see: comment in utility/lists.hpp)
175 list_csv_direct_item =
176 confix_p('\"', *c_escape_ch_p, '\"')
177 | longest_d[real_p | int_p]
178 ;
179
180 list_csv_direct =
181 list_p.direct(
182 (*list_csv_direct_item)[list_actor(vec_item)],
183 "<par>"
184 )[list_actor(vec_list)]
185 ;
186
187 result = parse (plist_csv_direct, list_csv_direct);
188
189 cout << "-----------------------------------------------------------------"
190 << endl;
191 if (result.hit)
192 {
193 cout
194 << "Parsing CSV list (comma separated values)" << endl
195 << "The list parser was generated with 'list_p.direct()'" << endl
196 << "\t" << plist_csv_direct << endl
197 << "Parsed successfully!" << endl << endl;
198
199 if (result.full)
200 {
201 cout << "Matched " << vec_list.size() <<
202 " list elements (full list): " << endl;
203 }
204 else
205 {
206 cout << "Matched " << vec_list.size() <<
207 " list elements: " << endl;
208 }
209
210 cout << "The list parser matched:" << endl;
211 for (std::vector<std::string>::iterator itl = vec_list.begin();
212 itl != vec_list.end(); ++itl)
213 {
214 cout << *itl << endl;
215 }
216
217 cout << endl << "Items got directly from the item parser:" << endl;
218 for (std::vector<std::string>::iterator it = vec_item.begin();
219 it != vec_item.end(); ++it)
220 {
221 cout << *it << endl;
222 }
223
224 }
225 else
226 {
227 cout << "Failed to parse CSV list!" << endl;
228 }
229
230 cout << endl;
231
232 return 0;
233 }
234