source: NonGTP/Boost/boost/spirit/dynamic/for.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_FOR_HPP
11#define BOOST_SPIRIT_FOR_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////////////////////////////////////////////////////////////////////////////////
18
19namespace boost { namespace spirit
20{
21    namespace impl
22    {
23
24        template <typename FuncT>
25        struct for_functor
26        {
27            typedef typename boost::call_traits<FuncT>::param_type  param_t;
28
29            for_functor(param_t f) : func(f) {}
30            for_functor() {}
31            FuncT func;
32        };
33
34        template <typename InitF>
35        struct for_init_functor : for_functor<InitF>
36        {
37            typedef for_functor<InitF>          base_t;
38            typedef typename base_t::param_t    param_t;
39
40            for_init_functor(param_t f) : base_t(f) {}
41            for_init_functor() : base_t() {}
42            void init() const { /*return*/ this->func(); }
43        };
44
45        template <typename StepF>
46        struct for_step_functor : for_functor<StepF>
47        {
48            typedef for_functor<StepF>          base_t;
49            typedef typename base_t::param_t    param_t;
50
51            for_step_functor(param_t f) : base_t(f) {}
52            for_step_functor() : base_t() {}
53            void step() const { /*return*/ this->func(); }
54        };
55
56        //////////////////////////////////
57        // for_parser
58        template
59        <
60            typename InitF, typename CondT, typename StepF,
61            typename ParsableT
62        >
63        struct for_parser
64            : private for_init_functor<InitF>
65            , private for_step_functor<StepF>
66            , private condition_evaluator<typename as_parser<CondT>::type>
67            , public unary
68            <
69                typename as_parser<ParsableT>::type,
70                parser< for_parser<InitF, CondT, StepF, ParsableT> >
71            >
72        {
73            typedef for_parser<InitF, CondT, StepF, ParsableT> self_t;
74            typedef as_parser<CondT>                           cond_as_parser_t;
75            typedef typename cond_as_parser_t::type            condition_t;
76            typedef condition_evaluator<condition_t>           eval_t;
77            typedef as_parser<ParsableT>                       as_parser_t;
78            typedef typename as_parser_t::type                 parser_t;
79            typedef unary< parser_t, parser< self_t > >        base_t;
80
81
82            //////////////////////////////
83            // constructor, saves init, condition and step functors
84            // for later use the parse member function
85            for_parser
86            (
87                InitF const &i, CondT const &c, StepF const &s,
88                ParsableT const &p
89            )
90                : for_init_functor<InitF>(i)
91                , for_step_functor<StepF>(s)
92                , eval_t(cond_as_parser_t::convert(c))
93                , base_t(as_parser_t::convert(p))
94            { }
95
96            for_parser()
97                : for_init_functor<InitF>()
98                , for_step_functor<StepF>()
99                , eval_t()
100                , base_t()
101            {}
102
103            //////////////////////////////
104            // parse member function
105            template <typename ScannerT>
106            typename parser_result<self_t, ScannerT>::type
107            parse(ScannerT const &scan) const
108            {
109                typedef typename parser_result<self_t, ScannerT>::type
110                    result_t;
111                typedef typename parser_result<parser_t, ScannerT>::type
112                    body_result_t;
113
114                typename ScannerT::iterator_t save(scan.first);
115
116                std::size_t length = 0;
117                int eval_length = 0;
118
119                this->init();
120                while ((eval_length = this->evaluate(scan))>=0)
121                {
122                    length += eval_length;
123                    body_result_t tmp(this->subject().parse(scan));
124                    if (tmp)
125                    {
126                        length+=tmp.length();
127                    }
128                    else
129                    {
130                        return scan.no_match();
131                    }
132                    this->step();
133                }
134
135                boost::spirit::nil_t attr;
136                return scan.create_match
137                    (length, attr, save, scan.first);
138            }
139        };
140
141        //////////////////////////////////
142        // for_parser_gen generates takes the body parser in brackets
143        // and returns the for_parser
144        template <typename InitF, typename CondT, typename StepF>
145        struct for_parser_gen
146        {
147            for_parser_gen(InitF const &i, CondT const &c, StepF const &s)
148                : init(i)
149                , condition(c)
150                , step(s)
151            {}
152
153            template <typename ParsableT>
154            for_parser<InitF, CondT, StepF, ParsableT>
155            operator[](ParsableT const &p) const
156            {
157                return for_parser<InitF, CondT, StepF, ParsableT>
158                    (init, condition, step, p);
159            }
160
161            InitF const &init;
162            CondT const &condition;
163            StepF const &step;
164        };
165    } // namespace impl
166
167    //////////////////////////////
168    // for_p, returns for-parser generator
169    // Usage: spirit::for_p(init-ftor, condition, step-ftor)[body]
170    template
171    <
172        typename InitF, typename ConditionT, typename StepF
173    >
174    impl::for_parser_gen<InitF, ConditionT, StepF>
175    for_p(InitF const &init_f, ConditionT const &condition, StepF const &step_f)
176    {
177        return impl::for_parser_gen<InitF, ConditionT, StepF>
178            (init_f, condition, step_f);
179    }
180
181}} // namespace boost::spirit
182
183#endif // BOOST_SPIRIT_FOR_HPP
Note: See TracBrowser for help on using the repository browser.