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