Line data Source code
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 : 46 0 : optional(S const& a) 47 0 : : base_t(a) {} 48 : 49 : template <typename ScannerT> 50 : typename parser_result<self_t, ScannerT>::type 51 0 : 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 0 : iterator_t save = scan.first; 56 0 : if (result_t r = this->subject().parse(scan)) 57 : { 58 0 : return r; 59 : } 60 : else 61 : { 62 0 : scan.first = save; 63 0 : 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> 78 : 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>