parser.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*=============================================================================
  2. Copyright (c) 2001-2014 Joel de Guzman
  3. Copyright (c) 2013 Agustin Berge
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. ==============================================================================*/
  7. #if !defined(BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM)
  8. #define BOOST_SPIRIT_X3_PARSER_OCTOBER_16_2008_0254PM
  9. #include <boost/mpl/bool.hpp>
  10. #include <boost/type_traits/is_base_of.hpp>
  11. #include <boost/type_traits/remove_cv.hpp>
  12. #include <boost/type_traits/remove_reference.hpp>
  13. #include <boost/utility/declval.hpp>
  14. #include <boost/utility/enable_if.hpp>
  15. #include <boost/spirit/home/x3/support/unused.hpp>
  16. #include <boost/spirit/home/x3/support/context.hpp>
  17. #include <boost/spirit/home/x3/support/traits/has_attribute.hpp>
  18. #include <boost/core/ignore_unused.hpp>
  19. #include <boost/assert.hpp>
  20. #include <string>
  21. #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
  22. #include <typeinfo>
  23. #endif
  24. namespace boost { namespace spirit { namespace x3
  25. {
  26. template <typename Subject, typename Action>
  27. struct action;
  28. template <typename Subject, typename Handler>
  29. struct guard;
  30. struct parser_base {};
  31. struct parser_id;
  32. template <typename Derived>
  33. struct parser : parser_base
  34. {
  35. typedef Derived derived_type;
  36. static bool const handles_container = false;
  37. static bool const is_pass_through_unary = false;
  38. static bool const has_action = false;
  39. constexpr Derived const& derived() const
  40. {
  41. return *static_cast<Derived const*>(this);
  42. }
  43. template <typename Action>
  44. constexpr action<Derived, Action> operator[](Action f) const
  45. {
  46. return { this->derived(), f };
  47. }
  48. template <typename Handler>
  49. constexpr guard<Derived, Handler> on_error(Handler f) const
  50. {
  51. return { this->derived(), f };
  52. }
  53. };
  54. struct unary_category;
  55. struct binary_category;
  56. template <typename Subject, typename Derived>
  57. struct unary_parser : parser<Derived>
  58. {
  59. typedef unary_category category;
  60. typedef Subject subject_type;
  61. static bool const has_action = Subject::has_action;
  62. constexpr unary_parser(Subject const& subject)
  63. : subject(subject) {}
  64. unary_parser const& get_unary() const { return *this; }
  65. Subject subject;
  66. };
  67. template <typename Left, typename Right, typename Derived>
  68. struct binary_parser : parser<Derived>
  69. {
  70. typedef binary_category category;
  71. typedef Left left_type;
  72. typedef Right right_type;
  73. static bool const has_action =
  74. left_type::has_action || right_type::has_action;
  75. constexpr binary_parser(Left const& left, Right const& right)
  76. : left(left), right(right) {}
  77. binary_parser const& get_binary() const { return *this; }
  78. Left left;
  79. Right right;
  80. };
  81. ///////////////////////////////////////////////////////////////////////////
  82. // as_parser: convert a type, T, into a parser.
  83. ///////////////////////////////////////////////////////////////////////////
  84. namespace extension
  85. {
  86. namespace detail
  87. {
  88. namespace as_parser_guard
  89. {
  90. void as_spirit_parser(...);
  91. template<typename T, typename R =
  92. decltype(as_spirit_parser(boost::declval<T const&>()))>
  93. struct deduce_as_parser
  94. {
  95. typedef R type;
  96. typedef typename
  97. boost::remove_cv<
  98. typename boost::remove_reference<R>::type
  99. >::type
  100. value_type;
  101. static type call(T const& v)
  102. {
  103. return as_spirit_parser(v);
  104. }
  105. };
  106. template<typename T>
  107. struct deduce_as_parser<T, void>
  108. {};
  109. }
  110. using as_parser_guard::deduce_as_parser;
  111. }
  112. template <typename T, typename Enable = void>
  113. struct as_parser : detail::deduce_as_parser<T> {};
  114. template <>
  115. struct as_parser<unused_type>
  116. {
  117. typedef unused_type type;
  118. typedef unused_type value_type;
  119. static constexpr type call(unused_type)
  120. {
  121. return unused;
  122. }
  123. };
  124. template <typename Derived>
  125. struct as_parser<Derived
  126. , typename enable_if<is_base_of<parser_base, Derived>>::type>
  127. {
  128. typedef Derived const& type;
  129. typedef Derived value_type;
  130. static constexpr type call(Derived const& p)
  131. {
  132. return p;
  133. }
  134. };
  135. template <typename Derived>
  136. struct as_parser<parser<Derived>>
  137. {
  138. typedef Derived const& type;
  139. typedef Derived value_type;
  140. static constexpr type call(parser<Derived> const& p)
  141. {
  142. return p.derived();
  143. }
  144. };
  145. }
  146. template <typename T>
  147. constexpr typename extension::as_parser<T>::type
  148. as_parser(T const& x)
  149. {
  150. return extension::as_parser<T>::call(x);
  151. }
  152. template <typename Derived>
  153. constexpr Derived const&
  154. as_parser(parser<Derived> const& p)
  155. {
  156. return p.derived();
  157. }
  158. ///////////////////////////////////////////////////////////////////////////
  159. // The main what function
  160. //
  161. // Note: unlike Spirit2, spirit parsers are no longer required to have a
  162. // "what" member function. In X3, we specialize the get_info struct
  163. // below where needed. If a specialization is not provided, the default
  164. // below will be used. The default "what" result will be the typeid
  165. // name of the parser if BOOST_SPIRIT_X3_NO_RTTI is not defined, otherwise
  166. // "undefined"
  167. ///////////////////////////////////////////////////////////////////////////
  168. template <typename Parser, typename Enable = void>
  169. struct get_info
  170. {
  171. typedef std::string result_type;
  172. std::string operator()(Parser const&) const
  173. {
  174. #if !defined(BOOST_SPIRIT_X3_NO_RTTI)
  175. return typeid(Parser).name();
  176. #else
  177. return "undefined";
  178. #endif
  179. }
  180. };
  181. template <typename Parser>
  182. std::string what(Parser const& p)
  183. {
  184. return get_info<Parser>()(p);
  185. }
  186. }}}
  187. namespace boost { namespace spirit { namespace x3 { namespace traits
  188. {
  189. template <typename Subject, typename Derived, typename Context>
  190. struct has_attribute<x3::unary_parser<Subject, Derived>, Context>
  191. : has_attribute<Subject, Context> {};
  192. template <typename Left, typename Right, typename Derived, typename Context>
  193. struct has_attribute<x3::binary_parser<Left, Right, Derived>, Context>
  194. : mpl::bool_<has_attribute<Left, Context>::value ||
  195. has_attribute<Right, Context>::value> {};
  196. }}}}
  197. #endif