File indexing completed on 2025-01-18 09:53:50
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007
0009 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007
0010
0011
0012 #if defined(_MSC_VER)
0013 # pragma once
0014 #endif
0015
0016 #include <boost/mpl/assert.hpp>
0017 #include <boost/type_traits/is_same.hpp>
0018 #include <boost/xpressive/detail/detail_fwd.hpp>
0019 #include <boost/xpressive/detail/static/static.hpp>
0020 #include <boost/proto/core.hpp>
0021
0022 namespace boost { namespace xpressive { namespace detail
0023 {
0024
0025
0026 template<uint_t Min, uint_t Max>
0027 struct generic_quant_tag
0028 {
0029 typedef mpl::integral_c<uint_t, Min> min_type;
0030 typedef mpl::integral_c<uint_t, Max> max_type;
0031 };
0032 }}}
0033
0034 namespace boost { namespace xpressive { namespace grammar_detail
0035 {
0036 using detail::uint_t;
0037
0038
0039
0040 template<typename Tag>
0041 struct min_type : Tag::min_type {};
0042
0043 template<>
0044 struct min_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, 1> {};
0045
0046 template<>
0047 struct min_type<proto::tag::dereference> : mpl::integral_c<uint_t, 0> {};
0048
0049 template<>
0050 struct min_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 0> {};
0051
0052 template<typename Tag>
0053 struct max_type : Tag::max_type {};
0054
0055 template<>
0056 struct max_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, UINT_MAX-1> {};
0057
0058 template<>
0059 struct max_type<proto::tag::dereference> : mpl::integral_c<uint_t, UINT_MAX-1> {};
0060
0061 template<>
0062 struct max_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 1> {};
0063
0064
0065
0066 template<typename Grammar, typename Greedy, typename Callable = proto::callable>
0067 struct as_simple_quantifier : proto::transform<as_simple_quantifier<Grammar, Greedy, Callable> >
0068 {
0069 template<typename Expr, typename State, typename Data>
0070 struct impl : proto::transform_impl<Expr, State, Data>
0071 {
0072 typedef
0073 typename proto::result_of::child<Expr>::type
0074 arg_type;
0075
0076 typedef
0077 typename Grammar::template impl<arg_type, detail::true_xpression, Data>::result_type
0078 xpr_type;
0079
0080 typedef
0081 detail::simple_repeat_matcher<xpr_type, Greedy>
0082 matcher_type;
0083
0084 typedef
0085 typename proto::terminal<matcher_type>::type
0086 result_type;
0087
0088 result_type operator ()(
0089 typename impl::expr_param expr
0090 , typename impl::state_param
0091 , typename impl::data_param data
0092 ) const
0093 {
0094 xpr_type xpr = typename Grammar::template impl<arg_type, detail::true_xpression, Data>()(
0095 proto::child(expr)
0096 , detail::true_xpression()
0097 , data
0098 );
0099
0100 typedef typename impl::expr expr_type;
0101 matcher_type matcher(
0102 xpr
0103 , (uint_t)min_type<typename expr_type::proto_tag>::value
0104 , (uint_t)max_type<typename expr_type::proto_tag>::value
0105 , xpr.get_width().value()
0106 );
0107
0108 return result_type::make(matcher);
0109 }
0110 };
0111 };
0112
0113
0114
0115 struct add_hidden_mark : proto::transform<add_hidden_mark>
0116 {
0117 template<typename Expr, typename State, typename Data>
0118 struct impl : proto::transform_impl<Expr, State, Data>
0119 {
0120 typedef typename impl::expr expr_type;
0121 typedef
0122 typename shift_right<
0123 terminal<detail::mark_begin_matcher>::type
0124 , typename shift_right<
0125 Expr
0126 , terminal<detail::mark_end_matcher>::type
0127 >::type
0128 >::type
0129 result_type;
0130
0131 result_type operator ()(
0132 typename impl::expr_param expr
0133 , typename impl::state_param
0134 , typename impl::data_param data
0135 ) const
0136 {
0137
0138 int mark_nbr = data.get_hidden_mark();
0139 detail::mark_begin_matcher begin(mark_nbr);
0140 detail::mark_end_matcher end(mark_nbr);
0141
0142 result_type that = {{begin}, {expr, {end}}};
0143 return that;
0144 }
0145 };
0146 };
0147
0148
0149
0150 struct InsertMark
0151 : or_<
0152 when<proto::assign<detail::basic_mark_tag, _>, _>
0153 , otherwise<add_hidden_mark>
0154 >
0155 {};
0156
0157
0158
0159 template<typename Greedy, uint_t Min, uint_t Max>
0160 struct as_default_quantifier_impl : proto::transform<as_default_quantifier_impl<Greedy, Min, Max> >
0161 {
0162 template<typename Expr, typename State, typename Data>
0163 struct impl : proto::transform_impl<Expr, State, Data>
0164 {
0165 typedef
0166 typename proto::result_of::child<Expr>::type
0167 xpr_type;
0168
0169 typedef
0170 typename InsertMark::impl<xpr_type, State, Data>::result_type
0171 marked_sub_type;
0172
0173 typedef
0174 typename shift_right<
0175 terminal<detail::repeat_begin_matcher>::type
0176 , typename shift_right<
0177 marked_sub_type
0178 , typename terminal<detail::repeat_end_matcher<Greedy> >::type
0179 >::type
0180 >::type
0181 result_type;
0182
0183 result_type operator ()(
0184 typename impl::expr_param expr
0185 , typename impl::state_param state
0186 , typename impl::data_param data
0187 ) const
0188 {
0189
0190 marked_sub_type marked_sub =
0191 InsertMark::impl<xpr_type, State, Data>()(proto::child(expr), state, data);
0192
0193
0194 int mark_number = proto::value(proto::left(marked_sub)).mark_number_;
0195 BOOST_ASSERT(0 != mark_number);
0196
0197 typedef typename impl::expr expr_type;
0198 uint_t min_ = (uint_t)min_type<typename expr_type::proto_tag>();
0199 uint_t max_ = (uint_t)max_type<typename expr_type::proto_tag>();
0200
0201 detail::repeat_begin_matcher begin(mark_number);
0202 detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_);
0203
0204 result_type that = {{begin}, {marked_sub, {end}}};
0205 return that;
0206 }
0207 };
0208 };
0209
0210
0211
0212 template<typename Greedy>
0213 struct optional_tag
0214 {};
0215
0216
0217
0218 template<typename Grammar, typename Greedy, typename Callable = proto::callable>
0219 struct as_default_optional : proto::transform<as_default_optional<Grammar, Greedy, Callable> >
0220 {
0221 template<typename Expr, typename State, typename Data>
0222 struct impl : proto::transform_impl<Expr, State, Data>
0223 {
0224 typedef
0225 detail::alternate_end_xpression
0226 end_xpr;
0227
0228 typedef
0229 detail::optional_matcher<
0230 typename Grammar::template impl<Expr, end_xpr, Data>::result_type
0231 , Greedy
0232 >
0233 result_type;
0234
0235 result_type operator ()(
0236 typename impl::expr_param expr
0237 , typename impl::state_param
0238 , typename impl::data_param data
0239 ) const
0240 {
0241 return result_type(
0242 typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data)
0243 );
0244 }
0245 };
0246 };
0247
0248
0249
0250 template<typename Grammar, typename Greedy, typename Callable = proto::callable>
0251 struct as_mark_optional : proto::transform<as_mark_optional<Grammar, Greedy, Callable> >
0252 {
0253 template<typename Expr, typename State, typename Data>
0254 struct impl : proto::transform_impl<Expr, State, Data>
0255 {
0256 typedef
0257 detail::alternate_end_xpression
0258 end_xpr;
0259
0260 typedef
0261 detail::optional_mark_matcher<
0262 typename Grammar::template impl<Expr, end_xpr, Data>::result_type
0263 , Greedy
0264 >
0265 result_type;
0266
0267 result_type operator ()(
0268 typename impl::expr_param expr
0269 , typename impl::state_param
0270 , typename impl::data_param data
0271 ) const
0272 {
0273 int mark_number = proto::value(proto::left(expr)).mark_number_;
0274
0275 return result_type(
0276 typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data)
0277 , mark_number
0278 );
0279 }
0280 };
0281 };
0282
0283
0284
0285 struct IsMarkerOrRepeater
0286 : or_<
0287 shift_right<terminal<detail::repeat_begin_matcher>, _>
0288 , assign<terminal<detail::mark_placeholder>, _>
0289 >
0290 {};
0291
0292
0293
0294 template<typename Grammar, typename Greedy>
0295 struct as_optional
0296 : or_<
0297 when<IsMarkerOrRepeater, as_mark_optional<Grammar, Greedy> >
0298 , otherwise<as_default_optional<Grammar, Greedy> >
0299 >
0300 {};
0301
0302
0303
0304 template<typename Greedy, typename Callable = proto::callable>
0305 struct make_optional_ : proto::transform<make_optional_<Greedy, Callable> >
0306 {
0307 template<typename Expr, typename State, typename Data>
0308 struct impl : proto::transform_impl<Expr, State, Data>
0309 {
0310 typedef typename impl::expr expr_type;
0311 typedef
0312 typename unary_expr<
0313 optional_tag<Greedy>
0314 , Expr
0315 >::type
0316 result_type;
0317
0318 result_type operator ()(
0319 typename impl::expr_param expr
0320 , typename impl::state_param
0321 , typename impl::data_param
0322 ) const
0323 {
0324 result_type that = {expr};
0325 return that;
0326 }
0327 };
0328 };
0329
0330
0331
0332 template<typename Greedy, uint_t Max>
0333 struct as_default_quantifier_impl<Greedy, 0, Max>
0334 : call<make_optional_<Greedy>(as_default_quantifier_impl<Greedy, 1, Max>)>
0335 {};
0336
0337
0338
0339 template<typename Greedy>
0340 struct as_default_quantifier_impl<Greedy, 0, 1>
0341 : call<make_optional_<Greedy>(_child)>
0342 {};
0343
0344
0345
0346 template<typename Greedy, typename Callable = proto::callable>
0347 struct as_default_quantifier : proto::transform<as_default_quantifier<Greedy, Callable> >
0348 {
0349 template<typename Expr, typename State, typename Data>
0350 struct impl : proto::transform_impl<Expr, State, Data>
0351 {
0352 typedef typename impl::expr expr_type;
0353 typedef
0354 as_default_quantifier_impl<
0355 Greedy
0356 , min_type<typename expr_type::proto_tag>::value
0357 , max_type<typename expr_type::proto_tag>::value
0358 >
0359 other;
0360
0361 typedef
0362 typename other::template impl<Expr, State, Data>::result_type
0363 result_type;
0364
0365 result_type operator ()(
0366 typename impl::expr_param expr
0367 , typename impl::state_param state
0368 , typename impl::data_param data
0369 ) const
0370 {
0371 return typename other::template impl<Expr, State, Data>()(expr, state, data);
0372 }
0373 };
0374 };
0375
0376 }}}
0377
0378 #endif