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