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