]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/repository/test/qi/subrule.cpp
1 /*=============================================================================
2 Copyright (c) 2001-2010 Joel de Guzman
3 Copyright (c) 2009 Francois Barel
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #include <boost/detail/lightweight_test.hpp>
9 #include <boost/spirit/include/qi_operator.hpp>
10 #include <boost/spirit/include/qi_char.hpp>
11 #include <boost/spirit/include/qi_string.hpp>
12 #include <boost/spirit/include/qi_numeric.hpp>
13 #include <boost/spirit/include/qi_auxiliary.hpp>
14 #include <boost/spirit/include/qi_nonterminal.hpp>
15 #include <boost/spirit/include/qi_action.hpp>
16 #include <boost/spirit/include/phoenix_core.hpp>
17 #include <boost/spirit/include/phoenix_operator.hpp>
18 #include <boost/spirit/include/phoenix_object.hpp>
19 #include <boost/spirit/include/phoenix_bind.hpp>
20 #include <boost/fusion/include/std_pair.hpp>
22 #include <boost/spirit/repository/include/qi_subrule.hpp>
32 using spirit_test::test_attr
;
33 using spirit_test::test
;
35 using namespace boost::spirit::ascii
;
36 using namespace boost::spirit::qi::labels
;
37 using boost::spirit::qi::locals
;
38 using boost::spirit::qi::rule
;
39 using boost::spirit::qi::int_
;
40 using boost::spirit::qi::fail
;
41 using boost::spirit::qi::on_error
;
42 using boost::spirit::qi::debug
;
43 using boost::spirit::repository::qi::subrule
;
45 namespace phx
= boost::phoenix
;
54 rule
<char const*> start
;
68 // subrules with no rule
69 BOOST_TEST(test("abcabcacb", (
76 // check subrule group behaves as a parser
77 BOOST_TEST(test("xabcabcacb", 'x' >> (
91 BOOST_TEST(test("abcabcacb", start
));
93 // subrule -> rule call
95 entry
= (a
| b
) >> (start
| b
)
99 BOOST_TEST(test("aaaabababaaabbb", start
));
100 BOOST_TEST(test("aaaabababaaabba", start
, false));
104 entry
= (a
| b
) >> (entry
| b
)
108 BOOST_TEST(test("aaaabababaaabbb", start
));
109 BOOST_TEST(test("aaaabababaaabba", start
, false));
112 #if defined(BOOST_CLANG) && defined(__has_warning)
113 # pragma clang diagnostic push
114 # if __has_warning("-Wself-assign-overloaded")
115 # pragma clang diagnostic ignored "-Wself-assign-overloaded"
119 #if defined(BOOST_CLANG) && defined(__has_warning)
120 # pragma clang diagnostic pop
125 { // basic tests w/ skipper, subrules declared const
127 subrule
<0> const entry("entry");
128 subrule
<1> const a("a");
129 subrule
<2> const b("b");
130 subrule
<3> const c("c");
131 rule
<char const*, space_type
> start("start");
145 BOOST_TEST(test(" a b c a b c a c b ", start
, space
));
148 entry
= (a
| b
) >> (entry
| b
)
152 BOOST_TEST(test(" a a a a b a b a b a a a b b b ", start
, space
));
153 BOOST_TEST(test(" a a a a b a b a b a a a b b a ", start
, space
, false));
156 #if defined(BOOST_CLANG) && defined(__has_warning)
157 # pragma clang diagnostic push
158 # if __has_warning("-Wself-assign-overloaded")
159 # pragma clang diagnostic ignored "-Wself-assign-overloaded"
163 #if defined(BOOST_CLANG) && defined(__has_warning)
164 # pragma clang diagnostic pop
172 rule
<char const*, char()> a
;
173 subrule
<0, char()> entry
;
175 a
= (entry
= alpha
[_val
= _1
])[_val
= _1
];
176 BOOST_TEST(test("x", a
[phx::ref(ch
) = _1
]));
177 BOOST_TEST(ch
== 'x');
179 a
%= (entry
= alpha
[_val
= _1
]);
180 BOOST_TEST(test_attr("z", a
, ch
)); // attribute is given.
181 BOOST_TEST(ch
== 'z');
184 { // auto subrules tests
187 rule
<char const*, char()> a
;
188 subrule
<0, char()> entry
;
190 a
= (entry
%= alpha
)[_val
= _1
];
191 BOOST_TEST(test("x", a
[phx::ref(ch
) = _1
]));
192 BOOST_TEST(ch
== 'x');
194 a
%= (entry
%= alpha
);
195 BOOST_TEST(test_attr("z", a
, ch
)); // attribute is given.
196 BOOST_TEST(ch
== 'z');
199 { // auto subrules tests: allow stl containers as attributes to
200 // sequences (in cases where attributes of the elements
201 // are convertible to the value_type of the container or if
202 // the element itself is an stl container with value_type
203 // that is convertible to the value_type of the attribute).
206 rule
<char const*, std::string()> r
;
207 subrule
<0, std::string()> entry
;
209 r
%= (entry
%= char_
>> *(',' >> char_
));
210 BOOST_TEST(test("a,b,c,d,e,f", r
[phx::ref(s
) = _1
]));
211 BOOST_TEST(s
== "abcdef");
213 BOOST_TEST(test("abcdef", (
214 entry
%= char_
>> char_
>> char_
>> char_
>> char_
>> char_
215 )[phx::ref(s
) = _1
]));
216 BOOST_TEST(s
== "abcdef");
219 { // synth attribute value-init
222 subrule
<0, char()> sr
;
223 BOOST_TEST(test_attr("abcdef", +(sr
= alpha
[_val
+= _1
]), s
));
224 BOOST_TEST(s
== "abcdef");
227 { // auto subrules aliasing tests
230 rule
<char const*, char()> r
;
231 subrule
<0, char()> a
;
232 subrule
<1, char()> b
;
238 BOOST_TEST(test("x", r
[phx::ref(ch
) = _1
]));
239 BOOST_TEST(ch
== 'x');
241 BOOST_TEST(test_attr("z", r
, ch
)); // attribute is given.
242 BOOST_TEST(ch
== 'z');
245 { // context (w/arg) tests
249 // entry subrule with 1 arg
250 rule
<char const*, char(int)> a
;
251 subrule
<1, char(int)> sr1
;
253 sr1
= alpha
[_val
= _1
+ _r1
]
255 BOOST_TEST(test("x", a(phx::val(1))[phx::ref(ch
) = _1
]));
256 BOOST_TEST(ch
== 'x' + 1);
258 // other subrule with 1 arg
259 subrule
<0, char()> sr0
;
262 , sr1
= alpha
[_val
= _1
+ _r1
]
265 // allow scalars as subrule args too
266 rule
<char const*, char()> b
;
268 sr1
= alpha
[_val
= _1
+ _r1
]
270 BOOST_TEST(test_attr("b", b
, ch
));
271 BOOST_TEST(ch
== 'b' + 1);
273 // entry subrule with 2 args
274 subrule
<2, char(int, int)> sr2
;
275 BOOST_TEST(test_attr("a", (
276 sr2
= alpha
[_val
= _1
+ _r1
+ _r2
]
278 BOOST_TEST(ch
== 'a' + 1 + 2);
280 // multiple subrules + args
281 BOOST_TEST(test_attr("ba", (
282 sr2
= alpha
[_val
= _1
+ _r1
+ _r2
] >> sr1(3)[_val
-= _1
]
283 , sr1
= alpha
[_val
= _1
+ _r1
]
285 BOOST_TEST(ch
== ('b' + 1 + 2) - ('a' + 3));
288 { // context (w/ reference arg) tests
291 subrule
<0, void(char&)> sr
; // 1 arg (reference) - direct
292 BOOST_TEST(test("x", (sr
= alpha
[_r1
= _1
])(phx::ref(ch
))));
293 BOOST_TEST(ch
== 'x');
295 rule
<char const*, void(char&)> a
; // forwarded via a rule
296 a
= (sr
= alpha
[_r1
= _1
])(_r1
);
297 BOOST_TEST(test("y", a(phx::ref(ch
))));
298 BOOST_TEST(ch
== 'y');
301 { // context (w/locals) tests
304 subrule
<0, locals
<char> > a
; // 1 local
306 a
= alpha
[_a
= _1
] >> char_(_a
)
308 BOOST_TEST(test("aa", r
));
309 BOOST_TEST(!test("ax", r
));
312 { // context (w/args and locals) tests
314 rule
<char const*, void(int)> a
;
315 subrule
<0, void(int), locals
<char> > sr
; // 1 arg + 1 local
317 sr
= alpha
[_a
= _1
+ _r1
] >> char_(_a
)
319 BOOST_TEST(test("ab", a(phx::val(1))));
320 BOOST_TEST(test("xy", a(phx::val(1))));
321 BOOST_TEST(!test("ax", a(phx::val(1))));
324 { // void() has unused type (void == unused_type)
326 std::pair
<int, char> attr
;
327 subrule
<0, void()> sr
;
328 BOOST_TEST(test_attr("123ax", int_
>> char_
>> (sr
= char_
), attr
));
329 BOOST_TEST(attr
.first
== 123);
330 BOOST_TEST(attr
.second
== 'a');
333 { // test that injected attributes are ok
336 subrule
<0, char(int)> sr
;
339 sr
= char_(_r1
)[_val
= _1
]
343 { // show that sra = srb and sra %= srb works as expected
344 subrule
<0, int()> sra
;
345 subrule
<1, int()> srb
;
348 BOOST_TEST(test_attr("123", (sra
%= int_
), attr
));
349 BOOST_TEST(attr
== 123);
351 BOOST_TEST(test_attr("123", (srb
%= sra
, sra
%= int_
), attr
));
352 BOOST_TEST(attr
== 123);
354 BOOST_TEST(test_attr("123", (srb
= sra
, sra
%= int_
), attr
));
355 BOOST_TEST(attr
== 123);
358 { // std::string as container attribute with auto subrules
360 subrule
<0, std::string()> text
;
362 BOOST_TEST(test_attr("x", (
363 text
%= +(!char_(')') >> !char_('>') >> char_
)
365 BOOST_TEST(attr
== "x");
368 // { // error handling
370 // using namespace boost::spirit::ascii;
371 // using boost::phoenix::construct;
372 // using boost::phoenix::bind;
374 // rule<char const*> r;
375 // r = '(' > int_ > ',' > int_ > ')';
380 // << phx::val("Error! Expecting: ")
382 // << phx::val(", got: \"")
383 // << construct<std::string>(_3, _2)
388 // BOOST_TEST(test("(123,456)", r));
389 // BOOST_TEST(!test("(abc,def)", r));
390 // BOOST_TEST(!test("(123,456]", r));
391 // BOOST_TEST(!test("(123;456)", r));
392 // BOOST_TEST(!test("[123,456]", r));
395 return boost::report_errors();