Update contrib.
1 /*=============================================================================
2 Copyright (c) 2002-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Hartmut Kaiser
4 http://spirit.sourceforge.net/
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
13 #include <boost/spirit/meta/impl/traverse.ipp>
15 namespace boost { namespace spirit
17 ///////////////////////////////////////////////////////////////////////////
19 // Post-order traversal of auxilliary parsers.
21 ///////////////////////////////////////////////////////////////////////////
24 // Return the parser type, which is generated as the result of the
25 // traverse function below.
27 template <typename MetaT, typename ParserT>
31 traverse_post_order_return<
34 , traverse_post_order_env<0, 0, 0, 0>
39 // Traverse a given parser and refactor it with the help of the given
40 // MetaT metafunction template.
42 template <typename MetaT, typename ParserT>
43 static typename result<MetaT, ParserT>::type
44 traverse(MetaT const &meta_, ParserT const &parser_)
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>());
52 ///////////////////////////////////////////////////////////////////////////
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.
60 ///////////////////////////////////////////////////////////////////////////
62 ///////////////////////////////////////////////////////////////////////////
63 // transform plain parsers
64 template <typename TransformT>
65 struct plain_identity_policy
67 template <typename ParserT, typename EnvT>
70 // plain parsers should be embedded and returned correctly
71 typedef typename ParserT::embed_t type;
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
82 //////////////////////////////////
83 // transform unary parsers
84 template <typename UnaryT, typename SubjectT>
85 struct unary_identity_policy_return
87 typedef typename UnaryT::parser_generator_t parser_generator_t;
88 typedef typename parser_generator_t
89 ::template result<SubjectT>::type type;
92 template <typename TransformT>
93 struct unary_identity_policy
95 template <typename UnaryT, typename SubjectT, typename EnvT>
99 typename unary_identity_policy_return<UnaryT, SubjectT>::type
103 template <typename UnaryT, typename SubjectT, typename EnvT>
104 typename parser_traversal_unary_result<
105 TransformT, UnaryT, SubjectT, EnvT>::type
107 UnaryT const &, SubjectT const &subject_, EnvT const& /*env*/) const
109 typedef typename UnaryT::parser_generator_t parser_generator_t;
110 return parser_generator_t::template generate<SubjectT>(subject_);
114 //////////////////////////////////
115 // transform action parsers
116 template <typename TransformT>
117 struct action_identity_policy
119 template <typename ActionT, typename SubjectT, typename EnvT>
122 typedef action<SubjectT, typename ActionT::predicate_t> type;
125 template <typename ActionT, typename SubjectT, typename EnvT>
126 typename parser_traversal_action_result<
127 TransformT, ActionT, SubjectT, EnvT
129 generate_action(ActionT const &action_, SubjectT const &subject_,
130 EnvT const& /*env*/) const
132 return subject_[action_.predicate()];
136 //////////////////////////////////
137 // transform binary parsers
138 template <typename BinaryT, typename LeftT, typename RightT>
139 struct binary_identity_policy_return
141 typedef typename BinaryT::parser_generator_t parser_generator_t;
142 typedef typename parser_generator_t
143 ::template result<LeftT, RightT>::type type;
146 template <typename TransformT>
147 struct binary_identity_policy
149 template <typename BinaryT, typename LeftT
150 , typename RightT, typename EnvT>
151 struct binary_result {
154 binary_identity_policy_return<BinaryT, LeftT, RightT>::type
158 template <typename BinaryT, typename LeftT
159 , typename RightT, typename EnvT>
160 typename parser_traversal_binary_result<
161 TransformT, BinaryT, LeftT, RightT, EnvT
164 BinaryT const &, LeftT const& left_
165 , RightT const& right_, EnvT const& /*env*/) const
167 typedef typename BinaryT::parser_generator_t parser_generator_t;
168 return parser_generator_t::
169 template generate<LeftT, RightT>(left_, right_);
173 ///////////////////////////////////////////////////////////////////////////
175 // transform_policies template
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
182 ///////////////////////////////////////////////////////////////////////////
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>
191 struct transform_policies :
194 public ActionPolicyT,
199 ///////////////////////////////////////////////////////////////////////////
201 // Identity transformation
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
210 // post_order::traverse(identity_transform(), some_parser)
212 ///////////////////////////////////////////////////////////////////////////
214 struct identity_transform : transform_policies<identity_transform> {};
216 }} // namespace boost::spirit
218 #endif // !defined(BOOST_SPIRIT_TRAVERSE_HPP)