source: NonGTP/Boost/boost/spirit/meta/traverse.hpp @ 857

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