EVOLUTION-MANAGER
Edit File: epsilon.hpp
/*============================================================================= Copyright (c) 1998-2003 Joel de Guzman Copyright (c) 2002-2003 Martin Wille http://spirit.sourceforge.net/ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef BOOST_SPIRIT_EPSILON_HPP #define BOOST_SPIRIT_EPSILON_HPP //////////////////////////////////////////////////////////////////////////////// #include <boost/spirit/home/classic/namespace.hpp> #include <boost/spirit/home/classic/core/parser.hpp> #include <boost/spirit/home/classic/meta/parser_traits.hpp> #include <boost/spirit/home/classic/core/composite/composite.hpp> #include <boost/spirit/home/classic/core/composite/no_actions.hpp> #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' #endif //////////////////////////////////////////////////////////////////////////////// namespace boost { namespace spirit { BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN /////////////////////////////////////////////////////////////////////////////// // // condition_parser class // // handles expresions of the form // // epsilon_p(cond) // // where cond is a function or a functor that returns a value suitable // to be used in boolean context. The expression returns a parser that // returns an empty match when the condition evaluates to true. // /////////////////////////////////////////////////////////////////////////////// template <typename CondT, bool positive_ = true> struct condition_parser : parser<condition_parser<CondT, positive_> > { typedef condition_parser<CondT, positive_> self_t; // not explicit! (needed for implementation of if_p et al.) condition_parser(CondT const& cond_) : cond(cond_) {} template <typename ScannerT> typename parser_result<self_t, ScannerT>::type parse(ScannerT const& scan) const { if (positive_ == bool(cond())) // allow cond to return int return scan.empty_match(); else return scan.no_match(); } condition_parser<CondT, !positive_> negate() const { return condition_parser<CondT, !positive_>(cond); } private: CondT cond; }; #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \ BOOST_WORKAROUND(BOOST_MSVC, == 1400) || \ BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) // VC 7.1, VC8 and Sun CC <= 5.8 do not support general // expressions of non-type template parameters in instantiations template <typename CondT> inline condition_parser<CondT, false> operator~(condition_parser<CondT, true> const& p) { return p.negate(); } template <typename CondT> inline condition_parser<CondT, true> operator~(condition_parser<CondT, false> const& p) { return p.negate(); } #else // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400 template <typename CondT, bool positive> inline condition_parser<CondT, !positive> operator~(condition_parser<CondT, positive> const& p) { return p.negate(); } #endif // BOOST_WORKAROUND(BOOST_MSVC, == 1310) || == 1400 /////////////////////////////////////////////////////////////////////////////// // // empty_match_parser class // // handles expressions of the form // epsilon_p(subject) // where subject is a parser. The expresion returns a composite // parser that returns an empty match if the subject parser matches. // /////////////////////////////////////////////////////////////////////////////// struct empty_match_parser_gen; struct negated_empty_match_parser_gen; template <typename SubjectT> struct negated_empty_match_parser; // Forward declaration template<typename SubjectT> struct empty_match_parser : unary<SubjectT, parser<empty_match_parser<SubjectT> > > { typedef empty_match_parser<SubjectT> self_t; typedef unary<SubjectT, parser<self_t> > base_t; typedef unary_parser_category parser_category_t; typedef empty_match_parser_gen parser_genererator_t; typedef self_t embed_t; explicit empty_match_parser(SubjectT const& p) : base_t(p) {} template <typename ScannerT> struct result { typedef typename match_result<ScannerT, nil_t>::type type; }; template <typename ScannerT> typename parser_result<self_t, ScannerT>::type parse(ScannerT const& scan) const { typename ScannerT::iterator_t save(scan.first); typedef typename no_actions_scanner<ScannerT>::policies_t policies_t; bool matches = this->subject().parse( scan.change_policies(policies_t(scan))); if (matches) { scan.first = save; // reset the position return scan.empty_match(); } else { return scan.no_match(); } } negated_empty_match_parser<SubjectT> negate() const { return negated_empty_match_parser<SubjectT>(this->subject()); } }; template<typename SubjectT> struct negated_empty_match_parser : public unary<SubjectT, parser<negated_empty_match_parser<SubjectT> > > { typedef negated_empty_match_parser<SubjectT> self_t; typedef unary<SubjectT, parser<self_t> > base_t; typedef unary_parser_category parser_category_t; typedef negated_empty_match_parser_gen parser_genererator_t; explicit negated_empty_match_parser(SubjectT const& p) : base_t(p) {} template <typename ScannerT> struct result { typedef typename match_result<ScannerT, nil_t>::type type; }; template <typename ScannerT> typename parser_result<self_t, ScannerT>::type parse(ScannerT const& scan) const { typename ScannerT::iterator_t save(scan.first); typedef typename no_actions_scanner<ScannerT>::policies_t policies_t; bool matches = this->subject().parse( scan.change_policies(policies_t(scan))); if (!matches) { scan.first = save; // reset the position return scan.empty_match(); } else { return scan.no_match(); } } empty_match_parser<SubjectT> negate() const { return empty_match_parser<SubjectT>(this->subject()); } }; struct empty_match_parser_gen { template <typename SubjectT> struct result { typedef empty_match_parser<SubjectT> type; }; template <typename SubjectT> static empty_match_parser<SubjectT> generate(parser<SubjectT> const& subject) { return empty_match_parser<SubjectT>(subject.derived()); } }; struct negated_empty_match_parser_gen { template <typename SubjectT> struct result { typedef negated_empty_match_parser<SubjectT> type; }; template <typename SubjectT> static negated_empty_match_parser<SubjectT> generate(parser<SubjectT> const& subject) { return negated_empty_match_parser<SubjectT>(subject.derived()); } }; ////////////////////////////// template <typename SubjectT> inline negated_empty_match_parser<SubjectT> operator~(empty_match_parser<SubjectT> const& p) { return p.negate(); } template <typename SubjectT> inline empty_match_parser<SubjectT> operator~(negated_empty_match_parser<SubjectT> const& p) { return p.negate(); } /////////////////////////////////////////////////////////////////////////////// // // epsilon_ parser and parser generator class // // Operates as primitive parser that always matches an empty sequence. // // Also operates as a parser generator. According to the type of the // argument an instance of empty_match_parser<> (when the argument is // a parser) or condition_parser<> (when the argument is not a parser) // is returned by operator(). // /////////////////////////////////////////////////////////////////////////////// namespace impl { template <typename SubjectT> struct epsilon_selector { typedef typename as_parser<SubjectT>::type subject_t; typedef typename mpl::if_< is_parser<subject_t> ,empty_match_parser<subject_t> ,condition_parser<subject_t> >::type type; }; } struct epsilon_parser : public parser<epsilon_parser> { typedef epsilon_parser self_t; epsilon_parser() {} template <typename ScannerT> typename parser_result<self_t, ScannerT>::type parse(ScannerT const& scan) const { return scan.empty_match(); } template <typename SubjectT> typename impl::epsilon_selector<SubjectT>::type operator()(SubjectT const& subject) const { typedef typename impl::epsilon_selector<SubjectT>::type result_t; return result_t(subject); } }; epsilon_parser const epsilon_p = epsilon_parser(); epsilon_parser const eps_p = epsilon_parser(); /////////////////////////////////////////////////////////////////////////////// BOOST_SPIRIT_CLASSIC_NAMESPACE_END }} // namespace BOOST_SPIRIT_CLASSIC_NS #ifdef BOOST_MSVC # pragma warning (pop) #endif #endif