/////////////////////////////////////////////////////////////////////////////// // as_quantifier.hpp // // Copyright 2008 Eric Niebler. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_QUANTIFIER_HPP_EAN_04_01_2007 // MS compatible compilers support #pragma once #if defined(_MSC_VER) # pragma once #endif #include #include #include #include #include namespace boost { namespace xpressive { namespace detail { /////////////////////////////////////////////////////////////////////////////// // generic_quant_tag template struct generic_quant_tag { typedef mpl::integral_c min_type; typedef mpl::integral_c max_type; }; }}} namespace boost { namespace xpressive { namespace grammar_detail { using detail::uint_t; /////////////////////////////////////////////////////////////////////////////// // min_type / max_type template struct min_type : Tag::min_type {}; template<> struct min_type : mpl::integral_c {}; template<> struct min_type : mpl::integral_c {}; template<> struct min_type : mpl::integral_c {}; template struct max_type : Tag::max_type {}; template<> struct max_type : mpl::integral_c {}; template<> struct max_type : mpl::integral_c {}; template<> struct max_type : mpl::integral_c {}; /////////////////////////////////////////////////////////////////////////////// // as_simple_quantifier template struct as_simple_quantifier : proto::transform > { template struct impl : proto::transform_impl { typedef typename proto::result_of::child::type arg_type; typedef typename Grammar::template impl::result_type xpr_type; typedef detail::simple_repeat_matcher matcher_type; typedef typename proto::terminal::type result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param , typename impl::data_param data ) const { xpr_type xpr = typename Grammar::template impl()( proto::child(expr) , detail::true_xpression() , data ); typedef typename impl::expr expr_type; matcher_type matcher( xpr , (uint_t)min_type::value , (uint_t)max_type::value , xpr.get_width().value() ); return result_type::make(matcher); } }; }; /////////////////////////////////////////////////////////////////////////////// // add_hidden_mark struct add_hidden_mark : proto::transform { template struct impl : proto::transform_impl { typedef typename impl::expr expr_type; typedef typename shift_right< terminal::type , typename shift_right< Expr , terminal::type >::type >::type result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param , typename impl::data_param data ) const { // we're inserting a hidden mark ... so grab the next hidden mark number. int mark_nbr = data.get_hidden_mark(); detail::mark_begin_matcher begin(mark_nbr); detail::mark_end_matcher end(mark_nbr); result_type that = {{begin}, {expr, {end}}}; return that; } }; }; /////////////////////////////////////////////////////////////////////////////// // InsertMark struct InsertMark : or_< when, _> , otherwise > {}; /////////////////////////////////////////////////////////////////////////////// // as_default_quantifier_impl template struct as_default_quantifier_impl : proto::transform > { template struct impl : proto::transform_impl { typedef typename proto::result_of::child::type xpr_type; typedef typename InsertMark::impl::result_type marked_sub_type; typedef typename shift_right< terminal::type , typename shift_right< marked_sub_type , typename terminal >::type >::type >::type result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param state , typename impl::data_param data ) const { // Ensure this sub-expression is book-ended with mark matchers marked_sub_type marked_sub = InsertMark::impl()(proto::child(expr), state, data); // Get the mark_number from the begin_mark_matcher int mark_number = proto::value(proto::left(marked_sub)).mark_number_; BOOST_ASSERT(0 != mark_number); typedef typename impl::expr expr_type; uint_t min_ = (uint_t)min_type(); uint_t max_ = (uint_t)max_type(); detail::repeat_begin_matcher begin(mark_number); detail::repeat_end_matcher end(mark_number, min_, max_); result_type that = {{begin}, {marked_sub, {end}}}; return that; } }; }; /////////////////////////////////////////////////////////////////////////////// // optional_tag template struct optional_tag {}; /////////////////////////////////////////////////////////////////////////////// // as_default_optional template struct as_default_optional : proto::transform > { template struct impl : proto::transform_impl { typedef detail::alternate_end_xpression end_xpr; typedef detail::optional_matcher< typename Grammar::template impl::result_type , Greedy > result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param , typename impl::data_param data ) const { return result_type( typename Grammar::template impl()(expr, end_xpr(), data) ); } }; }; /////////////////////////////////////////////////////////////////////////////// // as_mark_optional template struct as_mark_optional : proto::transform > { template struct impl : proto::transform_impl { typedef detail::alternate_end_xpression end_xpr; typedef detail::optional_mark_matcher< typename Grammar::template impl::result_type , Greedy > result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param , typename impl::data_param data ) const { int mark_number = proto::value(proto::left(expr)).mark_number_; return result_type( typename Grammar::template impl()(expr, end_xpr(), data) , mark_number ); } }; }; /////////////////////////////////////////////////////////////////////////////// // IsMarkerOrRepeater struct IsMarkerOrRepeater : or_< shift_right, _> , assign, _> > {}; /////////////////////////////////////////////////////////////////////////////// // as_optional template struct as_optional : or_< when > , otherwise > > {}; /////////////////////////////////////////////////////////////////////////////// // make_optional_ template struct make_optional_ : proto::transform > { template struct impl : proto::transform_impl { typedef typename impl::expr expr_type; typedef typename unary_expr< optional_tag , Expr >::type result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param , typename impl::data_param ) const { result_type that = {expr}; return that; } }; }; /////////////////////////////////////////////////////////////////////////////// // as_default_quantifier_impl template struct as_default_quantifier_impl : call(as_default_quantifier_impl)> {}; /////////////////////////////////////////////////////////////////////////////// // as_default_quantifier_impl template struct as_default_quantifier_impl : call(_child)> {}; /////////////////////////////////////////////////////////////////////////////// // as_default_quantifier template struct as_default_quantifier : proto::transform > { template struct impl : proto::transform_impl { typedef typename impl::expr expr_type; typedef as_default_quantifier_impl< Greedy , min_type::value , max_type::value > other; typedef typename other::template impl::result_type result_type; result_type operator ()( typename impl::expr_param expr , typename impl::state_param state , typename impl::data_param data ) const { return typename other::template impl()(expr, state, data); } }; }; }}} #endif