Back to home page

EIC code displayed by LXR

 
 

    


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

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // as_action.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler.
0005 //  Copyright 2008 David Jenkins.
0006 //
0007 //  Distributed under the Boost Software License, Version 1.0. (See
0008 //  accompanying file LICENSE_1_0.txt or copy at
0009 //  http://www.boost.org/LICENSE_1_0.txt)
0010 
0011 #ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_ACTION_HPP_EAN_04_05_2007
0012 #define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_ACTION_HPP_EAN_04_05_2007
0013 
0014 // MS compatible compilers support #pragma once
0015 #if defined(_MSC_VER)
0016 # pragma once
0017 #endif
0018 
0019 #include <boost/mpl/sizeof.hpp>
0020 #include <boost/mpl/min_max.hpp>
0021 #include <boost/mpl/apply_wrap.hpp>
0022 #include <boost/xpressive/detail/detail_fwd.hpp>
0023 #include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp>
0024 #include <boost/xpressive/detail/static/static.hpp>
0025 #include <boost/xpressive/detail/static/transforms/as_quantifier.hpp>
0026 #include <boost/proto/core.hpp>
0027 #include <boost/proto/transform/arg.hpp>
0028 #include <boost/proto/transform/call.hpp>
0029 #include <boost/proto/transform/make.hpp>
0030 #include <boost/proto/transform/when.hpp>
0031 #include <boost/proto/transform/fold.hpp>
0032 #include <boost/proto/transform/fold_tree.hpp>
0033 
0034 namespace boost { namespace xpressive { namespace detail
0035 {
0036     ///////////////////////////////////////////////////////////////////////////////
0037     // read_attr
0038     //  Placeholder that knows the slot number of an attribute as well as the type
0039     //  of the object stored in it.
0040     template<typename Nbr, typename Matcher>
0041     struct read_attr
0042     {
0043         typedef Nbr nbr_type;
0044         typedef Matcher matcher_type;
0045         static Nbr nbr() { return Nbr(); }
0046     };
0047 
0048     template<typename Nbr, typename Matcher>
0049     struct read_attr<Nbr, Matcher &>
0050     {
0051         typedef Nbr nbr_type;
0052         typedef Matcher matcher_type;
0053     };
0054 
0055 }}}
0056 
0057 namespace boost { namespace xpressive { namespace grammar_detail
0058 {
0059     ///////////////////////////////////////////////////////////////////////////////
0060     // FindAttr
0061     //  Look for patterns like (a1= terminal<RHS>) and return the type of the RHS.
0062     template<typename Nbr>
0063     struct FindAttr
0064       : or_<
0065             // Ignore nested actions, because attributes are scoped
0066             when< subscript<_, _>,                                  _state >
0067           , when< terminal<_>,                                      _state >
0068           , when< proto::assign<terminal<detail::attribute_placeholder<Nbr> >, _>, call<_value(_right)> >
0069           , otherwise< fold<_, _state, FindAttr<Nbr> > >
0070         >
0071     {};
0072 
0073     ///////////////////////////////////////////////////////////////////////////////
0074     // as_read_attr
0075     //  For patterns like (a1 = RHS)[ref(i) = a1], transform to
0076     //  (a1 = RHS)[ref(i) = read_attr<1, RHS>] so that when reading the attribute
0077     //  we know what type is stored in the attribute slot.
0078     struct as_read_attr : proto::transform<as_read_attr>
0079     {
0080         template<typename Expr, typename State, typename Data>
0081         struct impl : proto::transform_impl<Expr, State, Data>
0082         {
0083             typedef typename impl::expr expr_type;
0084             typedef
0085                 typename FindAttr<typename expr_type::proto_child0::nbr_type>::template impl<
0086                     State
0087                   , mpl::void_
0088                   , int
0089                 >::result_type
0090             attr_type;
0091 
0092             typedef
0093                 typename proto::terminal<
0094                     detail::read_attr<
0095                         typename expr_type::proto_child0::nbr_type
0096                       , BOOST_PROTO_UNCVREF(attr_type)
0097                     >
0098                 >::type
0099             result_type;
0100 
0101             result_type operator ()(proto::ignore, proto::ignore, proto::ignore) const
0102             {
0103                 result_type that = {{}};
0104                 return that;
0105             }
0106         };
0107     };
0108 
0109     ///////////////////////////////////////////////////////////////////////////////
0110     // DeepCopy
0111     //  Turn all refs into values, and also bind all attribute placeholders with
0112     //  the types from which they are being assigned.
0113     struct DeepCopy
0114       : or_<
0115             when< terminal<detail::attribute_placeholder<_> >,  as_read_attr>
0116           , when< terminal<_>,                                  proto::_deep_copy>
0117           , otherwise< nary_expr<_, vararg<DeepCopy> > >
0118         >
0119     {};
0120 
0121     ///////////////////////////////////////////////////////////////////////////////
0122     // attr_nbr
0123     //  For an attribute placeholder, return the attribute's slot number.
0124     struct attr_nbr : proto::transform<attr_nbr>
0125     {
0126         template<typename Expr, typename State, typename Data>
0127         struct impl : proto::transform_impl<Expr, State, Data>
0128         {
0129             typedef typename impl::expr expr_type;
0130             typedef typename expr_type::proto_child0::nbr_type::type result_type;
0131         };
0132     };
0133 
0134     struct max_attr;
0135 
0136     ///////////////////////////////////////////////////////////////////////////////
0137     // MaxAttr
0138     //  In an action (rx)[act], find the largest attribute slot being used.
0139     struct MaxAttr
0140       : or_<
0141             when< terminal<detail::attribute_placeholder<_> >, attr_nbr>
0142           , when< terminal<_>, make<mpl::int_<0> > >
0143             // Ignore nested actions, because attributes are scoped:
0144           , when< subscript<_, _>, make<mpl::int_<0> > >
0145           , otherwise< fold<_, make<mpl::int_<0> >, max_attr> >
0146         >
0147     {};
0148 
0149     ///////////////////////////////////////////////////////////////////////////////
0150     // max_attr
0151     //  Take the maximum of the current attr slot number and the state.
0152     struct max_attr : proto::transform<max_attr>
0153     {
0154         template<typename Expr, typename State, typename Data>
0155         struct impl : proto::transform_impl<Expr, State, Data>
0156         {
0157             typedef
0158                 typename mpl::max<
0159                     typename impl::state
0160                   , typename MaxAttr::template impl<Expr, State, Data>::result_type
0161                 >::type
0162             result_type;
0163         };
0164     };
0165 
0166     ///////////////////////////////////////////////////////////////////////////////
0167     // as_attr_matcher
0168     //  turn a1=matcher into attr_matcher<Matcher>(1)
0169     struct as_attr_matcher : proto::transform<as_attr_matcher>
0170     {
0171         template<typename Expr, typename State, typename Data>
0172         struct impl : proto::transform_impl<Expr, State, Data>
0173         {
0174             typedef typename impl::expr expr_type;
0175             typedef typename impl::data data_type;
0176             typedef
0177                 detail::attr_matcher<
0178                     typename proto::result_of::value<typename expr_type::proto_child1>::type
0179                   , typename data_type::traits_type
0180                   , typename data_type::icase_type
0181                 >
0182             result_type;
0183 
0184             result_type operator ()(
0185                 typename impl::expr_param expr
0186               , typename impl::state_param
0187               , typename impl::data_param data
0188             ) const
0189             {
0190                 return result_type(
0191                     proto::value(proto::left(expr)).nbr()
0192                   , proto::value(proto::right(expr))
0193                   , data.traits()
0194                 );
0195             }
0196         };
0197     };
0198 
0199     ///////////////////////////////////////////////////////////////////////////////
0200     // add_attrs
0201     //  Wrap an expression in attr_begin_matcher/attr_end_matcher pair
0202     struct add_attrs : proto::transform<add_attrs>
0203     {
0204         template<typename Expr, typename State, typename Data>
0205         struct impl : proto::transform_impl<Expr, State, Data>
0206         {
0207             typedef
0208                 detail::attr_begin_matcher<
0209                     typename MaxAttr::template impl<Expr, mpl::int_<0>, int>::result_type
0210                 >
0211             begin_type;
0212 
0213             typedef typename impl::expr expr_type;
0214 
0215             typedef
0216                 typename shift_right<
0217                     typename terminal<begin_type>::type
0218                   , typename shift_right<
0219                         Expr
0220                       , terminal<detail::attr_end_matcher>::type
0221                     >::type
0222                 >::type
0223             result_type;
0224 
0225             result_type operator ()(
0226                 typename impl::expr_param expr
0227               , typename impl::state_param
0228               , typename impl::data_param
0229             ) const
0230             {
0231                 begin_type begin;
0232                 detail::attr_end_matcher end;
0233                 result_type that = {{begin}, {expr, {end}}};
0234                 return that;
0235             }
0236         };
0237     };
0238 
0239     ///////////////////////////////////////////////////////////////////////////////
0240     // InsertAttrs
0241     struct InsertAttrs
0242       : if_<MaxAttr, add_attrs, _>
0243     {};
0244 
0245     ///////////////////////////////////////////////////////////////////////////////
0246     // CheckAssertion
0247     struct CheckAssertion
0248       : proto::function<terminal<detail::check_tag>, _>
0249     {};
0250 
0251     ///////////////////////////////////////////////////////////////////////////////
0252     // action_transform
0253     //  Turn A[B] into (mark_begin(n) >> A >> mark_end(n) >> action_matcher<B>(n))
0254     //  If A and B use attributes, wrap the above expression in
0255     //  a attr_begin_matcher<Count> / attr_end_matcher pair, where Count is
0256     //  the number of attribute slots used by the pattern/action.
0257     struct as_action : proto::transform<as_action>
0258     {
0259         template<typename Expr, typename State, typename Data>
0260         struct impl : proto::transform_impl<Expr, State, Data>
0261         {
0262             typedef typename proto::result_of::left<Expr>::type expr_type;
0263             typedef typename proto::result_of::right<Expr>::type action_type;
0264 
0265             typedef
0266                 typename DeepCopy::impl<action_type, expr_type, int>::result_type
0267             action_copy_type;
0268 
0269             typedef
0270                 typename InsertMark::impl<expr_type, State, Data>::result_type
0271             marked_expr_type;
0272 
0273             typedef
0274                 typename mpl::if_c<
0275                     proto::matches<action_type, CheckAssertion>::value
0276                   , detail::predicate_matcher<action_copy_type>
0277                   , detail::action_matcher<action_copy_type>
0278                 >::type
0279             matcher_type;
0280 
0281             typedef
0282                 typename proto::shift_right<
0283                     marked_expr_type
0284                   , typename proto::terminal<matcher_type>::type
0285                 >::type
0286             no_attr_type;
0287 
0288             typedef
0289                 typename InsertAttrs::impl<no_attr_type, State, Data>::result_type
0290             result_type;
0291 
0292             result_type operator ()(
0293                 typename impl::expr_param expr
0294               , typename impl::state_param state
0295               , typename impl::data_param data
0296             ) const
0297             {
0298                 int dummy = 0;
0299                 marked_expr_type marked_expr =
0300                     InsertMark::impl<expr_type, State, Data>()(proto::left(expr), state, data);
0301 
0302                 no_attr_type that = {
0303                     marked_expr
0304                   , {
0305                         matcher_type(
0306                             DeepCopy::impl<action_type, expr_type, int>()(
0307                                 proto::right(expr)
0308                               , proto::left(expr)
0309                               , dummy
0310                             )
0311                           , proto::value(proto::left(marked_expr)).mark_number_
0312                         )
0313                     }
0314                 };
0315                 return InsertAttrs::impl<no_attr_type, State, Data>()(that, state, data);
0316             }
0317         };
0318     };
0319 
0320 }}}
0321 
0322 #endif