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