expect_function.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*=============================================================================
  2. Copyright (c) 2001-2011 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(SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM)
  7. #define SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/support/unused.hpp>
  12. #include <boost/spirit/home/support/multi_pass_wrapper.hpp>
  13. #include <boost/throw_exception.hpp>
  14. namespace boost { namespace spirit { namespace qi { namespace detail
  15. {
  16. template <
  17. typename Iterator, typename Context
  18. , typename Skipper, typename Exception>
  19. struct expect_function
  20. {
  21. typedef Iterator iterator_type;
  22. typedef Context context_type;
  23. expect_function(
  24. Iterator& first_, Iterator const& last_
  25. , Context& context_, Skipper const& skipper_)
  26. : first(first_)
  27. , last(last_)
  28. , context(context_)
  29. , skipper(skipper_)
  30. , is_first(true)
  31. {
  32. }
  33. template <typename Component, typename Attribute>
  34. bool operator()(Component const& component, Attribute& attr) const
  35. {
  36. // if this is not the first component in the expect chain we
  37. // need to flush any multi_pass iterator we might be acting on
  38. if (!is_first)
  39. spirit::traits::clear_queue(first);
  40. // if we are testing the first component in the sequence,
  41. // return true if the parser fails, if this is not the first
  42. // component, throw exception if the parser fails
  43. if (!component.parse(first, last, context, skipper, attr))
  44. {
  45. if (is_first)
  46. {
  47. is_first = false;
  48. return true; // true means the match failed
  49. }
  50. boost::throw_exception(Exception(first, last, component.what(context)));
  51. #if defined(BOOST_NO_EXCEPTIONS)
  52. return true; // for systems not supporting exceptions
  53. #endif
  54. }
  55. is_first = false;
  56. return false;
  57. }
  58. template <typename Component>
  59. bool operator()(Component const& component) const
  60. {
  61. // if this is not the first component in the expect chain we
  62. // need to flush any multi_pass iterator we might be acting on
  63. if (!is_first)
  64. spirit::traits::clear_queue(first);
  65. // if we are testing the first component in the sequence,
  66. // return true if the parser fails, if this not the first
  67. // component, throw exception if the parser fails
  68. if (!component.parse(first, last, context, skipper, unused))
  69. {
  70. if (is_first)
  71. {
  72. is_first = false;
  73. return true;
  74. }
  75. boost::throw_exception(Exception(first, last, component.what(context)));
  76. #if defined(BOOST_NO_EXCEPTIONS)
  77. return false; // for systems not supporting exceptions
  78. #endif
  79. }
  80. is_first = false;
  81. return false;
  82. }
  83. Iterator& first;
  84. Iterator const& last;
  85. Context& context;
  86. Skipper const& skipper;
  87. mutable bool is_first;
  88. // silence MSVC warning C4512: assignment operator could not be generated
  89. BOOST_DELETED_FUNCTION(expect_function& operator= (expect_function const&))
  90. };
  91. }}}}
  92. #endif