9
3

skipper.ipp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*=============================================================================
  2. Copyright (c) 1998-2003 Joel de Guzman
  3. http://spirit.sourceforge.net/
  4. Use, modification and distribution is subject to the Boost Software
  5. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. ============================================================================*/
  8. #if !defined(BOOST_SPIRIT_SKIPPER_IPP)
  9. #define BOOST_SPIRIT_SKIPPER_IPP
  10. ///////////////////////////////////////////////////////////////////////////////
  11. namespace boost { namespace spirit {
  12. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  13. struct space_parser;
  14. template <typename BaseT>
  15. struct no_skipper_iteration_policy;
  16. namespace impl
  17. {
  18. template <typename ST, typename ScannerT, typename BaseT>
  19. inline void
  20. skipper_skip(
  21. ST const& s,
  22. ScannerT const& scan,
  23. skipper_iteration_policy<BaseT> const&)
  24. {
  25. typedef scanner_policies<
  26. no_skipper_iteration_policy<
  27. BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,
  28. BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,
  29. BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t
  30. > policies_t;
  31. scanner<BOOST_DEDUCED_TYPENAME ScannerT::iterator_t, policies_t>
  32. scan2(scan.first, scan.last, policies_t(scan));
  33. typedef typename ScannerT::iterator_t iterator_t;
  34. for (;;)
  35. {
  36. iterator_t save = scan.first;
  37. if (!s.parse(scan2))
  38. {
  39. scan.first = save;
  40. break;
  41. }
  42. }
  43. }
  44. template <typename ST, typename ScannerT, typename BaseT>
  45. inline void
  46. skipper_skip(
  47. ST const& s,
  48. ScannerT const& scan,
  49. no_skipper_iteration_policy<BaseT> const&)
  50. {
  51. for (;;)
  52. {
  53. typedef typename ScannerT::iterator_t iterator_t;
  54. iterator_t save = scan.first;
  55. if (!s.parse(scan))
  56. {
  57. scan.first = save;
  58. break;
  59. }
  60. }
  61. }
  62. template <typename ST, typename ScannerT>
  63. inline void
  64. skipper_skip(
  65. ST const& s,
  66. ScannerT const& scan,
  67. iteration_policy const&)
  68. {
  69. for (;;)
  70. {
  71. typedef typename ScannerT::iterator_t iterator_t;
  72. iterator_t save = scan.first;
  73. if (!s.parse(scan))
  74. {
  75. scan.first = save;
  76. break;
  77. }
  78. }
  79. }
  80. template <typename SkipT>
  81. struct phrase_parser
  82. {
  83. template <typename IteratorT, typename ParserT>
  84. static parse_info<IteratorT>
  85. parse(
  86. IteratorT const& first_,
  87. IteratorT const& last,
  88. ParserT const& p,
  89. SkipT const& skip)
  90. {
  91. typedef skip_parser_iteration_policy<SkipT> it_policy_t;
  92. typedef scanner_policies<it_policy_t> scan_policies_t;
  93. typedef scanner<IteratorT, scan_policies_t> scanner_t;
  94. it_policy_t iter_policy(skip);
  95. scan_policies_t policies(iter_policy);
  96. IteratorT first = first_;
  97. scanner_t scan(first, last, policies);
  98. match<nil_t> hit = p.parse(scan);
  99. return parse_info<IteratorT>(
  100. first, hit, hit && (first == last),
  101. hit.length());
  102. }
  103. };
  104. template <>
  105. struct phrase_parser<space_parser>
  106. {
  107. template <typename IteratorT, typename ParserT>
  108. static parse_info<IteratorT>
  109. parse(
  110. IteratorT const& first_,
  111. IteratorT const& last,
  112. ParserT const& p,
  113. space_parser const&)
  114. {
  115. typedef skipper_iteration_policy<> it_policy_t;
  116. typedef scanner_policies<it_policy_t> scan_policies_t;
  117. typedef scanner<IteratorT, scan_policies_t> scanner_t;
  118. IteratorT first = first_;
  119. scanner_t scan(first, last);
  120. match<nil_t> hit = p.parse(scan);
  121. return parse_info<IteratorT>(
  122. first, hit, hit && (first == last),
  123. hit.length());
  124. }
  125. };
  126. }
  127. ///////////////////////////////////////////////////////////////////////////
  128. //
  129. // Free parse functions using the skippers
  130. //
  131. ///////////////////////////////////////////////////////////////////////////
  132. template <typename IteratorT, typename ParserT, typename SkipT>
  133. inline parse_info<IteratorT>
  134. parse(
  135. IteratorT const& first,
  136. IteratorT const& last,
  137. parser<ParserT> const& p,
  138. parser<SkipT> const& skip)
  139. {
  140. return impl::phrase_parser<SkipT>::
  141. parse(first, last, p.derived(), skip.derived());
  142. }
  143. ///////////////////////////////////////////////////////////////////////////
  144. //
  145. // Parse function for null terminated strings using the skippers
  146. //
  147. ///////////////////////////////////////////////////////////////////////////
  148. template <typename CharT, typename ParserT, typename SkipT>
  149. inline parse_info<CharT const*>
  150. parse(
  151. CharT const* str,
  152. parser<ParserT> const& p,
  153. parser<SkipT> const& skip)
  154. {
  155. CharT const* last = str;
  156. while (*last)
  157. last++;
  158. return parse(str, last, p, skip);
  159. }
  160. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  161. }} // namespace boost::spirit
  162. #endif