source: NonGTP/Boost/boost/spirit/core/composite/epsilon.hpp @ 857

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