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