os/ossrv/ossrv_pub/boost_apis/boost/spirit/meta/traverse.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*=============================================================================
sl@0
     2
    Copyright (c) 2002-2003 Joel de Guzman
sl@0
     3
    Copyright (c) 2002-2003 Hartmut Kaiser
sl@0
     4
    http://spirit.sourceforge.net/
sl@0
     5
sl@0
     6
    Use, modification and distribution is subject to the Boost Software
sl@0
     7
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
sl@0
     8
    http://www.boost.org/LICENSE_1_0.txt)
sl@0
     9
=============================================================================*/
sl@0
    10
#if !defined(BOOST_SPIRIT_TRAVERSE_HPP)
sl@0
    11
#define BOOST_SPIRIT_TRAVERSE_HPP
sl@0
    12
sl@0
    13
#include <boost/spirit/meta/impl/traverse.ipp>
sl@0
    14
sl@0
    15
namespace boost { namespace spirit
sl@0
    16
{
sl@0
    17
    ///////////////////////////////////////////////////////////////////////////
sl@0
    18
    //
sl@0
    19
    //  Post-order traversal of auxilliary parsers.
sl@0
    20
    //
sl@0
    21
    ///////////////////////////////////////////////////////////////////////////
sl@0
    22
    struct post_order
sl@0
    23
    {
sl@0
    24
        //  Return the parser type, which is generated as the result of the
sl@0
    25
        //  traverse function below.
sl@0
    26
sl@0
    27
        template <typename MetaT, typename ParserT>
sl@0
    28
        struct result
sl@0
    29
        {
sl@0
    30
            typedef typename
sl@0
    31
                traverse_post_order_return<
sl@0
    32
                    MetaT
sl@0
    33
                  , ParserT
sl@0
    34
                  , traverse_post_order_env<0, 0, 0, 0>
sl@0
    35
                >::type
sl@0
    36
            type;
sl@0
    37
        };
sl@0
    38
sl@0
    39
        //  Traverse a given parser and refactor it with the help of the given
sl@0
    40
        //  MetaT metafunction template.
sl@0
    41
sl@0
    42
        template <typename MetaT, typename ParserT>
sl@0
    43
        static typename result<MetaT, ParserT>::type
sl@0
    44
        traverse(MetaT const &meta_, ParserT const &parser_)
sl@0
    45
        {
sl@0
    46
            typedef typename ParserT::parser_category_t parser_category_t;
sl@0
    47
            return impl::traverse_post_order<parser_category_t>::generate(
sl@0
    48
                meta_, parser_, traverse_post_order_env<0, 0, 0, 0>());
sl@0
    49
        }
sl@0
    50
    };
sl@0
    51
sl@0
    52
    ///////////////////////////////////////////////////////////////////////////
sl@0
    53
    //
sl@0
    54
    //  Transform policies
sl@0
    55
    //
sl@0
    56
    //      The following policy classes could be used to assemble some new
sl@0
    57
    //      transformation metafunction which uses identity transformations
sl@0
    58
    //      for some parser_category type parsers.
sl@0
    59
    //
sl@0
    60
    ///////////////////////////////////////////////////////////////////////////
sl@0
    61
sl@0
    62
    ///////////////////////////////////////////////////////////////////////////
sl@0
    63
    //  transform plain parsers
sl@0
    64
    template <typename TransformT>
sl@0
    65
    struct plain_identity_policy
sl@0
    66
    {
sl@0
    67
        template <typename ParserT, typename EnvT>
sl@0
    68
        struct plain_result
sl@0
    69
        {
sl@0
    70
            // plain parsers should be embedded and returned correctly
sl@0
    71
            typedef typename ParserT::embed_t type;
sl@0
    72
        };
sl@0
    73
sl@0
    74
        template <typename ParserT, typename EnvT>
sl@0
    75
        typename parser_traversal_plain_result<TransformT, ParserT, EnvT>::type
sl@0
    76
        generate_plain(ParserT const &parser_, EnvT const& /*env*/) const
sl@0
    77
        {
sl@0
    78
            return parser_;
sl@0
    79
        }
sl@0
    80
    };
sl@0
    81
sl@0
    82
    //////////////////////////////////
sl@0
    83
    //  transform unary parsers
sl@0
    84
    template <typename UnaryT, typename SubjectT>
sl@0
    85
    struct unary_identity_policy_return
sl@0
    86
    {
sl@0
    87
        typedef typename UnaryT::parser_generator_t parser_generator_t;
sl@0
    88
        typedef typename parser_generator_t
sl@0
    89
            ::template result<SubjectT>::type type;
sl@0
    90
    };
sl@0
    91
sl@0
    92
    template <typename TransformT>
sl@0
    93
    struct unary_identity_policy
sl@0
    94
    {
sl@0
    95
        template <typename UnaryT, typename SubjectT, typename EnvT>
sl@0
    96
        struct unary_result
sl@0
    97
        {
sl@0
    98
            typedef
sl@0
    99
                typename unary_identity_policy_return<UnaryT, SubjectT>::type
sl@0
   100
            type;
sl@0
   101
        };
sl@0
   102
sl@0
   103
        template <typename UnaryT, typename SubjectT, typename EnvT>
sl@0
   104
        typename parser_traversal_unary_result<
sl@0
   105
            TransformT, UnaryT, SubjectT, EnvT>::type
sl@0
   106
        generate_unary(
sl@0
   107
            UnaryT const &, SubjectT const &subject_, EnvT const& /*env*/) const
sl@0
   108
        {
sl@0
   109
            typedef typename UnaryT::parser_generator_t parser_generator_t;
sl@0
   110
            return parser_generator_t::template generate<SubjectT>(subject_);
sl@0
   111
        }
sl@0
   112
    };
sl@0
   113
sl@0
   114
    //////////////////////////////////
sl@0
   115
    //  transform action parsers
sl@0
   116
    template <typename TransformT>
sl@0
   117
    struct action_identity_policy
sl@0
   118
    {
sl@0
   119
        template <typename ActionT, typename SubjectT, typename EnvT>
sl@0
   120
        struct action_result
sl@0
   121
        {
sl@0
   122
            typedef action<SubjectT, typename ActionT::predicate_t> type;
sl@0
   123
        };
sl@0
   124
sl@0
   125
        template <typename ActionT, typename SubjectT, typename EnvT>
sl@0
   126
        typename parser_traversal_action_result<
sl@0
   127
            TransformT, ActionT, SubjectT, EnvT
sl@0
   128
        >::type
sl@0
   129
        generate_action(ActionT const &action_, SubjectT const &subject_,
sl@0
   130
            EnvT const& /*env*/) const
sl@0
   131
        {
sl@0
   132
            return subject_[action_.predicate()];
sl@0
   133
        }
sl@0
   134
    };
sl@0
   135
sl@0
   136
    //////////////////////////////////
sl@0
   137
    //  transform binary parsers
sl@0
   138
    template <typename BinaryT, typename LeftT, typename RightT>
sl@0
   139
    struct binary_identity_policy_return
sl@0
   140
    {
sl@0
   141
        typedef typename BinaryT::parser_generator_t parser_generator_t;
sl@0
   142
        typedef typename parser_generator_t
sl@0
   143
            ::template result<LeftT, RightT>::type type;
sl@0
   144
    };
sl@0
   145
sl@0
   146
    template <typename TransformT>
sl@0
   147
    struct binary_identity_policy
sl@0
   148
    {
sl@0
   149
        template <typename BinaryT, typename LeftT
sl@0
   150
            , typename RightT, typename EnvT>
sl@0
   151
        struct binary_result {
sl@0
   152
sl@0
   153
            typedef typename
sl@0
   154
                binary_identity_policy_return<BinaryT, LeftT, RightT>::type
sl@0
   155
            type;
sl@0
   156
        };
sl@0
   157
sl@0
   158
        template <typename BinaryT, typename LeftT
sl@0
   159
            , typename RightT, typename EnvT>
sl@0
   160
        typename parser_traversal_binary_result<
sl@0
   161
            TransformT, BinaryT, LeftT, RightT, EnvT
sl@0
   162
        >::type
sl@0
   163
        generate_binary(
sl@0
   164
            BinaryT const &, LeftT const& left_
sl@0
   165
          , RightT const& right_, EnvT const& /*env*/) const
sl@0
   166
        {
sl@0
   167
            typedef typename BinaryT::parser_generator_t parser_generator_t;
sl@0
   168
            return parser_generator_t::
sl@0
   169
                template generate<LeftT, RightT>(left_, right_);
sl@0
   170
        }
sl@0
   171
    };
sl@0
   172
sl@0
   173
    ///////////////////////////////////////////////////////////////////////////
sl@0
   174
    //
sl@0
   175
    //  transform_policies template
sl@0
   176
    //
sl@0
   177
    //      The transform_policies template metafunction could serve as a
sl@0
   178
    //      base class for new metafunctions to be passed to the traverse meta
sl@0
   179
    //      template (see above), where only minimal parts have to be
sl@0
   180
    //      overwritten.
sl@0
   181
    //
sl@0
   182
    ///////////////////////////////////////////////////////////////////////////
sl@0
   183
sl@0
   184
    template <
sl@0
   185
        typename TransformT,
sl@0
   186
        typename PlainPolicyT = plain_identity_policy<TransformT>,
sl@0
   187
        typename UnaryPolicyT = unary_identity_policy<TransformT>,
sl@0
   188
        typename ActionPolicyT = action_identity_policy<TransformT>,
sl@0
   189
        typename BinaryPolicyT = binary_identity_policy<TransformT>
sl@0
   190
    >
sl@0
   191
    struct transform_policies :
sl@0
   192
        public PlainPolicyT,
sl@0
   193
        public UnaryPolicyT,
sl@0
   194
        public ActionPolicyT,
sl@0
   195
        public BinaryPolicyT
sl@0
   196
    {
sl@0
   197
    };
sl@0
   198
sl@0
   199
    ///////////////////////////////////////////////////////////////////////////
sl@0
   200
    //
sl@0
   201
    //  Identity transformation
sl@0
   202
    //
sl@0
   203
    //      The identity_transform metafunction supplied to the traverse
sl@0
   204
    //      template will generate a new parser, which will be exactly
sl@0
   205
    //      identical to the parser given as the parameter to the traverse
sl@0
   206
    //      metafunction. I.e. the following conceptual 'equation' will be
sl@0
   207
    //      always true:
sl@0
   208
    //
sl@0
   209
    //      some_parser ==
sl@0
   210
    //          post_order::traverse(identity_transform(), some_parser)
sl@0
   211
    //
sl@0
   212
    ///////////////////////////////////////////////////////////////////////////
sl@0
   213
sl@0
   214
    struct identity_transform : transform_policies<identity_transform> {};
sl@0
   215
sl@0
   216
}} // namespace boost::spirit
sl@0
   217
sl@0
   218
#endif // !defined(BOOST_SPIRIT_TRAVERSE_HPP)