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