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