source: NonGTP/Boost/boost/spirit/dynamic/while.hpp @ 857

Revision 857, 6.4 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Copyright (c) 2002-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_WHILE_HPP
11#define BOOST_SPIRIT_WHILE_HPP
12
13#include <boost/spirit/core/parser.hpp>
14#include <boost/spirit/core/composite/composite.hpp>
15#include <boost/spirit/dynamic/impl/conditions.ipp>
16
17////////////////////////////////////////////////////////////////////////////////
18namespace boost { namespace spirit {
19
20    namespace impl {
21
22    //////////////////////////////////
23    // while parser
24    // object are created by while_parser_gen and do_parser_gen
25    template <typename ParsableT, typename CondT, bool is_do_parser>
26    struct while_parser
27        : public condition_evaluator< typename as_parser<CondT>::type >
28        , public unary // the parent stores a copy of the body parser
29        <
30            typename as_parser<ParsableT>::type,
31            parser<while_parser<ParsableT, CondT, is_do_parser> >
32        >
33    {
34        typedef while_parser<ParsableT, CondT, is_do_parser> self_t;
35
36        typedef as_parser<ParsableT>            as_parser_t;
37        typedef typename as_parser_t::type      parser_t;
38        typedef as_parser<CondT>                cond_as_parser_t;
39        typedef typename cond_as_parser_t::type condition_t;
40
41        typedef unary<parser_t, parser<self_t> > base_t;
42        typedef condition_evaluator<condition_t> eval_t;
43
44
45        //////////////////////////////
46        // constructor, saves condition and body parser
47        while_parser(ParsableT const &body, CondT const &cond)
48            : eval_t(cond_as_parser_t::convert(cond))
49            , base_t(as_parser_t::convert(body))
50        {}
51
52        //////////////////////////////
53        // result type computer.
54        template <typename ScannerT>
55        struct result
56        {
57            typedef typename match_result
58                <ScannerT, nil_t>::type type;
59        };
60
61        //////////////////////////////
62        // parse member function
63        template <typename ScannerT>
64        typename parser_result<self_t, ScannerT>::type
65        parse(ScannerT const& scan) const
66        {
67            typedef typename parser_result<parser_t, ScannerT>::type sresult_t;
68            typedef typename ScannerT::iterator_t                    iterator_t;
69
70            iterator_t save(scan.first);
71            std::size_t length = 0;
72            int eval_length = 0;
73
74            bool dont_check_condition = is_do_parser;
75
76            while (dont_check_condition || (eval_length=this->evaluate(scan))>=0)
77            {
78                dont_check_condition = false;
79                length += eval_length;
80                sresult_t tmp(this->subject().parse(scan));
81                if (tmp)
82                {
83                    length+=tmp.length();
84                }
85                else
86                {
87                    return scan.no_match();
88                }
89            }
90            return scan.create_match(length, nil_t(), save, scan.first);
91        }
92    };
93
94    //////////////////////////////////
95    // while-parser generator, takes the body-parser in brackets
96    // and returns the actual while-parser.
97    template <typename CondT>
98    struct while_parser_gen
99    {
100        //////////////////////////////
101        // constructor, saves the condition for use by operator[]
102        while_parser_gen(CondT const& cond_) : cond(cond_) {}
103
104        //////////////////////////////
105        // operator[] returns the actual while-parser object
106        template <typename ParsableT>
107        while_parser<ParsableT, CondT, false>
108        operator[](ParsableT const &subject) const
109        {
110            return while_parser<ParsableT, CondT, false>(subject, cond);
111        }
112    private:
113
114        //////////////////////////////
115        // the condition is stored by reference here.
116        // this should not cause any harm since object of type
117        // while_parser_gen<> are only used as temporaries
118        // the while-parser object constructed by the operator[]
119        // stores a copy of the condition.
120        CondT const &cond;
121    };
122
123    //////////////////////////////////
124    // do-while-parser generator, takes the condition as
125    // parameter to while_p member function and returns the
126    // actual do-while-parser.
127    template <typename ParsableT>
128    struct do_while_parser_gen
129    {
130        //////////////////////////////
131        // constructor. saves the body parser for use by while_p.
132        explicit do_while_parser_gen(ParsableT const &body_parser)
133            : body(body_parser)
134        {}
135
136        //////////////////////////////
137        // while_p returns the actual while-parser object
138        template <typename CondT>
139        while_parser<ParsableT, CondT, true>
140        while_p(CondT cond) const
141        {
142            return while_parser<ParsableT, CondT, true>(body, cond);
143        }
144    private:
145
146        //////////////////////////////
147        // the body is stored by reference here
148        // this should not cause any harm since object of type
149        // do_while_parser_gen<> are only used as temporaries
150        // the while-parser object constructed by the while_p
151        // member function stores a copy of the body parser.
152        ParsableT const &body;
153    };
154
155    struct do_parser_gen
156    {
157        inline do_parser_gen() {}
158
159        template <typename ParsableT>
160        impl::do_while_parser_gen<ParsableT>
161        operator[](ParsableT const& body) const
162        {
163            return impl::do_while_parser_gen<ParsableT>(body);
164        }
165    };
166} // namespace impl
167
168//////////////////////////////////
169// while_p function, while-parser generator
170// Usage: spirit::while_p(Condition)[Body]
171template <typename CondT>
172impl::while_parser_gen<CondT>
173while_p(CondT const& cond)
174{
175    return impl::while_parser_gen<CondT>(cond);
176}
177
178//////////////////////////////////
179// do_p functor, do-while-parser generator
180// Usage: spirit::do_p[Body].while_p(Condition)
181impl::do_parser_gen const do_p = impl::do_parser_gen();
182
183}} // namespace boost::spirit
184
185#endif // BOOST_SPIRIT_WHILE_HPP
Note: See TracBrowser for help on using the repository browser.