exceptions.ipp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*=============================================================================
  2. Copyright (c) 2001-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. #ifndef BOOST_SPIRIT_EXCEPTIONS_IPP
  9. #define BOOST_SPIRIT_EXCEPTIONS_IPP
  10. namespace boost { namespace spirit {
  11. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  12. namespace impl {
  13. #ifdef __BORLANDC__
  14. template <typename ParserT, typename ScannerT>
  15. typename parser_result<ParserT, ScannerT>::type
  16. fallback_parser_helper(ParserT const& subject, ScannerT const& scan);
  17. #endif
  18. template <typename RT, typename ParserT, typename ScannerT>
  19. RT fallback_parser_parse(ParserT const& p, ScannerT const& scan)
  20. {
  21. typedef typename ScannerT::iterator_t iterator_t;
  22. typedef typename RT::attr_t attr_t;
  23. typedef error_status<attr_t> error_status_t;
  24. typedef typename ParserT::error_descr_t error_descr_t;
  25. iterator_t save = scan.first;
  26. error_status_t hr(error_status_t::retry);
  27. while (hr.result == error_status_t::retry)
  28. {
  29. try
  30. {
  31. #ifndef __BORLANDC__
  32. return p.subject().parse(scan);
  33. #else
  34. return impl::fallback_parser_helper(p, scan);
  35. #endif
  36. }
  37. catch (parser_error<error_descr_t, iterator_t>& error)
  38. {
  39. scan.first = save;
  40. hr = p.handler(scan, error);
  41. switch (hr.result)
  42. {
  43. case error_status_t::fail:
  44. return scan.no_match();
  45. case error_status_t::accept:
  46. return scan.create_match
  47. (std::size_t(hr.length), hr.value, save, scan.first);
  48. case error_status_t::rethrow:
  49. boost::throw_exception(error);
  50. default:
  51. continue;
  52. }
  53. }
  54. }
  55. return scan.no_match();
  56. }
  57. ///////////////////////////////////////////////////////////////////////////
  58. //
  59. // Borland does not like calling the subject directly in the try block.
  60. // Removing the #ifdef __BORLANDC__ code makes Borland complain that
  61. // some variables and types cannot be found in the catch block. Weird!
  62. //
  63. ///////////////////////////////////////////////////////////////////////////
  64. #ifdef __BORLANDC__
  65. template <typename ParserT, typename ScannerT>
  66. typename parser_result<ParserT, ScannerT>::type
  67. fallback_parser_helper(ParserT const& p, ScannerT const& scan)
  68. {
  69. return p.subject().parse(scan);
  70. }
  71. #endif
  72. }
  73. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  74. }} // namespace boost::spirit::impl
  75. ///////////////////////////////////////////////////////////////////////////////
  76. #endif