123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- /*=============================================================================
- Copyright (c) 2001-2011 Joel de Guzman
- http://spirit.sourceforge.net/
- 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_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
- #define BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #include <boost/spirit/home/support/detail/make_cons.hpp>
- #include <boost/spirit/home/support/modify.hpp>
- #include <boost/phoenix/core/actor.hpp>
- #include <boost/phoenix/core/is_actor.hpp>
- #include <boost/proto/tags.hpp>
- #include <boost/proto/traits.hpp>
- #include <boost/proto/transform.hpp>
- namespace boost { namespace spirit
- {
- // There is no real "component" class. Each domain is responsible
- // for creating its own components. You need to specialize this for
- // each component in your domain. Use this as a guide.
- template <typename Domain, typename Tag, typename Enable = void>
- struct make_component
- {
- template <typename Sig>
- struct result;
- template <typename This, typename Elements, typename Modifiers>
- struct result<This(Elements, Modifiers)>;
- template <typename Elements, typename Modifiers>
- typename result<make_component(Elements, Modifiers)>::type
- operator()(Elements const& elements, Modifiers const& modifiers) const;
- };
- namespace tag
- {
- // Normally, we use proto tags as-is to distinguish operators.
- // The special case is proto::tag::subscript. Spirit uses this
- // as either sementic actions or directives. To distinguish between
- // the two, we use these special tags below.
- struct directive;
- struct action;
- }
- template <typename Domain, typename T, typename Enable = void>
- struct flatten_tree;
- }}
- namespace boost { namespace spirit { namespace detail
- {
- template <typename Expr, typename State, typename Data, typename Domain>
- struct make_terminal_impl
- : proto::transform_impl<Expr, State, Data>
- {
- typedef typename
- proto::result_of::value<Expr>::type
- value;
- typedef typename result_of::make_cons<value>::type elements;
- typedef
- make_component<Domain, proto::tag::terminal>
- make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements, Data)>::type
- result_type;
- result_type operator()(
- typename make_terminal_impl::expr_param expr
- , typename make_terminal_impl::state_param /*state*/
- , typename make_terminal_impl::data_param data
- ) const
- {
- return typename make_terminal_impl::make_component_()(
- detail::make_cons(proto::value(expr))
- , data
- );
- }
- };
- template <typename Expr, typename State, typename Data, typename Domain>
- struct make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
- : proto::transform_impl<phoenix::actor<Expr>, State, Data>
- {
- typedef phoenix::actor<Expr> value;
- typedef typename result_of::make_cons<value>::type elements;
- typedef make_component<Domain, proto::tag::terminal> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements, Data)>::type
- result_type;
- result_type operator()(
- typename make_terminal_impl::expr_param expr
- , typename make_terminal_impl::state_param /*state*/
- , typename make_terminal_impl::data_param data
- ) const
- {
- return typename make_terminal_impl::make_component_()(
- detail::make_cons(expr)
- , data
- );
- }
- };
- template <typename Expr, typename State, typename Data, typename Domain>
- struct make_terminal_impl<phoenix::actor<Expr> &, State, Data, Domain>
- : make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
- {};
- template <typename Expr, typename State, typename Data, typename Domain>
- struct make_terminal_impl<phoenix::actor<Expr> const &, State, Data, Domain>
- : make_terminal_impl<phoenix::actor<Expr>, State, Data, Domain>
- {};
- template <typename Domain>
- struct make_terminal : proto::transform<make_terminal<Domain> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : make_terminal_impl<Expr, State, Data, Domain> {};
- };
- template <typename Domain, typename Tag, typename Grammar>
- struct make_unary : proto::transform<make_unary<Domain, Tag, Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename
- proto::result_of::child_c<Expr, 0>::type
- child;
- typedef typename Grammar::
- template result<Grammar(child, State, Data)>::type
- child_component;
- typedef typename
- result_of::make_cons<child_component>::type
- elements;
- typedef make_component<Domain, Tag> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- return typename impl::make_component_()(
- detail::make_cons(
- Grammar()(proto::child(expr), state, data))
- , data
- );
- }
- };
- };
- // un-flattened version
- template <typename Domain, typename Tag, typename Grammar,
- bool flatten = flatten_tree<Domain, Tag>::value>
- struct make_binary
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename Grammar::
- template result<Grammar(
- typename proto::result_of::child_c<Expr, 0>::type
- , State, Data)>::type
- lhs_component;
- typedef typename Grammar::
- template result<Grammar(
- typename proto::result_of::child_c<Expr, 1>::type
- , State, Data)>::type
- rhs_component;
- typedef typename
- result_of::make_cons<
- lhs_component
- , typename result_of::make_cons<rhs_component>::type
- >::type
- elements_type;
- typedef make_component<Domain, Tag> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements_type, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- elements_type elements =
- detail::make_cons(
- Grammar()(
- proto::child_c<0>(expr), state, data) // LHS
- , detail::make_cons(
- Grammar()(
- proto::child_c<1>(expr), state, data) // RHS
- )
- );
- return make_component_()(elements, data);
- }
- };
- };
- template <typename Grammar>
- struct make_binary_helper : proto::transform<make_binary_helper<Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename Grammar::
- template result<Grammar(Expr, State, Data)>::type
- lhs;
- typedef typename result_of::make_cons<lhs, State>::type result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- return detail::make_cons(Grammar()(expr, state, data), state);
- }
- };
- };
- // Flattened version
- template <typename Domain, typename Tag, typename Grammar>
- struct make_binary<Domain, Tag, Grammar, true>
- : proto::transform<make_binary<Domain, Tag, Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename
- proto::reverse_fold_tree<
- proto::_
- , proto::make<fusion::nil_>
- , make_binary_helper<Grammar>
- >::template impl<Expr, State, Data>
- reverse_fold_tree;
- typedef typename reverse_fold_tree::result_type elements;
- typedef make_component<Domain, Tag> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- return make_component_()(
- reverse_fold_tree()(expr, state, data), data);
- }
- };
- };
- template <typename Domain, typename Grammar>
- struct make_directive : proto::transform<make_directive<Domain, Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename
- proto::result_of::child_c<Expr, 0>::type
- lhs;
- typedef typename
- proto::result_of::value<lhs>::type
- tag_type;
- typedef typename modify<Domain>::
- template result<modify<Domain>(tag_type, Data)>::type
- modifier_type;
- typedef typename Grammar::
- template result<Grammar(
- typename proto::result_of::child_c<Expr, 1>::type
- , State
- , modifier_type
- )>::type
- rhs_component;
- typedef typename
- result_of::make_cons<
- tag_type
- , typename result_of::make_cons<rhs_component>::type
- >::type
- elements_type;
- typedef make_component<Domain, tag::directive> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements_type, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- tag_type tag = proto::value(proto::child_c<0>(expr));
- typename remove_reference<modifier_type>::type
- modifier = modify<Domain>()(tag, data);
- elements_type elements =
- detail::make_cons(
- tag // LHS
- , detail::make_cons(
- Grammar()(
- proto::child_c<1>(expr) // RHS
- , state, modifier)
- )
- );
- return make_component_()(elements, data);
- }
- };
- };
- template <typename Domain, typename Grammar>
- struct make_action : proto::transform<make_action<Domain, Grammar> >
- {
- template<typename Expr, typename State, typename Data>
- struct impl : proto::transform_impl<Expr, State, Data>
- {
- typedef typename Grammar::
- template result<Grammar(
- typename proto::result_of::child_c<Expr, 0>::type
- , State
- , Data
- )>::type
- lhs_component;
- typedef
- typename mpl::eval_if_c<
- phoenix::is_actor<
- typename proto::result_of::child_c<Expr, 1>::type
- >::type::value
- , proto::result_of::child_c<Expr, 1>
- , proto::result_of::value<
- typename proto::result_of::child_c<Expr, 1>::type
- >
- >::type
- rhs_component;
- typedef typename
- result_of::make_cons<
- lhs_component
- , typename result_of::make_cons<rhs_component>::type
- >::type
- elements_type;
- typedef make_component<Domain, tag::action> make_component_;
- typedef typename
- make_component_::template
- result<make_component_(elements_type, Data)>::type
- result_type;
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- ) const
- {
- return
- (*this)(
- expr
- , state
- , data
- , typename phoenix::is_actor<
- typename proto::result_of::child_c<Expr, 1>::type
- >::type()
- );
- }
-
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- , mpl::false_
- ) const
- {
- elements_type elements =
- detail::make_cons(
- Grammar()(
- proto::child_c<0>(expr), state, data) // LHS
- , detail::make_cons(
- proto::value(proto::child_c<1>(expr))) // RHS
- );
- return make_component_()(elements, data);
- }
- result_type operator()(
- typename impl::expr_param expr
- , typename impl::state_param state
- , typename impl::data_param data
- , mpl::true_
- ) const
- {
- elements_type elements =
- detail::make_cons(
- Grammar()(
- proto::child_c<0>(expr), state, data) // LHS
- , detail::make_cons(
- proto::child_c<1>(expr)) // RHS
- );
- return make_component_()(elements, data);
- }
- };
- };
- }}}
- #endif
|