• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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