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