• 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 (with default_p)
37     struct switch_grammar_direct_default4
38     :   public grammar<switch_grammar_direct_default4>
39     {
40         template <typename ScannerT>
41         struct definition
42         {
definitiontest_grammars::switch_grammar_direct_default4::definition43             definition(switch_grammar_direct_default4 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
50                     )];
51             }
52 
53             rule<ScannerT> r;
starttest_grammars::switch_grammar_direct_default4::definition54             rule<ScannerT> const& start() const { return r; }
55         };
56     };
57 
58     struct switch_grammar_direct_default5
59     :   public grammar<switch_grammar_direct_default5>
60     {
61         template <typename ScannerT>
62         struct definition
63         {
definitiontest_grammars::switch_grammar_direct_default5::definition64             definition(switch_grammar_direct_default5 const& /*self*/)
65             {
66                 r = switch_p [(
67                         case_p<'a'>(int_p),
68                         case_p<'b'>(ch_p(',')),
69                         default_p,
70                         case_p<'c'>(str_p("bcd"))
71                     )];
72             }
73 
74             rule<ScannerT> r;
starttest_grammars::switch_grammar_direct_default5::definition75             rule<ScannerT> const& start() const { return r; }
76         };
77     };
78 
79     struct switch_grammar_direct_default6
80     :   public grammar<switch_grammar_direct_default6>
81     {
82         template <typename ScannerT>
83         struct definition
84         {
definitiontest_grammars::switch_grammar_direct_default6::definition85             definition(switch_grammar_direct_default6 const& /*self*/)
86             {
87                 r = switch_p [(
88                         default_p,
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_default6::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_default4
103     :   public grammar<switch_grammar_parser_default4>
104     {
105         template <typename ScannerT>
106         struct definition
107         {
definitiontest_grammars::switch_grammar_parser_default4::definition108             definition(switch_grammar_parser_default4 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
115                     )];
116             }
117 
118             rule<ScannerT> r;
starttest_grammars::switch_grammar_parser_default4::definition119             rule<ScannerT> const& start() const { return r; }
120         };
121     };
122 
123     struct switch_grammar_parser_default5
124     :   public grammar<switch_grammar_parser_default5>
125     {
126         template <typename ScannerT>
127         struct definition
128         {
definitiontest_grammars::switch_grammar_parser_default5::definition129             definition(switch_grammar_parser_default5 const& /*self*/)
130             {
131                 r = switch_p(anychar_p) [(
132                         case_p<'a'>(int_p),
133                         case_p<'b'>(ch_p(',')),
134                         default_p,
135                         case_p<'c'>(str_p("bcd"))
136                     )];
137             }
138 
139             rule<ScannerT> r;
starttest_grammars::switch_grammar_parser_default5::definition140             rule<ScannerT> const& start() const { return r; }
141         };
142     };
143 
144     struct switch_grammar_parser_default6
145     :   public grammar<switch_grammar_parser_default6>
146     {
147         template <typename ScannerT>
148         struct definition
149         {
definitiontest_grammars::switch_grammar_parser_default6::definition150             definition(switch_grammar_parser_default6 const& /*self*/)
151             {
152                 r = switch_p(anychar_p) [(
153                         default_p,
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_default6::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     struct switch_grammar_actor_default4
173     :   public grammar<switch_grammar_actor_default4>
174     {
175         template <typename ScannerT>
176         struct definition
177         {
definitiontest_grammars::switch_grammar_actor_default4::definition178             definition(switch_grammar_actor_default4 const& /*self*/)
179             {
180                 using phoenix::arg1;
181                 r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
182                     switch_p(r.val) [(
183                         case_p<0>(int_p),
184                         case_p<1>(ch_p(',')),
185                         case_p<2>(str_p("bcd")),
186                         default_p
187                     )];
188             }
189 
190             rule<ScannerT, select_result::context_t> r;
191             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_default4::definition192             start() const { return r; }
193         };
194     };
195 
196     struct switch_grammar_actor_default5
197     :   public grammar<switch_grammar_actor_default5>
198     {
199         template <typename ScannerT>
200         struct definition
201         {
definitiontest_grammars::switch_grammar_actor_default5::definition202             definition(switch_grammar_actor_default5 const& /*self*/)
203             {
204                 using phoenix::arg1;
205                 r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
206                     switch_p(r.val) [(
207                         case_p<0>(int_p),
208                         case_p<1>(ch_p(',')),
209                         default_p,
210                         case_p<2>(str_p("bcd"))
211                     )];
212             }
213 
214             rule<ScannerT, select_result::context_t> r;
215             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_default5::definition216             start() const { return r; }
217         };
218     };
219 
220     struct switch_grammar_actor_default6
221     :   public grammar<switch_grammar_actor_default6>
222     {
223         template <typename ScannerT>
224         struct definition
225         {
definitiontest_grammars::switch_grammar_actor_default6::definition226             definition(switch_grammar_actor_default6 const& /*self*/)
227             {
228                 using phoenix::arg1;
229                 r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >>
230                     switch_p(r.val) [(
231                         default_p,
232                         case_p<0>(int_p),
233                         case_p<1>(ch_p(',')),
234                         case_p<2>(str_p("bcd"))
235                     )];
236             }
237 
238             rule<ScannerT, select_result::context_t> r;
239             rule<ScannerT, select_result::context_t> const&
starttest_grammars::switch_grammar_actor_default6::definition240             start() const { return r; }
241         };
242     };
243 
244 }   // namespace test_grammars
245 
246 ///////////////////////////////////////////////////////////////////////////////
247 namespace tests {
248 
249     //  Tests for known (to the grammars) sequences
250     struct check_grammar_known {
251 
252         template <typename GrammarT>
operator ()tests::check_grammar_known253         void operator()(GrammarT)
254         {
255             GrammarT g;
256 
257             BOOST_TEST(parse("a1", g).full);
258             BOOST_TEST(!parse("a,", g).hit);
259             BOOST_TEST(!parse("abcd", g).hit);
260 
261             BOOST_TEST(parse("a 1", g, space_p).full);
262             BOOST_TEST(!parse("a ,", g, space_p).hit);
263             BOOST_TEST(!parse("a bcd", g, space_p).hit);
264 
265             BOOST_TEST(!parse("b1", g).hit);
266             BOOST_TEST(parse("b,", g).full);
267             BOOST_TEST(!parse("bbcd", g).hit);
268 
269             BOOST_TEST(!parse("b 1", g, space_p).hit);
270             BOOST_TEST(parse("b ,", g, space_p).full);
271             BOOST_TEST(!parse("b bcd", g, space_p).hit);
272 
273             BOOST_TEST(!parse("c1", g).hit);
274             BOOST_TEST(!parse("c,", g).hit);
275             BOOST_TEST(parse("cbcd", g).full);
276 
277             BOOST_TEST(!parse("c 1", g, space_p).hit);
278             BOOST_TEST(!parse("c ,", g, space_p).hit);
279             BOOST_TEST(parse("c bcd", g, space_p).full);
280         }
281     };
282 
283     //  Tests for known (to the grammars) sequences
284     //  Tests for the default branches (without parsers) of the grammars
285     struct check_grammar_default_plain {
286 
287         template <typename GrammarT>
operator ()tests::check_grammar_default_plain288         void operator()(GrammarT)
289         {
290             GrammarT g;
291 
292             BOOST_TEST(parse("d", g).full);
293             BOOST_TEST(parse(" d", g, space_p).full); // JDG 10-18-2005 removed trailing ' ' to
294                                                   // avoid post skip problems
295         }
296     };
297 
298 }   // namespace tests
299 
300 int
main()301 main()
302 {
303     //  Test switch_p parsers containing special (epsilon) default_p case
304     //  branches
305     typedef boost::mpl::list<
306     // switch_p syntax
307         test_grammars::switch_grammar_direct_default4,
308         test_grammars::switch_grammar_direct_default5,
309         test_grammars::switch_grammar_direct_default6,
310 
311     // switch_p(parser) syntax
312         test_grammars::switch_grammar_parser_default4,
313         test_grammars::switch_grammar_parser_default5,
314         test_grammars::switch_grammar_parser_default6,
315 
316     // switch_p(actor) syntax
317         test_grammars::switch_grammar_actor_default4,
318         test_grammars::switch_grammar_actor_default5,
319         test_grammars::switch_grammar_actor_default6
320     > default_epsilon_list_t;
321 
322     boost::mpl::for_each<default_epsilon_list_t>(tests::check_grammar_known());
323     boost::mpl::for_each<default_epsilon_list_t>(
324         tests::check_grammar_default_plain());
325 
326     return boost::report_errors();
327 }
328