sl@0: /*============================================================================= sl@0: Copyright (c) 2002-2003 Joel de Guzman sl@0: Copyright (c) 2002 Juan Carlos Arevalo-Baeza 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_IF_HPP sl@0: #define BOOST_SPIRIT_IF_HPP sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace boost { namespace spirit { sl@0: sl@0: namespace impl { sl@0: sl@0: ////////////////////////////////// sl@0: // if-else-parser, holds two alternative parsers and a conditional functor sl@0: // that selects between them. sl@0: template sl@0: struct if_else_parser sl@0: : public condition_evaluator::type> sl@0: , public binary sl@0: < sl@0: typename as_parser::type, sl@0: typename as_parser::type, sl@0: parser< if_else_parser > sl@0: > sl@0: { sl@0: typedef if_else_parser self_t; sl@0: sl@0: typedef as_parser as_parser_true_t; sl@0: typedef as_parser as_parser_false_t; sl@0: typedef typename as_parser_true_t::type parser_true_t; sl@0: typedef typename as_parser_false_t::type parser_false_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 binary > base_t; sl@0: typedef condition_evaluator eval_t; sl@0: sl@0: if_else_parser sl@0: ( sl@0: ParsableTrueT const& p_true, sl@0: ParsableFalseT const& p_false, sl@0: CondT const& cond_ sl@0: ) sl@0: : eval_t(cond_as_parser_t::convert(cond_)) sl@0: , base_t sl@0: ( sl@0: as_parser_true_t::convert(p_true), sl@0: as_parser_false_t::convert(p_false) sl@0: ) sl@0: { } sl@0: sl@0: template sl@0: struct result sl@0: { sl@0: typedef typename match_result::type type; sl@0: }; sl@0: sl@0: template sl@0: typename parser_result::type sl@0: parse(ScannerT const& scan) const sl@0: { sl@0: typedef typename parser_result sl@0: ::type then_result_t; sl@0: typedef typename parser_result sl@0: ::type else_result_t; sl@0: sl@0: typename ScannerT::iterator_t const save(scan.first); sl@0: sl@0: std::ptrdiff_t length = this->evaluate(scan); sl@0: if (length >= 0) sl@0: { sl@0: then_result_t then_result(this->left().parse(scan)); sl@0: if (then_result) sl@0: { sl@0: length += then_result.length(); sl@0: return scan.create_match(std::size_t(length), nil_t(), save, scan.first); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: else_result_t else_result(this->right().parse(scan)); sl@0: if (else_result) sl@0: { sl@0: length = else_result.length(); sl@0: return scan.create_match(std::size_t(length), nil_t(), save, scan.first); sl@0: } sl@0: } sl@0: return scan.no_match(); sl@0: } sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: // if-else-parser generator, takes the false-parser in brackets sl@0: // and returns the if-else-parser. sl@0: template sl@0: struct if_else_parser_gen sl@0: { sl@0: if_else_parser_gen(ParsableTrueT const& p_true_, CondT const& cond_) sl@0: : p_true(p_true_) sl@0: , cond(cond_) {} sl@0: sl@0: template sl@0: if_else_parser sl@0: < sl@0: ParsableTrueT, sl@0: ParsableFalseT, sl@0: CondT sl@0: > sl@0: operator[](ParsableFalseT const& p_false) const sl@0: { sl@0: return if_else_parser sl@0: ( sl@0: p_true, sl@0: p_false, sl@0: cond sl@0: ); sl@0: } sl@0: sl@0: ParsableTrueT const &p_true; sl@0: CondT const &cond; sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: // if-parser, conditionally runs a parser is a functor condition is true. sl@0: // If the condition is fales, it fails the parse. sl@0: // It can optionally become an if-else-parser through the member else_p. sl@0: template sl@0: struct if_parser sl@0: : public condition_evaluator::type> sl@0: , public unary sl@0: < sl@0: typename as_parser::type, sl@0: parser > > sl@0: { sl@0: typedef if_parser self_t; sl@0: typedef as_parser as_parser_t; sl@0: typedef typename as_parser_t::type parser_t; sl@0: sl@0: typedef as_parser cond_as_parser_t; sl@0: typedef typename cond_as_parser_t::type condition_t; sl@0: typedef condition_evaluator eval_t; sl@0: typedef unary > base_t; sl@0: sl@0: if_parser(ParsableT const& p, CondT const& cond_) sl@0: : eval_t(cond_as_parser_t::convert(cond_)) sl@0: , base_t(as_parser_t::convert(p)) sl@0: , else_p(p, cond_) sl@0: {} sl@0: sl@0: template sl@0: struct result sl@0: { sl@0: typedef typename match_result::type type; sl@0: }; sl@0: 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 t_result_t; sl@0: typename ScannerT::iterator_t const save(scan.first); sl@0: sl@0: std::ptrdiff_t length = this->evaluate(scan); sl@0: if (length >= 0) sl@0: { sl@0: t_result_t then_result(this->subject().parse(scan)); sl@0: if (then_result) sl@0: { sl@0: length += then_result.length(); sl@0: return scan.create_match(std::size_t(length), nil_t(), save, scan.first); sl@0: } sl@0: return scan.no_match(); sl@0: } sl@0: return scan.empty_match(); sl@0: } sl@0: sl@0: if_else_parser_gen else_p; sl@0: }; sl@0: sl@0: ////////////////////////////////// sl@0: // if-parser generator, takes the true-parser in brackets and returns the sl@0: // if-parser. sl@0: template sl@0: struct if_parser_gen sl@0: { sl@0: if_parser_gen(CondT const& cond_) : cond(cond_) {} sl@0: sl@0: template sl@0: if_parser sl@0: < sl@0: ParsableT, sl@0: CondT sl@0: > sl@0: operator[](ParsableT const& subject) const sl@0: { sl@0: return if_parser(subject, cond); sl@0: } sl@0: sl@0: CondT const &cond; sl@0: }; sl@0: sl@0: } // namespace impl sl@0: sl@0: ////////////////////////////////// sl@0: // if_p function, returns "if" parser generator sl@0: sl@0: template sl@0: impl::if_parser_gen sl@0: if_p(CondT const& cond) sl@0: { sl@0: return impl::if_parser_gen(cond); sl@0: } sl@0: sl@0: }} // namespace boost::spirit sl@0: sl@0: #endif // BOOST_SPIRIT_IF_HPP