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