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