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_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 : 51 0 : kleene_star(S const& a) 52 0 : : base_t(a) {} 53 : 54 : template <typename ScannerT> 55 : typename parser_result<self_t, ScannerT>::type 56 0 : 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 0 : result_t hit = scan.empty_match(); 61 : 62 : for (;;) 63 : { 64 0 : iterator_t save = scan.first; 65 0 : if (result_t next = this->subject().parse(scan)) 66 : { 67 0 : scan.concat_match(hit, next); 68 : } 69 : else 70 : { 71 0 : scan.first = save; 72 0 : 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> 92 : 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>