File indexing completed on 2025-01-31 10:01:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #if !defined(BOOST_SPIRIT_TRAVERSE_IPP)
0011 #define BOOST_SPIRIT_TRAVERSE_IPP
0012
0013
0014 #include <boost/spirit/home/classic/meta/fundamental.hpp>
0015
0016
0017 namespace boost { namespace spirit {
0018
0019 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0020
0021
0022 namespace impl
0023 {
0024
0025 template <typename CategoryT>
0026 struct traverse_post_order_return_category;
0027
0028 }
0029
0030
0031
0032
0033
0034
0035
0036 template <int Level, int Node, int Index, int LastLeft>
0037 struct traverse_post_order_env {
0038
0039 BOOST_STATIC_CONSTANT(int, level = Level);
0040 BOOST_STATIC_CONSTANT(int, node = Node);
0041 BOOST_STATIC_CONSTANT(int, index = Index);
0042 BOOST_STATIC_CONSTANT(int, lastleft = LastLeft);
0043 };
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 template <typename MetaT, typename ParserT, typename EnvT>
0056 struct traverse_post_order_return {
0057
0058 typedef typename ParserT::parser_category_t parser_category_t;
0059 typedef typename impl::traverse_post_order_return_category<parser_category_t>
0060 ::template result<MetaT, ParserT, EnvT>::type type;
0061 };
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 template <typename MetaT, typename ParserT, typename EnvT>
0075 struct parser_traversal_plain_result {
0076
0077 typedef typename MetaT::template plain_result<ParserT, EnvT>::type type;
0078 };
0079
0080
0081 template <typename MetaT, typename UnaryT, typename SubjectT, typename EnvT>
0082 struct parser_traversal_unary_result {
0083
0084 typedef typename MetaT
0085 ::template unary_result<UnaryT, SubjectT, EnvT>::type type;
0086 };
0087
0088
0089 template <typename MetaT, typename ActionT, typename SubjectT, typename EnvT>
0090 struct parser_traversal_action_result {
0091
0092 typedef typename MetaT
0093 ::template action_result<ActionT, SubjectT, EnvT>::type type;
0094 };
0095
0096
0097 template <
0098 typename MetaT, typename BinaryT, typename LeftT,
0099 typename RightT, typename EnvT
0100 >
0101 struct parser_traversal_binary_result {
0102
0103 BOOST_STATIC_CONSTANT(int,
0104 thisnum = (node_count<BinaryT>::value + EnvT::lastleft-1));
0105 BOOST_STATIC_CONSTANT(int,
0106 leftnum = (node_count<LeftT>::value + EnvT::lastleft-1));
0107 BOOST_STATIC_CONSTANT(int,
0108 leafnum = (leaf_count<LeftT>::value + EnvT::index));
0109
0110 typedef parser_traversal_binary_result self_t;
0111
0112
0113 typedef traverse_post_order_env<
0114 (EnvT::level+1), (self_t::leftnum), (EnvT::index), (EnvT::lastleft)
0115 > left_sub_env_t;
0116 typedef typename traverse_post_order_return<
0117 MetaT, LeftT, left_sub_env_t
0118 >::type
0119 left_t;
0120
0121
0122 typedef traverse_post_order_env<
0123 (EnvT::level+1), (self_t::thisnum-1), (self_t::leafnum), (self_t::leftnum+1)
0124 > right_sub_env_t;
0125 typedef typename traverse_post_order_return<
0126 MetaT, RightT, right_sub_env_t
0127 >::type
0128 right_t;
0129
0130 typedef typename MetaT::template binary_result<
0131 BinaryT, left_t, right_t, EnvT
0132 >::type
0133 type;
0134 };
0135
0136
0137 namespace impl
0138 {
0139
0140
0141
0142
0143
0144
0145
0146
0147 template <typename CategoryT>
0148 struct traverse_post_order_return_category;
0149
0150 template <>
0151 struct traverse_post_order_return_category<plain_parser_category> {
0152
0153 template <typename MetaT, typename ParserT, typename EnvT>
0154 struct result {
0155
0156 typedef typename parser_traversal_plain_result<
0157 MetaT, ParserT, EnvT
0158 >::type
0159 type;
0160 };
0161 };
0162
0163 template <>
0164 struct traverse_post_order_return_category<unary_parser_category> {
0165
0166 template <typename MetaT, typename ParserT, typename EnvT>
0167 struct result {
0168
0169 typedef typename parser_traversal_unary_result<
0170 MetaT, ParserT, typename ParserT::subject_t, EnvT
0171 >::type
0172 type;
0173 };
0174 };
0175
0176 template <>
0177 struct traverse_post_order_return_category<action_parser_category> {
0178
0179 template <typename MetaT, typename ParserT, typename EnvT>
0180 struct result {
0181
0182 typedef typename parser_traversal_action_result<
0183 MetaT, ParserT, typename ParserT::subject_t, EnvT
0184 >::type
0185 type;
0186 };
0187 };
0188
0189 template <>
0190 struct traverse_post_order_return_category<binary_parser_category> {
0191
0192 template <typename MetaT, typename ParserT, typename EnvT>
0193 struct result {
0194
0195 typedef typename parser_traversal_binary_result<
0196 MetaT, ParserT, typename ParserT::left_t,
0197 typename ParserT::right_t, EnvT
0198 >::type
0199 type;
0200 };
0201 };
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 template <typename CategoryT>
0220 struct traverse_post_order;
0221
0222 template <>
0223 struct traverse_post_order<plain_parser_category> {
0224
0225 template <typename MetaT, typename ParserT, typename EnvT>
0226 struct result {
0227
0228 typedef
0229 typename parser_traversal_plain_result<MetaT, ParserT, EnvT>::type
0230 type;
0231 };
0232
0233 template <typename MetaT, typename ParserT, typename EnvT>
0234 static
0235 typename parser_traversal_plain_result<MetaT, ParserT, EnvT>::type
0236 generate(MetaT const &meta_, ParserT const &parser_, EnvT const &env)
0237 {
0238 return meta_.generate_plain(parser_, env);
0239 }
0240 };
0241
0242 template <>
0243 struct traverse_post_order<unary_parser_category> {
0244
0245 template <
0246 typename MetaT, typename ParserT, typename SubjectT, typename EnvT
0247 >
0248 struct result {
0249
0250 typedef typename parser_traversal_unary_result<
0251 MetaT, ParserT, SubjectT, EnvT
0252 >::type
0253 type;
0254 };
0255
0256 template <typename MetaT, typename ParserT, typename EnvT>
0257 static
0258 typename parser_traversal_unary_result<
0259 MetaT, ParserT,
0260 typename traverse_post_order_return<
0261 MetaT, typename ParserT::subject_t, EnvT
0262 >::type,
0263 EnvT
0264 >::type
0265 generate(MetaT const &meta_, ParserT const &unary_, EnvT const &env)
0266 {
0267 typedef typename ParserT::subject_t subject_t;
0268 typedef typename subject_t::parser_category_t subject_category_t;
0269
0270 return meta_.generate_unary(
0271 unary_,
0272 traverse_post_order<subject_category_t>::generate(meta_,
0273 unary_.subject(),
0274 traverse_post_order_env<
0275 EnvT::level+1, EnvT::node-1, EnvT::index, EnvT::lastleft
0276 >()
0277 ),
0278 env
0279 );
0280 }
0281 };
0282
0283 template <>
0284 struct traverse_post_order<action_parser_category> {
0285
0286 template <
0287 typename MetaT, typename ParserT, typename SubjectT, typename EnvT
0288 >
0289 struct result {
0290
0291 typedef typename parser_traversal_action_result<
0292 MetaT, ParserT, SubjectT, EnvT
0293 >::type
0294 type;
0295 };
0296
0297 template <typename MetaT, typename ParserT, typename EnvT>
0298 static
0299 typename parser_traversal_action_result<
0300 MetaT, ParserT,
0301 typename traverse_post_order_return<
0302 MetaT, typename ParserT::subject_t, EnvT
0303 >::type,
0304 EnvT
0305 >::type
0306 generate(MetaT const &meta_, ParserT const &action_, EnvT const &env)
0307 {
0308 typedef typename ParserT::subject_t subject_t;
0309 typedef typename subject_t::parser_category_t subject_category_t;
0310
0311 return meta_.generate_action(
0312 action_,
0313 traverse_post_order<subject_category_t>::generate(meta_,
0314 action_.subject(),
0315 traverse_post_order_env<
0316 EnvT::level+1, EnvT::node-1, EnvT::index, EnvT::lastleft
0317 >()
0318 ),
0319 env
0320 );
0321 }
0322 };
0323
0324 template <>
0325 struct traverse_post_order<binary_parser_category> {
0326
0327 template <
0328 typename MetaT, typename ParserT, typename LeftT,
0329 typename RightT, typename EnvT
0330 >
0331 struct result {
0332
0333 typedef typename parser_traversal_binary_result<
0334 MetaT, ParserT, LeftT, RightT, EnvT
0335 >::type
0336 type;
0337 };
0338
0339 template <typename MetaT, typename ParserT, typename EnvT>
0340 static
0341 typename parser_traversal_binary_result<
0342 MetaT, ParserT,
0343 typename traverse_post_order_return<
0344 MetaT, typename ParserT::left_t, EnvT
0345 >::type,
0346 typename traverse_post_order_return<
0347 MetaT, typename ParserT::right_t, EnvT
0348 >::type,
0349 EnvT
0350 >::type
0351 generate(MetaT const &meta_, ParserT const &binary_, EnvT const& )
0352 {
0353 typedef typename ParserT::left_t left_t;
0354 typedef typename ParserT::right_t right_t;
0355 typedef typename left_t::parser_category_t left_category_t;
0356 typedef typename right_t::parser_category_t right_category_t;
0357
0358 enum {
0359 leftnum = (node_count<left_t>::value + EnvT::lastleft-1),
0360 thisnum = (node_count<ParserT>::value + EnvT::lastleft-1),
0361 rightnum = (thisnum-1),
0362 leafnum = (leaf_count<left_t>::value + EnvT::index)
0363 };
0364
0365 return meta_.generate_binary(
0366 binary_,
0367 traverse_post_order<left_category_t>::generate(
0368 meta_, binary_.left(),
0369 traverse_post_order_env<
0370 EnvT::level+1, leftnum, EnvT::index, EnvT::lastleft
0371 >()
0372 ),
0373 traverse_post_order<right_category_t>::generate(
0374 meta_, binary_.right(),
0375 traverse_post_order_env<
0376 EnvT::level+1, rightnum, leafnum, leftnum+1
0377 >()
0378 ),
0379 traverse_post_order_env<
0380 EnvT::level, thisnum, EnvT::index, EnvT::lastleft
0381 >()
0382 );
0383 }
0384 };
0385
0386 }
0387
0388
0389 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0390
0391 }}
0392
0393 #endif