1 /////////////////////////////////////////////////////////////////////////////// 2 // as_quantifier.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_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 9 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 10 11 // MS compatible compilers support #pragma once 12 #if defined(_MSC_VER) 13 # pragma once 14 #endif 15 16 #include <boost/mpl/assert.hpp> 17 #include <boost/type_traits/is_same.hpp> 18 #include <boost/xpressive/detail/detail_fwd.hpp> 19 #include <boost/xpressive/detail/static/static.hpp> 20 #include <boost/proto/core.hpp> 21 22 namespace boost { namespace xpressive { namespace detail 23 { 24 /////////////////////////////////////////////////////////////////////////////// 25 // generic_quant_tag 26 template<uint_t Min, uint_t Max> 27 struct generic_quant_tag 28 { 29 typedef mpl::integral_c<uint_t, Min> min_type; 30 typedef mpl::integral_c<uint_t, Max> max_type; 31 }; 32 }}} 33 34 namespace boost { namespace xpressive { namespace grammar_detail 35 { 36 using detail::uint_t; 37 38 /////////////////////////////////////////////////////////////////////////////// 39 // min_type / max_type 40 template<typename Tag> 41 struct min_type : Tag::min_type {}; 42 43 template<> 44 struct min_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, 1> {}; 45 46 template<> 47 struct min_type<proto::tag::dereference> : mpl::integral_c<uint_t, 0> {}; 48 49 template<> 50 struct min_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 0> {}; 51 52 template<typename Tag> 53 struct max_type : Tag::max_type {}; 54 55 template<> 56 struct max_type<proto::tag::unary_plus> : mpl::integral_c<uint_t, UINT_MAX-1> {}; 57 58 template<> 59 struct max_type<proto::tag::dereference> : mpl::integral_c<uint_t, UINT_MAX-1> {}; 60 61 template<> 62 struct max_type<proto::tag::logical_not> : mpl::integral_c<uint_t, 1> {}; 63 64 /////////////////////////////////////////////////////////////////////////////// 65 // as_simple_quantifier 66 template<typename Grammar, typename Greedy, typename Callable = proto::callable> 67 struct as_simple_quantifier : proto::transform<as_simple_quantifier<Grammar, Greedy, Callable> > 68 { 69 template<typename Expr, typename State, typename Data> 70 struct impl : proto::transform_impl<Expr, State, Data> 71 { 72 typedef 73 typename proto::result_of::child<Expr>::type 74 arg_type; 75 76 typedef 77 typename Grammar::template impl<arg_type, detail::true_xpression, Data>::result_type 78 xpr_type; 79 80 typedef 81 detail::simple_repeat_matcher<xpr_type, Greedy> 82 matcher_type; 83 84 typedef 85 typename proto::terminal<matcher_type>::type 86 result_type; 87 operator ()boost::xpressive::grammar_detail::as_simple_quantifier::impl88 result_type operator ()( 89 typename impl::expr_param expr 90 , typename impl::state_param 91 , typename impl::data_param data 92 ) const 93 { 94 xpr_type xpr = typename Grammar::template impl<arg_type, detail::true_xpression, Data>()( 95 proto::child(expr) 96 , detail::true_xpression() 97 , data 98 ); 99 100 typedef typename impl::expr expr_type; 101 matcher_type matcher( 102 xpr 103 , (uint_t)min_type<typename expr_type::proto_tag>::value 104 , (uint_t)max_type<typename expr_type::proto_tag>::value 105 , xpr.get_width().value() 106 ); 107 108 return result_type::make(matcher); 109 } 110 }; 111 }; 112 113 /////////////////////////////////////////////////////////////////////////////// 114 // add_hidden_mark 115 struct add_hidden_mark : proto::transform<add_hidden_mark> 116 { 117 template<typename Expr, typename State, typename Data> 118 struct impl : proto::transform_impl<Expr, State, Data> 119 { 120 typedef typename impl::expr expr_type; 121 typedef 122 typename shift_right< 123 terminal<detail::mark_begin_matcher>::type 124 , typename shift_right< 125 Expr 126 , terminal<detail::mark_end_matcher>::type 127 >::type 128 >::type 129 result_type; 130 operator ()boost::xpressive::grammar_detail::add_hidden_mark::impl131 result_type operator ()( 132 typename impl::expr_param expr 133 , typename impl::state_param 134 , typename impl::data_param data 135 ) const 136 { 137 // we're inserting a hidden mark ... so grab the next hidden mark number. 138 int mark_nbr = data.get_hidden_mark(); 139 detail::mark_begin_matcher begin(mark_nbr); 140 detail::mark_end_matcher end(mark_nbr); 141 142 result_type that = {{begin}, {expr, {end}}}; 143 return that; 144 } 145 }; 146 }; 147 148 /////////////////////////////////////////////////////////////////////////////// 149 // InsertMark 150 struct InsertMark 151 : or_< 152 when<proto::assign<detail::basic_mark_tag, _>, _> 153 , otherwise<add_hidden_mark> 154 > 155 {}; 156 157 /////////////////////////////////////////////////////////////////////////////// 158 // as_default_quantifier_impl 159 template<typename Greedy, uint_t Min, uint_t Max> 160 struct as_default_quantifier_impl : proto::transform<as_default_quantifier_impl<Greedy, Min, Max> > 161 { 162 template<typename Expr, typename State, typename Data> 163 struct impl : proto::transform_impl<Expr, State, Data> 164 { 165 typedef 166 typename proto::result_of::child<Expr>::type 167 xpr_type; 168 169 typedef 170 typename InsertMark::impl<xpr_type, State, Data>::result_type 171 marked_sub_type; 172 173 typedef 174 typename shift_right< 175 terminal<detail::repeat_begin_matcher>::type 176 , typename shift_right< 177 marked_sub_type 178 , typename terminal<detail::repeat_end_matcher<Greedy> >::type 179 >::type 180 >::type 181 result_type; 182 operator ()boost::xpressive::grammar_detail::as_default_quantifier_impl::impl183 result_type operator ()( 184 typename impl::expr_param expr 185 , typename impl::state_param state 186 , typename impl::data_param data 187 ) const 188 { 189 // Ensure this sub-expression is book-ended with mark matchers 190 marked_sub_type marked_sub = 191 InsertMark::impl<xpr_type, State, Data>()(proto::child(expr), state, data); 192 193 // Get the mark_number from the begin_mark_matcher 194 int mark_number = proto::value(proto::left(marked_sub)).mark_number_; 195 BOOST_ASSERT(0 != mark_number); 196 197 typedef typename impl::expr expr_type; 198 uint_t min_ = (uint_t)min_type<typename expr_type::proto_tag>(); 199 uint_t max_ = (uint_t)max_type<typename expr_type::proto_tag>(); 200 201 detail::repeat_begin_matcher begin(mark_number); 202 detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_); 203 204 result_type that = {{begin}, {marked_sub, {end}}}; 205 return that; 206 } 207 }; 208 }; 209 210 /////////////////////////////////////////////////////////////////////////////// 211 // optional_tag 212 template<typename Greedy> 213 struct optional_tag 214 {}; 215 216 /////////////////////////////////////////////////////////////////////////////// 217 // as_default_optional 218 template<typename Grammar, typename Greedy, typename Callable = proto::callable> 219 struct as_default_optional : proto::transform<as_default_optional<Grammar, Greedy, Callable> > 220 { 221 template<typename Expr, typename State, typename Data> 222 struct impl : proto::transform_impl<Expr, State, Data> 223 { 224 typedef 225 detail::alternate_end_xpression 226 end_xpr; 227 228 typedef 229 detail::optional_matcher< 230 typename Grammar::template impl<Expr, end_xpr, Data>::result_type 231 , Greedy 232 > 233 result_type; 234 operator ()boost::xpressive::grammar_detail::as_default_optional::impl235 result_type operator ()( 236 typename impl::expr_param expr 237 , typename impl::state_param 238 , typename impl::data_param data 239 ) const 240 { 241 return result_type( 242 typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data) 243 ); 244 } 245 }; 246 }; 247 248 /////////////////////////////////////////////////////////////////////////////// 249 // as_mark_optional 250 template<typename Grammar, typename Greedy, typename Callable = proto::callable> 251 struct as_mark_optional : proto::transform<as_mark_optional<Grammar, Greedy, Callable> > 252 { 253 template<typename Expr, typename State, typename Data> 254 struct impl : proto::transform_impl<Expr, State, Data> 255 { 256 typedef 257 detail::alternate_end_xpression 258 end_xpr; 259 260 typedef 261 detail::optional_mark_matcher< 262 typename Grammar::template impl<Expr, end_xpr, Data>::result_type 263 , Greedy 264 > 265 result_type; 266 operator ()boost::xpressive::grammar_detail::as_mark_optional::impl267 result_type operator ()( 268 typename impl::expr_param expr 269 , typename impl::state_param 270 , typename impl::data_param data 271 ) const 272 { 273 int mark_number = proto::value(proto::left(expr)).mark_number_; 274 275 return result_type( 276 typename Grammar::template impl<Expr, end_xpr, Data>()(expr, end_xpr(), data) 277 , mark_number 278 ); 279 } 280 }; 281 }; 282 283 /////////////////////////////////////////////////////////////////////////////// 284 // IsMarkerOrRepeater 285 struct IsMarkerOrRepeater 286 : or_< 287 shift_right<terminal<detail::repeat_begin_matcher>, _> 288 , assign<terminal<detail::mark_placeholder>, _> 289 > 290 {}; 291 292 /////////////////////////////////////////////////////////////////////////////// 293 // as_optional 294 template<typename Grammar, typename Greedy> 295 struct as_optional 296 : or_< 297 when<IsMarkerOrRepeater, as_mark_optional<Grammar, Greedy> > 298 , otherwise<as_default_optional<Grammar, Greedy> > 299 > 300 {}; 301 302 /////////////////////////////////////////////////////////////////////////////// 303 // make_optional_ 304 template<typename Greedy, typename Callable = proto::callable> 305 struct make_optional_ : proto::transform<make_optional_<Greedy, Callable> > 306 { 307 template<typename Expr, typename State, typename Data> 308 struct impl : proto::transform_impl<Expr, State, Data> 309 { 310 typedef typename impl::expr expr_type; 311 typedef 312 typename unary_expr< 313 optional_tag<Greedy> 314 , Expr 315 >::type 316 result_type; 317 operator ()boost::xpressive::grammar_detail::make_optional_::impl318 result_type operator ()( 319 typename impl::expr_param expr 320 , typename impl::state_param 321 , typename impl::data_param 322 ) const 323 { 324 result_type that = {expr}; 325 return that; 326 } 327 }; 328 }; 329 330 /////////////////////////////////////////////////////////////////////////////// 331 // as_default_quantifier_impl 332 template<typename Greedy, uint_t Max> 333 struct as_default_quantifier_impl<Greedy, 0, Max> 334 : call<make_optional_<Greedy>(as_default_quantifier_impl<Greedy, 1, Max>)> 335 {}; 336 337 /////////////////////////////////////////////////////////////////////////////// 338 // as_default_quantifier_impl 339 template<typename Greedy> 340 struct as_default_quantifier_impl<Greedy, 0, 1> 341 : call<make_optional_<Greedy>(_child)> 342 {}; 343 344 /////////////////////////////////////////////////////////////////////////////// 345 // as_default_quantifier 346 template<typename Greedy, typename Callable = proto::callable> 347 struct as_default_quantifier : proto::transform<as_default_quantifier<Greedy, Callable> > 348 { 349 template<typename Expr, typename State, typename Data> 350 struct impl : proto::transform_impl<Expr, State, Data> 351 { 352 typedef typename impl::expr expr_type; 353 typedef 354 as_default_quantifier_impl< 355 Greedy 356 , min_type<typename expr_type::proto_tag>::value 357 , max_type<typename expr_type::proto_tag>::value 358 > 359 other; 360 361 typedef 362 typename other::template impl<Expr, State, Data>::result_type 363 result_type; 364 operator ()boost::xpressive::grammar_detail::as_default_quantifier::impl365 result_type operator ()( 366 typename impl::expr_param expr 367 , typename impl::state_param state 368 , typename impl::data_param data 369 ) const 370 { 371 return typename other::template impl<Expr, State, Data>()(expr, state, data); 372 } 373 }; 374 }; 375 376 }}} 377 378 #endif 379