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