sl@0: /*============================================================================= sl@0: Copyright (c) 2002-2003 Joel de Guzman sl@0: Copyright (c) 2002-2003 Hartmut Kaiser sl@0: http://spirit.sourceforge.net/ sl@0: sl@0: Use, modification and distribution is subject to the Boost Software sl@0: License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at sl@0: http://www.boost.org/LICENSE_1_0.txt) sl@0: =============================================================================*/ sl@0: #if !defined(BOOST_SPIRIT_TRAVERSE_HPP) sl@0: #define BOOST_SPIRIT_TRAVERSE_HPP sl@0: sl@0: #include sl@0: sl@0: namespace boost { namespace spirit sl@0: { sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: // sl@0: // Post-order traversal of auxilliary parsers. sl@0: // sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: struct post_order sl@0: { sl@0: // Return the parser type, which is generated as the result of the sl@0: // traverse function below. sl@0: sl@0: template sl@0: struct result sl@0: { sl@0: typedef typename sl@0: traverse_post_order_return< sl@0: MetaT sl@0: , ParserT sl@0: , traverse_post_order_env<0, 0, 0, 0> sl@0: >::type sl@0: type; sl@0: }; sl@0: sl@0: // Traverse a given parser and refactor it with the help of the given sl@0: // MetaT metafunction template. sl@0: sl@0: template sl@0: static typename result::type sl@0: traverse(MetaT const &meta_, ParserT const &parser_) sl@0: { sl@0: typedef typename ParserT::parser_category_t parser_category_t; sl@0: return impl::traverse_post_order::generate( sl@0: meta_, parser_, traverse_post_order_env<0, 0, 0, 0>()); sl@0: } sl@0: }; sl@0: sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: // sl@0: // Transform policies sl@0: // sl@0: // The following policy classes could be used to assemble some new sl@0: // transformation metafunction which uses identity transformations sl@0: // for some parser_category type parsers. sl@0: // sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: // transform plain parsers sl@0: template sl@0: struct plain_identity_policy sl@0: { sl@0: template sl@0: struct plain_result sl@0: { sl@0: // plain parsers should be embedded and returned correctly sl@0: typedef typename ParserT::embed_t type; sl@0: }; sl@0: sl@0: template sl@0: typename parser_traversal_plain_result::type sl@0: generate_plain(ParserT const &parser_, EnvT const& /*env*/) const sl@0: { sl@0: return parser_; sl@0: } sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: // transform unary parsers sl@0: template sl@0: struct unary_identity_policy_return sl@0: { sl@0: typedef typename UnaryT::parser_generator_t parser_generator_t; sl@0: typedef typename parser_generator_t sl@0: ::template result::type type; sl@0: }; sl@0: sl@0: template sl@0: struct unary_identity_policy sl@0: { sl@0: template sl@0: struct unary_result sl@0: { sl@0: typedef sl@0: typename unary_identity_policy_return::type sl@0: type; sl@0: }; sl@0: sl@0: template sl@0: typename parser_traversal_unary_result< sl@0: TransformT, UnaryT, SubjectT, EnvT>::type sl@0: generate_unary( sl@0: UnaryT const &, SubjectT const &subject_, EnvT const& /*env*/) const sl@0: { sl@0: typedef typename UnaryT::parser_generator_t parser_generator_t; sl@0: return parser_generator_t::template generate(subject_); sl@0: } sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: // transform action parsers sl@0: template sl@0: struct action_identity_policy sl@0: { sl@0: template sl@0: struct action_result sl@0: { sl@0: typedef action type; sl@0: }; sl@0: sl@0: template sl@0: typename parser_traversal_action_result< sl@0: TransformT, ActionT, SubjectT, EnvT sl@0: >::type sl@0: generate_action(ActionT const &action_, SubjectT const &subject_, sl@0: EnvT const& /*env*/) const sl@0: { sl@0: return subject_[action_.predicate()]; sl@0: } sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: // transform binary parsers sl@0: template sl@0: struct binary_identity_policy_return sl@0: { sl@0: typedef typename BinaryT::parser_generator_t parser_generator_t; sl@0: typedef typename parser_generator_t sl@0: ::template result::type type; sl@0: }; sl@0: sl@0: template sl@0: struct binary_identity_policy sl@0: { sl@0: template sl@0: struct binary_result { sl@0: sl@0: typedef typename sl@0: binary_identity_policy_return::type sl@0: type; sl@0: }; sl@0: sl@0: template sl@0: typename parser_traversal_binary_result< sl@0: TransformT, BinaryT, LeftT, RightT, EnvT sl@0: >::type sl@0: generate_binary( sl@0: BinaryT const &, LeftT const& left_ sl@0: , RightT const& right_, EnvT const& /*env*/) const sl@0: { sl@0: typedef typename BinaryT::parser_generator_t parser_generator_t; sl@0: return parser_generator_t:: sl@0: template generate(left_, right_); sl@0: } sl@0: }; sl@0: sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: // sl@0: // transform_policies template sl@0: // sl@0: // The transform_policies template metafunction could serve as a sl@0: // base class for new metafunctions to be passed to the traverse meta sl@0: // template (see above), where only minimal parts have to be sl@0: // overwritten. sl@0: // sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: sl@0: template < sl@0: typename TransformT, sl@0: typename PlainPolicyT = plain_identity_policy, sl@0: typename UnaryPolicyT = unary_identity_policy, sl@0: typename ActionPolicyT = action_identity_policy, sl@0: typename BinaryPolicyT = binary_identity_policy sl@0: > sl@0: struct transform_policies : sl@0: public PlainPolicyT, sl@0: public UnaryPolicyT, sl@0: public ActionPolicyT, sl@0: public BinaryPolicyT sl@0: { sl@0: }; sl@0: sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: // sl@0: // Identity transformation sl@0: // sl@0: // The identity_transform metafunction supplied to the traverse sl@0: // template will generate a new parser, which will be exactly sl@0: // identical to the parser given as the parameter to the traverse sl@0: // metafunction. I.e. the following conceptual 'equation' will be sl@0: // always true: sl@0: // sl@0: // some_parser == sl@0: // post_order::traverse(identity_transform(), some_parser) sl@0: // sl@0: /////////////////////////////////////////////////////////////////////////// sl@0: sl@0: struct identity_transform : transform_policies {}; sl@0: sl@0: }} // namespace boost::spirit sl@0: sl@0: #endif // !defined(BOOST_SPIRIT_TRAVERSE_HPP)