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 =============================================================================*/
10 #include <boost/detail/lightweight_test.hpp>
13 #define BOOST_SPIRIT_SWITCH_CASE_LIMIT 6
14 #define BOOST_SPIRIT_SELECT_LIMIT 6
15 #define PHOENIX_LIMIT 6
17 //#define BOOST_SPIRIT_DEBUG
18 #include <boost/mpl/list.hpp>
19 #include <boost/mpl/for_each.hpp>
21 #include <boost/spirit/include/classic_primitives.hpp>
22 #include <boost/spirit/include/classic_numerics.hpp>
23 #include <boost/spirit/include/classic_actions.hpp>
24 #include <boost/spirit/include/classic_operators.hpp>
25 #include <boost/spirit/include/classic_rule.hpp>
26 #include <boost/spirit/include/classic_grammar.hpp>
27 #include <boost/spirit/include/classic_switch.hpp>
28 #include <boost/spirit/include/classic_select.hpp>
29 #include <boost/spirit/include/classic_closure.hpp>
31 using namespace BOOST_SPIRIT_CLASSIC_NS
;
33 namespace test_grammars
{
35 ///////////////////////////////////////////////////////////////////////////////
36 // Test the direct switch_p usage (with default_p)
37 struct switch_grammar_direct_default4
38 : public grammar
<switch_grammar_direct_default4
>
40 template <typename ScannerT
>
43 definition(switch_grammar_direct_default4
const& /*self*/)
47 case_p
<'b'>(ch_p(',')),
48 case_p
<'c'>(str_p("bcd")),
54 rule
<ScannerT
> const& start() const { return r
; }
58 struct switch_grammar_direct_default5
59 : public grammar
<switch_grammar_direct_default5
>
61 template <typename ScannerT
>
64 definition(switch_grammar_direct_default5
const& /*self*/)
68 case_p
<'b'>(ch_p(',')),
70 case_p
<'c'>(str_p("bcd"))
75 rule
<ScannerT
> const& start() const { return r
; }
79 struct switch_grammar_direct_default6
80 : public grammar
<switch_grammar_direct_default6
>
82 template <typename ScannerT
>
85 definition(switch_grammar_direct_default6
const& /*self*/)
90 case_p
<'b'>(ch_p(',')),
91 case_p
<'c'>(str_p("bcd"))
96 rule
<ScannerT
> const& start() const { return r
; }
100 ///////////////////////////////////////////////////////////////////////////////
101 // Test the switch_p usage given a parser as the switch condition
102 struct switch_grammar_parser_default4
103 : public grammar
<switch_grammar_parser_default4
>
105 template <typename ScannerT
>
108 definition(switch_grammar_parser_default4
const& /*self*/)
110 r
= switch_p(anychar_p
) [
112 case_p
<'b'>(ch_p(',')),
113 case_p
<'c'>(str_p("bcd")),
119 rule
<ScannerT
> const& start() const { return r
; }
123 struct switch_grammar_parser_default5
124 : public grammar
<switch_grammar_parser_default5
>
126 template <typename ScannerT
>
129 definition(switch_grammar_parser_default5
const& /*self*/)
131 r
= switch_p(anychar_p
) [
133 case_p
<'b'>(ch_p(',')),
135 case_p
<'c'>(str_p("bcd"))
140 rule
<ScannerT
> const& start() const { return r
; }
144 struct switch_grammar_parser_default6
145 : public grammar
<switch_grammar_parser_default6
>
147 template <typename ScannerT
>
150 definition(switch_grammar_parser_default6
const& /*self*/)
152 r
= switch_p(anychar_p
) [
155 case_p
<'b'>(ch_p(',')),
156 case_p
<'c'>(str_p("bcd"))
161 rule
<ScannerT
> const& start() const { return r
; }
165 ///////////////////////////////////////////////////////////////////////////////
166 // Test the switch_p usage given an actor as the switch condition
167 struct select_result
: public BOOST_SPIRIT_CLASSIC_NS::closure
<select_result
, int>
172 struct switch_grammar_actor_default4
173 : public grammar
<switch_grammar_actor_default4
>
175 template <typename ScannerT
>
178 definition(switch_grammar_actor_default4
const& /*self*/)
181 r
= select_p('a', 'b', 'c', 'd')[r
.val
= arg1
] >>
184 case_p
<1>(ch_p(',')),
185 case_p
<2>(str_p("bcd")),
190 rule
<ScannerT
, select_result::context_t
> r
;
191 rule
<ScannerT
, select_result::context_t
> const&
192 start() const { return r
; }
196 struct switch_grammar_actor_default5
197 : public grammar
<switch_grammar_actor_default5
>
199 template <typename ScannerT
>
202 definition(switch_grammar_actor_default5
const& /*self*/)
205 r
= select_p('a', 'b', 'c', 'd')[r
.val
= arg1
] >>
208 case_p
<1>(ch_p(',')),
210 case_p
<2>(str_p("bcd"))
214 rule
<ScannerT
, select_result::context_t
> r
;
215 rule
<ScannerT
, select_result::context_t
> const&
216 start() const { return r
; }
220 struct switch_grammar_actor_default6
221 : public grammar
<switch_grammar_actor_default6
>
223 template <typename ScannerT
>
226 definition(switch_grammar_actor_default6
const& /*self*/)
229 r
= select_p('a', 'b', 'c', 'd')[r
.val
= arg1
] >>
233 case_p
<1>(ch_p(',')),
234 case_p
<2>(str_p("bcd"))
238 rule
<ScannerT
, select_result::context_t
> r
;
239 rule
<ScannerT
, select_result::context_t
> const&
240 start() const { return r
; }
244 } // namespace test_grammars
246 ///////////////////////////////////////////////////////////////////////////////
249 // Tests for known (to the grammars) sequences
250 struct check_grammar_known
{
252 template <typename GrammarT
>
253 void operator()(GrammarT
)
257 BOOST_TEST(parse("a1", g
).full
);
258 BOOST_TEST(!parse("a,", g
).hit
);
259 BOOST_TEST(!parse("abcd", g
).hit
);
261 BOOST_TEST(parse("a 1", g
, space_p
).full
);
262 BOOST_TEST(!parse("a ,", g
, space_p
).hit
);
263 BOOST_TEST(!parse("a bcd", g
, space_p
).hit
);
265 BOOST_TEST(!parse("b1", g
).hit
);
266 BOOST_TEST(parse("b,", g
).full
);
267 BOOST_TEST(!parse("bbcd", g
).hit
);
269 BOOST_TEST(!parse("b 1", g
, space_p
).hit
);
270 BOOST_TEST(parse("b ,", g
, space_p
).full
);
271 BOOST_TEST(!parse("b bcd", g
, space_p
).hit
);
273 BOOST_TEST(!parse("c1", g
).hit
);
274 BOOST_TEST(!parse("c,", g
).hit
);
275 BOOST_TEST(parse("cbcd", g
).full
);
277 BOOST_TEST(!parse("c 1", g
, space_p
).hit
);
278 BOOST_TEST(!parse("c ,", g
, space_p
).hit
);
279 BOOST_TEST(parse("c bcd", g
, space_p
).full
);
283 // Tests for known (to the grammars) sequences
284 // Tests for the default branches (without parsers) of the grammars
285 struct check_grammar_default_plain
{
287 template <typename GrammarT
>
288 void operator()(GrammarT
)
292 BOOST_TEST(parse("d", g
).full
);
293 BOOST_TEST(parse(" d", g
, space_p
).full
); // JDG 10-18-2005 removed trailing ' ' to
294 // avoid post skip problems
303 // Test switch_p parsers containing special (epsilon) default_p case
305 typedef boost::mpl::list
<
307 test_grammars::switch_grammar_direct_default4
,
308 test_grammars::switch_grammar_direct_default5
,
309 test_grammars::switch_grammar_direct_default6
,
311 // switch_p(parser) syntax
312 test_grammars::switch_grammar_parser_default4
,
313 test_grammars::switch_grammar_parser_default5
,
314 test_grammars::switch_grammar_parser_default6
,
316 // switch_p(actor) syntax
317 test_grammars::switch_grammar_actor_default4
,
318 test_grammars::switch_grammar_actor_default5
,
319 test_grammars::switch_grammar_actor_default6
320 > default_epsilon_list_t
;
322 boost::mpl::for_each
<default_epsilon_list_t
>(tests::check_grammar_known());
323 boost::mpl::for_each
<default_epsilon_list_t
>(
324 tests::check_grammar_default_plain());
326 return boost::report_errors();