1/*============================================================================= 2 Copyright (c) 2001-2003 Joel de Guzman 3 http://spirit.sourceforge.net/ 4 5 Use, modification and distribution is subject to the Boost Software 6 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8=============================================================================*/ 9#ifndef BOOST_SPIRIT_EXCEPTIONS_IPP 10#define BOOST_SPIRIT_EXCEPTIONS_IPP 11 12namespace boost { namespace spirit { 13 14BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 15 16namespace impl { 17 18#ifdef __BORLANDC__ 19 template <typename ParserT, typename ScannerT> 20 typename parser_result<ParserT, ScannerT>::type 21 fallback_parser_helper(ParserT const& subject, ScannerT const& scan); 22#endif 23 24 template <typename RT, typename ParserT, typename ScannerT> 25 RT fallback_parser_parse(ParserT const& p, ScannerT const& scan) 26 { 27 typedef typename ScannerT::iterator_t iterator_t; 28 typedef typename RT::attr_t attr_t; 29 typedef error_status<attr_t> error_status_t; 30 typedef typename ParserT::error_descr_t error_descr_t; 31 32 iterator_t save = scan.first; 33 error_status_t hr(error_status_t::retry); 34 35 while (hr.result == error_status_t::retry) 36 { 37 try 38 { 39 #ifndef __BORLANDC__ 40 return p.subject().parse(scan); 41 #else 42 return impl::fallback_parser_helper(p, scan); 43 #endif 44 } 45 46 catch (parser_error<error_descr_t, iterator_t>& error) 47 { 48 scan.first = save; 49 hr = p.handler(scan, error); 50 switch (hr.result) 51 { 52 case error_status_t::fail: 53 return scan.no_match(); 54 case error_status_t::accept: 55 return scan.create_match 56 (std::size_t(hr.length), hr.value, save, scan.first); 57 case error_status_t::rethrow: 58 boost::throw_exception(error); 59 default: 60 continue; 61 } 62 } 63 } 64 return scan.no_match(); 65 } 66 67/////////////////////////////////////////////////////////////////////////// 68// 69// Borland does not like calling the subject directly in the try block. 70// Removing the #ifdef __BORLANDC__ code makes Borland complain that 71// some variables and types cannot be found in the catch block. Weird! 72// 73/////////////////////////////////////////////////////////////////////////// 74#ifdef __BORLANDC__ 75 76 template <typename ParserT, typename ScannerT> 77 typename parser_result<ParserT, ScannerT>::type 78 fallback_parser_helper(ParserT const& p, ScannerT const& scan) 79 { 80 return p.subject().parse(scan); 81 } 82 83#endif 84 85} 86 87BOOST_SPIRIT_CLASSIC_NAMESPACE_END 88 89}} // namespace boost::spirit::impl 90 91/////////////////////////////////////////////////////////////////////////////// 92#endif 93 94