1 /*============================================================================= 2 Copyright (c) 2002-2003 Joel de Guzman 3 Copyright (c) 2002-2003 Hartmut Kaiser 4 http://spirit.sourceforge.net/ 5 6 Distributed under the Boost Software License, Version 1.0. (See accompanying 7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 #if !defined(BOOST_SPIRIT_TRAVERSE_HPP) 10 #define BOOST_SPIRIT_TRAVERSE_HPP 11 12 #include <boost/spirit/home/classic/namespace.hpp> 13 #include <boost/spirit/home/classic/meta/impl/traverse.ipp> 14 15 namespace boost { namespace spirit { 16 17 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 18 19 /////////////////////////////////////////////////////////////////////////// 20 // 21 // Post-order traversal of auxiliary parsers. 22 // 23 /////////////////////////////////////////////////////////////////////////// 24 struct post_order 25 { 26 // Return the parser type, which is generated as the result of the 27 // traverse function below. 28 29 template <typename MetaT, typename ParserT> 30 struct result 31 { 32 typedef typename 33 traverse_post_order_return< 34 MetaT 35 , ParserT 36 , traverse_post_order_env<0, 0, 0, 0> 37 >::type 38 type; 39 }; 40 41 // Traverse a given parser and refactor it with the help of the given 42 // MetaT metafunction template. 43 44 template <typename MetaT, typename ParserT> 45 static typename result<MetaT, ParserT>::type traverseboost::spirit::post_order46 traverse(MetaT const &meta_, ParserT const &parser_) 47 { 48 typedef typename ParserT::parser_category_t parser_category_t; 49 return impl::traverse_post_order<parser_category_t>::generate( 50 meta_, parser_, traverse_post_order_env<0, 0, 0, 0>()); 51 } 52 }; 53 54 /////////////////////////////////////////////////////////////////////////// 55 // 56 // Transform policies 57 // 58 // The following policy classes could be used to assemble some new 59 // transformation metafunction which uses identity transformations 60 // for some parser_category type parsers. 61 // 62 /////////////////////////////////////////////////////////////////////////// 63 64 /////////////////////////////////////////////////////////////////////////// 65 // transform plain parsers 66 template <typename TransformT> 67 struct plain_identity_policy 68 { 69 template <typename ParserT, typename EnvT> 70 struct plain_result 71 { 72 // plain parsers should be embedded and returned correctly 73 typedef typename ParserT::embed_t type; 74 }; 75 76 template <typename ParserT, typename EnvT> 77 typename parser_traversal_plain_result<TransformT, ParserT, EnvT>::type generate_plainboost::spirit::plain_identity_policy78 generate_plain(ParserT const &parser_, EnvT const& /*env*/) const 79 { 80 return parser_; 81 } 82 }; 83 84 ////////////////////////////////// 85 // transform unary parsers 86 template <typename UnaryT, typename SubjectT> 87 struct unary_identity_policy_return 88 { 89 typedef typename UnaryT::parser_generator_t parser_generator_t; 90 typedef typename parser_generator_t 91 ::template result<SubjectT>::type type; 92 }; 93 94 template <typename TransformT> 95 struct unary_identity_policy 96 { 97 template <typename UnaryT, typename SubjectT, typename EnvT> 98 struct unary_result 99 { 100 typedef 101 typename unary_identity_policy_return<UnaryT, SubjectT>::type 102 type; 103 }; 104 105 template <typename UnaryT, typename SubjectT, typename EnvT> 106 typename parser_traversal_unary_result< 107 TransformT, UnaryT, SubjectT, EnvT>::type generate_unaryboost::spirit::unary_identity_policy108 generate_unary( 109 UnaryT const &, SubjectT const &subject_, EnvT const& /*env*/) const 110 { 111 typedef typename UnaryT::parser_generator_t parser_generator_t; 112 return parser_generator_t::template generate<SubjectT>(subject_); 113 } 114 }; 115 116 ////////////////////////////////// 117 // transform action parsers 118 template <typename TransformT> 119 struct action_identity_policy 120 { 121 template <typename ActionT, typename SubjectT, typename EnvT> 122 struct action_result 123 { 124 typedef action<SubjectT, typename ActionT::predicate_t> type; 125 }; 126 127 template <typename ActionT, typename SubjectT, typename EnvT> 128 typename parser_traversal_action_result< 129 TransformT, ActionT, SubjectT, EnvT 130 >::type generate_actionboost::spirit::action_identity_policy131 generate_action(ActionT const &action_, SubjectT const &subject_, 132 EnvT const& /*env*/) const 133 { 134 return subject_[action_.predicate()]; 135 } 136 }; 137 138 ////////////////////////////////// 139 // transform binary parsers 140 template <typename BinaryT, typename LeftT, typename RightT> 141 struct binary_identity_policy_return 142 { 143 typedef typename BinaryT::parser_generator_t parser_generator_t; 144 typedef typename parser_generator_t 145 ::template result<LeftT, RightT>::type type; 146 }; 147 148 template <typename TransformT> 149 struct binary_identity_policy 150 { 151 template <typename BinaryT, typename LeftT 152 , typename RightT, typename EnvT> 153 struct binary_result { 154 155 typedef typename 156 binary_identity_policy_return<BinaryT, LeftT, RightT>::type 157 type; 158 }; 159 160 template <typename BinaryT, typename LeftT 161 , typename RightT, typename EnvT> 162 typename parser_traversal_binary_result< 163 TransformT, BinaryT, LeftT, RightT, EnvT 164 >::type generate_binaryboost::spirit::binary_identity_policy165 generate_binary( 166 BinaryT const &, LeftT const& left_ 167 , RightT const& right_, EnvT const& /*env*/) const 168 { 169 typedef typename BinaryT::parser_generator_t parser_generator_t; 170 return parser_generator_t:: 171 template generate<LeftT, RightT>(left_, right_); 172 } 173 }; 174 175 /////////////////////////////////////////////////////////////////////////// 176 // 177 // transform_policies template 178 // 179 // The transform_policies template metafunction could serve as a 180 // base class for new metafunctions to be passed to the traverse meta 181 // template (see above), where only minimal parts have to be 182 // overwritten. 183 // 184 /////////////////////////////////////////////////////////////////////////// 185 186 template < 187 typename TransformT, 188 typename PlainPolicyT = plain_identity_policy<TransformT>, 189 typename UnaryPolicyT = unary_identity_policy<TransformT>, 190 typename ActionPolicyT = action_identity_policy<TransformT>, 191 typename BinaryPolicyT = binary_identity_policy<TransformT> 192 > 193 struct transform_policies : 194 public PlainPolicyT, 195 public UnaryPolicyT, 196 public ActionPolicyT, 197 public BinaryPolicyT 198 { 199 }; 200 201 /////////////////////////////////////////////////////////////////////////// 202 // 203 // Identity transformation 204 // 205 // The identity_transform metafunction supplied to the traverse 206 // template will generate a new parser, which will be exactly 207 // identical to the parser given as the parameter to the traverse 208 // metafunction. I.e. the following conceptual 'equation' will be 209 // always true: 210 // 211 // some_parser == 212 // post_order::traverse(identity_transform(), some_parser) 213 // 214 /////////////////////////////////////////////////////////////////////////// 215 216 struct identity_transform : transform_policies<identity_transform> {}; 217 218 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 219 220 }} // namespace BOOST_SPIRIT_CLASSIC_NS 221 222 #endif // !defined(BOOST_SPIRIT_TRAVERSE_HPP) 223