sl@0: /*============================================================================= sl@0: Copyright (c) 2002-2003 Joel de Guzman sl@0: Copyright (c) 2002-2003 Martin Wille sl@0: http://spirit.sourceforge.net/ sl@0: sl@0: Use, modification and distribution is subject to the Boost Software sl@0: License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at sl@0: http://www.boost.org/LICENSE_1_0.txt) sl@0: =============================================================================*/ sl@0: #ifndef BOOST_SPIRIT_WHILE_HPP sl@0: #define BOOST_SPIRIT_WHILE_HPP sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: //////////////////////////////////////////////////////////////////////////////// sl@0: namespace boost { namespace spirit { sl@0: sl@0: namespace impl { sl@0: sl@0: ////////////////////////////////// sl@0: // while parser sl@0: // object are created by while_parser_gen and do_parser_gen sl@0: template sl@0: struct while_parser sl@0: : public condition_evaluator< typename as_parser::type > sl@0: , public unary // the parent stores a copy of the body parser sl@0: < sl@0: typename as_parser::type, sl@0: parser > sl@0: > sl@0: { sl@0: typedef while_parser self_t; sl@0: sl@0: typedef as_parser as_parser_t; sl@0: typedef typename as_parser_t::type parser_t; sl@0: typedef as_parser cond_as_parser_t; sl@0: typedef typename cond_as_parser_t::type condition_t; sl@0: sl@0: typedef unary > base_t; sl@0: typedef condition_evaluator eval_t; sl@0: sl@0: sl@0: ////////////////////////////// sl@0: // constructor, saves condition and body parser sl@0: while_parser(ParsableT const &body, CondT const &cond) sl@0: : eval_t(cond_as_parser_t::convert(cond)) sl@0: , base_t(as_parser_t::convert(body)) sl@0: {} sl@0: sl@0: ////////////////////////////// sl@0: // result type computer. sl@0: template sl@0: struct result sl@0: { sl@0: typedef typename match_result sl@0: ::type type; sl@0: }; sl@0: sl@0: ////////////////////////////// sl@0: // parse member function sl@0: template sl@0: typename parser_result::type sl@0: parse(ScannerT const& scan) const sl@0: { sl@0: typedef typename parser_result::type sresult_t; sl@0: typedef typename ScannerT::iterator_t iterator_t; sl@0: sl@0: iterator_t save(scan.first); sl@0: std::size_t length = 0; sl@0: int eval_length = 0; sl@0: sl@0: bool dont_check_condition = is_do_parser; sl@0: sl@0: while (dont_check_condition || (eval_length=this->evaluate(scan))>=0) sl@0: { sl@0: dont_check_condition = false; sl@0: length += eval_length; sl@0: sresult_t tmp(this->subject().parse(scan)); sl@0: if (tmp) sl@0: { sl@0: length+=tmp.length(); sl@0: } sl@0: else sl@0: { sl@0: return scan.no_match(); sl@0: } sl@0: } sl@0: return scan.create_match(length, nil_t(), save, scan.first); sl@0: } sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: // while-parser generator, takes the body-parser in brackets sl@0: // and returns the actual while-parser. sl@0: template sl@0: struct while_parser_gen sl@0: { sl@0: ////////////////////////////// sl@0: // constructor, saves the condition for use by operator[] sl@0: while_parser_gen(CondT const& cond_) : cond(cond_) {} sl@0: sl@0: ////////////////////////////// sl@0: // operator[] returns the actual while-parser object sl@0: template sl@0: while_parser sl@0: operator[](ParsableT const &subject) const sl@0: { sl@0: return while_parser(subject, cond); sl@0: } sl@0: private: sl@0: sl@0: ////////////////////////////// sl@0: // the condition is stored by reference here. sl@0: // this should not cause any harm since object of type sl@0: // while_parser_gen<> are only used as temporaries sl@0: // the while-parser object constructed by the operator[] sl@0: // stores a copy of the condition. sl@0: CondT const &cond; sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: // do-while-parser generator, takes the condition as sl@0: // parameter to while_p member function and returns the sl@0: // actual do-while-parser. sl@0: template sl@0: struct do_while_parser_gen sl@0: { sl@0: ////////////////////////////// sl@0: // constructor. saves the body parser for use by while_p. sl@0: explicit do_while_parser_gen(ParsableT const &body_parser) sl@0: : body(body_parser) sl@0: {} sl@0: sl@0: ////////////////////////////// sl@0: // while_p returns the actual while-parser object sl@0: template sl@0: while_parser sl@0: while_p(CondT cond) const sl@0: { sl@0: return while_parser(body, cond); sl@0: } sl@0: private: sl@0: sl@0: ////////////////////////////// sl@0: // the body is stored by reference here sl@0: // this should not cause any harm since object of type sl@0: // do_while_parser_gen<> are only used as temporaries sl@0: // the while-parser object constructed by the while_p sl@0: // member function stores a copy of the body parser. sl@0: ParsableT const &body; sl@0: }; sl@0: sl@0: struct do_parser_gen sl@0: { sl@0: inline do_parser_gen() {} sl@0: sl@0: template sl@0: impl::do_while_parser_gen sl@0: operator[](ParsableT const& body) const sl@0: { sl@0: return impl::do_while_parser_gen(body); sl@0: } sl@0: }; sl@0: } // namespace impl sl@0: sl@0: ////////////////////////////////// sl@0: // while_p function, while-parser generator sl@0: // Usage: spirit::while_p(Condition)[Body] sl@0: template sl@0: impl::while_parser_gen sl@0: while_p(CondT const& cond) sl@0: { sl@0: return impl::while_parser_gen(cond); sl@0: } sl@0: sl@0: ////////////////////////////////// sl@0: // do_p functor, do-while-parser generator sl@0: // Usage: spirit::do_p[Body].while_p(Condition) sl@0: impl::do_parser_gen const do_p = impl::do_parser_gen(); sl@0: sl@0: }} // namespace boost::spirit sl@0: sl@0: #endif // BOOST_SPIRIT_WHILE_HPP