stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,145 @@
/*=============================================================================
Copyright (c) 2001-2011 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_DEBUG_HANDLER_DECEMBER_05_2008_0734PM)
#define BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
#include <boost/spirit/home/qi/operator/expect.hpp>
#include <boost/function.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/out.hpp>
#include <iostream>
namespace boost { namespace spirit { namespace qi
{
template <
typename Iterator, typename Context
, typename Skipper, typename F>
struct debug_handler
{
typedef function<
bool(Iterator& first, Iterator const& last
, Context& context
, Skipper const& skipper
)>
function_type;
debug_handler(
function_type subject_
, F f_
, std::string const& rule_name_)
: subject(subject_)
, f(f_)
, rule_name(rule_name_)
{
}
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
f(first, last, context, pre_parse, rule_name);
try // subject might throw an exception
{
if (subject(first, last, context, skipper))
{
f(first, last, context, successful_parse, rule_name);
return true;
}
f(first, last, context, failed_parse, rule_name);
}
catch (expectation_failure<Iterator> const& e)
{
f(first, last, context, failed_parse, rule_name);
boost::throw_exception(e);
}
return false;
}
function_type subject;
F f;
std::string rule_name;
};
template <typename Iterator
, typename T1, typename T2, typename T3, typename T4, typename F>
void debug(rule<Iterator, T1, T2, T3, T4>& r, F f)
{
typedef rule<Iterator, T1, T2, T3, T4> rule_type;
typedef
debug_handler<
Iterator
, typename rule_type::context_type
, typename rule_type::skipper_type
, F>
debug_handler;
r.f = debug_handler(r.f, f, r.name());
}
struct simple_trace;
namespace detail
{
// This class provides an extra level of indirection through a
// template to produce the simple_trace type. This way, the use
// of simple_trace below is hidden behind a dependent type, so
// that compilers eagerly type-checking template definitions
// won't complain that simple_trace is incomplete.
template<typename T>
struct get_simple_trace
{
typedef simple_trace type;
};
}
template <typename Iterator
, typename T1, typename T2, typename T3, typename T4>
void debug(rule<Iterator, T1, T2, T3, T4>& r)
{
typedef rule<Iterator, T1, T2, T3, T4> rule_type;
typedef
debug_handler<
Iterator
, typename rule_type::context_type
, typename rule_type::skipper_type
, simple_trace>
debug_handler;
typedef typename qi::detail::get_simple_trace<Iterator>::type trace;
r.f = debug_handler(r.f, trace(), r.name());
}
}}}
///////////////////////////////////////////////////////////////////////////////
// Utility macro for easy enabling of rule and grammar debugging
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
#if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
#define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
#else
#define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
#endif
#endif
#define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
BOOST_SPIRIT_DEBUG_NODE(name); \
/***/
#define BOOST_SPIRIT_DEBUG_NODES(seq) \
BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \
/***/
#endif
@@ -0,0 +1,24 @@
/*=============================================================================
Copyright (c) 2001-2011 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_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)
#define BOOST_SPIRIT_DEBUG_HANDLER_STATE_APR_21_2010_0733PM
#if defined(_MSC_VER)
#pragma once
#endif
namespace boost { namespace spirit { namespace qi
{
enum debug_handler_state
{
pre_parse
, successful_parse
, failed_parse
};
}}}
#endif
@@ -0,0 +1,53 @@
/*=============================================================================
Copyright (c) 2001-2011 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)
==============================================================================*/
#ifndef BOOST_PP_IS_ITERATING
#include <boost/preprocessor/iterate.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define BOOST_PP_FILENAME_1 \
<boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
#define BOOST_PP_ITERATION_LIMITS (1, SPIRIT_ARGUMENTS_LIMIT)
#include BOOST_PP_ITERATE()
///////////////////////////////////////////////////////////////////////////////
//
// Preprocessor vertical repetition code
//
///////////////////////////////////////////////////////////////////////////////
#else // defined(BOOST_PP_IS_ITERATING)
#define N BOOST_PP_ITERATION()
template <BOOST_PP_ENUM_PARAMS(N, typename A)>
typename lazy_enable_if_c<
(params_size == N)
, proto::terminal<
spirit::qi::parameterized_nonterminal<
parameterized_subject_type
, fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> >
>
>::type
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& f)) const
{
typedef fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> vector_type;
typedef spirit::qi::parameterized_nonterminal<
parameterized_subject_type, vector_type> parameterized_type;
typedef typename proto::terminal<parameterized_type>::type result_type;
return result_type::make(
parameterized_type(
this->get_parameterized_subject()
, fusion::make_vector(BOOST_PP_ENUM_PARAMS(N, f)))
);
}
#undef N
#endif // defined(BOOST_PP_IS_ITERATING)
@@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2009 Francois Barel
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_PARAMETERIZED_AUGUST_09_2009_0539AM)
#define BOOST_SPIRIT_PARAMETERIZED_AUGUST_09_2009_0539AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/ref.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/home/qi/parser.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// parameterized_nonterminal: parser representing the invocation of a
// nonterminal, passing inherited attributes
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Params>
struct parameterized_nonterminal
: parser<parameterized_nonterminal<Subject, Params> >
{
parameterized_nonterminal(Subject const& subject, Params const& params_)
: ref(subject), params(params_)
{
}
template <typename Context, typename Iterator>
struct attribute
// Forward to subject.
: Subject::template attribute<Context, Iterator> {};
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
// Forward to subject, passing the additional
// params argument to parse.
return ref.get().parse(first, last, context, skipper, attr_, params);
}
template <typename Context>
info what(Context& context) const
{
// Forward to subject.
return ref.get().what(context);
}
boost::reference_wrapper<Subject const> ref;
Params params;
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Params, typename Attribute
, typename Context, typename Iterator>
struct handles_container<qi::parameterized_nonterminal<Subject, Params>
, Attribute, Context, Iterator>
: handles_container<typename remove_const<Subject>::type
, Attribute, Context, Iterator>
{};
}}}
#endif
@@ -0,0 +1,87 @@
/*=============================================================================
Copyright (c) 2001-2011 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_PARSER_BINDER_DECEMBER_05_2008_0516_PM)
#define BOOST_SPIRIT_PARSER_BINDER_DECEMBER_05_2008_0516_PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/fusion/include/at.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
// parser_binder for plain rules
template <typename Parser, typename Auto>
struct parser_binder
{
parser_binder(Parser const& p_)
: p(p_) {}
template <typename Iterator, typename Skipper, typename Context>
bool call(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, mpl::true_) const
{
// If DeducedAuto is false (semantic actions is present), the
// component's attribute is unused.
return p.parse(first, last, context, skipper, unused);
}
template <typename Iterator, typename Skipper, typename Context>
bool call(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, mpl::false_) const
{
// If DeducedAuto is true (no semantic action), we pass the rule's
// attribute on to the component.
return p.parse(first, last, context, skipper
, fusion::at_c<0>(context.attributes));
}
template <typename Iterator, typename Skipper, typename Context>
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
// If Auto is false, we need to deduce whether to apply auto rule
typedef typename traits::has_semantic_action<Parser>::type auto_rule;
return call(first, last, context, skipper, auto_rule());
}
Parser p;
};
// parser_binder for auto rules
template <typename Parser>
struct parser_binder<Parser, mpl::true_>
{
parser_binder(Parser const& p_)
: p(p_) {}
template <typename Iterator, typename Skipper, typename Context>
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
// If Auto is true, we pass the rule's attribute on to the component.
return p.parse(first, last, context, skipper
, fusion::at_c<0>(context.attributes));
}
Parser p;
};
template <typename Auto, typename Parser>
inline parser_binder<Parser, Auto>
bind_parser(Parser const& p)
{
return parser_binder<Parser, Auto>(p);
}
}}}}
#endif
@@ -0,0 +1,176 @@
/*=============================================================================
Copyright (c) 2001-2011 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_ERROR_HANDLER_APRIL_29_2007_1042PM)
#define BOOST_SPIRIT_ERROR_HANDLER_APRIL_29_2007_1042PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/operator/expect.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/support/multi_pass_wrapper.hpp>
#include <boost/function.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace qi
{
enum error_handler_result
{
fail
, retry
, accept
, rethrow
};
namespace detail
{
// Helper template allowing to manage the inhibit clear queue flag in
// a multi_pass iterator. This is the usual specialization used for
// anything but a multi_pass iterator.
template <typename Iterator, bool active>
struct reset_on_exit
{
reset_on_exit(Iterator&) {}
};
// For 'retry' or 'fail' error handlers we need to inhibit the flushing
// of the internal multi_pass buffers which otherwise might happen at
// deterministic expectation points inside the encapsulated right hand
// side of rule.
template <typename Iterator>
struct reset_on_exit<Iterator, true>
{
reset_on_exit(Iterator& it)
: it_(it)
, inhibit_clear_queue_(spirit::traits::inhibit_clear_queue(it))
{
spirit::traits::inhibit_clear_queue(it_, true);
}
~reset_on_exit()
{
// reset inhibit flag in multi_pass on exit
spirit::traits::inhibit_clear_queue(it_, inhibit_clear_queue_);
}
Iterator& it_;
bool inhibit_clear_queue_;
};
}
template <
typename Iterator, typename Context
, typename Skipper, typename F, error_handler_result action
>
struct error_handler
{
typedef function<
bool(Iterator& first, Iterator const& last
, Context& context
, Skipper const& skipper
)>
function_type;
error_handler(function_type subject_, F f_)
: subject(subject_)
, f(f_)
{
}
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
typedef qi::detail::reset_on_exit<Iterator
, traits::is_multi_pass<Iterator>::value &&
(action == retry || action == fail)> on_exit_type;
on_exit_type on_exit(first);
for(;;)
{
try
{
Iterator i = first;
bool r = subject(i, last, context, skipper);
if (r)
first = i;
return r;
}
catch (expectation_failure<Iterator> const& x)
{
typedef
fusion::vector<
Iterator&
, Iterator const&
, Iterator const&
, info const&>
params;
error_handler_result r = action;
params args(first, last, x.first, x.what_);
f(args, context, r);
// The assertions below will fire if you are using a
// multi_pass as the underlying iterator, one of your error
// handlers forced its guarded rule to 'fail' or 'retry',
// and the error handler has not been instantiated using
// either 'fail' or 'retry' in the first place. Please see
// the multi_pass docs for more information.
switch (r)
{
case fail:
BOOST_ASSERT(
!traits::is_multi_pass<Iterator>::value ||
action == retry || action == fail);
return false;
case retry:
BOOST_ASSERT(
!traits::is_multi_pass<Iterator>::value ||
action == retry || action == fail);
continue;
case accept: return true;
case rethrow: boost::throw_exception(x);
}
}
}
return false;
}
function_type subject;
F f;
};
template <
error_handler_result action
, typename Iterator, typename T0, typename T1, typename T2
, typename F>
void on_error(rule<Iterator, T0, T1, T2>& r, F f)
{
typedef rule<Iterator, T0, T1, T2> rule_type;
typedef
error_handler<
Iterator
, typename rule_type::context_type
, typename rule_type::skipper_type
, F
, action>
error_handler;
r.f = error_handler(r.f, f);
}
// Error handling support when <action> is not
// specified. We will default to <fail>.
template <typename Iterator, typename T0, typename T1
, typename T2, typename F>
void on_error(rule<Iterator, T0, T1, T2>& r, F f)
{
on_error<fail>(r, f);
}
}}}
#endif
@@ -0,0 +1,132 @@
/*=============================================================================
Copyright (c) 2001-2011 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_GRAMMAR_FEBRUARY_19_2007_0236PM)
#define BOOST_SPIRIT_GRAMMAR_FEBRUARY_19_2007_0236PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
#include <boost/spirit/home/qi/reference.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace qi
{
template <
typename Iterator, typename T1, typename T2, typename T3
, typename T4>
struct grammar
: proto::extends<
typename proto::terminal<
reference<rule<Iterator, T1, T2, T3, T4> const>
>::type
, grammar<Iterator, T1, T2, T3, T4>
>
, parser<grammar<Iterator, T1, T2, T3, T4> >
, noncopyable
{
typedef Iterator iterator_type;
typedef rule<Iterator, T1, T2, T3, T4> start_type;
typedef typename start_type::sig_type sig_type;
typedef typename start_type::locals_type locals_type;
typedef typename start_type::skipper_type skipper_type;
typedef typename start_type::encoding_type encoding_type;
typedef grammar<Iterator, T1, T2, T3, T4> base_type;
typedef reference<start_type const> reference_;
typedef typename proto::terminal<reference_>::type terminal;
static size_t const params_size = start_type::params_size;
template <typename Context, typename Iterator_>
struct attribute
{
typedef typename start_type::attr_type type;
};
grammar(
start_type const& start
, std::string const& name = "unnamed-grammar")
: proto::extends<terminal, base_type>(terminal::make(reference_(start)))
, name_(name)
{}
// This constructor is used to catch if the start rule is not
// compatible with the grammar.
template <typename Iterator_,
typename T1_, typename T2_, typename T3_, typename T4_>
grammar(
rule<Iterator_, T1_, T2_, T3_, T4_> const&
, std::string const& = "unnamed-grammar")
{
// If you see the assertion below failing then the start rule
// passed to the constructor of the grammar is not compatible with
// the grammar (i.e. it uses different template parameters).
BOOST_SPIRIT_ASSERT_MSG(
(is_same<start_type, rule<Iterator_, T1_, T2_, T3_, T4_> >::value)
, incompatible_start_rule, (rule<Iterator_, T1_, T2_, T3_, T4_>));
}
std::string name() const
{
return name_;
}
void name(std::string const& str)
{
name_ = str;
}
template <typename Context, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
return this->proto_base().child0.parse(
first, last, context, skipper, attr_);
}
template <typename Context>
info what(Context&) const
{
return info(name_);
}
// bring in the operator() overloads
start_type const& get_parameterized_subject() const
{ return this->proto_base().child0.ref.get(); }
typedef start_type parameterized_subject_type;
#include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
std::string name_;
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <
typename IteratorA, typename IteratorB, typename Attribute
, typename Context, typename T1, typename T2, typename T3, typename T4>
struct handles_container<
qi::grammar<IteratorA, T1, T2, T3, T4>, Attribute, Context, IteratorB>
: traits::is_container<
typename attribute_of<
qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type
>
{};
}}}
#endif
@@ -0,0 +1,31 @@
// Copyright (c) 2001-2011 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_NONTERMINAL_FWD_DEC_24_2010_1105PM)
#define BOOST_SPIRIT_QI_NONTERMINAL_FWD_DEC_24_2010_1105PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi
{
// forward declaration only
template <
typename Iterator, typename T1 = unused_type
, typename T2 = unused_type, typename T3 = unused_type
, typename T4 = unused_type>
struct rule;
template <
typename Iterator, typename T1 = unused_type
, typename T2 = unused_type, typename T3 = unused_type
, typename T4 = unused_type>
struct grammar;
}}}
#endif
@@ -0,0 +1,440 @@
/*=============================================================================
Copyright (c) 2001-2011 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_RULE_FEBRUARY_12_2007_1020AM)
#define BOOST_SPIRIT_RULE_FEBRUARY_12_2007_1020AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/function.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/as_list.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/spirit/home/support/context.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/home/qi/reference.hpp>
#include <boost/spirit/home/qi/nonterminal/detail/parameterized.hpp>
#include <boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp>
#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
#include <boost/spirit/home/qi/skip_over.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace spirit { namespace qi
{
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
using spirit::_pass_type;
using spirit::_val_type;
using spirit::_a_type;
using spirit::_b_type;
using spirit::_c_type;
using spirit::_d_type;
using spirit::_e_type;
using spirit::_f_type;
using spirit::_g_type;
using spirit::_h_type;
using spirit::_i_type;
using spirit::_j_type;
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using spirit::_pass;
using spirit::_val;
using spirit::_a;
using spirit::_b;
using spirit::_c;
using spirit::_d;
using spirit::_e;
using spirit::_f;
using spirit::_g;
using spirit::_h;
using spirit::_i;
using spirit::_j;
#endif
using spirit::info;
using spirit::locals;
template <
typename Iterator, typename T1, typename T2, typename T3
, typename T4>
struct rule
: proto::extends<
typename proto::terminal<
reference<rule<Iterator, T1, T2, T3, T4> const>
>::type
, rule<Iterator, T1, T2, T3, T4>
>
, parser<rule<Iterator, T1, T2, T3, T4> >
{
typedef Iterator iterator_type;
typedef rule<Iterator, T1, T2, T3, T4> this_type;
typedef reference<this_type const> reference_;
typedef typename proto::terminal<reference_>::type terminal;
typedef proto::extends<terminal, this_type> base_type;
typedef mpl::vector<T1, T2, T3, T4> template_params;
// The rule's locals_type: a sequence of types to be used as local variables
typedef typename
spirit::detail::extract_locals<template_params>::type
locals_type;
// The rule's skip-parser type
typedef typename
spirit::detail::extract_component<
qi::domain, template_params>::type
skipper_type;
// The rule's encoding type
typedef typename
spirit::detail::extract_encoding<template_params>::type
encoding_type;
// The rule's signature
typedef typename
spirit::detail::extract_sig<template_params, encoding_type, qi::domain>::type
sig_type;
// This is the rule's attribute type
typedef typename
spirit::detail::attr_from_sig<sig_type>::type
attr_type;
typedef typename add_reference<attr_type>::type attr_reference_type;
// parameter_types is a sequence of types passed as parameters to the rule
typedef typename
spirit::detail::params_from_sig<sig_type>::type
parameter_types;
static size_t const params_size =
fusion::result_of::size<parameter_types>::type::value;
typedef context<
fusion::cons<attr_reference_type, parameter_types>
, locals_type>
context_type;
typedef function<
bool(Iterator& first, Iterator const& last
, context_type& context
, skipper_type const& skipper
)>
function_type;
typedef typename
mpl::if_<
is_same<encoding_type, unused_type>
, unused_type
, tag::char_code<tag::encoding, encoding_type>
>::type
encoding_modifier_type;
explicit rule(std::string const& name = "unnamed-rule")
: base_type(terminal::make(reference_(*this)))
, name_(name)
{
}
rule(rule const& rhs)
: base_type(terminal::make(reference_(*this)))
, name_(rhs.name_)
, f(rhs.f)
{
}
template <typename Auto, typename Expr>
static void define(rule& /*lhs*/, Expr const& /*expr*/, mpl::false_)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
}
template <typename Auto, typename Expr>
static void define(rule& lhs, Expr const& expr, mpl::true_)
{
lhs.f = detail::bind_parser<Auto>(
compile<qi::domain>(expr, encoding_modifier_type()));
}
template <typename Expr>
rule(Expr const& expr, std::string const& name = "unnamed-rule")
: base_type(terminal::make(reference_(*this)))
, name_(name)
{
define<mpl::false_>(*this, expr, traits::matches<qi::domain, Expr>());
}
rule& operator=(rule const& rhs)
{
// The following assertion fires when you try to initialize a rule
// from an uninitialized one. Did you mean to refer to the right
// hand side rule instead of assigning from it? In this case you
// should write lhs = rhs.alias();
BOOST_ASSERT(rhs.f && "Did you mean rhs.alias() instead of rhs?");
f = rhs.f;
name_ = rhs.name_;
return *this;
}
std::string const& name() const
{
return name_;
}
void name(std::string const& str)
{
name_ = str;
}
template <typename Expr>
rule& operator=(Expr const& expr)
{
define<mpl::false_>(*this, expr, traits::matches<qi::domain, Expr>());
return *this;
}
// VC7.1 has problems to resolve 'rule' without explicit template parameters
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1400)
// g++ 3.3 barfs if this is a member function :(
template <typename Expr>
friend rule& operator%=(rule& r, Expr const& expr)
{
define<mpl::true_>(r, expr, traits::matches<qi::domain, Expr>());
return r;
}
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
// non-const version needed to suppress proto's %= kicking in
template <typename Expr>
friend rule& operator%=(rule& r, Expr& expr)
{
return r %= static_cast<Expr const&>(expr);
}
#else
// for rvalue references
template <typename Expr>
friend rule& operator%=(rule& r, Expr&& expr)
{
define<mpl::true_>(r, expr, traits::matches<qi::domain, Expr>());
return r;
}
#endif
#else
// both friend functions have to be defined out of class as VC7.1
// will complain otherwise
template <typename OutputIterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr const& expr);
// non-const version needed to suppress proto's %= kicking in
template <typename OutputIterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr& expr);
#endif
template <typename Context, typename Iterator_>
struct attribute
{
typedef attr_type type;
};
template <typename Context, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr_param) const
{
if (f)
{
// do a preskip if this is an implied lexeme
if (is_same<skipper_type, unused_type>::value)
qi::skip_over(first, last, skipper);
typedef traits::make_attribute<attr_type, Attribute> make_attribute;
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
typename make_attribute::type, attr_type, domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr_param);
typename transform::type attr_ = transform::pre(made_attr);
// If you are seeing a compilation error here, you are probably
// trying to use a rule or a grammar which has inherited
// attributes, without passing values for them.
context_type context(attr_);
// If you are seeing a compilation error here stating that the
// fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
{
// do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr_param, attr_);
return true;
}
// inform attribute transformation of failed rhs
traits::fail_transform(attr_param, attr_);
}
return false;
}
template <typename Context, typename Skipper
, typename Attribute, typename Params>
bool parse(Iterator& first, Iterator const& last
, Context& caller_context, Skipper const& skipper
, Attribute& attr_param, Params const& params) const
{
if (f)
{
// do a preskip if this is an implied lexeme
if (is_same<skipper_type, unused_type>::value)
qi::skip_over(first, last, skipper);
typedef traits::make_attribute<attr_type, Attribute> make_attribute;
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
typename make_attribute::type, attr_type, domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr_param);
typename transform::type attr_ = transform::pre(made_attr);
// If you are seeing a compilation error here, you are probably
// trying to use a rule or a grammar which has inherited
// attributes, passing values of incompatible types for them.
context_type context(attr_, params, caller_context);
// If you are seeing a compilation error here stating that the
// fourth parameter can't be converted to a required target type
// then you are probably trying to use a rule or a grammar with
// an incompatible skipper type.
if (f(first, last, context, skipper))
{
// do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr_param, attr_);
return true;
}
// inform attribute transformation of failed rhs
traits::fail_transform(attr_param, attr_);
}
return false;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info(name_);
}
reference_ alias() const
{
return reference_(*this);
}
typename proto::terminal<this_type>::type copy() const
{
typename proto::terminal<this_type>::type result = {*this};
return result;
}
// bring in the operator() overloads
rule const& get_parameterized_subject() const { return *this; }
typedef rule parameterized_subject_type;
#include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
std::string name_;
function_type f;
};
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
template <typename OutputIterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr const& expr)
{
// Report invalid expression error as early as possible.
// If you got an error_invalid_expression error message here,
// then the expression (expr) is not a valid spirit qi expression.
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
typedef typename
rule<OutputIterator_, T1_, T2_, T3_, T4_>::encoding_modifier_type
encoding_modifier_type;
r.f = detail::bind_parser<mpl::true_>(
compile<qi::domain>(expr, encoding_modifier_type()));
return r;
}
template <typename Iterator_, typename T1_, typename T2_
, typename T3_, typename T4_, typename Expr>
rule<Iterator_, T1_, T2_, T3_, T4_>& operator%=(
rule<Iterator_, T1_, T2_, T3_, T4_>& r, Expr& expr)
{
return r %= static_cast<Expr const&>(expr);
}
#endif
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <
typename IteratorA, typename IteratorB, typename Attribute
, typename Context, typename T1, typename T2, typename T3, typename T4>
struct handles_container<
qi::rule<IteratorA, T1, T2, T3, T4>, Attribute, Context, IteratorB>
: traits::is_container<
typename attribute_of<
qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
>::type
>
{};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,135 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2001-2011 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_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
#define BOOST_SPIRIT_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
#include <boost/fusion/include/out.hpp>
#include <iostream>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/spirit/home/support/attributes.hpp>
// The stream to use for debug output
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#endif
// number of tokens to print while debugging
#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
#endif
// number of spaces to indent
#if !defined(BOOST_SPIRIT_DEBUG_INDENT)
#define BOOST_SPIRIT_DEBUG_INDENT 2
#endif
namespace boost { namespace spirit { namespace qi
{
namespace detail
{
template<typename Char>
inline void token_printer(std::ostream& o, Char c)
{
// allow to customize the token printer routine
spirit::traits::print_token(o, c);
}
}
struct simple_trace
{
int& get_indent() const
{
static int indent = 0;
return indent;
}
void print_indent(int n) const
{
n *= BOOST_SPIRIT_DEBUG_INDENT;
for (int i = 0; i != n; ++i)
BOOST_SPIRIT_DEBUG_OUT << ' ';
}
template <typename Iterator>
void print_some(
char const* tag
, int /*indent*/
, Iterator first, Iterator const& last) const
{
print_indent(get_indent());
BOOST_SPIRIT_DEBUG_OUT << '<' << tag << '>';
int const n = BOOST_SPIRIT_DEBUG_PRINT_SOME;
for (int i = 0; first != last && i != n && *first; ++i, ++first)
detail::token_printer(BOOST_SPIRIT_DEBUG_OUT, *first);
BOOST_SPIRIT_DEBUG_OUT << "</" << tag << '>' << std::endl;
// $$$ FIXME convert invalid xml characters (e.g. '<') to valid
// character entities. $$$
}
template <typename Iterator, typename Context, typename State>
void operator()(
Iterator const& first
, Iterator const& last
, Context const& context
, State state
, std::string const& rule_name) const
{
switch (state)
{
case pre_parse:
print_indent(get_indent()++);
BOOST_SPIRIT_DEBUG_OUT
<< '<' << rule_name << '>'
<< std::endl;
print_some("try", get_indent(), first, last);
break;
case successful_parse:
print_some("success", get_indent(), first, last);
print_indent(get_indent());
BOOST_SPIRIT_DEBUG_OUT
<< "<attributes>";
traits::print_attribute(
BOOST_SPIRIT_DEBUG_OUT,
context.attributes
);
BOOST_SPIRIT_DEBUG_OUT
<< "</attributes>";
if (!fusion::empty(context.locals))
BOOST_SPIRIT_DEBUG_OUT
<< "<locals>"
<< context.locals
<< "</locals>";
BOOST_SPIRIT_DEBUG_OUT << std::endl;
print_indent(--get_indent());
BOOST_SPIRIT_DEBUG_OUT
<< "</" << rule_name << '>'
<< std::endl;
break;
case failed_parse:
print_indent(get_indent());
BOOST_SPIRIT_DEBUG_OUT << "<fail/>" << std::endl;
print_indent(--get_indent());
BOOST_SPIRIT_DEBUG_OUT
<< "</" << rule_name << '>'
<< std::endl;
break;
}
}
};
}}}
#endif
@@ -0,0 +1,83 @@
/*=============================================================================
Copyright (c) 2001-2011 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_SUCCESS_HANDLER_FEBRUARY_25_2011_1051AM)
#define BOOST_SPIRIT_SUCCESS_HANDLER_FEBRUARY_25_2011_1051AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/function.hpp>
namespace boost { namespace spirit { namespace qi
{
template <
typename Iterator, typename Context
, typename Skipper, typename F
>
struct success_handler
{
typedef function<
bool(Iterator& first, Iterator const& last
, Context& context
, Skipper const& skipper
)>
function_type;
success_handler(function_type subject_, F f_)
: subject(subject_)
, f(f_)
{
}
bool operator()(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper) const
{
Iterator i = first;
bool r = subject(i, last, context, skipper);
if (r)
{
typedef
fusion::vector<
Iterator&
, Iterator const&
, Iterator const&>
params;
skip_over(first, last, skipper);
params args(first, last, i);
f(args, context);
first = i;
}
return r;
}
function_type subject;
F f;
};
template <
typename Iterator, typename T0, typename T1, typename T2
, typename F>
void on_success(rule<Iterator, T0, T1, T2>& r, F f)
{
typedef rule<Iterator, T0, T1, T2> rule_type;
typedef
success_handler<
Iterator
, typename rule_type::context_type
, typename rule_type::skipper_type
, F>
success_handler;
r.f = success_handler(r.f, f);
}
}}}
#endif