9
3

optional.hpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*=============================================================================
  2. Copyright (c) 1998-2003 Joel de Guzman
  3. Copyright (c) 2001 Daniel Nuffer
  4. Copyright (c) 2002 Hartmut Kaiser
  5. http://spirit.sourceforge.net/
  6. Distributed under the Boost Software License, Version 1.0. (See accompanying
  7. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. =============================================================================*/
  9. #if !defined(BOOST_SPIRIT_OPTIONAL_HPP)
  10. #define BOOST_SPIRIT_OPTIONAL_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/primitives/primitives.hpp>
  14. #include <boost/spirit/home/classic/core/composite/composite.hpp>
  15. #include <boost/spirit/home/classic/meta/as_parser.hpp>
  16. namespace boost { namespace spirit {
  17. BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
  18. ///////////////////////////////////////////////////////////////////////////
  19. //
  20. // optional class
  21. //
  22. // Handles expressions of the form:
  23. //
  24. // !a
  25. //
  26. // where a is a parser. The expression returns a composite
  27. // parser that matches its subject zero (0) or one (1) time.
  28. //
  29. ///////////////////////////////////////////////////////////////////////////
  30. struct optional_parser_gen;
  31. template <typename S>
  32. struct optional
  33. : public unary<S, parser<optional<S> > >
  34. {
  35. typedef optional<S> self_t;
  36. typedef unary_parser_category parser_category_t;
  37. typedef optional_parser_gen parser_generator_t;
  38. typedef unary<S, parser<self_t> > base_t;
  39. optional(S const& a)
  40. : base_t(a) {}
  41. template <typename ScannerT>
  42. typename parser_result<self_t, ScannerT>::type
  43. parse(ScannerT const& scan) const
  44. {
  45. typedef typename parser_result<self_t, ScannerT>::type result_t;
  46. typedef typename ScannerT::iterator_t iterator_t;
  47. iterator_t save = scan.first;
  48. if (result_t r = this->subject().parse(scan))
  49. {
  50. return r;
  51. }
  52. else
  53. {
  54. scan.first = save;
  55. return scan.empty_match();
  56. }
  57. }
  58. };
  59. struct optional_parser_gen
  60. {
  61. template <typename S>
  62. struct result
  63. {
  64. typedef optional<S> type;
  65. };
  66. template <typename S>
  67. static optional<S>
  68. generate(parser<S> const& a)
  69. {
  70. return optional<S>(a.derived());
  71. }
  72. };
  73. template <typename S>
  74. optional<S>
  75. operator!(parser<S> const& a);
  76. BOOST_SPIRIT_CLASSIC_NAMESPACE_END
  77. }} // namespace BOOST_SPIRIT_CLASSIC_NS
  78. #endif
  79. #include <boost/spirit/home/classic/core/composite/impl/optional.ipp>