]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // grammar.hpp | |
3 | // | |
4 | // Copyright 2008 Eric Niebler. Distributed under the Boost | |
5 | // Software License, Version 1.0. (See accompanying file | |
6 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
7 | ||
8 | #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_GRAMMAR_HPP_EAN_11_12_2006 | |
9 | #define BOOST_XPRESSIVE_DETAIL_STATIC_GRAMMAR_HPP_EAN_11_12_2006 | |
10 | ||
11 | // MS compatible compilers support #pragma once | |
12 | #if defined(_MSC_VER) | |
13 | # pragma once | |
14 | #endif | |
15 | ||
16 | #include <boost/mpl/if.hpp> | |
17 | #include <boost/mpl/bool.hpp> | |
18 | #include <boost/mpl/assert.hpp> | |
19 | #include <boost/proto/core.hpp> | |
20 | #include <boost/xpressive/detail/static/is_pure.hpp> | |
21 | #include <boost/xpressive/detail/static/transforms/as_matcher.hpp> | |
22 | #include <boost/xpressive/detail/static/transforms/as_alternate.hpp> | |
23 | #include <boost/xpressive/detail/static/transforms/as_sequence.hpp> | |
24 | #include <boost/xpressive/detail/static/transforms/as_quantifier.hpp> | |
25 | #include <boost/xpressive/detail/static/transforms/as_marker.hpp> | |
26 | #include <boost/xpressive/detail/static/transforms/as_set.hpp> | |
27 | #include <boost/xpressive/detail/static/transforms/as_independent.hpp> | |
28 | #include <boost/xpressive/detail/static/transforms/as_modifier.hpp> | |
29 | #include <boost/xpressive/detail/static/transforms/as_inverse.hpp> | |
30 | #include <boost/xpressive/detail/static/transforms/as_action.hpp> | |
31 | #include <boost/xpressive/detail/detail_fwd.hpp> | |
32 | ||
33 | #define BOOST_XPRESSIVE_CHECK_REGEX(Expr, Char)\ | |
34 | BOOST_MPL_ASSERT\ | |
35 | ((\ | |
36 | typename boost::mpl::if_c<\ | |
37 | boost::xpressive::is_valid_regex<Expr, Char>::value\ | |
38 | , boost::mpl::true_\ | |
39 | , boost::xpressive::INVALID_REGULAR_EXPRESSION\ | |
40 | >::type\ | |
41 | )); | |
42 | ||
43 | ////////////////////////////////////////////////////////////////////////// | |
44 | //**********************************************************************// | |
45 | //* << NOTE! >> *// | |
46 | //* *// | |
47 | //* Whenever you change this grammar, you MUST also make corresponding *// | |
48 | //* changes to width_of.hpp and is_pure.hpp. *// | |
49 | //* *// | |
50 | //**********************************************************************// | |
51 | ////////////////////////////////////////////////////////////////////////// | |
52 | ||
53 | namespace boost { namespace xpressive | |
54 | { | |
55 | template<typename Char> | |
56 | struct Grammar; | |
57 | ||
58 | template<typename Char> | |
59 | struct ActionableGrammar; | |
60 | ||
61 | namespace grammar_detail | |
62 | { | |
63 | /////////////////////////////////////////////////////////////////////////// | |
64 | // CharLiteral | |
65 | template<typename Char> | |
66 | struct CharLiteral; | |
67 | ||
68 | /////////////////////////////////////////////////////////////////////////// | |
69 | // ListSet | |
70 | template<typename Char> | |
71 | struct ListSet; | |
72 | ||
73 | /////////////////////////////////////////////////////////////////////////// | |
74 | // as_repeat | |
75 | template<typename Char, typename Gram, typename Greedy> | |
76 | struct as_repeat | |
77 | : if_< | |
78 | make<detail::use_simple_repeat<_child, Char> > | |
79 | , as_simple_quantifier<Gram, Greedy> | |
80 | , as_default_quantifier<Greedy> | |
81 | > | |
82 | {}; | |
83 | ||
84 | /////////////////////////////////////////////////////////////////////////// | |
85 | // NonGreedyRepeatCases | |
86 | template<typename Gram> | |
87 | struct NonGreedyRepeatCases | |
88 | { | |
89 | template<typename Tag, typename Dummy = void> | |
90 | struct case_ | |
91 | : not_<_> | |
92 | {}; | |
93 | ||
94 | template<typename Dummy> | |
95 | struct case_<tag::dereference, Dummy> | |
96 | : dereference<Gram> | |
97 | {}; | |
98 | ||
99 | template<typename Dummy> | |
100 | struct case_<tag::unary_plus, Dummy> | |
101 | : unary_plus<Gram> | |
102 | {}; | |
103 | ||
104 | template<typename Dummy> | |
105 | struct case_<tag::logical_not, Dummy> | |
106 | : logical_not<Gram> | |
107 | {}; | |
108 | ||
109 | template<uint_t Min, uint_t Max, typename Dummy> | |
110 | struct case_<detail::generic_quant_tag<Min, Max>, Dummy> | |
111 | : unary_expr<detail::generic_quant_tag<Min, Max>, Gram> | |
112 | {}; | |
113 | }; | |
114 | ||
115 | /////////////////////////////////////////////////////////////////////////// | |
116 | // InvertibleCases | |
117 | template<typename Char, typename Gram> | |
118 | struct InvertibleCases | |
119 | { | |
120 | template<typename Tag, typename Dummy = void> | |
121 | struct case_ | |
122 | : not_<_> | |
123 | {}; | |
124 | ||
125 | template<typename Dummy> | |
126 | struct case_<tag::comma, Dummy> | |
127 | : when<ListSet<Char>, as_list_set_matcher<Char> > | |
128 | {}; | |
129 | ||
130 | template<typename Dummy> | |
131 | struct case_<tag::assign, Dummy> | |
132 | : when<ListSet<Char>, as_list_set_matcher<Char> > | |
133 | {}; | |
134 | ||
135 | template<typename Dummy> | |
136 | struct case_<tag::subscript, Dummy> | |
137 | : when<subscript<detail::set_initializer_type, Gram>, call<as_set_matcher<Gram>(_right)> > | |
138 | {}; | |
139 | ||
140 | template<typename Dummy> | |
141 | struct case_<detail::lookahead_tag, Dummy> | |
142 | : when< | |
143 | unary_expr<detail::lookahead_tag, Gram> | |
144 | , as_lookahead<Gram> | |
145 | > | |
146 | {}; | |
147 | ||
148 | template<typename Dummy> | |
149 | struct case_<detail::lookbehind_tag, Dummy> | |
150 | : when< | |
151 | unary_expr<detail::lookbehind_tag, Gram> | |
152 | , as_lookbehind<Gram> | |
153 | > | |
154 | {}; | |
155 | ||
156 | template<typename Dummy> | |
157 | struct case_<tag::terminal, Dummy> | |
158 | : when< | |
159 | or_< | |
160 | CharLiteral<Char> | |
161 | , terminal<detail::posix_charset_placeholder> | |
162 | , terminal<detail::range_placeholder<_> > | |
163 | , terminal<detail::logical_newline_placeholder> | |
164 | , terminal<detail::assert_word_placeholder<detail::word_boundary<mpl::true_> > > | |
165 | > | |
166 | , as_matcher | |
167 | > | |
168 | {}; | |
169 | }; | |
170 | ||
171 | /////////////////////////////////////////////////////////////////////////// | |
172 | // Cases | |
173 | template<typename Char, typename Gram> | |
174 | struct Cases | |
175 | { | |
176 | template<typename Tag, typename Dummy = void> | |
177 | struct case_ | |
178 | : not_<_> | |
179 | {}; | |
180 | ||
181 | template<typename Dummy> | |
182 | struct case_<tag::terminal, Dummy> | |
183 | : when< | |
184 | _ | |
185 | , in_sequence<as_matcher> | |
186 | > | |
187 | {}; | |
188 | ||
189 | template<typename Dummy> | |
190 | struct case_<tag::shift_right, Dummy> | |
191 | : when< | |
192 | shift_right<Gram, Gram> | |
193 | , reverse_fold<_, _state, Gram> | |
194 | > | |
195 | {}; | |
196 | ||
197 | template<typename Dummy> | |
198 | struct case_<tag::bitwise_or, Dummy> | |
199 | : when< | |
200 | bitwise_or<Gram, Gram> | |
201 | , in_sequence< | |
202 | as_alternate_matcher< | |
203 | reverse_fold_tree<_, make<fusion::nil>, in_alternate_list<Gram> > | |
204 | > | |
205 | > | |
206 | > | |
207 | {}; | |
208 | ||
209 | template<typename Dummy, typename Greedy> | |
210 | struct case_<optional_tag<Greedy> , Dummy> | |
211 | : when< | |
212 | unary_expr<optional_tag<Greedy>, Gram> | |
213 | , in_sequence<call<as_optional<Gram, Greedy>(_child)> > | |
214 | > | |
215 | {}; | |
216 | ||
217 | template<typename Dummy> | |
218 | struct case_<tag::dereference, Dummy> | |
219 | : when< | |
220 | dereference<Gram> | |
221 | , call<Gram(as_repeat<Char, Gram, mpl::true_>)> | |
222 | > | |
223 | {}; | |
224 | ||
225 | template<typename Dummy> | |
226 | struct case_<tag::unary_plus, Dummy> | |
227 | : when< | |
228 | unary_plus<Gram> | |
229 | , call<Gram(as_repeat<Char, Gram, mpl::true_>)> | |
230 | > | |
231 | {}; | |
232 | ||
233 | template<typename Dummy> | |
234 | struct case_<tag::logical_not, Dummy> | |
235 | : when< | |
236 | logical_not<Gram> | |
237 | , call<Gram(as_repeat<Char, Gram, mpl::true_>)> | |
238 | > | |
239 | {}; | |
240 | ||
241 | template<uint_t Min, uint_t Max, typename Dummy> | |
242 | struct case_<detail::generic_quant_tag<Min, Max>, Dummy> | |
243 | : when< | |
244 | unary_expr<detail::generic_quant_tag<Min, Max>, Gram> | |
245 | , call<Gram(as_repeat<Char, Gram, mpl::true_>)> | |
246 | > | |
247 | {}; | |
248 | ||
249 | template<typename Dummy> | |
250 | struct case_<tag::negate, Dummy> | |
251 | : when< | |
252 | negate<switch_<NonGreedyRepeatCases<Gram> > > | |
253 | , call<Gram(call<as_repeat<Char, Gram, mpl::false_>(_child)>)> | |
254 | > | |
255 | {}; | |
256 | ||
257 | template<typename Dummy> | |
258 | struct case_<tag::complement, Dummy> | |
259 | : when< | |
260 | complement<switch_<InvertibleCases<Char, Gram> > > | |
261 | , in_sequence<call<as_inverse(call<switch_<InvertibleCases<Char, Gram> >(_child)>)> > | |
262 | > | |
263 | {}; | |
264 | ||
265 | template<typename Dummy> | |
266 | struct case_<detail::modifier_tag, Dummy> | |
267 | : when<binary_expr<detail::modifier_tag, _, Gram>, as_modifier<Gram> > | |
268 | {}; | |
269 | ||
270 | template<typename Dummy> | |
271 | struct case_<detail::lookahead_tag, Dummy> | |
272 | : when< | |
273 | unary_expr<detail::lookahead_tag, Gram> | |
274 | , in_sequence<as_lookahead<Gram> > | |
275 | > | |
276 | {}; | |
277 | ||
278 | template<typename Dummy> | |
279 | struct case_<detail::lookbehind_tag, Dummy> | |
280 | : when< | |
281 | unary_expr<detail::lookbehind_tag, Gram> | |
282 | , in_sequence<as_lookbehind<Gram> > | |
283 | > | |
284 | {}; | |
285 | ||
286 | template<typename Dummy> | |
287 | struct case_<detail::keeper_tag, Dummy> | |
288 | : when< | |
289 | unary_expr<detail::keeper_tag, Gram> | |
290 | , in_sequence<as_keeper<Gram> > | |
291 | > | |
292 | {}; | |
293 | ||
294 | template<typename Dummy> | |
295 | struct case_<tag::comma, Dummy> | |
296 | : when<ListSet<Char>, in_sequence<as_list_set_matcher<Char> > > | |
297 | {}; | |
298 | ||
299 | template<typename Dummy> | |
300 | struct case_<tag::assign, Dummy> | |
301 | : or_< | |
302 | when<assign<detail::basic_mark_tag, Gram>, call<Gram(as_marker)> > | |
303 | , when<ListSet<Char>, in_sequence<as_list_set_matcher<Char> > > | |
304 | > | |
305 | {}; | |
306 | ||
307 | template<typename Dummy> | |
308 | struct case_<tag::subscript, Dummy> | |
309 | : or_< | |
310 | when<subscript<detail::set_initializer_type, Gram>, in_sequence<call<as_set_matcher<Gram>(_right)> > > | |
311 | , when<subscript<ActionableGrammar<Char>, _>, call<ActionableGrammar<Char>(as_action)> > | |
312 | > | |
313 | {}; | |
314 | }; | |
315 | ||
316 | /////////////////////////////////////////////////////////////////////////// | |
317 | // ActionableCases | |
318 | template<typename Char, typename Gram> | |
319 | struct ActionableCases | |
320 | { | |
321 | template<typename Tag, typename Dummy = void> | |
322 | struct case_ | |
323 | : Cases<Char, Gram>::template case_<Tag> | |
324 | {}; | |
325 | ||
326 | // Only in sub-expressions with actions attached do we allow attribute assignements | |
327 | template<typename Dummy> | |
328 | struct case_<proto::tag::assign, Dummy> | |
329 | : or_< | |
330 | typename Cases<Char, Gram>::template case_<proto::tag::assign> | |
331 | , when<proto::assign<terminal<detail::attribute_placeholder<_> >, _>, in_sequence<as_attr_matcher> > | |
332 | > | |
333 | {}; | |
334 | }; | |
335 | ||
336 | } // namespace detail | |
337 | ||
338 | /////////////////////////////////////////////////////////////////////////// | |
339 | // Grammar | |
340 | template<typename Char> | |
341 | struct Grammar | |
342 | : proto::switch_<grammar_detail::Cases<Char, Grammar<Char> > > | |
343 | {}; | |
344 | ||
345 | template<typename Char> | |
346 | struct ActionableGrammar | |
347 | : proto::switch_<grammar_detail::ActionableCases<Char, ActionableGrammar<Char> > > | |
348 | {}; | |
349 | ||
350 | /////////////////////////////////////////////////////////////////////////// | |
351 | // INVALID_REGULAR_EXPRESSION | |
352 | struct INVALID_REGULAR_EXPRESSION | |
353 | : mpl::false_ | |
354 | {}; | |
355 | ||
356 | /////////////////////////////////////////////////////////////////////////// | |
357 | // is_valid_regex | |
358 | template<typename Expr, typename Char> | |
359 | struct is_valid_regex | |
360 | : proto::matches<Expr, Grammar<Char> > | |
361 | {}; | |
362 | ||
363 | }} // namespace boost::xpressive | |
364 | ||
365 | #endif |