blob: 1c29e69f199a991c890eb16a3864eed6f2adcecd [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_QI_CONFIX_AUG_26_2008_1012AM)
#define BOOST_SPIRIT_QI_CONFIX_AUG_26_2008_1012AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/auxiliary/confix.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// the director for a confix() generated parser
struct confix_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
traits::attribute_of<
qi::domain, subject_type, Context, Iterator>::type
type;
};
private:
///////////////////////////////////////////////////////////////////////
template <
typename Iterator, typename Context
, typename Skipper, typename Expr>
static void parse_helper(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, Expr const& e)
{
BOOST_MPL_ASSERT_MSG(
(spirit::traits::is_component<qi::domain, Expr>::value),
expression_is_not_convertible_to_a_parser, (Context, Expr));
typedef
typename result_of::as_component<qi::domain, Expr>::type
expr;
expr eg = spirit::as_component(qi::domain(), e);
typedef typename expr::director director;
director::parse(eg, first, last, context, skipper, unused);
}
template <typename Context, typename Expr>
static std::string what_helper(Expr const& e, Context& ctx)
{
typedef
typename result_of::as_component<qi::domain, Expr>::type
expr;
expr eg = spirit::as_component(qi::domain(), e);
typedef typename expr::director director;
return director::what(eg, ctx);
}
public:
///////////////////////////////////////////////////////////////////////
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)
{
// parse the prefix
parse_helper(first, last, context, skipper,
spirit::detail::confix_extractor::prefix(
proto::child_c<0>(spirit::argument1(component))));
// generate the embedded items
typedef typename
spirit::result_of::subject<Component>::type::director
director;
bool result = director::parse(spirit::subject(component),
first, last, context, skipper, attr);
// append the suffix
parse_helper(first, last, context, skipper,
spirit::detail::confix_extractor::suffix(
proto::child_c<0>(spirit::argument1(component))));
return result;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "confix(";
result += what_helper(spirit::detail::confix_extractor::prefix(
proto::child_c<0>(spirit::argument1(component))), ctx);
result += ", ";
result += what_helper(spirit::detail::confix_extractor::suffix(
proto::child_c<0>(spirit::argument1(component))), ctx);
result += ")[";
typedef typename
spirit::result_of::subject<Component>::type::director
director;
result += director::what(spirit::subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif