1/*=============================================================================
2 Copyright (c) 1998-2003 Joel de Guzman
3 Copyright (c) 2002-2003 Martin Wille
4 http://spirit.sourceforge.net/
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9#ifndef BOOST_SPIRIT_EPSILON_HPP
10#define BOOST_SPIRIT_EPSILON_HPP
11
12////////////////////////////////////////////////////////////////////////////////
13#include <boost/spirit/home/classic/namespace.hpp>
14#include <boost/spirit/home/classic/core/parser.hpp>
15#include <boost/spirit/home/classic/meta/parser_traits.hpp>
16#include <boost/spirit/home/classic/core/composite/composite.hpp>
17#include <boost/spirit/home/classic/core/composite/no_actions.hpp>
18
19#if defined(BOOST_MSVC)
20# pragma warning(push)
21# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
22#endif
23
24////////////////////////////////////////////////////////////////////////////////
25namespace boost { namespace spirit {
26
27BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
28
29///////////////////////////////////////////////////////////////////////////////
30//
31// condition_parser class
32//
33// handles expressions of the form
34//
35// epsilon_p(cond)
36//
37// where cond is a function or a functor that returns a value suitable
38// to be used in boolean context. The expression returns a parser that
39// returns an empty match when the condition evaluates to true.
40//
41///////////////////////////////////////////////////////////////////////////////
42 template <typename CondT, bool positive_ = true>
43 struct condition_parser : parser<condition_parser<CondT, positive_> >
44 {
45 typedef condition_parser<CondT, positive_> self_t;
46
47 // not explicit! (needed for implementation of if_p et al.)
48 condition_parser(CondT const& cond_) : cond(cond_) {}
49
50 template <typename ScannerT>
51 typename parser_result<self_t, ScannerT>::type
52 parse(ScannerT const& scan) const
53 {
54 if (positive_ == bool(cond())) // allow cond to return int
55 return scan.empty_match();
56 else
57 return scan.no_match();
58 }
59
60 condition_parser<CondT, !positive_>
61 negate() const
62 { return condition_parser<CondT, !positive_>(cond); }
63
64 private:
65
66 CondT cond;
67 };
68
69#if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \
70 BOOST_WORKAROUND(BOOST_MSVC, == 1400) || \
71 BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580)
72// VC 7.1, VC8 and Sun CC <= 5.8 do not support general
73// expressions of non-type template parameters in instantiations
74 template <typename CondT>
75 inline condition_parser<CondT, false>
76 operator~(condition_parser<CondT, true> const& p)
77 { return p.negate(); }
78
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) || == 1400
84 template <typename CondT, bool positive>
85 inline condition_parser<CondT, !positive>
86 operator~(condition_parser<CondT, positive> const& p)
87 { return p.negate(); }
88#endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400
89
90///////////////////////////////////////////////////////////////////////////////
91//
92// empty_match_parser class
93//
94// handles expressions of the form
95// epsilon_p(subject)
96// where subject is a parser. The expression returns a composite
97// parser that returns an empty match if the subject parser matches.
98//
99///////////////////////////////////////////////////////////////////////////////
100 struct empty_match_parser_gen;
101 struct negated_empty_match_parser_gen;
102
103 template <typename SubjectT>
104 struct negated_empty_match_parser; // Forward declaration
105
106 template<typename SubjectT>
107 struct empty_match_parser
108 : unary<SubjectT, parser<empty_match_parser<SubjectT> > >
109 {
110 typedef empty_match_parser<SubjectT> self_t;
111 typedef unary<SubjectT, parser<self_t> > base_t;
112 typedef unary_parser_category parser_category_t;
113 typedef empty_match_parser_gen parser_genererator_t;
114 typedef self_t embed_t;
115
116 explicit empty_match_parser(SubjectT const& p) : base_t(p) {}
117
118 template <typename ScannerT>
119 struct result
120 { typedef typename match_result<ScannerT, nil_t>::type type; };
121
122 template <typename ScannerT>
123 typename parser_result<self_t, ScannerT>::type
124 parse(ScannerT const& scan) const
125 {
126 typename ScannerT::iterator_t save(scan.first);
127
128 typedef typename no_actions_scanner<ScannerT>::policies_t
129 policies_t;
130
131 bool matches = this->subject().parse(
132 scan.change_policies(policies_t(scan)));
133 if (matches)
134 {
135 scan.first = save; // reset the position
136 return scan.empty_match();
137 }
138 else
139 {
140 return scan.no_match();
141 }
142 }
143
144 negated_empty_match_parser<SubjectT>
145 negate() const
146 { return negated_empty_match_parser<SubjectT>(this->subject()); }
147 };
148
149 template<typename SubjectT>
150 struct negated_empty_match_parser
151 : public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > >
152 {
153 typedef negated_empty_match_parser<SubjectT> self_t;
154 typedef unary<SubjectT, parser<self_t> > base_t;
155 typedef unary_parser_category parser_category_t;
156 typedef negated_empty_match_parser_gen parser_genererator_t;
157
158 explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {}
159
160 template <typename ScannerT>
161 struct result
162 { typedef typename match_result<ScannerT, nil_t>::type type; };
163
164 template <typename ScannerT>
165 typename parser_result<self_t, ScannerT>::type
166 parse(ScannerT const& scan) const
167 {
168 typename ScannerT::iterator_t save(scan.first);
169
170 typedef typename no_actions_scanner<ScannerT>::policies_t
171 policies_t;
172
173 bool matches = this->subject().parse(
174 scan.change_policies(policies_t(scan)));
175 if (!matches)
176 {
177 scan.first = save; // reset the position
178 return scan.empty_match();
179 }
180 else
181 {
182 return scan.no_match();
183 }
184 }
185
186 empty_match_parser<SubjectT>
187 negate() const
188 { return empty_match_parser<SubjectT>(this->subject()); }
189 };
190
191 struct empty_match_parser_gen
192 {
193 template <typename SubjectT>
194 struct result
195 { typedef empty_match_parser<SubjectT> type; };
196
197 template <typename SubjectT>
198 static empty_match_parser<SubjectT>
199 generate(parser<SubjectT> const& subject)
200 { return empty_match_parser<SubjectT>(subject.derived()); }
201 };
202
203 struct negated_empty_match_parser_gen
204 {
205 template <typename SubjectT>
206 struct result
207 { typedef negated_empty_match_parser<SubjectT> type; };
208
209 template <typename SubjectT>
210 static negated_empty_match_parser<SubjectT>
211 generate(parser<SubjectT> const& subject)
212 { return negated_empty_match_parser<SubjectT>(subject.derived()); }
213 };
214
215 //////////////////////////////
216 template <typename SubjectT>
217 inline negated_empty_match_parser<SubjectT>
218 operator~(empty_match_parser<SubjectT> const& p)
219 { return p.negate(); }
220
221 template <typename SubjectT>
222 inline empty_match_parser<SubjectT>
223 operator~(negated_empty_match_parser<SubjectT> const& p)
224 { return p.negate(); }
225
226///////////////////////////////////////////////////////////////////////////////
227//
228// epsilon_ parser and parser generator class
229//
230// Operates as primitive parser that always matches an empty sequence.
231//
232// Also operates as a parser generator. According to the type of the
233// argument an instance of empty_match_parser<> (when the argument is
234// a parser) or condition_parser<> (when the argument is not a parser)
235// is returned by operator().
236//
237///////////////////////////////////////////////////////////////////////////////
238 namespace impl
239 {
240 template <typename SubjectT>
241 struct epsilon_selector
242 {
243 typedef typename as_parser<SubjectT>::type subject_t;
244 typedef typename
245 mpl::if_<
246 is_parser<subject_t>
247 ,empty_match_parser<subject_t>
248 ,condition_parser<subject_t>
249 >::type type;
250 };
251 }
252
253 struct epsilon_parser : public parser<epsilon_parser>
254 {
255 typedef epsilon_parser self_t;
256
257 epsilon_parser() {}
258
259 template <typename ScannerT>
260 typename parser_result<self_t, ScannerT>::type
261 parse(ScannerT const& scan) const
262 { return scan.empty_match(); }
263
264 template <typename SubjectT>
265 typename impl::epsilon_selector<SubjectT>::type
266 operator()(SubjectT const& subject) const
267 {
268 typedef typename impl::epsilon_selector<SubjectT>::type result_t;
269 return result_t(subject);
270 }
271 };
272
273 epsilon_parser const epsilon_p = epsilon_parser();
274 epsilon_parser const eps_p = epsilon_parser();
275
276///////////////////////////////////////////////////////////////////////////////
277BOOST_SPIRIT_CLASSIC_NAMESPACE_END
278
279}} // namespace BOOST_SPIRIT_CLASSIC_NS
280
281#ifdef BOOST_MSVC
282# pragma warning (pop)
283#endif
284
285#endif
286

source code of boost/libs/spirit/include/boost/spirit/home/classic/core/composite/epsilon.hpp