1 | // Copyright (c) 2001-2011 Hartmut Kaiser |
2 | // |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
5 | |
6 | #include <boost/spirit/include/qi_operator.hpp> |
7 | #include <boost/spirit/include/qi_char.hpp> |
8 | #include <boost/spirit/include/qi_string.hpp> |
9 | #include <boost/spirit/include/qi_numeric.hpp> |
10 | #include <boost/spirit/include/qi_directive.hpp> |
11 | #include <boost/spirit/include/qi_action.hpp> |
12 | #include <boost/spirit/include/qi_auxiliary.hpp> |
13 | #include <boost/spirit/include/qi_nonterminal.hpp> |
14 | #include <boost/spirit/include/support_argument.hpp> |
15 | #include <boost/fusion/include/adapt_struct.hpp> |
16 | #include <boost/fusion/include/std_pair.hpp> |
17 | #include <boost/fusion/include/vector.hpp> |
18 | |
19 | #include <string> |
20 | #include <vector> |
21 | #include <set> |
22 | #include <map> |
23 | #include <iostream> |
24 | #include "test.hpp" |
25 | |
26 | using namespace spirit_test; |
27 | |
28 | inline bool compare(std::vector<char> const& v, std::string const& s) |
29 | { |
30 | return v.size() == s.size() && std::equal(first1: v.begin(), last1: v.end(), first2: s.begin()); |
31 | } |
32 | |
33 | struct A |
34 | { |
35 | int i1; |
36 | double d2; |
37 | }; |
38 | |
39 | BOOST_FUSION_ADAPT_STRUCT( |
40 | A, |
41 | (int, i1) |
42 | (double, d2) |
43 | ) |
44 | |
45 | int main() |
46 | { |
47 | using boost::spirit::qi::char_; |
48 | using boost::spirit::qi::omit; |
49 | |
50 | { |
51 | std::vector<std::vector<char> > v1; |
52 | BOOST_TEST(test_attr("abc,def,gh" , *~char_(',') % ',', v1) && |
53 | v1.size() == 3 && |
54 | compare(v1[0], "abc" ) && |
55 | compare(v1[1], "def" ) && |
56 | compare(v1[2], "gh" )); |
57 | |
58 | std::vector<std::string> v2; |
59 | BOOST_TEST(test_attr("abc,def,gh" , *~char_(',') % ',', v2) && |
60 | v2.size() == 3 && v2[0] == "abc" && v2[1] == "def" && v2[2] == "gh" ); |
61 | |
62 | BOOST_TEST(test("abc,def,gh" , *~char_(',') % ',')); |
63 | BOOST_TEST(test("abc,def,gh" , omit[*~char_(',')] % ',')); |
64 | } |
65 | |
66 | { |
67 | std::vector<char> v1; |
68 | BOOST_TEST(test_attr("a" , char_ >> -(char_ % ','), v1) && |
69 | compare(v1, "a" )); |
70 | v1.clear(); |
71 | BOOST_TEST(test_attr("ab,c" , char_ >> -(char_ % ','), v1) && |
72 | compare(v1, "abc" )); |
73 | v1.clear(); |
74 | BOOST_TEST(test_attr("a" , char_ >> -char_, v1) && |
75 | compare(v1, "a" )); |
76 | v1.clear(); |
77 | BOOST_TEST(test_attr("ab" , char_ >> -char_, v1) && |
78 | compare(v1, "ab" )); |
79 | |
80 | std::vector<boost::optional<char> > v2; |
81 | BOOST_TEST(test_attr("a" , char_ >> -char_, v2) && |
82 | v2.size() == 2 && |
83 | boost::get<char>(v2[0]) == 'a' && |
84 | !v2[1]); |
85 | v2.clear(); |
86 | BOOST_TEST(test_attr("ab" , char_ >> -char_, v2) && |
87 | v2.size() == 2 && |
88 | boost::get<char>(v2[0]) == 'a' && |
89 | boost::get<char>(v2[1]) == 'b'); |
90 | |
91 | std::string s; |
92 | BOOST_TEST(test_attr("a" , char_ >> -(char_ % ','), s) && |
93 | s == "a" ); |
94 | s.clear(); |
95 | BOOST_TEST(test_attr("ab,c" , char_ >> -(char_ % ','), s) && |
96 | s == "abc" ); |
97 | s.clear(); |
98 | BOOST_TEST(test_attr("ab" , char_ >> -char_, s) && |
99 | s == "ab" ); |
100 | s.clear(); |
101 | BOOST_TEST(test_attr("a" , char_ >> -char_, s) && |
102 | s == "a" ); |
103 | |
104 | BOOST_TEST(test("a" , char_ >> -(char_ % ','))); |
105 | BOOST_TEST(test("ab,c" , char_ >> -(char_ % ','))); |
106 | BOOST_TEST(test("a" , char_ >> -char_)); |
107 | BOOST_TEST(test("ab" , char_ >> -char_)); |
108 | } |
109 | |
110 | { |
111 | using boost::spirit::qi::eps; |
112 | |
113 | std::vector<char> v; |
114 | BOOST_TEST(test_attr("a" , char_ >> ((char_ % ',') | eps), v) && |
115 | compare(v, "a" )); |
116 | v.clear(); |
117 | BOOST_TEST(test_attr("ab,c" , char_ >> ((char_ % ',') | eps), v) && |
118 | compare(v, "abc" )); |
119 | |
120 | std::string s; |
121 | BOOST_TEST(test_attr("a" , char_ >> ((char_ % ',') | eps), s) && |
122 | s == "a" ); |
123 | s.clear(); |
124 | BOOST_TEST(test_attr("ab,c" , char_ >> ((char_ % ',') | eps), s) && |
125 | s == "abc" ); |
126 | |
127 | BOOST_TEST(test("a" , char_ >> ((char_ % ',') | eps))); |
128 | BOOST_TEST(test("ab,c" , char_ >> ((char_ % ',') | eps))); |
129 | } |
130 | |
131 | { |
132 | std::vector<char> v1; |
133 | BOOST_TEST(test_attr("abc1,abc2" , |
134 | *~char_(',') >> *(',' >> *~char_(',')), v1) && |
135 | compare(v1, "abc1abc2" )); |
136 | |
137 | std::vector<std::string> v2; |
138 | BOOST_TEST(test_attr("abc1,abc2" , |
139 | *~char_(',') >> *(',' >> *~char_(',')), v2) && |
140 | v2.size() == 2 && |
141 | v2[0] == "abc1" && |
142 | v2[1] == "abc2" ); |
143 | |
144 | std::string s; |
145 | BOOST_TEST(test_attr("abc1,abc2" , |
146 | *~char_(',') >> *(',' >> *~char_(',')), s) && |
147 | s == "abc1abc2" ); |
148 | } |
149 | |
150 | { |
151 | using boost::spirit::qi::alpha; |
152 | using boost::spirit::qi::digit; |
153 | |
154 | std::vector<char> v1; |
155 | BOOST_TEST(test_attr("ab1cd2" , *(alpha >> alpha | +digit), v1) && |
156 | compare(v1, "ab1cd2" )); |
157 | v1.clear(); |
158 | BOOST_TEST(test_attr("ab1cd2" , *(alpha >> alpha | digit), v1) && |
159 | compare(v1, "ab1cd2" )); |
160 | |
161 | std::string s1; |
162 | BOOST_TEST(test_attr("ab1cd2" , *(alpha >> alpha | +digit), s1) && |
163 | s1 == "ab1cd2" ); |
164 | s1.clear(); |
165 | BOOST_TEST(test_attr("ab1cd2" , *(alpha >> alpha | digit), s1) && |
166 | s1 == "ab1cd2" ); |
167 | } |
168 | |
169 | { |
170 | using boost::spirit::qi::rule; |
171 | using boost::spirit::qi::space; |
172 | using boost::spirit::qi::space_type; |
173 | using boost::spirit::qi::int_; |
174 | using boost::spirit::qi::double_; |
175 | |
176 | std::vector<A> v; |
177 | BOOST_TEST(test_attr("A 1 2.0" , 'A' >> *(int_ >> double_), v, space) && |
178 | v.size() == 1 && v[0].i1 == 1 && v[0].d2 == 2.0); |
179 | |
180 | v.clear(); |
181 | BOOST_TEST(test_attr("1 2.0" , *(int_ >> double_), v, space) && |
182 | v.size() == 1 && v[0].i1 == 1 && v[0].d2 == 2.0); |
183 | |
184 | v.clear(); |
185 | rule<char const*, std::vector<A>()> r = *(int_ >> ',' >> double_); |
186 | BOOST_TEST(test_attr("1,2.0" , r, v) && |
187 | v.size() == 1 && v[0].i1 == 1 && v[0].d2 == 2.0); |
188 | } |
189 | |
190 | { |
191 | using boost::spirit::qi::rule; |
192 | using boost::spirit::qi::int_; |
193 | using boost::spirit::qi::double_; |
194 | |
195 | rule<char const*, A()> r = int_ >> ',' >> double_; |
196 | rule<char const*, std::vector<A>()> r2 = 'A' >> *(r >> ',' >> r); |
197 | |
198 | std::vector<A> v; |
199 | BOOST_TEST(test_attr("A1,2.0,3,4.0" , r2, v) && |
200 | v.size() == 2 && v[0].i1 == 1.0 && v[0].d2 == 2.0 && |
201 | v[1].i1 == 3.0 && v[1].d2 == 4.0); |
202 | |
203 | v.clear(); |
204 | BOOST_TEST(test_attr("A1,2.0,3,4.0" , 'A' >> *(r >> ',' >> r), v) && |
205 | v.size() == 2 && v[0].i1 == 1.0 && v[0].d2 == 2.0 && |
206 | v[1].i1 == 3.0 && v[1].d2 == 4.0); |
207 | |
208 | v.clear(); |
209 | BOOST_TEST(test_attr("1,2.0,3,4.0" , *(r >> ',' >> r), v) && |
210 | v.size() == 2 && v[0].i1 == 1.0 && v[0].d2 == 2.0 && |
211 | v[1].i1 == 3.0 && v[1].d2 == 4.0); |
212 | } |
213 | |
214 | { |
215 | using boost::spirit::qi::rule; |
216 | using boost::spirit::qi::int_; |
217 | using boost::spirit::qi::double_; |
218 | using boost::fusion::at_c; |
219 | |
220 | typedef boost::fusion::vector<int, double> data_type; |
221 | |
222 | rule<char const*, data_type()> r = int_ >> ',' >> double_; |
223 | rule<char const*, std::vector<data_type>()> r2 = 'A' >> *(r >> ',' >> r); |
224 | |
225 | std::vector<data_type> v; |
226 | BOOST_TEST(test_attr("A1,2.0,3,4.0" , r2, v) && |
227 | v.size() == 2 && at_c<0>(v[0]) == 1 && at_c<1>(v[0]) == 2.0 && |
228 | at_c<0>(v[1]) == 3 && at_c<1>(v[1]) == 4.0); |
229 | |
230 | v.clear(); |
231 | BOOST_TEST(test_attr("A1,2.0,3,4.0" , 'A' >> *(r >> ',' >> r), v) && |
232 | v.size() == 2 && at_c<0>(v[0]) == 1 && at_c<1>(v[0]) == 2.0 && |
233 | at_c<0>(v[1]) == 3 && at_c<1>(v[1]) == 4.0); |
234 | |
235 | v.clear(); |
236 | BOOST_TEST(test_attr("1,2.0,3,4.0" , *(r >> ',' >> r), v) && |
237 | v.size() == 2 && at_c<0>(v[0]) == 1 && at_c<1>(v[0]) == 2.0 && |
238 | at_c<0>(v[1]) == 3 && at_c<1>(v[1]) == 4.0); |
239 | } |
240 | |
241 | // doesn't currently work |
242 | // { |
243 | // std::vector<std::vector<char> > v2; |
244 | // BOOST_TEST(test_attr("ab1cd123", *(alpha >> alpha | +digit), v2) && |
245 | // v2.size() == 4 && |
246 | // compare(v2[0], "ab") && |
247 | // compare(v2[1], "1") && |
248 | // compare(v2[2], "cd") && |
249 | // compare(v2[3], "123")); |
250 | // |
251 | // std::vector<std::string> v3; |
252 | // BOOST_TEST(test_attr("ab1cd123", *(alpha >> alpha | +digit), v3) && |
253 | // v3.size() == 4 && |
254 | // v3[0] == "ab" && |
255 | // v3[1] == "1" && |
256 | // v3[2] == "cd" && |
257 | // v3[3] == "123"); |
258 | // } |
259 | |
260 | return boost::report_errors(); |
261 | } |
262 | |
263 | |