PageRenderTime 17ms CodeModel.GetById 2ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/spirit/home/classic/dynamic/if.hpp

http://hadesmem.googlecode.com/
C++ Header | 229 lines | 174 code | 31 blank | 24 comment | 5 complexity | 7049c680dea4cd19206a8cce319b027f MD5 | raw file
  1/*=============================================================================
  2    Copyright (c) 2002-2003 Joel de Guzman
  3    Copyright (c) 2002 Juan Carlos Arevalo-Baeza
  4    Copyright (c) 2002-2003 Martin Wille
  5    http://spirit.sourceforge.net/
  6
  7  Distributed under the Boost Software License, Version 1.0. (See accompanying
  8  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9=============================================================================*/
 10#ifndef BOOST_SPIRIT_IF_HPP
 11#define BOOST_SPIRIT_IF_HPP
 12
 13#include <boost/spirit/home/classic/namespace.hpp>
 14#include <boost/spirit/home/classic/core/parser.hpp>
 15#include <boost/spirit/home/classic/core/composite/composite.hpp>
 16#include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
 17
 18namespace boost { namespace spirit {
 19
 20BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
 21
 22    namespace impl {
 23
 24    //////////////////////////////////
 25    // if-else-parser, holds two alternative parsers and a conditional functor
 26    // that selects between them.
 27    template <typename ParsableTrueT, typename ParsableFalseT, typename CondT>
 28    struct if_else_parser
 29        : public condition_evaluator<typename as_parser<CondT>::type>
 30        , public binary
 31        <
 32            typename as_parser<ParsableTrueT>::type,
 33            typename as_parser<ParsableFalseT>::type,
 34            parser< if_else_parser<ParsableTrueT, ParsableFalseT, CondT> >
 35        >
 36    {
 37        typedef if_else_parser<ParsableTrueT, ParsableFalseT, CondT>  self_t;
 38
 39        typedef as_parser<ParsableTrueT>            as_parser_true_t;
 40        typedef as_parser<ParsableFalseT>           as_parser_false_t;
 41        typedef typename as_parser_true_t::type     parser_true_t;
 42        typedef typename as_parser_false_t::type    parser_false_t;
 43        typedef as_parser<CondT>                    cond_as_parser_t;
 44        typedef typename cond_as_parser_t::type     condition_t;
 45
 46        typedef binary<parser_true_t, parser_false_t, parser<self_t> > base_t;
 47        typedef condition_evaluator<condition_t>                       eval_t;
 48
 49        if_else_parser
 50        (
 51            ParsableTrueT  const& p_true,
 52            ParsableFalseT const& p_false,
 53            CondT          const& cond_
 54        )
 55            : eval_t(cond_as_parser_t::convert(cond_))
 56            , base_t
 57                (
 58                    as_parser_true_t::convert(p_true),
 59                    as_parser_false_t::convert(p_false)
 60                )
 61        { }
 62
 63        template <typename ScannerT>
 64        struct result
 65        {
 66            typedef typename match_result<ScannerT, nil_t>::type type;
 67        };
 68
 69        template <typename ScannerT>
 70        typename parser_result<self_t, ScannerT>::type
 71        parse(ScannerT const& scan) const
 72        {
 73            typedef typename parser_result
 74                <parser_true_t, ScannerT>::type   then_result_t;
 75            typedef typename parser_result
 76                <parser_false_t, ScannerT>::type  else_result_t;
 77
 78            typename ScannerT::iterator_t const  save(scan.first);
 79
 80            std::ptrdiff_t length = this->evaluate(scan);
 81            if (length >= 0)
 82            {
 83                then_result_t then_result(this->left().parse(scan));
 84                if (then_result)
 85                {
 86                    length += then_result.length();
 87                    return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
 88                }
 89            }
 90            else
 91            {
 92                else_result_t else_result(this->right().parse(scan));
 93                if (else_result)
 94                {
 95                    length = else_result.length();
 96                    return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
 97                }
 98            }
 99            return scan.no_match();
100        }
101    };
102
103    //////////////////////////////////
104    // if-else-parser generator, takes the false-parser in brackets
105    // and returns the if-else-parser.
106    template <typename ParsableTrueT, typename CondT>
107    struct if_else_parser_gen
108    {
109        if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_)
110            : p_true(p_true_)
111            , cond(cond_) {}
112
113        template <typename ParsableFalseT>
114        if_else_parser
115        <
116            ParsableTrueT,
117            ParsableFalseT,
118            CondT
119        >
120        operator[](ParsableFalseT const& p_false) const
121        {
122            return if_else_parser<ParsableTrueT, ParsableFalseT, CondT>
123                (
124                    p_true,
125                    p_false,
126                    cond
127                );
128        }
129
130        ParsableTrueT const &p_true;
131        CondT const &cond;
132    };
133
134    //////////////////////////////////
135    // if-parser, conditionally runs a parser is a functor condition is true.
136    // If the condition is fales, it fails the parse.
137    // It can optionally become an if-else-parser through the member else_p.
138    template <typename ParsableT, typename CondT>
139    struct if_parser
140        : public condition_evaluator<typename as_parser<CondT>::type>
141        , public unary
142        <
143            typename as_parser<ParsableT>::type,
144            parser<if_parser<ParsableT, CondT> > >
145    {
146        typedef if_parser<ParsableT, CondT>           self_t;
147        typedef as_parser<ParsableT>                  as_parser_t;
148        typedef typename as_parser_t::type            parser_t;
149
150        typedef as_parser<CondT>                      cond_as_parser_t;
151        typedef typename cond_as_parser_t::type       condition_t;
152        typedef condition_evaluator<condition_t>      eval_t;
153        typedef unary<parser_t, parser<self_t> >      base_t;
154
155        if_parser(ParsableT const& p, CondT const& cond_)
156            : eval_t(cond_as_parser_t::convert(cond_))
157            , base_t(as_parser_t::convert(p))
158            , else_p(p, cond_)
159        {}
160
161        template <typename ScannerT>
162        struct result
163        {
164            typedef typename match_result<ScannerT, nil_t>::type type;
165        };
166
167        template <typename ScannerT>
168        typename parser_result<self_t, ScannerT>::type
169        parse(ScannerT const& scan) const
170        {
171            typedef typename parser_result<parser_t, ScannerT>::type t_result_t;
172            typename ScannerT::iterator_t const save(scan.first);
173
174            std::ptrdiff_t length = this->evaluate(scan);
175            if (length >= 0)
176            {
177                t_result_t then_result(this->subject().parse(scan));
178                if (then_result)
179                {
180                    length += then_result.length();
181                    return scan.create_match(std::size_t(length), nil_t(), save, scan.first);
182                }
183                return scan.no_match();
184            }
185            return scan.empty_match();
186        }
187
188        if_else_parser_gen<ParsableT, CondT> else_p;
189    };
190
191    //////////////////////////////////
192    // if-parser generator, takes the true-parser in brackets and returns the
193    // if-parser.
194    template <typename CondT>
195    struct if_parser_gen
196    {
197        if_parser_gen(CondT const& cond_) : cond(cond_) {}
198
199        template <typename ParsableT>
200        if_parser
201        <
202            ParsableT,
203            CondT
204        >
205        operator[](ParsableT const& subject) const
206        {
207            return if_parser<ParsableT, CondT>(subject, cond);
208        }
209
210        CondT const &cond;
211    };
212
213} // namespace impl
214
215//////////////////////////////////
216// if_p function, returns "if" parser generator
217
218template <typename CondT>
219impl::if_parser_gen<CondT>
220if_p(CondT const& cond)
221{
222    return impl::if_parser_gen<CondT>(cond);
223}
224
225BOOST_SPIRIT_CLASSIC_NAMESPACE_END
226
227}} // namespace BOOST_SPIRIT_CLASSIC_NS
228
229#endif // BOOST_SPIRIT_IF_HPP