123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- /*=============================================================================
- 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
|