Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:01:58

0001 /*=============================================================================
0002     Copyright (c) 2002-2003 Joel de Guzman
0003     Copyright (c) 2002-2003 Hartmut Kaiser
0004     http://spirit.sourceforge.net/
0005 
0006     Use, modification and distribution is subject to the Boost Software
0007     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0008     http://www.boost.org/LICENSE_1_0.txt)
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 }   // namespace impl
0029 
0030 ///////////////////////////////////////////////////////////////////////////////
0031 //
0032 //  Environment class for post_order_traversal
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 //  traverse_post_order_return template
0048 //
0049 //      This template is a helper for dispatching the calculation of a parser
0050 //      type result for a traversal level to the corresponding parser_category
0051 //      based specialization.
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 //  parser_traversal_..._result templates
0066 //
0067 //      These are metafunctions, which calculate the resulting parser type
0068 //      for all subparsers and feed these types to the user supplied
0069 //      metafunctions to get back the resulting parser type of this traversal
0070 //      level.
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     // left traversal environment and resulting parser type
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     // right traversal environment and resulting parser type
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     //  Meta functions, which dispatch the calculation of the return type of
0142     //  of the post_order traverse function to the result template of the
0143     //  corresponding parser_category based metafunction template.
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     //  Post-order parser traversal
0206     //
0207     //      The following templates contain the parser_category based code for
0208     //
0209     //        - calculating the type of the resulting parser, which is to be
0210     //          returned from a level of traversal
0211     //        - traversing down the composite parser structure, this traversal
0212     //          returnes a new parser object
0213     //
0214     //      Both tasks are delegated to the MetaT metafunction supplied by the
0215     //      user.
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& /*env*/)
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 }   //  namespace impl
0387 
0388 ///////////////////////////////////////////////////////////////////////////////
0389 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0390 
0391 }} // namespace boost::spirit
0392 
0393 #endif // !defined(BOOST_SPIRIT_TRAVERSE_IPP)