blob: 21fdaea6b55191fdd18e406206d5687d3e7904ac [file] [log] [blame]
/*=============================================================================
Copyright (c) 2001-2008 Hartmut Kaiser
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)
==============================================================================*/
#if !defined(BOOST_SPIRIT_PRIMITIVES_APR_18_2008_0751PM)
#define BOOST_SPIRIT_PRIMITIVES_APR_18_2008_0751PM
#include <boost/mpl/bool.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// the end_director_base is a base class for various end parsers
///////////////////////////////////////////////////////////////////////////
template <typename Parser, typename StoreIterator = mpl::false_>
struct end_director_base
{
typedef mpl::false_ stores_iterator;
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& /*attr*/)
{
qi::skip(first, last, skipper);
return Parser::test(first, last);
}
// subclasses are required to implement test:
template <typename Iterator>
bool test(Iterator& first, Iterator const& last);
};
///////////////////////////////////////////////////////////////////////////
// same as end_director_base above, but stores iterator
///////////////////////////////////////////////////////////////////////////
template <typename Parser>
struct end_director_base<Parser, mpl::true_>
{
typedef mpl::true_ stores_iterator;
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& /*attr*/)
{
qi::skip(first, last, skipper);
Iterator it = first;
if (!Parser::test(it, last))
return false;
first = it;
return true;
}
// subclasses are required to implement test:
template <typename Iterator>
bool test(Iterator& first, Iterator const& last);
};
///////////////////////////////////////////////////////////////////////////
// ~eoi, ~eol: 'not end of line' or 'not end of input'
template <typename Positive>
struct negated_end_director
: end_director_base<
negated_end_director<Positive>,
typename Positive::director::stores_iterator
>
{
template <typename Iterator>
static bool test (Iterator& first, Iterator const& last)
{
return !Positive::director::test(first, last);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "not " +
Positive::director::what(fusion::at_c<0>(component.elements), ctx);
}
};
///////////////////////////////////////////////////////////////////////////
// eoi: end of input
struct eoi_director : end_director_base<eoi_director>
{
template <typename Iterator>
static bool test (Iterator& first, Iterator const& last)
{
return first == last;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "eoi";
}
};
///////////////////////////////////////////////////////////////////////////
// the eol_director matches line endings
///////////////////////////////////////////////////////////////////////////
struct eol_director : end_director_base<eol_director, mpl::true_>
{
template <typename Iterator>
static bool test (Iterator& first, Iterator const& last)
{
bool matched = false;
if (first != last && *first == '\r') // CR
{
matched = true;
++first;
}
if (first != last && *first == '\n') // LF
{
matched = true;
++first;
}
return matched;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "eol";
}
};
///////////////////////////////////////////////////////////////////////////////
}}}
#endif