277 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| /*=============================================================================
 | |
|     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
 | 
