Initial Commit
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
/*=============================================================================
|
||||
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
|
||||
Reference in New Issue
Block a user