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
 |