]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
12 | namespace boost { namespace spirit { | |
13 | ||
14 | BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN | |
15 | ||
16 | namespace 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 | ||
87 | BOOST_SPIRIT_CLASSIC_NAMESPACE_END | |
88 | ||
89 | }} // namespace boost::spirit::impl | |
90 | ||
91 | /////////////////////////////////////////////////////////////////////////////// | |
92 | #endif | |
93 |