PageRenderTime 30ms CodeModel.GetById 8ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/xpressive/detail/static/transforms/as_action.hpp

http://hadesmem.googlecode.com/
C++ Header | 322 lines | 236 code | 33 blank | 53 comment | 1 complexity | 854c3fb38ed1725cecfa25bb76d65aa9 MD5 | raw file
  1///////////////////////////////////////////////////////////////////////////////
  2// as_action.hpp
  3//
  4//  Copyright 2008 Eric Niebler.
  5//  Copyright 2008 David Jenkins.
  6//
  7//  Distributed under the Boost Software License, Version 1.0. (See
  8//  accompanying file LICENSE_1_0.txt or copy at
  9//  http://www.boost.org/LICENSE_1_0.txt)
 10
 11#ifndef BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_ACTION_HPP_EAN_04_05_2007
 12#define BOOST_XPRESSIVE_DETAIL_STATIC_TRANSFORMS_AS_ACTION_HPP_EAN_04_05_2007
 13
 14// MS compatible compilers support #pragma once
 15#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 16# pragma once
 17#endif
 18
 19#include <boost/mpl/sizeof.hpp>
 20#include <boost/mpl/min_max.hpp>
 21#include <boost/mpl/apply_wrap.hpp>
 22#include <boost/xpressive/detail/detail_fwd.hpp>
 23#include <boost/xpressive/detail/core/matcher/attr_end_matcher.hpp>
 24#include <boost/xpressive/detail/static/static.hpp>
 25#include <boost/xpressive/detail/static/transforms/as_quantifier.hpp>
 26#include <boost/proto/core.hpp>
 27#include <boost/proto/transform/arg.hpp>
 28#include <boost/proto/transform/call.hpp>
 29#include <boost/proto/transform/make.hpp>
 30#include <boost/proto/transform/when.hpp>
 31#include <boost/proto/transform/fold.hpp>
 32#include <boost/proto/transform/fold_tree.hpp>
 33
 34namespace boost { namespace xpressive { namespace detail
 35{
 36    ///////////////////////////////////////////////////////////////////////////////
 37    // read_attr
 38    //  Placeholder that knows the slot number of an attribute as well as the type
 39    //  of the object stored in it.
 40    template<typename Nbr, typename Matcher>
 41    struct read_attr
 42    {
 43        typedef Nbr nbr_type;
 44        typedef Matcher matcher_type;
 45        static Nbr nbr() { return Nbr(); }
 46    };
 47
 48    template<typename Nbr, typename Matcher>
 49    struct read_attr<Nbr, Matcher &>
 50    {
 51        typedef Nbr nbr_type;
 52        typedef Matcher matcher_type;
 53    };
 54
 55}}}
 56
 57namespace boost { namespace xpressive { namespace grammar_detail
 58{
 59    ///////////////////////////////////////////////////////////////////////////////
 60    // FindAttr
 61    //  Look for patterns like (a1= terminal<RHS>) and return the type of the RHS.
 62    template<typename Nbr>
 63    struct FindAttr
 64      : or_<
 65            // Ignore nested actions, because attributes are scoped
 66            when< subscript<_, _>,                                  _state >
 67          , when< terminal<_>,                                      _state >
 68          , when< proto::assign<terminal<detail::attribute_placeholder<Nbr> >, _>, call<_value(_right)> >
 69          , otherwise< fold<_, _state, FindAttr<Nbr> > >
 70        >
 71    {};
 72
 73    ///////////////////////////////////////////////////////////////////////////////
 74    // as_read_attr
 75    //  For patterns like (a1 = RHS)[ref(i) = a1], transform to
 76    //  (a1 = RHS)[ref(i) = read_attr<1, RHS>] so that when reading the attribute
 77    //  we know what type is stored in the attribute slot.
 78    struct as_read_attr : proto::transform<as_read_attr>
 79    {
 80        template<typename Expr, typename State, typename Data>
 81        struct impl : proto::transform_impl<Expr, State, Data>
 82        {
 83            typedef typename impl::expr expr_type;
 84            typedef
 85                typename FindAttr<typename expr_type::proto_child0::nbr_type>::template impl<
 86                    State
 87                  , mpl::void_
 88                  , int
 89                >::result_type
 90            attr_type;
 91
 92            typedef
 93                typename proto::terminal<
 94                    detail::read_attr<
 95                        typename expr_type::proto_child0::nbr_type
 96                      , BOOST_PROTO_UNCVREF(attr_type)
 97                    >
 98                >::type
 99            result_type;
100
101            result_type operator ()(proto::ignore, proto::ignore, proto::ignore) const
102            {
103                result_type that = {{}};
104                return that;
105            }
106        };
107    };
108
109    ///////////////////////////////////////////////////////////////////////////////
110    // DeepCopy
111    //  Turn all refs into values, and also bind all attribute placeholders with
112    //  the types from which they are being assigned.
113    struct DeepCopy
114      : or_<
115            when< terminal<detail::attribute_placeholder<_> >,  as_read_attr>
116          , when< terminal<_>,                                  proto::_deep_copy>
117          , otherwise< nary_expr<_, vararg<DeepCopy> > >
118        >
119    {};
120
121    ///////////////////////////////////////////////////////////////////////////////
122    // attr_nbr
123    //  For an attribute placeholder, return the attribute's slot number.
124    struct attr_nbr : proto::transform<attr_nbr>
125    {
126        template<typename Expr, typename State, typename Data>
127        struct impl : proto::transform_impl<Expr, State, Data>
128        {
129            typedef typename impl::expr expr_type;
130            typedef typename expr_type::proto_child0::nbr_type::type result_type;
131        };
132    };
133
134    struct max_attr;
135
136    ///////////////////////////////////////////////////////////////////////////////
137    // MaxAttr
138    //  In an action (rx)[act], find the largest attribute slot being used.
139    struct MaxAttr
140      : or_<
141            when< terminal<detail::attribute_placeholder<_> >, attr_nbr>
142          , when< terminal<_>, make<mpl::int_<0> > >
143            // Ignore nested actions, because attributes are scoped:
144          , when< subscript<_, _>, make<mpl::int_<0> > >
145          , otherwise< fold<_, make<mpl::int_<0> >, max_attr> >
146        >
147    {};
148
149    ///////////////////////////////////////////////////////////////////////////////
150    // max_attr
151    //  Take the maximum of the current attr slot number and the state.
152    struct max_attr : proto::transform<max_attr>
153    {
154        template<typename Expr, typename State, typename Data>
155        struct impl : proto::transform_impl<Expr, State, Data>
156        {
157            typedef
158                typename mpl::max<
159                    typename impl::state
160                  , typename MaxAttr::template impl<Expr, State, Data>::result_type
161                >::type
162            result_type;
163        };
164    };
165
166    ///////////////////////////////////////////////////////////////////////////////
167    // as_attr_matcher
168    //  turn a1=matcher into attr_matcher<Matcher>(1)
169    struct as_attr_matcher : proto::transform<as_attr_matcher>
170    {
171        template<typename Expr, typename State, typename Data>
172        struct impl : proto::transform_impl<Expr, State, Data>
173        {
174            typedef typename impl::expr expr_type;
175            typedef typename impl::data data_type;
176            typedef
177                detail::attr_matcher<
178                    typename proto::result_of::value<typename expr_type::proto_child1>::type
179                  , typename data_type::traits_type
180                  , typename data_type::icase_type
181                >
182            result_type;
183
184            result_type operator ()(
185                typename impl::expr_param expr
186              , typename impl::state_param
187              , typename impl::data_param data
188            ) const
189            {
190                return result_type(
191                    proto::value(proto::left(expr)).nbr()
192                  , proto::value(proto::right(expr))
193                  , data.traits()
194                );
195            }
196        };
197    };
198
199    ///////////////////////////////////////////////////////////////////////////////
200    // add_attrs
201    //  Wrap an expression in attr_begin_matcher/attr_end_matcher pair
202    struct add_attrs : proto::transform<add_attrs>
203    {
204        template<typename Expr, typename State, typename Data>
205        struct impl : proto::transform_impl<Expr, State, Data>
206        {
207            typedef
208                detail::attr_begin_matcher<
209                    typename MaxAttr::template impl<Expr, mpl::int_<0>, int>::result_type
210                >
211            begin_type;
212
213            typedef typename impl::expr expr_type;
214
215            typedef
216                typename shift_right<
217                    typename terminal<begin_type>::type
218                  , typename shift_right<
219                        Expr
220                      , terminal<detail::attr_end_matcher>::type
221                    >::type
222                >::type
223            result_type;
224
225            result_type operator ()(
226                typename impl::expr_param expr
227              , typename impl::state_param
228              , typename impl::data_param
229            ) const
230            {
231                begin_type begin;
232                detail::attr_end_matcher end;
233                result_type that = {{begin}, {expr, {end}}};
234                return that;
235            }
236        };
237    };
238
239    ///////////////////////////////////////////////////////////////////////////////
240    // InsertAttrs
241    struct InsertAttrs
242      : if_<MaxAttr, add_attrs, _>
243    {};
244
245    ///////////////////////////////////////////////////////////////////////////////
246    // CheckAssertion
247    struct CheckAssertion
248      : proto::function<terminal<detail::check_tag>, _>
249    {};
250
251    ///////////////////////////////////////////////////////////////////////////////
252    // action_transform
253    //  Turn A[B] into (mark_begin(n) >> A >> mark_end(n) >> action_matcher<B>(n))
254    //  If A and B use attributes, wrap the above expression in
255    //  a attr_begin_matcher<Count> / attr_end_matcher pair, where Count is
256    //  the number of attribute slots used by the pattern/action.
257    struct as_action : proto::transform<as_action>
258    {
259        template<typename Expr, typename State, typename Data>
260        struct impl : proto::transform_impl<Expr, State, Data>
261        {
262            typedef typename proto::result_of::left<Expr>::type expr_type;
263            typedef typename proto::result_of::right<Expr>::type action_type;
264
265            typedef
266                typename DeepCopy::impl<action_type, expr_type, int>::result_type
267            action_copy_type;
268
269            typedef
270                typename InsertMark::impl<expr_type, State, Data>::result_type
271            marked_expr_type;
272
273            typedef
274                typename mpl::if_c<
275                    proto::matches<action_type, CheckAssertion>::value
276                  , detail::predicate_matcher<action_copy_type>
277                  , detail::action_matcher<action_copy_type>
278                >::type
279            matcher_type;
280
281            typedef
282                typename proto::shift_right<
283                    marked_expr_type
284                  , typename proto::terminal<matcher_type>::type
285                >::type
286            no_attr_type;
287
288            typedef
289                typename InsertAttrs::impl<no_attr_type, State, Data>::result_type
290            result_type;
291
292            result_type operator ()(
293                typename impl::expr_param expr
294              , typename impl::state_param state
295              , typename impl::data_param data
296            ) const
297            {
298                int dummy = 0;
299                marked_expr_type marked_expr =
300                    InsertMark::impl<expr_type, State, Data>()(proto::left(expr), state, data);
301
302                no_attr_type that = {
303                    marked_expr
304                  , {
305                        matcher_type(
306                            DeepCopy::impl<action_type, expr_type, int>()(
307                                proto::right(expr)
308                              , proto::left(expr)
309                              , dummy
310                            )
311                          , proto::value(proto::left(marked_expr)).mark_number_
312                        )
313                    }
314                };
315                return InsertAttrs::impl<no_attr_type, State, Data>()(that, state, data);
316            }
317        };
318    };
319
320}}}
321
322#endif