• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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