Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:09:00

0001 /*=============================================================================
0002     Copyright (c) 2002-2003 Joel de Guzman
0003     Copyright (c) 2002-2003 Martin Wille
0004     http://spirit.sourceforge.net/
0005 
0006   Distributed under the Boost Software License, Version 1.0. (See accompanying
0007   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 =============================================================================*/
0009 #ifndef BOOST_SPIRIT_WHILE_HPP
0010 #define BOOST_SPIRIT_WHILE_HPP
0011 
0012 #include <boost/spirit/home/classic/namespace.hpp>
0013 #include <boost/spirit/home/classic/core/parser.hpp>
0014 #include <boost/spirit/home/classic/core/composite/composite.hpp>
0015 #include <boost/spirit/home/classic/dynamic/impl/conditions.ipp>
0016 
0017 ////////////////////////////////////////////////////////////////////////////////
0018 namespace boost { namespace spirit {
0019 
0020 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0021 
0022     namespace impl {
0023 
0024     //////////////////////////////////
0025     // while parser
0026     // object are created by while_parser_gen and do_parser_gen
0027     template <typename ParsableT, typename CondT, bool is_do_parser>
0028     struct while_parser
0029         : public condition_evaluator< typename as_parser<CondT>::type >
0030         , public unary // the parent stores a copy of the body parser
0031         <
0032             typename as_parser<ParsableT>::type,
0033             parser<while_parser<ParsableT, CondT, is_do_parser> >
0034         >
0035     {
0036         typedef while_parser<ParsableT, CondT, is_do_parser> self_t;
0037 
0038         typedef as_parser<ParsableT>            as_parser_t;
0039         typedef typename as_parser_t::type      parser_t;
0040         typedef as_parser<CondT>                cond_as_parser_t;
0041         typedef typename cond_as_parser_t::type condition_t;
0042 
0043         typedef unary<parser_t, parser<self_t> > base_t;
0044         typedef condition_evaluator<condition_t> eval_t;
0045 
0046 
0047         //////////////////////////////
0048         // constructor, saves condition and body parser
0049         while_parser(ParsableT const &body, CondT const &cond)
0050             : eval_t(cond_as_parser_t::convert(cond))
0051             , base_t(as_parser_t::convert(body))
0052         {}
0053 
0054         //////////////////////////////
0055         // result type computer.
0056         template <typename ScannerT>
0057         struct result
0058         {
0059             typedef typename match_result
0060                 <ScannerT, nil_t>::type type;
0061         };
0062 
0063         //////////////////////////////
0064         // parse member function
0065         template <typename ScannerT>
0066         typename parser_result<self_t, ScannerT>::type
0067         parse(ScannerT const& scan) const
0068         {
0069             typedef typename parser_result<parser_t, ScannerT>::type sresult_t;
0070             typedef typename ScannerT::iterator_t                    iterator_t;
0071 
0072             iterator_t save(scan.first);
0073             std::size_t length = 0;
0074             std::ptrdiff_t eval_length = 0;
0075 
0076             bool dont_check_condition = is_do_parser;
0077 
0078             while (dont_check_condition || (eval_length=this->evaluate(scan))>=0)
0079             {
0080                 dont_check_condition = false;
0081                 length += eval_length;
0082                 sresult_t tmp(this->subject().parse(scan));
0083                 if (tmp)
0084                 {
0085                     length+=tmp.length();
0086                 }
0087                 else
0088                 {
0089                     return scan.no_match();
0090                 }
0091             }
0092             return scan.create_match(length, nil_t(), save, scan.first);
0093         }
0094     };
0095 
0096     //////////////////////////////////
0097     // while-parser generator, takes the body-parser in brackets
0098     // and returns the actual while-parser.
0099     template <typename CondT>
0100     struct while_parser_gen
0101     {
0102         //////////////////////////////
0103         // constructor, saves the condition for use by operator[]
0104         while_parser_gen(CondT const& cond_) : cond(cond_) {}
0105 
0106         //////////////////////////////
0107         // operator[] returns the actual while-parser object
0108         template <typename ParsableT>
0109         while_parser<ParsableT, CondT, false>
0110         operator[](ParsableT const &subject) const
0111         {
0112             return while_parser<ParsableT, CondT, false>(subject, cond);
0113         }
0114     private:
0115 
0116         //////////////////////////////
0117         // the condition is stored by reference here.
0118         // this should not cause any harm since object of type
0119         // while_parser_gen<> are only used as temporaries
0120         // the while-parser object constructed by the operator[]
0121         // stores a copy of the condition.
0122         CondT const &cond;
0123     };
0124 
0125     //////////////////////////////////
0126     // do-while-parser generator, takes the condition as
0127     // parameter to while_p member function and returns the
0128     // actual do-while-parser.
0129     template <typename ParsableT>
0130     struct do_while_parser_gen
0131     {
0132         //////////////////////////////
0133         // constructor. saves the body parser for use by while_p.
0134         explicit do_while_parser_gen(ParsableT const &body_parser)
0135             : body(body_parser)
0136         {}
0137 
0138         //////////////////////////////
0139         // while_p returns the actual while-parser object
0140         template <typename CondT>
0141         while_parser<ParsableT, CondT, true>
0142         while_p(CondT cond) const
0143         {
0144             return while_parser<ParsableT, CondT, true>(body, cond);
0145         }
0146     private:
0147 
0148         //////////////////////////////
0149         // the body is stored by reference here
0150         // this should not cause any harm since object of type
0151         // do_while_parser_gen<> are only used as temporaries
0152         // the while-parser object constructed by the while_p
0153         // member function stores a copy of the body parser.
0154         ParsableT const &body;
0155     };
0156 
0157     struct do_parser_gen
0158     {
0159         inline do_parser_gen() {}
0160 
0161         template <typename ParsableT>
0162         impl::do_while_parser_gen<ParsableT>
0163         operator[](ParsableT const& body) const
0164         {
0165             return impl::do_while_parser_gen<ParsableT>(body);
0166         }
0167     };
0168 } // namespace impl
0169 
0170 //////////////////////////////////
0171 // while_p function, while-parser generator
0172 // Usage: spirit::while_p(Condition)[Body]
0173 template <typename CondT>
0174 impl::while_parser_gen<CondT>
0175 while_p(CondT const& cond)
0176 {
0177     return impl::while_parser_gen<CondT>(cond);
0178 }
0179 
0180 //////////////////////////////////
0181 // do_p functor, do-while-parser generator
0182 // Usage: spirit::do_p[Body].while_p(Condition)
0183 impl::do_parser_gen const do_p = impl::do_parser_gen();
0184 
0185 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0186 
0187 }} // namespace BOOST_SPIRIT_CLASSIC_NS
0188 
0189 #endif // BOOST_SPIRIT_WHILE_HPP