Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / xpressive / detail / static / grammar.hpp
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