~ubuntu-branches/ubuntu/breezy/aqsis/breezy

« back to all changes in this revision

Viewing changes to boost/boost/spirit/core/composite/epsilon.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Will Newton
  • Date: 2004-12-07 20:06:49 UTC
  • Revision ID: james.westby@ubuntu.com-20041207200649-fccswkrvp4oc8lmn
Tags: upstream-0.9.3
ImportĀ upstreamĀ versionĀ 0.9.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*=============================================================================
 
2
    Spirit v1.6.1
 
3
    Copyright (c) 1998-2003 Joel de Guzman
 
4
    Copyright (c) 2002-2003 Martin Wille
 
5
    http://spirit.sourceforge.net/
 
6
 
 
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
 
14
 
 
15
////////////////////////////////////////////////////////////////////////////////
 
16
#if !defined(BOOST_SPIRIT_PARSER_HPP)
 
17
#include "boost/spirit/core/parser.hpp"
 
18
#endif
 
19
 
 
20
#if !defined(BOOST_SPIRIT_PARSER_TRAITS_HPP)
 
21
#include "boost/spirit/core/meta/parser_traits.hpp"
 
22
#endif
 
23
 
 
24
#if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
 
25
#include "boost/spirit/core/composite/composite.hpp"
 
26
#endif
 
27
 
 
28
////////////////////////////////////////////////////////////////////////////////
 
29
namespace boost { namespace spirit {
 
30
 
 
31
///////////////////////////////////////////////////////////////////////////////
 
32
//
 
33
//  condition_parser class
 
34
//
 
35
//      handles expresions of the form
 
36
//          epsilon_p(cond)
 
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
 
40
//      to true.
 
41
//
 
42
///////////////////////////////////////////////////////////////////////////////
 
43
template <typename CondT, bool positive = true>
 
44
struct condition_parser
 
45
    : public impl::subject<CondT, parser<condition_parser<CondT, positive> > >
 
46
{
 
47
    typedef condition_parser<CondT, positive> self_t;
 
48
    typedef impl::subject<CondT, parser<self_t> > base_t;
 
49
 
 
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() {}
 
53
 
 
54
    template <typename ScannerT>
 
55
    typename parser_result<self_t, ScannerT>::type
 
56
    parse(ScannerT const& scan) const
 
57
    {
 
58
        if (positive == this->get()())
 
59
            return scan.empty_match();
 
60
        else
 
61
            return scan.no_match();
 
62
    }
 
63
 
 
64
    condition_parser<CondT, !positive>
 
65
    negate() const
 
66
    {
 
67
        return condition_parser<CondT, !positive>(this->get());
 
68
    }
 
69
 
 
70
private:
 
71
};
 
72
 
 
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(); }
 
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)
 
84
template <typename CondT, bool positive>
 
85
inline condition_parser<CondT, !positive>
 
86
operator~(condition_parser<CondT, positive> const &p)
 
87
{
 
88
    return p.negate();
 
89
}
 
90
#endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310)
 
91
 
 
92
///////////////////////////////////////////////////////////////////////////////
 
93
//
 
94
//  empty_match_parser class
 
95
//
 
96
//      handles expressions of the form
 
97
//          epsilon_p(subject)
 
98
//      where subject is a parser. The expresion returns a composite
 
99
//      parser that returns an empty match if the subject parser matches.
 
100
//
 
101
///////////////////////////////////////////////////////////////////////////////
 
102
struct empty_match_parser_gen;
 
103
struct negated_empty_match_parser_gen;
 
104
 
 
105
template<typename SubjectT> struct negated_empty_match_parser;
 
106
 
 
107
template<typename SubjectT>
 
108
struct empty_match_parser
 
109
    : public unary<SubjectT, parser<empty_match_parser<SubjectT> > >
 
110
{
 
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;
 
116
 
 
117
    explicit empty_match_parser(SubjectT const &p) : base_t(p) {}
 
118
    empty_match_parser() : base_t() {}
 
119
 
 
120
    template <typename ScannerT>
 
121
    struct result
 
122
    {
 
123
        typedef typename match_result<ScannerT, nil_t>::type type;
 
124
    };
 
125
 
 
126
    template <typename ScannerT>
 
127
    typename parser_result<self_t, ScannerT>::type
 
128
    parse(ScannerT const& scan) const
 
129
    {
 
130
        typename ScannerT::iterator_t save(scan.first);
 
131
        bool matches = this->subject().parse(scan);
 
132
        if (matches)
 
133
        {
 
134
            scan.first = save; // reset the position
 
135
            return scan.empty_match();
 
136
        }
 
137
        else
 
138
            return scan.no_match();
 
139
    }
 
140
 
 
141
    negated_empty_match_parser<SubjectT>
 
142
    negate() const
 
143
    {
 
144
        return negated_empty_match_parser<SubjectT>(this->subject());
 
145
    }
 
146
};
 
