/Src/Dependencies/Boost/boost/spirit/home/classic/error_handling/exceptions.hpp

http://hadesmem.googlecode.com/ · C++ Header · 365 lines · 187 code · 44 blank · 134 comment · 1 complexity · 261113c6002ce566b9b756fc9debe591 MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2003 Joel de Guzman
  3. http://spirit.sourceforge.net/
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #ifndef BOOST_SPIRIT_EXCEPTIONS_HPP
  8. #define BOOST_SPIRIT_EXCEPTIONS_HPP
  9. #include <boost/config.hpp>
  10. #include <boost/throw_exception.hpp>
  11. #include <boost/spirit/home/classic/namespace.hpp>
  12. #include <boost/spirit/home/classic/core/parser.hpp>
  13. #include <boost/spirit/home/classic/core/composite/composite.hpp>
  14. #include <exception>
  15. #include <boost/spirit/home/classic/error_handling/exceptions_fwd.hpp>
  16. namespace boost { namespace spirit {
  17. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  18. ///////////////////////////////////////////////////////////////////////////
  19. //
  20. // parser_error_base class
  21. //
  22. // This is the base class of parser_error (see below). This may be
  23. // used to catch any type of parser error.
  24. //
  25. // This exception shouldn't propagate outside the parser. However to
  26. // avoid quirks of many platforms/implementations which fall outside
  27. // the C++ standard, we derive parser_error_base from std::exception
  28. // to allow a single catch handler to catch all exceptions.
  29. //
  30. ///////////////////////////////////////////////////////////////////////////
  31. class parser_error_base : public std::exception
  32. {
  33. protected:
  34. parser_error_base() {}
  35. virtual ~parser_error_base() throw() {}
  36. public:
  37. parser_error_base(parser_error_base const& rhs)
  38. : std::exception(rhs) {}
  39. parser_error_base& operator=(parser_error_base const&)
  40. {
  41. return *this;
  42. }
  43. };
  44. ///////////////////////////////////////////////////////////////////////////
  45. //
  46. // parser_error class
  47. //
  48. // Generic parser exception class. This is the base class for all
  49. // parser exceptions. The exception holds the iterator position
  50. // where the error was encountered in its member variable "where".
  51. // The parser_error also holds information regarding the error
  52. // (error descriptor) in its member variable "descriptor".
  53. //
  54. // The throw_ function creates and throws a parser_error given
  55. // an iterator and an error descriptor.
  56. //
  57. ///////////////////////////////////////////////////////////////////////////
  58. template <typename ErrorDescrT, typename IteratorT>
  59. struct parser_error : public parser_error_base
  60. {
  61. typedef ErrorDescrT error_descr_t;
  62. typedef IteratorT iterator_t;
  63. parser_error(IteratorT where_, ErrorDescrT descriptor_)
  64. : where(where_), descriptor(descriptor_) {}
  65. parser_error(parser_error const& rhs)
  66. : parser_error_base(rhs)
  67. , where(rhs.where), descriptor(rhs.descriptor) {}
  68. parser_error&
  69. operator=(parser_error const& rhs)
  70. {
  71. where = rhs.where;
  72. descriptor = rhs.descriptor;
  73. return *this;
  74. }
  75. virtual
  76. ~parser_error() throw() {}
  77. virtual const char*
  78. what() const throw()
  79. {
  80. return "BOOST_SPIRIT_CLASSIC_NS::parser_error";
  81. }
  82. IteratorT where;
  83. ErrorDescrT descriptor;
  84. };
  85. //////////////////////////////////
  86. template <typename ErrorDescrT, typename IteratorT>
  87. inline void
  88. throw_(IteratorT where, ErrorDescrT descriptor)
  89. {
  90. boost::throw_exception(
  91. parser_error<ErrorDescrT, IteratorT>(where, descriptor));
  92. }
  93. ///////////////////////////////////////////////////////////////////////////
  94. //
  95. // assertive_parser class
  96. //
  97. // An assertive_parser class is a parser that throws an exception
  98. // in response to a parsing failure. The assertive_parser throws a
  99. // parser_error exception rather than returning an unsuccessful
  100. // match to signal that the parser failed to match the input.
  101. //
  102. ///////////////////////////////////////////////////////////////////////////
  103. template <typename ErrorDescrT, typename ParserT>
  104. struct assertive_parser
  105. : public unary<ParserT, parser<assertive_parser<ErrorDescrT, ParserT> > >
  106. {
  107. typedef assertive_parser<ErrorDescrT, ParserT> self_t;
  108. typedef unary<ParserT, parser<self_t> > base_t;
  109. typedef unary_parser_category parser_category_t;
  110. assertive_parser(ParserT const& parser, ErrorDescrT descriptor_)
  111. : base_t(parser), descriptor(descriptor_) {}
  112. template <typename ScannerT>
  113. struct result
  114. {
  115. typedef typename parser_result<ParserT, ScannerT>::type type;
  116. };
  117. template <typename ScannerT>
  118. typename parser_result<self_t, ScannerT>::type
  119. parse(ScannerT const& scan) const
  120. {
  121. typedef typename parser_result<ParserT, ScannerT>::type result_t;
  122. typedef typename ScannerT::iterator_t iterator_t;
  123. result_t hit = this->subject().parse(scan);
  124. if (!hit)
  125. {
  126. throw_(scan.first, descriptor);
  127. }
  128. return hit;
  129. }
  130. ErrorDescrT descriptor;
  131. };
  132. ///////////////////////////////////////////////////////////////////////////
  133. //
  134. // assertion class
  135. //
  136. // assertive_parsers are never instantiated directly. The assertion
  137. // class is used to indirectly create an assertive_parser object.
  138. // Before declaring the grammar, we declare some assertion objects.
  139. // Examples:
  140. //
  141. // enum Errors
  142. // {
  143. // program_expected, begin_expected, end_expected
  144. // };
  145. //
  146. // assertion<Errors> expect_program(program_expected);
  147. // assertion<Errors> expect_begin(begin_expected);
  148. // assertion<Errors> expect_end(end_expected);
  149. //
  150. // Now, we can use these assertions as wrappers around parsers:
  151. //
  152. // expect_end(str_p("end"))
  153. //
  154. // Take note that although the example uses enums to hold the
  155. // information regarding the error (error desccriptor), we are free
  156. // to use other types such as integers and strings. Enums are
  157. // convenient for error handlers to easily catch since C++ treats
  158. // enums as unique types.
  159. //
  160. ///////////////////////////////////////////////////////////////////////////
  161. template <typename ErrorDescrT>
  162. struct assertion
  163. {
  164. assertion(ErrorDescrT descriptor_)
  165. : descriptor(descriptor_) {}
  166. template <typename ParserT>
  167. assertive_parser<ErrorDescrT, ParserT>
  168. operator()(ParserT const& parser) const
  169. {
  170. return assertive_parser<ErrorDescrT, ParserT>(parser, descriptor);
  171. }
  172. ErrorDescrT descriptor;
  173. };
  174. ///////////////////////////////////////////////////////////////////////////
  175. //
  176. // error_status<T>
  177. //
  178. // Where T is an attribute type compatible with the match attribute
  179. // of the fallback_parser's subject (defaults to nil_t). The class
  180. // error_status reports the result of an error handler (see
  181. // fallback_parser). result can be one of:
  182. //
  183. // fail: quit and fail (return a no_match)
  184. // retry: attempt error recovery, possibly moving the scanner
  185. // accept: force success returning a matching length, moving
  186. // the scanner appropriately and returning an attribute
  187. // value
  188. // rethrow: rethrows the error.
  189. //
  190. ///////////////////////////////////////////////////////////////////////////
  191. template <typename T>
  192. struct error_status
  193. {
  194. enum result_t { fail, retry, accept, rethrow };
  195. error_status(
  196. result_t result_ = fail,
  197. std::ptrdiff_t length_ = -1,
  198. T const& value_ = T())
  199. : result(result_), length(length_), value(value_) {}
  200. result_t result;
  201. std::ptrdiff_t length;
  202. T value;
  203. };
  204. ///////////////////////////////////////////////////////////////////////////
  205. //
  206. // fallback_parser class
  207. //
  208. // Handles exceptions of type parser_error<ErrorDescrT, IteratorT>
  209. // thrown somewhere inside its embedded ParserT object. The class
  210. // sets up a try block before delegating parsing to its subject.
  211. // When an exception is caught, the catch block then calls the
  212. // HandlerT object. HandlerT may be a function or a functor (with
  213. // an operator() member function) compatible with the interface:
  214. //
  215. // error_status<T>
  216. // handler(ScannerT const& scan, ErrorT error);
  217. //
  218. // Where scan points to the scanner state prior to parsing and error
  219. // is the error that arose (see parser_error). The handler must
  220. // return an error_status<T> object (see above).
  221. //
  222. ///////////////////////////////////////////////////////////////////////////
  223. namespace impl
  224. {
  225. template <typename RT, typename ParserT, typename ScannerT>
  226. RT fallback_parser_parse(ParserT const& p, ScannerT const& scan);
  227. }
  228. template <typename ErrorDescrT, typename ParserT, typename HandlerT>
  229. struct fallback_parser
  230. : public unary<ParserT,
  231. parser<fallback_parser<ErrorDescrT, ParserT, HandlerT> > >
  232. {
  233. typedef fallback_parser<ErrorDescrT, ParserT, HandlerT>
  234. self_t;
  235. typedef ErrorDescrT
  236. error_descr_t;
  237. typedef unary<ParserT, parser<self_t> >
  238. base_t;
  239. typedef unary_parser_category
  240. parser_category_t;
  241. fallback_parser(ParserT const& parser, HandlerT const& handler_)
  242. : base_t(parser), handler(handler_) {}
  243. template <typename ScannerT>
  244. struct result
  245. {
  246. typedef typename parser_result<ParserT, ScannerT>::type type;
  247. };
  248. template <typename ScannerT>
  249. typename parser_result<self_t, ScannerT>::type
  250. parse(ScannerT const& scan) const
  251. {
  252. typedef typename parser_result<self_t, ScannerT>::type result_t;
  253. return impl::fallback_parser_parse<result_t>(*this, scan);
  254. }
  255. HandlerT handler;
  256. };
  257. ///////////////////////////////////////////////////////////////////////////
  258. //
  259. // guard class
  260. //
  261. // fallback_parser objects are not instantiated directly. The guard
  262. // class is used to indirectly create a fallback_parser object.
  263. // guards are typically predeclared just like assertions (see the
  264. // assertion class above; the example extends the previous example
  265. // introduced in the assertion class above):
  266. //
  267. // guard<Errors> my_guard;
  268. //
  269. // Errors, in this example is the error descriptor type we want to
  270. // detect; This is essentially the ErrorDescrT template parameter
  271. // of the fallback_parser class.
  272. //
  273. // my_guard may now be used in a grammar declaration as:
  274. //
  275. // my_guard(p)[h]
  276. //
  277. // where p is a parser, h is a function or functor compatible with
  278. // fallback_parser's HandlerT (see above).
  279. //
  280. ///////////////////////////////////////////////////////////////////////////
  281. template <typename ErrorDescrT, typename ParserT>
  282. struct guard_gen : public unary<ParserT, nil_t>
  283. {
  284. typedef guard<ErrorDescrT> parser_generator_t;
  285. typedef unary_parser_category parser_category_t;
  286. guard_gen(ParserT const& p)
  287. : unary<ParserT, nil_t>(p) {}
  288. template <typename HandlerT>
  289. fallback_parser<ErrorDescrT, ParserT, HandlerT>
  290. operator[](HandlerT const& handler) const
  291. {
  292. return fallback_parser<ErrorDescrT, ParserT, HandlerT>
  293. (this->subject(), handler);
  294. }
  295. };
  296. template <typename ErrorDescrT>
  297. struct guard
  298. {
  299. template <typename ParserT>
  300. struct result
  301. {
  302. typedef guard_gen<ErrorDescrT, ParserT> type;
  303. };
  304. template <typename ParserT>
  305. static guard_gen<ErrorDescrT, ParserT>
  306. generate(ParserT const& parser)
  307. {
  308. return guard_gen<ErrorDescrT, ParserT>(parser);
  309. }
  310. template <typename ParserT>
  311. guard_gen<ErrorDescrT, ParserT>
  312. operator()(ParserT const& parser) const
  313. {
  314. return guard_gen<ErrorDescrT, ParserT>(parser);
  315. }
  316. };
  317. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  318. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  319. #include <boost/spirit/home/classic/error_handling/impl/exceptions.ipp>
  320. #endif