blob: 21162409d8010d51d2e8cbe061783bacf6f5b2e5 [file] [log] [blame]
/*=============================================================================
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