traverse.hpp 7.7 KB

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