1 /*=============================================================================
2     Copyright (c) 2003 Hartmut Kaiser
3     http://spirit.sourceforge.net/
4 
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 =============================================================================*/
9 #include <iostream>
10 #include <boost/detail/lightweight_test.hpp>
11 
12 
13 #define BOOST_SPIRIT_SWITCH_CASE_LIMIT 6
14 #define BOOST_SPIRIT_SELECT_LIMIT 6
15 #define PHOENIX_LIMIT 6
16 
17 //#define BOOST_SPIRIT_DEBUG
18 #include <boost/mpl/list.hpp>
19 #include <boost/mpl/for_each.hpp>
20 
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>
30 
31 using namespace BOOST_SPIRIT_CLASSIC_NS;
32 
33 namespace test_grammars {
34 
35 ///////////////////////////////////////////////////////////////////////////////
36 //  Test the direct switch_p usage (with default_p)
37     struct switch_grammar_direct_default1
38     :   public grammar<switch_grammar_direct_default1>
39     {
40         template <typename ScannerT>
41         struct definition
42         {
definitiontest_grammars::switch_grammar_direct_default1::definition43             definition(switch_grammar_direct_default1 const& /*self*/)
44             {
45                 r = switch_p [
46                         case_p<'a'>(int_p),
47                         case_p<'b'>(ch_p(',')),
48                         case_p<'c'>(str_p("bcd")),
49                         default_p(str_p("default"))
50                     ];
51             }
52 
53             rule<ScannerT> r;
starttest_grammars::switch_grammar_direct_default1::definition54             rule<ScannerT> const& start() const { return r; }
55         };
56     };
57 
58     struct switch_grammar_direct_default2
59     :   public grammar<switch_grammar_direct_default2>
60     {
61         template <typename ScannerT>
62         struct definition
63         {
definitiontest_grammars::switch_grammar_direct_default2::definition64             definition(switch_grammar_direct_default2 const& /*self*/)
65             {
66                 r = switch_p [
67                         case_p<'a'>(int_p),
68                         case_p<'b'>(ch_p(',')),
69                         default_p(str_p("default")),
70                         case_p<'c'>(str_p("bcd"))
71                     ];
72             }
73 
74             rule<ScannerT> r;
starttest_grammars::switch_grammar_direct_default2::definition75             rule<ScannerT> const& start() const { return r; }
76         };
77     };
78 
79     struct switch_grammar_direct_default3
80     :   public grammar<switch_grammar_direct_default3>
81     {
82         template <typename ScannerT>
83         struct definition
84         {
definitiontest_grammars::switch_grammar_direct_default3::definition85             definition(switch_grammar_direct_default3 const& /*self*/)
86             {
87                 r = switch_p [
88                         default_p(str_p("default")),
89                         case_p<'a'>(int_p),
90                         case_p<'b'>(ch_p(',')),
91                         case_p<'c'>(str_p("bcd"))
92                     ];
93             }
94 
95             rule<ScannerT> r;
starttest_grammars::switch_grammar_direct_default3::definition96             rule<ScannerT> const& start() const { return r; }
97         };
98     };
99 
100 ///////////////////////////////////////////////////////////////////////////////
101 //  Test the switch_p usage given a parser as the switch condition
102     struct switch_grammar_parser_default1
103     :   public grammar<switch_grammar_parser_default1>
104     {
105         template <typename ScannerT>
106         struct definition
107         {
definitiontest_grammars::switch_grammar_parser_default1::definition108             definition(switch_grammar_parser_default1 const& /*self*/)
109             {
110                 r = switch_p(anychar_p) [
111                         case_p<'a'>(int_p),
112                         case_p<'b'>(ch_p(',')),
113                         case_p<'c'>(str_p("bcd")),
114                         default_p(str_p("default"))
115                     ];
116             }
117 
118             rule<ScannerT> r;
starttest_grammars::switch_grammar_parser_default1::definition119             rule<ScannerT> const& start() const { return r; }
120         };
121     };
122 
123     struct switch_grammar_parser_default2
124     :   public grammar<switch_grammar_parser_default2>
125     {
126         template <typename ScannerT>
127         struct definition
128         {
definitiontest_grammars::switch_grammar_parser_default2::definition129             definition(switch_grammar_parser_default2 const& /*self*/)
130             {
131                 r = switch_p(anychar_p) [
132                         case_p<'a'>(int_p),
133                         case_p<'b'>(ch_p(',')),
134                         default_p(str_p("default")),
135                         case_p<'c'>(str_p("bcd"))
136                     ];
137             }
138 
139             rule<ScannerT> r;
starttest_grammars::switch_grammar_parser_default2::definition140             rule<ScannerT> const& start() const { return r; }
141         };
142     };
143 
144     struct switch_grammar_parser_default3
145     :   public grammar<switch_grammar_parser_default3>
146     {
147         template <typename ScannerT>
148         struct definition
149         {
definitiontest_grammars::switch_grammar_parser_default3::definition150             definition(switch_grammar_parser_default3 const& /*self*/)
151             {
152                 r = switch_p(anychar_p) [
153                         default_p(str_p("default")),
154                         case_p<'a'>(int_p),
155                         case_p<'b'>(ch_p(',')),
156                         case_p<'c'>(str_p("bcd"))
157                     ];
158             }
159 
160             rule<ScannerT> r;
starttest_grammars::switch_grammar_parser_default3::definition161             rule<ScannerT> const& start() const { return r; }
162         };
163     };
164 
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>
168     {
169         member1 val;
170     };
171 
172     ///////////////////////////////////////////////////////////////////////////
173     struct switch_grammar_actor_default1
174     :   public grammar<switch_grammar_actor_default1>
175     {
176         template <typename ScannerT>
177         struct definition
178         {
definitiontest_grammars::switch_grammar_actor_default1::definition179             definition(switch_grammar_actor_default1 const& /*self*/)
180             {
181                 using phoenix::arg1;
182                 r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
183                     switch_p(r.val) [
184                         case_p<0>(int_p),
185                         case_p<1>(ch_p(',')),
186                         case_p<2>(str_p("bcd")),
187                         default_p(str_p("default"))
188                     ];
189             }
190 
191             rule<ScannerT, select_result::context_t> r;
192             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_default1::definition193             start() const { return r; }
194         };
195     };
196 
197     struct switch_grammar_actor_default2
198     :   public grammar<switch_grammar_actor_default2>
199     {
200         template <typename ScannerT>
201         struct definition
202         {
definitiontest_grammars::switch_grammar_actor_default2::definition203             definition(switch_grammar_actor_default2 const& /*self*/)
204             {
205                 using phoenix::arg1;
206                 r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
207                     switch_p(r.val) [
208                         case_p<0>(int_p),
209                         case_p<1>(ch_p(',')),
210                         default_p(str_p("default")),
211                         case_p<2>(str_p("bcd"))
212                     ];
213             }
214 
215             rule<ScannerT, select_result::context_t> r;
216             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_default2::definition217             start() const { return r; }
218         };
219     };
220 
221     struct switch_grammar_actor_default3
222     :   public grammar<switch_grammar_actor_default3>
223     {
224         template <typename ScannerT>
225         struct definition
226         {
definitiontest_grammars::switch_grammar_actor_default3::definition227             definition(switch_grammar_actor_default3 const& /*self*/)
228             {
229                 using phoenix::arg1;
230                 r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
231                     switch_p(r.val) [
232                         default_p(str_p("default")),
233                         case_p<0>(int_p),
234                         case_p<1>(ch_p(',')),
235                         case_p<2>(str_p("bcd"))
236                     ];
237             }
238 
239             rule<ScannerT, select_result::context_t> r;
240             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_default3::definition241             start() const { return r; }
242         };
243     };
244 
245 }   // namespace test_grammars
246 
247 ///////////////////////////////////////////////////////////////////////////////
248 namespace tests {
249 
250     //  Tests for known (to the grammars) sequences
251     struct check_grammar_known {
252 
253         template <typename GrammarT>
operator ()tests::check_grammar_known254         void operator()(GrammarT)
255         {
256             GrammarT g;
257 
258             BOOST_TEST(parse("a1", g).full);
259             BOOST_TEST(!parse("a,", g).hit);
260             BOOST_TEST(!parse("abcd", g).hit);
261 
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);
265 
266             BOOST_TEST(!parse("b1", g).hit);
267             BOOST_TEST(parse("b,", g).full);
268             BOOST_TEST(!parse("bbcd", g).hit);
269 
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);
273 
274             BOOST_TEST(!parse("c1", g).hit);
275             BOOST_TEST(!parse("c,", g).hit);
276             BOOST_TEST(parse("cbcd", g).full);
277 
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);
281         }
282     };
283 
284     // Tests for unknown (to the grammar) sequences
285     struct check_grammar_unknown_default {
286 
287         template <typename GrammarT>
operator ()tests::check_grammar_unknown_default288         void operator()(GrammarT)
289         {
290             GrammarT g;
291 
292             BOOST_TEST(!parse("d1", g).hit);
293             BOOST_TEST(!parse("d,", g).hit);
294             BOOST_TEST(!parse("dbcd", g).hit);
295 
296             BOOST_TEST(!parse("d 1", g, space_p).hit);
297             BOOST_TEST(!parse("d ,", g, space_p).hit);
298             BOOST_TEST(!parse("d bcd", g, space_p).hit);
299         }
300     };
301 
302     //  Tests for the default branches (with parsers) of the grammars
303     struct check_grammar_default {
304 
305         template <typename GrammarT>
operator ()tests::check_grammar_default306         void operator()(GrammarT)
307         {
308             GrammarT g;
309 
310             BOOST_TEST(parse("ddefault", g).full);
311             BOOST_TEST(parse("d default", g, space_p).full);
312         }
313     };
314 
315 }   // namespace tests
316 
317 int
main()318 main()
319 {
320     //  Test switch_p parsers containing general default_p(...) case branches
321     typedef boost::mpl::list<
322     // switch_p syntax
323         test_grammars::switch_grammar_direct_default1,
324         test_grammars::switch_grammar_direct_default2,
325         test_grammars::switch_grammar_direct_default3,
326 
327     // switch_p(parser) syntax
328         test_grammars::switch_grammar_parser_default1,
329         test_grammars::switch_grammar_parser_default2,
330         test_grammars::switch_grammar_parser_default3,
331 
332     // switch_p(actor) syntax
333         test_grammars::switch_grammar_actor_default1,
334         test_grammars::switch_grammar_actor_default2,
335         test_grammars::switch_grammar_actor_default3
336     > default_list_t;
337 
338     boost::mpl::for_each<default_list_t>(tests::check_grammar_known());
339     boost::mpl::for_each<default_list_t>(tests::check_grammar_unknown_default());
340     boost::mpl::for_each<default_list_t>(tests::check_grammar_default());
341 
342     return boost::report_errors();
343 }
344