1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 =============================================================================*/
9 #if !defined(BOOST_SPIRIT_TRAVERSE_HPP)
10 #define BOOST_SPIRIT_TRAVERSE_HPP
12 #include <boost/spirit/home/classic/namespace.hpp>
13 #include <boost/spirit/home/classic/meta/impl/traverse.ipp>
15 namespace boost { namespace spirit {
17 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
19 ///////////////////////////////////////////////////////////////////////////
21 // Post-order traversal of auxilliary parsers.
23 ///////////////////////////////////////////////////////////////////////////
26 // Return the parser type, which is generated as the result of the
27 // traverse function below.
29 template <typename MetaT, typename ParserT>
33 traverse_post_order_return<
36 , traverse_post_order_env<0, 0, 0, 0>
41 // Traverse a given parser and refactor it with the help of the given
42 // MetaT metafunction template.
44 template <typename MetaT, typename ParserT>
45 static typename result<MetaT, ParserT>::type
46 traverse(MetaT const &meta_, ParserT const &parser_)
48 typedef typename ParserT::parser_category_t parser_category_t;
49 return impl::traverse_post_order<parser_category_t>::generate(
50 meta_, parser_, traverse_post_order_env<0, 0, 0, 0>());
54 ///////////////////////////////////////////////////////////////////////////
58 // The following policy classes could be used to assemble some new
59 // transformation metafunction which uses identity transformations
60 // for some parser_category type parsers.
62 ///////////////////////////////////////////////////////////////////////////
64 ///////////////////////////////////////////////////////////////////////////
65 // transform plain parsers
66 template <typename TransformT>
67 struct plain_identity_policy
69 template <typename ParserT, typename EnvT>
72 // plain parsers should be embedded and returned correctly
73 typedef typename ParserT::embed_t type;
76 template <typename ParserT, typename EnvT>
77 typename parser_traversal_plain_result<TransformT, ParserT, EnvT>::type
78 generate_plain(ParserT const &parser_, EnvT const& /*env*/) const
84 //////////////////////////////////
85 // transform unary parsers
86 template <typename UnaryT, typename SubjectT>
87 struct unary_identity_policy_return
89 typedef typename UnaryT::parser_generator_t parser_generator_t;
90 typedef typename parser_generator_t
91 ::template result<SubjectT>::type type;
94 template <typename TransformT>
95 struct unary_identity_policy
97 template <typename UnaryT, typename SubjectT, typename EnvT>
101 typename unary_identity_policy_return<UnaryT, SubjectT>::type
105 template <typename UnaryT, typename SubjectT, typename EnvT>
106 typename parser_traversal_unary_result<
107 TransformT, UnaryT, SubjectT, EnvT>::type
109 UnaryT const &, SubjectT const &subject_, EnvT const& /*env*/) const
111 typedef typename UnaryT::parser_generator_t parser_generator_t;
112 return parser_generator_t::template generate<SubjectT>(subject_);
116 //////////////////////////////////
117 // transform action parsers
118 template <typename TransformT>
119 struct action_identity_policy
121 template <typename ActionT, typename SubjectT, typename EnvT>
124 typedef action<SubjectT, typename ActionT::predicate_t> type;
127 template <typename ActionT, typename SubjectT, typename EnvT>
128 typename parser_traversal_action_result<
129 TransformT, ActionT, SubjectT, EnvT
131 generate_action(ActionT const &action_, SubjectT const &subject_,
132 EnvT const& /*env*/) const
134 return subject_[action_.predicate()];
138 //////////////////////////////////
139 // transform binary parsers
140 template <typename BinaryT, typename LeftT, typename RightT>
141 struct binary_identity_policy_return
143 typedef typename BinaryT::parser_generator_t parser_generator_t;
144 typedef typename parser_generator_t
145 ::template result<LeftT, RightT>::type type;
148 template <typename TransformT>
149 struct binary_identity_policy
151 template <typename BinaryT, typename LeftT
152 , typename RightT, typename EnvT>
153 struct binary_result {
156 binary_identity_policy_return<BinaryT, LeftT, RightT>::type
160 template <typename BinaryT, typename LeftT
161 , typename RightT, typename EnvT>
162 typename parser_traversal_binary_result<
163 TransformT, BinaryT, LeftT, RightT, EnvT
166 BinaryT const &, LeftT const& left_
167 , RightT const& right_, EnvT const& /*env*/) const
169 typedef typename BinaryT::parser_generator_t parser_generator_t;
170 return parser_generator_t::
171 template generate<LeftT, RightT>(left_, right_);
175 ///////////////////////////////////////////////////////////////////////////
177 // transform_policies template
179 // The transform_policies template metafunction could serve as a
180 // base class for new metafunctions to be passed to the traverse meta
181 // template (see above), where only minimal parts have to be
184 ///////////////////////////////////////////////////////////////////////////
188 typename PlainPolicyT = plain_identity_policy<TransformT>,
189 typename UnaryPolicyT = unary_identity_policy<TransformT>,
190 typename ActionPolicyT = action_identity_policy<TransformT>,
191 typename BinaryPolicyT = binary_identity_policy<TransformT>
193 struct transform_policies :
196 public ActionPolicyT,
201 ///////////////////////////////////////////////////////////////////////////
203 // Identity transformation
205 // The identity_transform metafunction supplied to the traverse
206 // template will generate a new parser, which will be exactly
207 // identical to the parser given as the parameter to the traverse
208 // metafunction. I.e. the following conceptual 'equation' will be
212 // post_order::traverse(identity_transform(), some_parser)
214 ///////////////////////////////////////////////////////////////////////////
216 struct identity_transform : transform_policies<identity_transform> {};
218 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
220 }} // namespace BOOST_SPIRIT_CLASSIC_NS
222 #endif // !defined(BOOST_SPIRIT_TRAVERSE_HPP)