parse.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*=============================================================================
  2. Copyright (c) 2001-2014 Joel de Guzman
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. =============================================================================*/
  6. #if !defined(BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM)
  7. #define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM
  8. #include <boost/spirit/home/x3/support/context.hpp>
  9. #include <boost/spirit/home/x3/core/parser.hpp>
  10. #include <boost/spirit/home/x3/core/skip_over.hpp>
  11. #include <boost/iterator/iterator_concepts.hpp>
  12. namespace boost { namespace spirit { namespace x3
  13. {
  14. ///////////////////////////////////////////////////////////////////////////
  15. template <typename Iterator, typename Parser, typename Attribute>
  16. inline bool
  17. parse_main(
  18. Iterator& first
  19. , Iterator last
  20. , Parser const& p
  21. , Attribute& attr)
  22. {
  23. // Make sure the iterator is at least a readable forward traversal iterator.
  24. // If you got a compilation error here, then you are using a weaker iterator
  25. // while calling this function, you need to supply a readable forward traversal
  26. // iterator instead.
  27. BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>));
  28. BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>));
  29. // If you get an error no matching function for call to 'as_parser'
  30. // here, then p is not a parser or there is no suitable conversion
  31. // from p to a parser.
  32. return as_parser(p).parse(first, last, unused, unused, attr);
  33. }
  34. ///////////////////////////////////////////////////////////////////////////
  35. template <typename Iterator, typename Parser, typename Attribute>
  36. inline bool
  37. parse(
  38. Iterator& first
  39. , Iterator last
  40. , Parser const& p
  41. , Attribute& attr)
  42. {
  43. return parse_main(first, last, p, attr);
  44. }
  45. ///////////////////////////////////////////////////////////////////////////
  46. template <typename Iterator, typename Parser, typename Attribute>
  47. inline bool
  48. parse(
  49. Iterator const& first_
  50. , Iterator last
  51. , Parser const& p
  52. , Attribute& attr)
  53. {
  54. Iterator first = first_;
  55. return parse_main(first, last, p, attr);
  56. }
  57. ///////////////////////////////////////////////////////////////////////////
  58. template <typename Iterator, typename Parser>
  59. inline bool
  60. parse(
  61. Iterator& first
  62. , Iterator last
  63. , Parser const& p)
  64. {
  65. return parse_main(first, last, p, unused);
  66. }
  67. ///////////////////////////////////////////////////////////////////////////
  68. template <typename Iterator, typename Parser>
  69. inline bool
  70. parse(
  71. Iterator const& first_
  72. , Iterator last
  73. , Parser const& p)
  74. {
  75. Iterator first = first_;
  76. return parse_main(first, last, p, unused);
  77. }
  78. ///////////////////////////////////////////////////////////////////////////
  79. enum class skip_flag
  80. {
  81. post_skip, // force post-skipping in phrase_parse()
  82. dont_post_skip // inhibit post-skipping in phrase_parse()
  83. };
  84. ///////////////////////////////////////////////////////////////////////////
  85. template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
  86. inline bool
  87. phrase_parse_main(
  88. Iterator& first
  89. , Iterator last
  90. , Parser const& p
  91. , Skipper const& s
  92. , Attribute& attr
  93. , skip_flag post_skip = skip_flag::post_skip)
  94. {
  95. // Make sure the iterator is at least a readable forward traversal iterator.
  96. // If you got a compilation error here, then you are using a weaker iterator
  97. // while calling this function, you need to supply a readable forward traversal
  98. // iterator instead.
  99. BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>));
  100. BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>));
  101. static_assert(!std::is_same<Skipper, unused_type>::value,
  102. "Error! Skipper cannot be unused_type.");
  103. // If you get an error no matching function for call to 'as_parser'
  104. // here, for either p or s, then p or s is not a parser or there is
  105. // no suitable conversion from p to a parser.
  106. auto skipper_ctx = make_context<skipper_tag>(as_parser(s));
  107. bool r = as_parser(p).parse(first, last, skipper_ctx, unused, attr);
  108. if (post_skip == skip_flag::post_skip)
  109. x3::skip_over(first, last, skipper_ctx);
  110. return r;
  111. }
  112. ///////////////////////////////////////////////////////////////////////////
  113. template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
  114. inline bool
  115. phrase_parse(
  116. Iterator& first
  117. , Iterator last
  118. , Parser const& p
  119. , Skipper const& s
  120. , Attribute& attr
  121. , skip_flag post_skip = skip_flag::post_skip)
  122. {
  123. return phrase_parse_main(first, last, p, s, attr, post_skip);
  124. }
  125. ///////////////////////////////////////////////////////////////////////////
  126. template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
  127. inline bool
  128. phrase_parse(
  129. Iterator const& first_
  130. , Iterator last
  131. , Parser const& p
  132. , Skipper const& s
  133. , Attribute& attr
  134. , skip_flag post_skip = skip_flag::post_skip)
  135. {
  136. Iterator first = first_;
  137. return phrase_parse_main(first, last, p, s, attr, post_skip);
  138. }
  139. ///////////////////////////////////////////////////////////////////////////
  140. template <typename Iterator, typename Parser, typename Skipper>
  141. inline bool
  142. phrase_parse(
  143. Iterator& first
  144. , Iterator last
  145. , Parser const& p
  146. , Skipper const& s
  147. , skip_flag post_skip = skip_flag::post_skip)
  148. {
  149. return phrase_parse_main(first, last, p, s, unused, post_skip);
  150. }
  151. ///////////////////////////////////////////////////////////////////////////
  152. template <typename Iterator, typename Parser, typename Skipper>
  153. inline bool
  154. phrase_parse(
  155. Iterator const& first_
  156. , Iterator last
  157. , Parser const& p
  158. , Skipper const& s
  159. , skip_flag post_skip = skip_flag::post_skip)
  160. {
  161. Iterator first = first_;
  162. return phrase_parse_main(first, last, p, s, unused, post_skip);
  163. }
  164. ///////////////////////////////////////////////////////////////////////////
  165. template <typename Skipper>
  166. struct phrase_parse_context
  167. {
  168. typedef decltype(
  169. make_context<skipper_tag>(as_parser(std::declval<Skipper>())))
  170. type;
  171. };
  172. }}}
  173. #endif