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_KLEENE_STAR_HPP) 11 #define BOOST_SPIRIT_KLEENE_STAR_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 // kleene_star 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 more times. 33 // 34 /////////////////////////////////////////////////////////////////////////// 35 struct kleene_star_parser_gen; 36 37 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 38 #pragma warning(push) 39 #pragma warning(disable:4512) //assignment operator could not be generated 40 #endif 41 42 template <typename S> 43 struct kleene_star 44 : public unary<S, parser<kleene_star<S> > > 45 { 46 typedef kleene_star<S> self_t; 47 typedef unary_parser_category parser_category_t; 48 typedef kleene_star_parser_gen parser_generator_t; 49 typedef unary<S, parser<self_t> > base_t; 50 kleene_starboost::spirit::kleene_star51 kleene_star(S const& a) 52 : base_t(a) {} 53 54 template <typename ScannerT> 55 typename parser_result<self_t, ScannerT>::type parseboost::spirit::kleene_star56 parse(ScannerT const& scan) const 57 { 58 typedef typename parser_result<self_t, ScannerT>::type result_t; 59 typedef typename ScannerT::iterator_t iterator_t; 60 result_t hit = scan.empty_match(); 61 62 for (;;) 63 { 64 iterator_t save = scan.first; 65 if (result_t next = this->subject().parse(scan)) 66 { 67 scan.concat_match(hit, next); 68 } 69 else 70 { 71 scan.first = save; 72 return hit; 73 } 74 } 75 } 76 }; 77 78 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 79 #pragma warning(pop) 80 #endif 81 82 struct kleene_star_parser_gen 83 { 84 template <typename S> 85 struct result 86 { 87 typedef kleene_star<S> type; 88 }; 89 90 template <typename S> 91 static kleene_star<S> generateboost::spirit::kleene_star_parser_gen92 generate(parser<S> const& a) 93 { 94 return kleene_star<S>(a.derived()); 95 } 96 }; 97 98 ////////////////////////////////// 99 template <typename S> 100 kleene_star<S> 101 operator*(parser<S> const& a); 102 103 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 104 105 }} // namespace BOOST_SPIRIT_CLASSIC_NS 106 107 #endif 108 109 #include <boost/spirit/home/classic/core/composite/impl/kleene_star.ipp> 110