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 7 Distributed under the Boost Software License, Version 1.0. (See accompanying 8 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 =============================================================================*/ 10 #if !defined(BOOST_SPIRIT_OPTIONAL_HPP) 11 #define BOOST_SPIRIT_OPTIONAL_HPP 12 13 #include <boost/spirit/home/classic/namespace.hpp> 14 #include <boost/spirit/home/classic/core/parser.hpp> 15 #include <boost/spirit/home/classic/core/primitives/primitives.hpp> 16 #include <boost/spirit/home/classic/core/composite/composite.hpp> 17 #include <boost/spirit/home/classic/meta/as_parser.hpp> 18 19 namespace boost { namespace spirit { 20 21 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 22 23 /////////////////////////////////////////////////////////////////////////// 24 // 25 // optional class 26 // 27 // Handles expressions of the form: 28 // 29 // !a 30 // 31 // where a is a parser. The expression returns a composite 32 // parser that matches its subject zero (0) or one (1) time. 33 // 34 /////////////////////////////////////////////////////////////////////////// 35 struct optional_parser_gen; 36 37 template <typename S> 38 struct optional 39 : public unary<S, parser<optional<S> > > 40 { 41 typedef optional<S> self_t; 42 typedef unary_parser_category parser_category_t; 43 typedef optional_parser_gen parser_generator_t; 44 typedef unary<S, parser<self_t> > base_t; 45 optionalboost::spirit::optional46 optional(S const& a) 47 : base_t(a) {} 48 49 template <typename ScannerT> 50 typename parser_result<self_t, ScannerT>::type parseboost::spirit::optional51 parse(ScannerT const& scan) const 52 { 53 typedef typename parser_result<self_t, ScannerT>::type result_t; 54 typedef typename ScannerT::iterator_t iterator_t; 55 iterator_t save = scan.first; 56 if (result_t r = this->subject().parse(scan)) 57 { 58 return r; 59 } 60 else 61 { 62 scan.first = save; 63 return scan.empty_match(); 64 } 65 } 66 }; 67 68 struct optional_parser_gen 69 { 70 template <typename S> 71 struct result 72 { 73 typedef optional<S> type; 74 }; 75 76 template <typename S> 77 static optional<S> generateboost::spirit::optional_parser_gen78 generate(parser<S> const& a) 79 { 80 return optional<S>(a.derived()); 81 } 82 }; 83 84 template <typename S> 85 optional<S> 86 operator!(parser<S> const& a); 87 88 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 89 90 }} // namespace BOOST_SPIRIT_CLASSIC_NS 91 92 #endif 93 94 #include <boost/spirit/home/classic/core/composite/impl/optional.ipp> 95