]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 : public grammar<switch_grammar_direct> | |
38 | { | |
39 | template <typename ScannerT> | |
40 | struct definition | |
41 | { | |
42 | definition(switch_grammar_direct const& /*self*/) | |
43 | { | |
20effc67 | 44 | r = switch_p [( |
7c673cae FG |
45 | case_p<'a'>(int_p), |
46 | case_p<'b'>(ch_p(',')), | |
47 | case_p<'c'>(str_p("bcd")), | |
48 | case_p<'d'>(eps_p) | |
20effc67 | 49 | )]; |
7c673cae FG |
50 | } |
51 | ||
52 | rule<ScannerT> r; | |
53 | rule<ScannerT> const& start() const { return r; } | |
54 | }; | |
55 | }; | |
56 | ||
57 | /////////////////////////////////////////////////////////////////////////////// | |
58 | // Test the switch_p usage given a parser as the switch condition | |
59 | struct switch_grammar_parser : public grammar<switch_grammar_parser> | |
60 | { | |
61 | template <typename ScannerT> | |
62 | struct definition | |
63 | { | |
64 | definition(switch_grammar_parser const& /*self*/) | |
65 | { | |
20effc67 | 66 | r = switch_p(anychar_p) [( |
7c673cae FG |
67 | case_p<'a'>(int_p), |
68 | case_p<'b'>(ch_p(',')), | |
69 | case_p<'c'>(str_p("bcd")), | |
70 | case_p<'d'>(eps_p) | |
20effc67 | 71 | )]; |
7c673cae FG |
72 | } |
73 | ||
74 | rule<ScannerT> r; | |
75 | rule<ScannerT> const& start() const { return r; } | |
76 | }; | |
77 | }; | |
78 | ||
79 | /////////////////////////////////////////////////////////////////////////////// | |
80 | // Test the switch_p usage given an actor as the switch condition | |
81 | struct select_result : public BOOST_SPIRIT_CLASSIC_NS::closure<select_result, int> | |
82 | { | |
83 | member1 val; | |
84 | }; | |
85 | ||
86 | struct switch_grammar_actor : public grammar<switch_grammar_actor> | |
87 | { | |
88 | template <typename ScannerT> | |
89 | struct definition | |
90 | { | |
91 | definition(switch_grammar_actor const& /*self*/) | |
92 | { | |
93 | using phoenix::arg1; | |
94 | r = select_p('a', 'b', 'c', 'd')[r.val = arg1] >> | |
20effc67 | 95 | switch_p(r.val) [( |
7c673cae FG |
96 | case_p<0>(int_p), |
97 | case_p<1>(ch_p(',')), | |
98 | case_p<2>(str_p("bcd")), | |
99 | case_p<3>(eps_p) | |
20effc67 | 100 | )]; |
7c673cae FG |
101 | } |
102 | ||
103 | rule<ScannerT, select_result::context_t> r; | |
104 | rule<ScannerT, select_result::context_t> const& | |
105 | start() const { return r; } | |
106 | }; | |
107 | }; | |
108 | ||
109 | } // namespace test_grammars | |
110 | ||
111 | /////////////////////////////////////////////////////////////////////////////// | |
112 | namespace tests { | |
113 | ||
114 | // Tests for known (to the grammars) sequences | |
115 | struct check_grammar_known { | |
116 | ||
117 | template <typename GrammarT> | |
118 | void operator()(GrammarT) | |
119 | { | |
120 | GrammarT g; | |
121 | ||
122 | BOOST_TEST(parse("a1", g).full); | |
123 | BOOST_TEST(!parse("a,", g).hit); | |
124 | BOOST_TEST(!parse("abcd", g).hit); | |
125 | BOOST_TEST(!parse("a", g).hit); | |
126 | ||
127 | BOOST_TEST(parse("a 1", g, space_p).full); | |
128 | BOOST_TEST(!parse("a ,", g, space_p).hit); | |
129 | BOOST_TEST(!parse("a bcd", g, space_p).hit); | |
130 | BOOST_TEST(!parse("a ", g, space_p).hit); | |
131 | ||
132 | BOOST_TEST(!parse("b1", g).hit); | |
133 | BOOST_TEST(parse("b,", g).full); | |
134 | BOOST_TEST(!parse("bbcd", g).hit); | |
135 | BOOST_TEST(!parse("b", g).hit); | |
136 | ||
137 | BOOST_TEST(!parse("b 1", g, space_p).hit); | |
138 | BOOST_TEST(parse("b ,", g, space_p).full); | |
139 | BOOST_TEST(!parse("b bcd", g, space_p).hit); | |
140 | BOOST_TEST(!parse("b ", g, space_p).hit); | |
141 | ||
142 | BOOST_TEST(!parse("c1", g).hit); | |
143 | BOOST_TEST(!parse("c,", g).hit); | |
144 | BOOST_TEST(parse("cbcd", g).full); | |
145 | BOOST_TEST(!parse("c", g).hit); | |
146 | ||
147 | BOOST_TEST(!parse("c 1", g, space_p).hit); | |
148 | BOOST_TEST(!parse("c ,", g, space_p).hit); | |
149 | BOOST_TEST(parse("c bcd", g, space_p).full); | |
150 | BOOST_TEST(!parse("c ", g, space_p).hit); | |
151 | ||
152 | BOOST_TEST(parse("d1", g).hit); | |
153 | BOOST_TEST(parse("d,", g).hit); | |
154 | BOOST_TEST(parse("dbcd", g).hit); | |
155 | BOOST_TEST(parse("d", g).full); | |
156 | ||
157 | BOOST_TEST(parse("d 1", g, space_p).hit); | |
158 | BOOST_TEST(parse("d ,", g, space_p).hit); | |
159 | BOOST_TEST(parse("d bcd", g, space_p).hit); | |
160 | BOOST_TEST(parse(" d", g, space_p).full); // JDG 10-18-2005 removed trailing ' ' to | |
161 | // avoid post skip problems | |
162 | ||
163 | BOOST_TEST(parse(" a 1 b , c bcd d", *g, space_p).full); | |
164 | // JDG 10-18-2005 removed trailing ' ' to avoid post skip problems | |
165 | } | |
166 | }; | |
167 | ||
168 | // Tests for unknown (to the grammar) sequences | |
169 | struct check_grammar_unknown_default { | |
170 | ||
171 | template <typename GrammarT> | |
172 | void operator()(GrammarT) | |
173 | { | |
174 | GrammarT g; | |
175 | ||
176 | BOOST_TEST(!parse("x1", g).hit); | |
177 | BOOST_TEST(!parse("x,", g).hit); | |
178 | BOOST_TEST(!parse("xbcd", g).hit); | |
179 | ||
180 | BOOST_TEST(!parse("x 1", g, space_p).hit); | |
181 | BOOST_TEST(!parse("x ,", g, space_p).hit); | |
182 | BOOST_TEST(!parse("x bcd", g, space_p).hit); | |
183 | } | |
184 | }; | |
185 | ||
186 | } // namespace tests | |
187 | ||
188 | int | |
189 | main() | |
190 | { | |
191 | // Test switch_p without any default_p case branches | |
192 | typedef boost::mpl::list< | |
193 | test_grammars::switch_grammar_direct, | |
194 | test_grammars::switch_grammar_parser, | |
195 | test_grammars::switch_grammar_actor | |
196 | > grammar_list_t; | |
197 | ||
198 | boost::mpl::for_each<grammar_list_t>(tests::check_grammar_known()); | |
199 | boost::mpl::for_each<grammar_list_t>(tests::check_grammar_unknown_default()); | |
200 | ||
201 | return boost::report_errors(); | |
202 | } |