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