/*=============================================================================
|
Copyright (c) 2001-2014 Joel de Guzman
|
|
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_X3_PARSE_APRIL_16_2006_0442PM)
|
#define BOOST_SPIRIT_X3_PARSE_APRIL_16_2006_0442PM
|
|
#include <boost/spirit/home/x3/support/context.hpp>
|
#include <boost/spirit/home/x3/core/parser.hpp>
|
#include <boost/spirit/home/x3/core/skip_over.hpp>
|
#include <boost/iterator/iterator_concepts.hpp>
|
|
namespace boost { namespace spirit { namespace x3
|
{
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser, typename Attribute>
|
inline bool
|
parse_main(
|
Iterator& first
|
, Iterator last
|
, Parser const& p
|
, Attribute& attr)
|
{
|
// Make sure the iterator is at least a readable forward traversal iterator.
|
// If you got a compilation error here, then you are using a weaker iterator
|
// while calling this function, you need to supply a readable forward traversal
|
// iterator instead.
|
BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>));
|
BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>));
|
|
// If you get an error no matching function for call to 'as_parser'
|
// here, then p is not a parser or there is no suitable conversion
|
// from p to a parser.
|
return as_parser(p).parse(first, last, unused, unused, attr);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser, typename Attribute>
|
inline bool
|
parse(
|
Iterator& first
|
, Iterator last
|
, Parser const& p
|
, Attribute& attr)
|
{
|
return parse_main(first, last, p, attr);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser, typename Attribute>
|
inline bool
|
parse(
|
Iterator const& first_
|
, Iterator last
|
, Parser const& p
|
, Attribute& attr)
|
{
|
Iterator first = first_;
|
return parse_main(first, last, p, attr);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser>
|
inline bool
|
parse(
|
Iterator& first
|
, Iterator last
|
, Parser const& p)
|
{
|
return parse_main(first, last, p, unused);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser>
|
inline bool
|
parse(
|
Iterator const& first_
|
, Iterator last
|
, Parser const& p)
|
{
|
Iterator first = first_;
|
return parse_main(first, last, p, unused);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
enum class skip_flag
|
{
|
post_skip, // force post-skipping in phrase_parse()
|
dont_post_skip // inhibit post-skipping in phrase_parse()
|
};
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
|
inline bool
|
phrase_parse_main(
|
Iterator& first
|
, Iterator last
|
, Parser const& p
|
, Skipper const& s
|
, Attribute& attr
|
, skip_flag post_skip = skip_flag::post_skip)
|
{
|
// Make sure the iterator is at least a readable forward traversal iterator.
|
// If you got a compilation error here, then you are using a weaker iterator
|
// while calling this function, you need to supply a readable forward traversal
|
// iterator instead.
|
BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<Iterator>));
|
BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversalConcept<Iterator>));
|
|
static_assert(!std::is_same<Skipper, unused_type>::value,
|
"Error! Skipper cannot be unused_type.");
|
|
// If you get an error no matching function for call to 'as_parser'
|
// here, for either p or s, then p or s is not a parser or there is
|
// no suitable conversion from p to a parser.
|
auto skipper_ctx = make_context<skipper_tag>(as_parser(s));
|
bool r = as_parser(p).parse(first, last, skipper_ctx, unused, attr);
|
if (post_skip == skip_flag::post_skip)
|
x3::skip_over(first, last, skipper_ctx);
|
return r;
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
|
inline bool
|
phrase_parse(
|
Iterator& first
|
, Iterator last
|
, Parser const& p
|
, Skipper const& s
|
, Attribute& attr
|
, skip_flag post_skip = skip_flag::post_skip)
|
{
|
return phrase_parse_main(first, last, p, s, attr, post_skip);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser, typename Skipper, typename Attribute>
|
inline bool
|
phrase_parse(
|
Iterator const& first_
|
, Iterator last
|
, Parser const& p
|
, Skipper const& s
|
, Attribute& attr
|
, skip_flag post_skip = skip_flag::post_skip)
|
{
|
Iterator first = first_;
|
return phrase_parse_main(first, last, p, s, attr, post_skip);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser, typename Skipper>
|
inline bool
|
phrase_parse(
|
Iterator& first
|
, Iterator last
|
, Parser const& p
|
, Skipper const& s
|
, skip_flag post_skip = skip_flag::post_skip)
|
{
|
return phrase_parse_main(first, last, p, s, unused, post_skip);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Iterator, typename Parser, typename Skipper>
|
inline bool
|
phrase_parse(
|
Iterator const& first_
|
, Iterator last
|
, Parser const& p
|
, Skipper const& s
|
, skip_flag post_skip = skip_flag::post_skip)
|
{
|
Iterator first = first_;
|
return phrase_parse_main(first, last, p, s, unused, post_skip);
|
}
|
|
///////////////////////////////////////////////////////////////////////////
|
template <typename Skipper>
|
struct phrase_parse_context
|
{
|
typedef decltype(
|
make_context<skipper_tag>(as_parser(std::declval<Skipper>())))
|
type;
|
};
|
}}}
|
|
#endif
|