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 (with default_p)
38 struct switch_grammar_direct_default4
39 : public grammar
<switch_grammar_direct_default4
>
41 template <typename ScannerT
>
44 definition(switch_grammar_direct_default4
const& /*self*/)
48 case_p
<'b'>(ch_p(',')),
49 case_p
<'c'>(str_p("bcd")),
55 rule
<ScannerT
> const& start() const { return r
; }
59 struct switch_grammar_direct_default5
60 : public grammar
<switch_grammar_direct_default5
>
62 template <typename ScannerT
>
65 definition(switch_grammar_direct_default5
const& /*self*/)
69 case_p
<'b'>(ch_p(',')),
71 case_p
<'c'>(str_p("bcd"))
76 rule
<ScannerT
> const& start() const { return r
; }
80 struct switch_grammar_direct_default6
81 : public grammar
<switch_grammar_direct_default6
>
83 template <typename ScannerT
>
86 definition(switch_grammar_direct_default6
const& /*self*/)
91 case_p
<'b'>(ch_p(',')),
92 case_p
<'c'>(str_p("bcd"))
97 rule
<ScannerT
> const& start() const { return r
; }
101 ///////////////////////////////////////////////////////////////////////////////
102 // Test the switch_p usage given a parser as the switch condition
103 struct switch_grammar_parser_default4
104 : public grammar
<switch_grammar_parser_default4
>
106 template <typename ScannerT
>
109 definition(switch_grammar_parser_default4
const& /*self*/)
111 r
= switch_p(anychar_p
) [(
113 case_p
<'b'>(ch_p(',')),
114 case_p
<'c'>(str_p("bcd")),
120 rule
<ScannerT
> const& start() const { return r
; }
124 struct switch_grammar_parser_default5
125 : public grammar
<switch_grammar_parser_default5
>
127 template <typename ScannerT
>
130 definition(switch_grammar_parser_default5
const& /*self*/)
132 r
= switch_p(anychar_p
) [(
134 case_p
<'b'>(ch_p(',')),
136 case_p
<'c'>(str_p("bcd"))
141 rule
<ScannerT
> const& start() const { return r
; }
145 struct switch_grammar_parser_default6
146 : public grammar
<switch_grammar_parser_default6
>
148 template <typename ScannerT
>
151 definition(switch_grammar_parser_default6
const& /*self*/)
153 r
= switch_p(anychar_p
) [(
156 case_p
<'b'>(ch_p(',')),
157 case_p
<'c'>(str_p("bcd"))
162 rule
<ScannerT
> const& start() const { return r
; }
166 ///////////////////////////////////////////////////////////////////////////////
167 // Test the switch_p usage given an actor as the switch condition
168 struct select_result
: public BOOST_SPIRIT_CLASSIC_NS::closure
<select_result
, int>
173 struct switch_grammar_actor_default4
174 : public grammar
<switch_grammar_actor_default4
>
176 template <typename ScannerT
>
179 definition(switch_grammar_actor_default4
const& /*self*/)
182 r
= select_p('a', 'b', 'c', 'd')[r
.val
= arg1
] >>
185 case_p
<1>(ch_p(',')),
186 case_p
<2>(str_p("bcd")),
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_default5
198 : public grammar
<switch_grammar_actor_default5
>
200 template <typename ScannerT
>
203 definition(switch_grammar_actor_default5
const& /*self*/)
206 r
= select_p('a', 'b', 'c', 'd')[r
.val
= arg1
] >>
209 case_p
<1>(ch_p(',')),
211 case_p
<2>(str_p("bcd"))
215 rule
<ScannerT
, select_result::context_t
> r
;
216 rule
<ScannerT
, select_result::context_t
> const&
217 start() const { return r
; }
221 struct switch_grammar_actor_default6
222 : public grammar
<switch_grammar_actor_default6
>
224 template <typename ScannerT
>
227 definition(switch_grammar_actor_default6
const& /*self*/)
230 r
= select_p('a', 'b', 'c', 'd')[r
.val
= arg1
] >>
234 case_p
<1>(ch_p(',')),
235 case_p
<2>(str_p("bcd"))
239 rule
<ScannerT
, select_result::context_t
> r
;
240 rule
<ScannerT
, select_result::context_t
> const&
241 start() const { return r
; }
245 } // namespace test_grammars
247 ///////////////////////////////////////////////////////////////////////////////
250 // Tests for known (to the grammars) sequences
251 struct check_grammar_known
{
253 template <typename GrammarT
>
254 void operator()(GrammarT
)
258 BOOST_TEST(parse("a1", g
).full
);
259 BOOST_TEST(!parse("a,", g
).hit
);
260 BOOST_TEST(!parse("abcd", g
).hit
);
262 BOOST_TEST(parse("a 1", g
, space_p
).full
);
263 BOOST_TEST(!parse("a ,", g
, space_p
).hit
);
264 BOOST_TEST(!parse("a bcd", g
, space_p
).hit
);
266 BOOST_TEST(!parse("b1", g
).hit
);
267 BOOST_TEST(parse("b,", g
).full
);
268 BOOST_TEST(!parse("bbcd", g
).hit
);
270 BOOST_TEST(!parse("b 1", g
, space_p
).hit
);
271 BOOST_TEST(parse("b ,", g
, space_p
).full
);
272 BOOST_TEST(!parse("b bcd", g
, space_p
).hit
);
274 BOOST_TEST(!parse("c1", g
).hit
);
275 BOOST_TEST(!parse("c,", g
).hit
);
276 BOOST_TEST(parse("cbcd", g
).full
);
278 BOOST_TEST(!parse("c 1", g
, space_p
).hit
);
279 BOOST_TEST(!parse("c ,", g
, space_p
).hit
);
280 BOOST_TEST(parse("c bcd", g
, space_p
).full
);
284 // Tests for known (to the grammars) sequences
285 // Tests for the default branches (without parsers) of the grammars
286 struct check_grammar_default_plain
{
288 template <typename GrammarT
>
289 void operator()(GrammarT
)
293 BOOST_TEST(parse("d", g
).full
);
294 BOOST_TEST(parse(" d", g
, space_p
).full
); // JDG 10-18-2005 removed trailing ' ' to
295 // avoid post skip problems
304 // Test switch_p parsers containing special (epsilon) default_p case
306 typedef boost::mpl::list
<
308 test_grammars::switch_grammar_direct_default4
,
309 test_grammars::switch_grammar_direct_default5
,
310 test_grammars::switch_grammar_direct_default6
,
312 // switch_p(parser) syntax
313 test_grammars::switch_grammar_parser_default4
,
314 test_grammars::switch_grammar_parser_default5
,
315 test_grammars::switch_grammar_parser_default6
,
317 // switch_p(actor) syntax
318 test_grammars::switch_grammar_actor_default4
,
319 test_grammars::switch_grammar_actor_default5
,
320 test_grammars::switch_grammar_actor_default6
321 > default_epsilon_list_t
;
323 boost::mpl::for_each
<default_epsilon_list_t
>(tests::check_grammar_known());
324 boost::mpl::for_each
<default_epsilon_list_t
>(
325 tests::check_grammar_default_plain());
327 return boost::report_errors();