147
 
 
148
template<typename SubjectT>
 
149
struct negated_empty_match_parser
 
150
    : public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > >
 
151
{
 
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;
 
156
 
 
157
    explicit negated_empty_match_parser(SubjectT const &p) : base_t(p) {}
 
158
    negated_empty_match_parser() : base_t() {}
 
159
 
 
160
    template <typename ScannerT>
 
161
    struct result
 
162
    {
 
163
        typedef typename match_result<ScannerT, nil_t>::type type;
 
164
    };
 
165
 
 
166
    template <typename ScannerT>
 
167
    typename parser_result<self_t, ScannerT>::type
 
168
    parse(ScannerT const& scan) const
 
169
    {
 
170
        typename ScannerT::iterator_t save(scan.first);
 
171
 
 
172
        bool matches = this->subject().parse(scan);
 
173
        if (!matches)
 
174
        {
 
175
            scan.first = save; // reset the position
 
176
            return scan.empty_match();
 
177
        }
 
178
        else
 
179
            return scan.no_match();
 
180
    }
 
181
 
 
182
    empty_match_parser<SubjectT>
 
183
    negate() const
 
184
    {
 
185
        return empty_match_parser<SubjectT>(this->subject());
 
186
    }
 
187
};
 
188
 
 
189
//////////////////////////////
 
190
struct empty_match_parser_gen
 
191
{
 
192
    template <typename SubjectT>
 
193
    struct result
 
194
    {
 
195
        typedef empty_match_parser<SubjectT> type;
 
196
    };
 
197
 
 
198
    template <typename SubjectT>
 
199
    static empty_match_parser<SubjectT>
 
200
    generate(parser<SubjectT> const &subject)
 
201
    {
 
202
        return empty_match_parser<SubjectT>(subject.derived());
 
203
    }
 
204
};
 
205
 
 
206
struct negated_empty_match_parser_gen
 
207
{
 
208
    template <typename SubjectT>
 
209
    struct result
 
210
    {
 
211
        typedef negated_empty_match_parser<SubjectT> type;
 
212
    };
 
213
 
 
214
    template <typename SubjectT>
 
215
    static negated_empty_match_parser<SubjectT>
 
216
    generate(parser<SubjectT> const &subject)
 
217
    {
 
218
        return negated_empty_match_parser<SubjectT>(subject.derived());
 
219
    }
 
220
};
 
221
 
 
222
//////////////////////////////
 
223
template <typename SubjectT>
 
224
inline /*struct*/ negated_empty_match_parser<SubjectT>
 
225
operator ~(empty_match_parser<SubjectT> const &p)
 
226
{
 
227
    return p.negate();
 
228
}
 
229
 
 
230
template <typename SubjectT>
 
231
inline /*struct*/ empty_match_parser<SubjectT>
 
232
operator ~(negated_empty_match_parser<SubjectT> const &p)
 
233
{
 
234
    return p.negate();
 
235
}
 
236
 
 
237
///////////////////////////////////////////////////////////////////////////////
 
238
//
 
239
//  epsilon_ parser and parser generator class
 
240
//
 
241
//      Operates as primitive parser that always matches an empty sequence.
 
242
//
 
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().
 
247
//
 
248
///////////////////////////////////////////////////////////////////////////////
 
249
namespace impl
 
250
{
 
251
    template <typename SubjectT>
 
252
    struct epsilon_selector
 
253
    {
 
254
        typedef typename as_parser<SubjectT>::type subject_t;
 
255
        typedef typename
 
256
            mpl::if_<
 
257
                is_parser<subject_t>
 
258
                ,empty_match_parser<subject_t>
 
259
                ,condition_parser<subject_t>
 
260
                >::type type;
 
261
    };
 
262
} // namespace impl
 
263
 
 
264
struct epsilon_parser : public parser<epsilon_parser>
 
265
{
 
266
    typedef epsilon_parser self_t;
 
267
 
 
268
    epsilon_parser() {}
 
269
 
 
270
    template <typename ScannerT>
 
271
    typename parser_result<self_t, ScannerT>::type
 
272
    parse(ScannerT const& scan) const
 
273
    { return scan.empty_match(); }
 
274
 
 
275
    template <typename SubjectT>
 
276
    typename impl::epsilon_selector<SubjectT>::type
 
277
    operator()(SubjectT const &subject) const
 
278
    {
 
279
        typedef typename impl::epsilon_selector<SubjectT>::type result_t;
 
280
        return result_t(subject);
 
281
    }
 
282
};
 
283
 
 
284
//////////////////////////////////
 
285
epsilon_parser const epsilon_p = epsilon_parser();
 
286
epsilon_parser const eps_p = epsilon_parser();
 
287
 
 
288
///////////////////////////////////////////////////////////////////////////////
 
289
}} // namespace boost::spirit
 
290
 
 
291
#endif