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
: public grammar
<switch_grammar_direct
>
40 template <typename ScannerT
>
43 definition(switch_grammar_direct
const& /*self*/)
47 case_p
<'b'>(ch_p(',')),
48 case_p
<'c'>(str_p("bcd")),
54 rule
<ScannerT
> const& start() const { return r
; }
58 ///////////////////////////////////////////////////////////////////////////////
59 // Test the switch_p usage given a parser as the switch condition
60 struct switch_grammar_parser
: public grammar
<switch_grammar_parser
>
62 template <typename ScannerT
>
65 definition(switch_grammar_parser
const& /*self*/)
67 r
= switch_p(anychar_p
) [(
69 case_p
<'b'>(ch_p(',')),
70 case_p
<'c'>(str_p("bcd")),
76 rule
<ScannerT
> const& start() const { return r
; }
80 ///////////////////////////////////////////////////////////////////////////////
81 // Test the switch_p usage given an actor as the switch condition
82 struct select_result
: public BOOST_SPIRIT_CLASSIC_NS::closure
<select_result
, int>
87 struct switch_grammar_actor
: public grammar
<switch_grammar_actor
>
89 template <typename ScannerT
>
92 definition(switch_grammar_actor
const& /*self*/)
95 r
= select_p('a', 'b', 'c', 'd')[r
.val
= arg1
] >>
99 case_p
<2>(str_p("bcd")),
104 rule
<ScannerT
, select_result::context_t
> r
;
105 rule
<ScannerT
, select_result::context_t
> const&
106 start() const { return r
; }
110 } // namespace test_grammars
112 ///////////////////////////////////////////////////////////////////////////////
115 // Tests for known (to the grammars) sequences
116 struct check_grammar_known
{
118 template <typename GrammarT
>
119 void operator()(GrammarT
)
123 BOOST_TEST(parse("a1", g
).full
);
124 BOOST_TEST(!parse("a,", g
).hit
);
125 BOOST_TEST(!parse("abcd", g
).hit
);
126 BOOST_TEST(!parse("a", g
).hit
);
128 BOOST_TEST(parse("a 1", g
, space_p
).full
);
129 BOOST_TEST(!parse("a ,", g
, space_p
).hit
);
130 BOOST_TEST(!parse("a bcd", g
, space_p
).hit
);
131 BOOST_TEST(!parse("a ", g
, space_p
).hit
);
133 BOOST_TEST(!parse("b1", g
).hit
);
134 BOOST_TEST(parse("b,", g
).full
);
135 BOOST_TEST(!parse("bbcd", g
).hit
);
136 BOOST_TEST(!parse("b", g
).hit
);
138 BOOST_TEST(!parse("b 1", g
, space_p
).hit
);
139 BOOST_TEST(parse("b ,", g
, space_p
).full
);
140 BOOST_TEST(!parse("b bcd", g
, space_p
).hit
);
141 BOOST_TEST(!parse("b ", g
, space_p
).hit
);
143 BOOST_TEST(!parse("c1", g
).hit
);
144 BOOST_TEST(!parse("c,", g
).hit
);
145 BOOST_TEST(parse("cbcd", g
).full
);
146 BOOST_TEST(!parse("c", g
).hit
);
148 BOOST_TEST(!parse("c 1", g
, space_p
).hit
);
149 BOOST_TEST(!parse("c ,", g
, space_p
).hit
);
150 BOOST_TEST(parse("c bcd", g
, space_p
).full
);
151 BOOST_TEST(!parse("c ", g
, space_p
).hit
);
153 BOOST_TEST(parse("d1", g
).hit
);
154 BOOST_TEST(parse("d,", g
).hit
);
155 BOOST_TEST(parse("dbcd", g
).hit
);
156 BOOST_TEST(parse("d", g
).full
);
158 BOOST_TEST(parse("d 1", g
, space_p
).hit
);
159 BOOST_TEST(parse("d ,", g
, space_p
).hit
);
160 BOOST_TEST(parse("d bcd", g
, space_p
).hit
);
161 BOOST_TEST(parse(" d", g
, space_p
).full
); // JDG 10-18-2005 removed trailing ' ' to
162 // avoid post skip problems
164 BOOST_TEST(parse(" a 1 b , c bcd d", *g
, space_p
).full
);
165 // JDG 10-18-2005 removed trailing ' ' to avoid post skip problems
169 // Tests for unknown (to the grammar) sequences
170 struct check_grammar_unknown_default
{
172 template <typename GrammarT
>
173 void operator()(GrammarT
)
177 BOOST_TEST(!parse("x1", g
).hit
);
178 BOOST_TEST(!parse("x,", g
).hit
);
179 BOOST_TEST(!parse("xbcd", g
).hit
);
181 BOOST_TEST(!parse("x 1", g
, space_p
).hit
);
182 BOOST_TEST(!parse("x ,", g
, space_p
).hit
);
183 BOOST_TEST(!parse("x bcd", g
, space_p
).hit
);
192 // Test switch_p without any default_p case branches
193 typedef boost::mpl::list
<
194 test_grammars::switch_grammar_direct
,
195 test_grammars::switch_grammar_parser
,
196 test_grammars::switch_grammar_actor
199 boost::mpl::for_each
<grammar_list_t
>(tests::check_grammar_known());
200 boost::mpl::for_each
<grammar_list_t
>(tests::check_grammar_unknown_default());
202 return boost::report_errors();