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   Distributed under the Boost Software License, Version 1.0. (See accompanying
0007   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 =============================================================================*/
0009 #if !defined(BOOST_SPIRIT_TRAVERSE_HPP)
0010 #define BOOST_SPIRIT_TRAVERSE_HPP
0011 
0012 #include <boost/spirit/home/classic/namespace.hpp>
0013 #include <boost/spirit/home/classic/meta/impl/traverse.ipp>
0014 
0015 namespace boost { namespace spirit {
0016 
0017 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0018 
0019     ///////////////////////////////////////////////////////////////////////////
0020     //
0021     //  Post-order traversal of auxiliary parsers.
0022     //
0023     ///////////////////////////////////////////////////////////////////////////
0024     struct post_order
0025     {
0026         //  Return the parser type, which is generated as the result of the
0027         //  traverse function below.
0028 
0029         template <typename MetaT, typename ParserT>
0030         struct result
0031         {
0032             typedef typename
0033                 traverse_post_order_return<
0034                     MetaT
0035                   , ParserT
0036                   , traverse_post_order_env<0, 0, 0, 0>
0037                 >::type
0038             type;
0039         };
0040 
0041         //  Traverse a given parser and refactor it with the help of the given
0042         //  MetaT metafunction template.
0043 
0044         template <typename MetaT, typename ParserT>
0045         static typename result<MetaT, ParserT>::type
0046         traverse(MetaT const &meta_, ParserT const &parser_)
0047         {
0048             typedef typename ParserT::parser_category_t parser_category_t;
0049             return impl::traverse_post_order<parser_category_t>::generate(
0050                 meta_, parser_, traverse_post_order_env<0, 0, 0, 0>());
0051         }
0052     };
0053 
0054     ///////////////////////////////////////////////////////////////////////////
0055     //
0056     //  Transform policies
0057     //
0058     //      The following policy classes could be used to assemble some new
0059     //      transformation metafunction which uses identity transformations
0060     //      for some parser_category type parsers.
0061     //
0062     ///////////////////////////////////////////////////////////////////////////
0063 
0064     ///////////////////////////////////////////////////////////////////////////
0065     //  transform plain parsers
0066     template <typename TransformT>
0067     struct plain_identity_policy
0068     {
0069         template <typename ParserT, typename EnvT>
0070         struct plain_result
0071         {
0072             // plain parsers should be embedded and returned correctly
0073             typedef typename ParserT::embed_t type;
0074         };
0075 
0076         template <typename ParserT, typename EnvT>
0077         typename parser_traversal_plain_result<TransformT, ParserT, EnvT>::type
0078         generate_plain(ParserT const &parser_, EnvT const& /*env*/) const
0079         {
0080             return parser_;
0081         }
0082     };
0083 
0084     //////////////////////////////////
0085     //  transform unary parsers
0086     template <typename UnaryT, typename SubjectT>
0087     struct unary_identity_policy_return
0088     {
0089         typedef typename UnaryT::parser_generator_t parser_generator_t;
0090         typedef typename parser_generator_t
0091             ::template result<SubjectT>::type type;
0092     };
0093 
0094     template <typename TransformT>
0095     struct unary_identity_policy
0096     {
0097         template <typename UnaryT, typename SubjectT, typename EnvT>
0098         struct unary_result
0099         {
0100             typedef
0101                 typename unary_identity_policy_return<UnaryT, SubjectT>::type
0102             type;
0103         };
0104 
0105         template <typename UnaryT, typename SubjectT, typename EnvT>
0106         typename parser_traversal_unary_result<
0107             TransformT, UnaryT, SubjectT, EnvT>::type
0108         generate_unary(
0109             UnaryT const &, SubjectT const &subject_, EnvT const& /*env*/) const
0110         {
0111             typedef typename UnaryT::parser_generator_t parser_generator_t;
0112             return parser_generator_t::template generate<SubjectT>(subject_);
0113         }
0114     };
0115 
0116     //////////////////////////////////
0117     //  transform action parsers
0118     template <typename TransformT>
0119     struct action_identity_policy
0120     {
0121         template <typename ActionT, typename SubjectT, typename EnvT>
0122         struct action_result
0123         {
0124             typedef action<SubjectT, typename ActionT::predicate_t> type;
0125         };
0126 
0127         template <typename ActionT, typename SubjectT, typename EnvT>
0128         typename parser_traversal_action_result<
0129             TransformT, ActionT, SubjectT, EnvT
0130         >::type
0131         generate_action(ActionT const &action_, SubjectT const &subject_,
0132             EnvT const& /*env*/) const
0133         {
0134             return subject_[action_.predicate()];
0135         }
0136     };
0137 
0138     //////////////////////////////////
0139     //  transform binary parsers
0140     template <typename BinaryT, typename LeftT, typename RightT>
0141     struct binary_identity_policy_return
0142     {
0143         typedef typename BinaryT::parser_generator_t parser_generator_t;
0144         typedef typename parser_generator_t
0145             ::template result<LeftT, RightT>::type type;
0146     };
0147 
0148     template <typename TransformT>
0149     struct binary_identity_policy
0150     {
0151         template <typename BinaryT, typename LeftT
0152             , typename RightT, typename EnvT>
0153         struct binary_result {
0154 
0155             typedef typename
0156                 binary_identity_policy_return<BinaryT, LeftT, RightT>::type
0157             type;
0158         };
0159 
0160         template <typename BinaryT, typename LeftT
0161             , typename RightT, typename EnvT>
0162         typename parser_traversal_binary_result<
0163             TransformT, BinaryT, LeftT, RightT, EnvT
0164         >::type
0165         generate_binary(
0166             BinaryT const &, LeftT const& left_
0167           , RightT const& right_, EnvT const& /*env*/) const
0168         {
0169             typedef typename BinaryT::parser_generator_t parser_generator_t;
0170             return parser_generator_t::
0171                 template generate<LeftT, RightT>(left_, right_);
0172         }
0173     };
0174 
0175     ///////////////////////////////////////////////////////////////////////////
0176     //
0177     //  transform_policies template
0178     //
0179     //      The transform_policies template metafunction could serve as a
0180     //      base class for new metafunctions to be passed to the traverse meta
0181     //      template (see above), where only minimal parts have to be
0182     //      overwritten.
0183     //
0184     ///////////////////////////////////////////////////////////////////////////
0185 
0186     template <
0187         typename TransformT,
0188         typename PlainPolicyT = plain_identity_policy<TransformT>,
0189         typename UnaryPolicyT = unary_identity_policy<TransformT>,
0190         typename ActionPolicyT = action_identity_policy<TransformT>,
0191         typename BinaryPolicyT = binary_identity_policy<TransformT>
0192     >
0193     struct transform_policies :
0194         public PlainPolicyT,
0195         public UnaryPolicyT,
0196         public ActionPolicyT,
0197         public BinaryPolicyT
0198     {
0199     };
0200 
0201     ///////////////////////////////////////////////////////////////////////////
0202     //
0203     //  Identity transformation
0204     //
0205     //      The identity_transform metafunction supplied to the traverse
0206     //      template will generate a new parser, which will be exactly
0207     //      identical to the parser given as the parameter to the traverse
0208     //      metafunction. I.e. the following conceptual 'equation' will be
0209     //      always true:
0210     //
0211     //      some_parser ==
0212     //          post_order::traverse(identity_transform(), some_parser)
0213     //
0214     ///////////////////////////////////////////////////////////////////////////
0215 
0216     struct identity_transform : transform_policies<identity_transform> {};
0217 
0218 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0219 
0220 }} // namespace BOOST_SPIRIT_CLASSIC_NS
0221 
0222 #endif // !defined(BOOST_SPIRIT_TRAVERSE_HPP)