1 /*=============================================================================
2 Copyright (c) 2003 Hartmut Kaiser
3 http://spirit.sourceforge.net/
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 =============================================================================*/
12 #define BOOST_SPIRIT_SWITCH_CASE_LIMIT 6
13 #define BOOST_SPIRIT_SELECT_LIMIT 6
14 #define PHOENIX_LIMIT 6
16 //#define BOOST_SPIRIT_DEBUG
17 #include <boost/mpl/list.hpp>
18 #include <boost/mpl/for_each.hpp>
20 #include <boost/spirit/include/classic_primitives.hpp>
21 #include <boost/spirit/include/classic_numerics.hpp>
22 #include <boost/spirit/include/classic_actions.hpp>
23 #include <boost/spirit/include/classic_operators.hpp>
24 #include <boost/spirit/include/classic_rule.hpp>
25 #include <boost/spirit/include/classic_grammar.hpp>
26 #include <boost/spirit/include/classic_switch.hpp>
27 #include <boost/spirit/include/classic_select.hpp>
28 #include <boost/spirit/include/classic_closure.hpp>
30 #include <boost/core/lightweight_test.hpp>
32 using namespace BOOST_SPIRIT_CLASSIC_NS
;
34 namespace test_grammars
{
36 ///////////////////////////////////////////////////////////////////////////////
37 // Test the direct switch_p usage
38 struct switch_grammar_direct_single
39 : public grammar
<switch_grammar_direct_single
>
41 template <typename ScannerT
>
44 definition(switch_grammar_direct_single
const& /*self*/)
52 rule
<ScannerT
> const& start() const { return r
; }
56 struct switch_grammar_direct_default_single1
57 : public grammar
<switch_grammar_direct_default_single1
>
59 template <typename ScannerT
>
62 definition(switch_grammar_direct_default_single1
const& /*self*/)
65 default_p(str_p("default"))
70 rule
<ScannerT
> const& start() const { return r
; }
74 struct switch_grammar_direct_default_single2
75 : public grammar
<switch_grammar_direct_default_single2
>
77 template <typename ScannerT
>
80 definition(switch_grammar_direct_default_single2
const& /*self*/)
88 rule
<ScannerT
> const& start() const { return r
; }
92 ///////////////////////////////////////////////////////////////////////////////
93 // Test the switch_p usage given a parser as the switch condition
94 struct switch_grammar_parser_single
95 : public grammar
<switch_grammar_parser_single
>
97 template <typename ScannerT
>
100 definition(switch_grammar_parser_single
const& /*self*/)
102 r
= switch_p(anychar_p
) [
108 rule
<ScannerT
> const& start() const { return r
; }
112 struct switch_grammar_parser_default_single1
113 : public grammar
<switch_grammar_parser_default_single1
>
115 template <typename ScannerT
>
118 definition(switch_grammar_parser_default_single1
const& /*self*/)
120 r
= switch_p(anychar_p
) [
121 default_p(str_p("default"))
126 rule
<ScannerT
> const& start() const { return r
; }
130 struct switch_grammar_parser_default_single2
131 : public grammar
<switch_grammar_parser_default_single2
>
133 template <typename ScannerT
>
136 definition(switch_grammar_parser_default_single2
const& /*self*/)
138 r
= switch_p(anychar_p
) [
144 rule
<ScannerT
> const& start() const { return r
; }
148 ///////////////////////////////////////////////////////////////////////////////
149 // Test the switch_p usage given an actor as the switch condition
150 struct select_result
: public BOOST_SPIRIT_CLASSIC_NS::closure
<select_result
, int>
155 struct switch_grammar_actor_single
156 : public grammar
<switch_grammar_actor_single
>
158 template <typename ScannerT
>
161 definition(switch_grammar_actor_single
const& /*self*/)
164 r
= select_p('a')[r
.val
= arg1
] >>
170 rule
<ScannerT
, select_result::context_t
> r
;
171 rule
<ScannerT
, select_result::context_t
> const&
172 start() const { return r
; }
176 struct switch_grammar_actor_default_single1
177 : public grammar
<switch_grammar_actor_default_single1
>
179 template <typename ScannerT
>
182 definition(switch_grammar_actor_default_single1
const& /*self*/)
185 r
= select_p('d')[r
.val
= arg1
] >>
187 default_p(str_p("default"))
191 rule
<ScannerT
, select_result::context_t
> r
;
192 rule
<ScannerT
, select_result::context_t
> const&
193 start() const { return r
; }
197 struct switch_grammar_actor_default_single2
198 : public grammar
<switch_grammar_actor_default_single2
>
200 template <typename ScannerT
>
203 definition(switch_grammar_actor_default_single2
const& /*self*/)
206 r
= select_p('d')[r
.val
= arg1
] >>
212 rule
<ScannerT
, select_result::context_t
> r
;
213 rule
<ScannerT
, select_result::context_t
> const&
214 start() const { return r
; }
218 } // namespace test_grammars
220 ///////////////////////////////////////////////////////////////////////////////
223 // Tests for known (to the grammars) sequences
224 struct check_grammar_unknown
{
226 template <typename GrammarT
>
227 void operator()(GrammarT
)
231 BOOST_TEST(!parse("a1", g
).hit
);
232 BOOST_TEST(!parse("a,", g
).hit
);
233 BOOST_TEST(!parse("abcd", g
).hit
);
235 BOOST_TEST(!parse("a 1", g
, space_p
).hit
);
236 BOOST_TEST(!parse("a ,", g
, space_p
).hit
);
237 BOOST_TEST(!parse("a bcd", g
, space_p
).hit
);
239 BOOST_TEST(!parse("b1", g
).hit
);
240 BOOST_TEST(!parse("b,", g
).hit
);
241 BOOST_TEST(!parse("bbcd", g
).hit
);
243 BOOST_TEST(!parse("b 1", g
, space_p
).hit
);
244 BOOST_TEST(!parse("b ,", g
, space_p
).hit
);
245 BOOST_TEST(!parse("b bcd", g
, space_p
).hit
);
247 BOOST_TEST(!parse("c1", g
).hit
);
248 BOOST_TEST(!parse("c,", g
).hit
);
249 BOOST_TEST(!parse("cbcd", g
).hit
);
251 BOOST_TEST(!parse("c 1", g
, space_p
).hit
);
252 BOOST_TEST(!parse("c ,", g
, space_p
).hit
);
253 BOOST_TEST(!parse("c bcd", g
, space_p
).hit
);
257 // Tests for the default branches (with parsers) of the grammars
258 struct check_grammar_default
{
260 template <typename GrammarT
>
261 void operator()(GrammarT
)
265 BOOST_TEST(parse("ddefault", g
).full
);
266 BOOST_TEST(parse("d default", g
, space_p
).full
);
270 // Tests for the default branches (without parsers) of the grammars
271 struct check_grammar_default_plain
{
273 template <typename GrammarT
>
274 void operator()(GrammarT
)
278 BOOST_TEST(parse("d", g
).full
);
279 BOOST_TEST(parse(" d", g
, space_p
).full
); // JDG 10-18-2005 removed trailing ' ' to
280 // avoid post skip problems
284 // Tests grammars with a single case_p branch
285 struct check_grammar_single
{
287 template <typename GrammarT
>
288 void operator()(GrammarT
)
292 BOOST_TEST(parse("a1", g
).full
);
293 BOOST_TEST(!parse("a,", g
).hit
);
294 BOOST_TEST(!parse("abcd", g
).hit
);
296 BOOST_TEST(parse("a 1", g
, space_p
).full
);
297 BOOST_TEST(!parse("a ,", g
, space_p
).hit
);
298 BOOST_TEST(!parse("a bcd", g
, space_p
).hit
);
300 BOOST_TEST(!parse("b1", g
).hit
);
301 BOOST_TEST(!parse("b,", g
).hit
);
302 BOOST_TEST(!parse("bbcd", g
).hit
);
304 BOOST_TEST(!parse("b 1", g
, space_p
).hit
);
305 BOOST_TEST(!parse("b ,", g
, space_p
).hit
);
306 BOOST_TEST(!parse("b bcd", g
, space_p
).hit
);
308 BOOST_TEST(!parse("c1", g
).hit
);
309 BOOST_TEST(!parse("c,", g
).hit
);
310 BOOST_TEST(!parse("cbcd", g
).hit
);
312 BOOST_TEST(!parse("c 1", g
, space_p
).hit
);
313 BOOST_TEST(!parse("c ,", g
, space_p
).hit
);
314 BOOST_TEST(!parse("c bcd", g
, space_p
).hit
);
323 // Test switch_p with a single case_p branch
324 typedef boost::mpl::list
<
325 test_grammars::switch_grammar_direct_single
,
326 test_grammars::switch_grammar_parser_single
,
327 test_grammars::switch_grammar_actor_single
330 boost::mpl::for_each
<single_list_t
>(tests::check_grammar_single());
332 typedef boost::mpl::list
<
333 test_grammars::switch_grammar_direct_default_single1
,
334 test_grammars::switch_grammar_parser_default_single1
,
335 test_grammars::switch_grammar_actor_default_single1
338 boost::mpl::for_each
<default_single_t
>(tests::check_grammar_default());
339 boost::mpl::for_each
<default_single_t
>(tests::check_grammar_unknown());
341 typedef boost::mpl::list
<
342 test_grammars::switch_grammar_direct_default_single2
,
343 test_grammars::switch_grammar_parser_default_single2
,
344 test_grammars::switch_grammar_actor_default_single2
345 > default_plain_single_t
;
347 boost::mpl::for_each
<default_plain_single_t
>(
348 tests::check_grammar_default_plain());
350 return boost::report_errors();