• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
37     struct switch_grammar_direct_single
38     :   public grammar<switch_grammar_direct_single>
39     {
40         template <typename ScannerT>
41         struct definition
42         {
definitiontest_grammars::switch_grammar_direct_single::definition43             definition(switch_grammar_direct_single const& /*self*/)
44             {
45                 r = switch_p [
46                         case_p<'a'>(int_p)
47                     ];
48             }
49 
50             rule<ScannerT> r;
starttest_grammars::switch_grammar_direct_single::definition51             rule<ScannerT> const& start() const { return r; }
52         };
53     };
54 
55     struct switch_grammar_direct_default_single1
56     :   public grammar<switch_grammar_direct_default_single1>
57     {
58         template <typename ScannerT>
59         struct definition
60         {
definitiontest_grammars::switch_grammar_direct_default_single1::definition61             definition(switch_grammar_direct_default_single1 const& /*self*/)
62             {
63                 r = switch_p [
64                         default_p(str_p("default"))
65                     ];
66             }
67 
68             rule<ScannerT> r;
starttest_grammars::switch_grammar_direct_default_single1::definition69             rule<ScannerT> const& start() const { return r; }
70         };
71     };
72 
73     struct switch_grammar_direct_default_single2
74     :   public grammar<switch_grammar_direct_default_single2>
75     {
76         template <typename ScannerT>
77         struct definition
78         {
definitiontest_grammars::switch_grammar_direct_default_single2::definition79             definition(switch_grammar_direct_default_single2 const& /*self*/)
80             {
81                 r = switch_p [
82                         default_p
83                     ];
84             }
85 
86             rule<ScannerT> r;
starttest_grammars::switch_grammar_direct_default_single2::definition87             rule<ScannerT> const& start() const { return r; }
88         };
89     };
90 
91 ///////////////////////////////////////////////////////////////////////////////
92 //  Test the switch_p usage given a parser as the switch condition
93     struct switch_grammar_parser_single
94     :   public grammar<switch_grammar_parser_single>
95     {
96         template <typename ScannerT>
97         struct definition
98         {
definitiontest_grammars::switch_grammar_parser_single::definition99             definition(switch_grammar_parser_single const& /*self*/)
100             {
101                 r = switch_p(anychar_p) [
102                         case_p<'a'>(int_p)
103                     ];
104             }
105 
106             rule<ScannerT> r;
starttest_grammars::switch_grammar_parser_single::definition107             rule<ScannerT> const& start() const { return r; }
108         };
109     };
110 
111     struct switch_grammar_parser_default_single1
112     :   public grammar<switch_grammar_parser_default_single1>
113     {
114         template <typename ScannerT>
115         struct definition
116         {
definitiontest_grammars::switch_grammar_parser_default_single1::definition117             definition(switch_grammar_parser_default_single1 const& /*self*/)
118             {
119                 r = switch_p(anychar_p) [
120                         default_p(str_p("default"))
121                     ];
122             }
123 
124             rule<ScannerT> r;
starttest_grammars::switch_grammar_parser_default_single1::definition125             rule<ScannerT> const& start() const { return r; }
126         };
127     };
128 
129     struct switch_grammar_parser_default_single2
130     :   public grammar<switch_grammar_parser_default_single2>
131     {
132         template <typename ScannerT>
133         struct definition
134         {
definitiontest_grammars::switch_grammar_parser_default_single2::definition135             definition(switch_grammar_parser_default_single2 const& /*self*/)
136             {
137                 r = switch_p(anychar_p) [
138                         default_p
139                     ];
140             }
141 
142             rule<ScannerT> r;
starttest_grammars::switch_grammar_parser_default_single2::definition143             rule<ScannerT> const& start() const { return r; }
144         };
145     };
146 
147 ///////////////////////////////////////////////////////////////////////////////
148 //  Test the switch_p usage given an actor as the switch condition
149     struct select_result : public BOOST_SPIRIT_CLASSIC_NS::closure<select_result, int>
150     {
151         member1 val;
152     };
153 
154     struct switch_grammar_actor_single
155     :   public grammar<switch_grammar_actor_single>
156     {
157         template <typename ScannerT>
158         struct definition
159         {
definitiontest_grammars::switch_grammar_actor_single::definition160             definition(switch_grammar_actor_single const& /*self*/)
161             {
162                 using phoenix::arg1;
163                 r = select_p('a')[r.val = arg1] >>
164                     switch_p(r.val) [
165                         case_p<0>(int_p)
166                     ];
167             }
168 
169             rule<ScannerT, select_result::context_t> r;
170             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_single::definition171             start() const { return r; }
172         };
173     };
174 
175     struct switch_grammar_actor_default_single1
176     :   public grammar<switch_grammar_actor_default_single1>
177     {
178         template <typename ScannerT>
179         struct definition
180         {
definitiontest_grammars::switch_grammar_actor_default_single1::definition181             definition(switch_grammar_actor_default_single1 const& /*self*/)
182             {
183                 using phoenix::arg1;
184                 r = select_p('d')[r.val = arg1] >>
185                     switch_p(r.val) [
186                         default_p(str_p("default"))
187                     ];
188             }
189 
190             rule<ScannerT, select_result::context_t> r;
191             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_default_single1::definition192             start() const { return r; }
193         };
194     };
195 
196     struct switch_grammar_actor_default_single2
197     :   public grammar<switch_grammar_actor_default_single2>
198     {
199         template <typename ScannerT>
200         struct definition
201         {
definitiontest_grammars::switch_grammar_actor_default_single2::definition202             definition(switch_grammar_actor_default_single2 const& /*self*/)
203             {
204                 using phoenix::arg1;
205                 r = select_p('d')[r.val = arg1] >>
206                     switch_p(r.val) [
207                         default_p
208                     ];
209             }
210 
211             rule<ScannerT, select_result::context_t> r;
212             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_default_single2::definition213             start() const { return r; }
214         };
215     };
216 
217 }   // namespace test_grammars
218 
219 ///////////////////////////////////////////////////////////////////////////////
220 namespace tests {
221 
222     //  Tests for known (to the grammars) sequences
223     struct check_grammar_unknown {
224 
225         template <typename GrammarT>
operator ()tests::check_grammar_unknown226         void operator()(GrammarT)
227         {
228             GrammarT g;
229 
230             BOOST_TEST(!parse("a1", g).hit);
231             BOOST_TEST(!parse("a,", g).hit);
232             BOOST_TEST(!parse("abcd", g).hit);
233 
234             BOOST_TEST(!parse("a 1", g, space_p).hit);
235             BOOST_TEST(!parse("a ,", g, space_p).hit);
236             BOOST_TEST(!parse("a bcd", g, space_p).hit);
237 
238             BOOST_TEST(!parse("b1", g).hit);
239             BOOST_TEST(!parse("b,", g).hit);
240             BOOST_TEST(!parse("bbcd", g).hit);
241 
242             BOOST_TEST(!parse("b 1", g, space_p).hit);
243             BOOST_TEST(!parse("b ,", g, space_p).hit);
244             BOOST_TEST(!parse("b bcd", g, space_p).hit);
245 
246             BOOST_TEST(!parse("c1", g).hit);
247             BOOST_TEST(!parse("c,", g).hit);
248             BOOST_TEST(!parse("cbcd", g).hit);
249 
250             BOOST_TEST(!parse("c 1", g, space_p).hit);
251             BOOST_TEST(!parse("c ,", g, space_p).hit);
252             BOOST_TEST(!parse("c bcd", g, space_p).hit);
253         }
254     };
255 
256     //  Tests for the default branches (with parsers) of the grammars
257     struct check_grammar_default {
258 
259         template <typename GrammarT>
operator ()tests::check_grammar_default260         void operator()(GrammarT)
261         {
262             GrammarT g;
263 
264             BOOST_TEST(parse("ddefault", g).full);
265             BOOST_TEST(parse("d default", g, space_p).full);
266         }
267     };
268 
269     //  Tests for the default branches (without parsers) of the grammars
270     struct check_grammar_default_plain {
271 
272         template <typename GrammarT>
operator ()tests::check_grammar_default_plain273         void operator()(GrammarT)
274         {
275             GrammarT g;
276 
277             BOOST_TEST(parse("d", g).full);
278             BOOST_TEST(parse(" d", g, space_p).full); // JDG 10-18-2005 removed trailing ' ' to
279                                                   // avoid post skip problems
280         }
281     };
282 
283     //  Tests grammars with a single case_p branch
284     struct check_grammar_single {
285 
286         template <typename GrammarT>
operator ()tests::check_grammar_single287         void operator()(GrammarT)
288         {
289             GrammarT g;
290 
291             BOOST_TEST(parse("a1", g).full);
292             BOOST_TEST(!parse("a,", g).hit);
293             BOOST_TEST(!parse("abcd", g).hit);
294 
295             BOOST_TEST(parse("a 1", g, space_p).full);
296             BOOST_TEST(!parse("a ,", g, space_p).hit);
297             BOOST_TEST(!parse("a bcd", g, space_p).hit);
298 
299             BOOST_TEST(!parse("b1", g).hit);
300             BOOST_TEST(!parse("b,", g).hit);
301             BOOST_TEST(!parse("bbcd", g).hit);
302 
303             BOOST_TEST(!parse("b 1", g, space_p).hit);
304             BOOST_TEST(!parse("b ,", g, space_p).hit);
305             BOOST_TEST(!parse("b bcd", g, space_p).hit);
306 
307             BOOST_TEST(!parse("c1", g).hit);
308             BOOST_TEST(!parse("c,", g).hit);
309             BOOST_TEST(!parse("cbcd", g).hit);
310 
311             BOOST_TEST(!parse("c 1", g, space_p).hit);
312             BOOST_TEST(!parse("c ,", g, space_p).hit);
313             BOOST_TEST(!parse("c bcd", g, space_p).hit);
314         }
315     };
316 
317 }   // namespace tests
318 
319 int
main()320 main()
321 {
322     // Test switch_p with a single case_p branch
323     typedef boost::mpl::list<
324         test_grammars::switch_grammar_direct_single,
325         test_grammars::switch_grammar_parser_single,
326         test_grammars::switch_grammar_actor_single
327     > single_list_t;
328 
329     boost::mpl::for_each<single_list_t>(tests::check_grammar_single());
330 
331     typedef boost::mpl::list<
332         test_grammars::switch_grammar_direct_default_single1,
333         test_grammars::switch_grammar_parser_default_single1,
334         test_grammars::switch_grammar_actor_default_single1
335     > default_single_t;
336 
337     boost::mpl::for_each<default_single_t>(tests::check_grammar_default());
338     boost::mpl::for_each<default_single_t>(tests::check_grammar_unknown());
339 
340     typedef boost::mpl::list<
341         test_grammars::switch_grammar_direct_default_single2,
342         test_grammars::switch_grammar_parser_default_single2,
343         test_grammars::switch_grammar_actor_default_single2
344     > default_plain_single_t;
345 
346     boost::mpl::for_each<default_plain_single_t>(
347         tests::check_grammar_default_plain());
348 
349     return boost::report_errors();
350 }
351