1
/*=============================================================================
3
Copyright (c) 1998-2003 Joel de Guzman
4
Copyright (c) 2002-2003 Martin Wille
5
http://spirit.sourceforge.net/
7
Permission to copy, use, modify, sell and distribute this software is
8
granted provided this copyright notice appears in all copies. This
9
software is provided "as is" without express or implied warranty, and
10
with no claim as to its suitability for any purpose.
11
=============================================================================*/
12
#ifndef BOOST_SPIRIT_EPSILON_HPP
13
#define BOOST_SPIRIT_EPSILON_HPP
15
////////////////////////////////////////////////////////////////////////////////
16
#if !defined(BOOST_SPIRIT_PARSER_HPP)
17
#include "boost/spirit/core/parser.hpp"
20
#if !defined(BOOST_SPIRIT_PARSER_TRAITS_HPP)
21
#include "boost/spirit/core/meta/parser_traits.hpp"
24
#if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
25
#include "boost/spirit/core/composite/composite.hpp"
28
////////////////////////////////////////////////////////////////////////////////
29
namespace boost { namespace spirit {
31
///////////////////////////////////////////////////////////////////////////////
33
// condition_parser class
35
// handles expresions of the form
37
// where cond is a function or a functor that returns a value
38
// suitable to be used in boolean context. The expression returns
39
// a parser that returns an empty match when the condition evaluates
42
///////////////////////////////////////////////////////////////////////////////
43
template <typename CondT, bool positive = true>
44
struct condition_parser
45
: public impl::subject<CondT, parser<condition_parser<CondT, positive> > >
47
typedef condition_parser<CondT, positive> self_t;
48
typedef impl::subject<CondT, parser<self_t> > base_t;
50
// not explicit! (needed for implementation of if_p et al.)
51
condition_parser(CondT const &cond) : base_t(cond) {}
52
condition_parser() : base_t() {}
54
template <typename ScannerT>
55
typename parser_result<self_t, ScannerT>::type
56
parse(ScannerT const& scan) const
58
if (positive == this->get()())
59
return scan.empty_match();
61
return scan.no_match();
64
condition_parser<CondT, !positive>
67
return condition_parser<CondT, !positive>(this->get());
73
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) // VC 7.1
74
template <typename CondT>
75
inline condition_parser<CondT, false>
76
operator~(condition_parser<CondT, true> const& p)
77
{ return p.negate(); }
79
template <typename CondT>
80
inline condition_parser<CondT, true>
81
operator~(condition_parser<CondT, false> const& p)
82
{ return p.negate(); }
83
#else // BOOST_WORKAROUND(BOOST_MSVC, == 1310)
84
template <typename CondT, bool positive>
85
inline condition_parser<CondT, !positive>
86
operator~(condition_parser<CondT, positive> const &p)
90
#endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310)
92
///////////////////////////////////////////////////////////////////////////////
94
// empty_match_parser class
96
// handles expressions of the form
98
// where subject is a parser. The expresion returns a composite
99
// parser that returns an empty match if the subject parser matches.
101
///////////////////////////////////////////////////////////////////////////////
102
struct empty_match_parser_gen;
103
struct negated_empty_match_parser_gen;
105
template<typename SubjectT> struct negated_empty_match_parser;
107
template<typename SubjectT>
108
struct empty_match_parser
109
: public unary<SubjectT, parser<empty_match_parser<SubjectT> > >
111
typedef empty_match_parser<SubjectT> self_t;
112
typedef unary<SubjectT, parser<self_t> > base_t;
113
typedef unary_parser_category parser_category_t;
114
typedef empty_match_parser_gen parser_genererator_t;
115
typedef self_t embed_t;
117
explicit empty_match_parser(SubjectT const &p) : base_t(p) {}
118
empty_match_parser() : base_t() {}
120
template <typename ScannerT>
123
typedef typename match_result<ScannerT, nil_t>::type type;
126
template <typename ScannerT>
127
typename parser_result<self_t, ScannerT>::type
128
parse(ScannerT const& scan) const
130
typename ScannerT::iterator_t save(scan.first);
131
bool matches = this->subject().parse(scan);
134
scan.first = save; // reset the position
135
return scan.empty_match();
138
return scan.no_match();
141
negated_empty_match_parser<SubjectT>
144
return negated_empty_match_parser<SubjectT>(this->subject());
148
template<typename SubjectT>
149
struct negated_empty_match_parser
150
: public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > >
152
typedef negated_empty_match_parser<SubjectT> self_t;
153
typedef unary<SubjectT, parser<self_t> > base_t;
154
typedef unary_parser_category parser_category_t;
155
typedef negated_empty_match_parser_gen parser_genererator_t;
157
explicit negated_empty_match_parser(SubjectT const &p) : base_t(p) {}
158
negated_empty_match_parser() : base_t() {}
160
template <typename ScannerT>
163
typedef typename match_result<ScannerT, nil_t>::type type;
166
template <typename ScannerT>
167
typename parser_result<self_t, ScannerT>::type
168
parse(ScannerT const& scan) const
170
typename ScannerT::iterator_t save(scan.first);
172
bool matches = this->subject().parse(scan);
175
scan.first = save; // reset the position
176
return scan.empty_match();
179
return scan.no_match();
182
empty_match_parser<SubjectT>
185
return empty_match_parser<SubjectT>(this->subject());
189
//////////////////////////////
190
struct empty_match_parser_gen
192
template <typename SubjectT>
195
typedef empty_match_parser<SubjectT> type;
198
template <typename SubjectT>
199
static empty_match_parser<SubjectT>
200
generate(parser<SubjectT> const &subject)
202
return empty_match_parser<SubjectT>(subject.derived());
206
struct negated_empty_match_parser_gen
208
template <typename SubjectT>
211
typedef negated_empty_match_parser<SubjectT> type;
214
template <typename SubjectT>
215
static negated_empty_match_parser<SubjectT>
216
generate(parser<SubjectT> const &subject)
218
return negated_empty_match_parser<SubjectT>(subject.derived());
222
//////////////////////////////
223
template <typename SubjectT>
224
inline /*struct*/ negated_empty_match_parser<SubjectT>
225
operator ~(empty_match_parser<SubjectT> const &p)
230
template <typename SubjectT>
231
inline /*struct*/ empty_match_parser<SubjectT>
232
operator ~(negated_empty_match_parser<SubjectT> const &p)
237
///////////////////////////////////////////////////////////////////////////////
239
// epsilon_ parser and parser generator class
241
// Operates as primitive parser that always matches an empty sequence.
243
// Also operates as a parser generator. According to the type of the
244
// argument an instance of empty_match_parser<> (when the argument is
245
// a parser) or condition_parser<> (when the argument is not a parser)
246
// is returned by operator().
248
///////////////////////////////////////////////////////////////////////////////
251
template <typename SubjectT>
252
struct epsilon_selector
254
typedef typename as_parser<SubjectT>::type subject_t;
258
,empty_match_parser<subject_t>
259
,condition_parser<subject_t>
264
struct epsilon_parser : public parser<epsilon_parser>
266
typedef epsilon_parser self_t;
270
template <typename ScannerT>
271
typename parser_result<self_t, ScannerT>::type
272
parse(ScannerT const& scan) const
273
{ return scan.empty_match(); }
275
template <typename SubjectT>
276
typename impl::epsilon_selector<SubjectT>::type
277
operator()(SubjectT const &subject) const
279
typedef typename impl::epsilon_selector<SubjectT>::type result_t;
280
return result_t(subject);
284
//////////////////////////////////
285
epsilon_parser const epsilon_p = epsilon_parser();
286
epsilon_parser const eps_p = epsilon_parser();
288
///////////////////////////////////////////////////////////////////////////////
289
}} // namespace boost::spirit