| /*============================================================================= |
| 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> |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| 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 |
| |
| #endif |