Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:50

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // as_quantifier.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // MS compatible compilers support #pragma once
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     // generic_quant_tag
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     // min_type / max_type
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     // as_simple_quantifier
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     // add_hidden_mark
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                 // we're inserting a hidden mark ... so grab the next hidden mark number.
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     // InsertMark
0150     struct InsertMark
0151       : or_<
0152             when<proto::assign<detail::basic_mark_tag, _>, _>
0153           , otherwise<add_hidden_mark>
0154         >
0155     {};
0156 
0157     ///////////////////////////////////////////////////////////////////////////////
0158     // as_default_quantifier_impl
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                 // Ensure this sub-expression is book-ended with mark matchers
0190                 marked_sub_type marked_sub =
0191                     InsertMark::impl<xpr_type, State, Data>()(proto::child(expr), state, data);
0192 
0193                 // Get the mark_number from the begin_mark_matcher
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     // optional_tag
0212     template<typename Greedy>
0213     struct optional_tag
0214     {};
0215 
0216     ///////////////////////////////////////////////////////////////////////////////
0217     // as_default_optional
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     // as_mark_optional
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     // IsMarkerOrRepeater
0285     struct IsMarkerOrRepeater
0286       : or_<
0287             shift_right<terminal<detail::repeat_begin_matcher>, _>
0288           , assign<terminal<detail::mark_placeholder>, _>
0289         >
0290     {};
0291 
0292     ///////////////////////////////////////////////////////////////////////////////
0293     // as_optional
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     // make_optional_
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     // as_default_quantifier_impl
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     // as_default_quantifier_impl
0339     template<typename Greedy>
0340     struct as_default_quantifier_impl<Greedy, 0, 1>
0341       : call<make_optional_<Greedy>(_child)>
0342     {};
0343 
0344     ///////////////////////////////////////////////////////////////////////////////
0345     // as_default_quantifier
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