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,18 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// 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(SPIRIT_REPOSITORY_KARMA_APR_28_2009_1259PM)
#define SPIRIT_REPOSITORY_KARMA_APR_28_2009_1259PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/repository/home/karma/directive.hpp>
#include <boost/spirit/repository/home/karma/nonterminal.hpp>
#endif
@@ -0,0 +1,17 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// 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(SPIRIT_REPOSITORY_KARMA_DIRECTIVE_APR_28_2009_1258PM)
#define SPIRIT_REPOSITORY_KARMA_DIRECTIVE_APR_28_2009_1258PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/repository/home/karma/directive/confix.hpp>
#endif
@@ -0,0 +1,140 @@
// 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_REPOSITORY_KARMA_CONFIX_AUG_19_2008_1041AM)
#define BOOST_SPIRIT_REPOSITORY_KARMA_CONFIX_AUG_19_2008_1041AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/repository/home/support/confix.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/mpl/or.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables confix(..., ...)[]
template <typename Prefix, typename Suffix>
struct use_directive<karma::domain
, terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> > >
: mpl::true_ {};
// enables *lazy* confix(..., ...)[g]
template <>
struct use_lazy_directive<karma::domain, repository::tag::confix, 2>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace repository { namespace karma
{
using repository::confix_type;
using repository::confix;
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Prefix, typename Suffix>
struct confix_generator
: spirit::karma::primitive_generator<confix_generator<Subject, Prefix, Suffix> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
confix_generator(Subject const& subject, Prefix const& prefix
, Suffix const& suffix)
: subject(subject), prefix(prefix), suffix(suffix) {}
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename Context, typename Delimiter
, typename Attribute>
bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
, Attribute const& attr) const
{
// generate the prefix, the embedded item and the suffix
return prefix.generate(sink, ctx, d, unused) &&
subject.generate(sink, ctx, d, attr) &&
suffix.generate(sink, ctx, d, unused);
}
template <typename Context>
info what(Context const& ctx) const
{
return info("confix", subject.what(ctx));
}
Subject subject;
Prefix prefix;
Suffix suffix;
};
}}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
///////////////////////////////////////////////////////////////////////////
// Generator generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
// creates confix(..., ...)[] directive generator
template <typename Prefix, typename Suffix, typename Subject
, typename Modifiers>
struct make_directive<
terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> >
, Subject, Modifiers>
{
typedef typename
result_of::compile<karma::domain, Prefix, Modifiers>::type
prefix_type;
typedef typename
result_of::compile<karma::domain, Suffix, Modifiers>::type
suffix_type;
typedef repository::karma::confix_generator<
Subject, prefix_type, suffix_type> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<karma::domain>(fusion::at_c<0>(term.args), modifiers)
, compile<karma::domain>(fusion::at_c<1>(term.args), modifiers));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
template <typename Subject, typename Prefix, typename Suffix>
struct has_semantic_action<
repository::karma::confix_generator<Subject, Prefix, Suffix> >
: mpl::or_<
has_semantic_action<Subject>
, has_semantic_action<Prefix>
, has_semantic_action<Suffix>
> {};
}}}
#endif
@@ -0,0 +1,18 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// 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(SPIRIT_REPOSITORY_KARMA_NONTERMINAL_AUG_12_2009_0807PM)
#define SPIRIT_REPOSITORY_KARMA_NONTERMINAL_AUG_12_2009_0807PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/repository/home/karma/nonterminal/subrule.hpp>
#endif
@@ -0,0 +1,564 @@
// Copyright (c) 2009 Francois Barel
// Copyright (c) 2001-2011 Joel de Guzman
// Copyright (c) 2001-2012 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_REPOSITORY_KARMA_SUBRULE_AUGUST_12_2009_0813PM)
#define BOOST_SPIRIT_REPOSITORY_KARMA_SUBRULE_AUGUST_12_2009_0813PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/meta_compiler.hpp>
#include <boost/spirit/home/karma/generator.hpp>
#include <boost/spirit/home/karma/reference.hpp>
#include <boost/spirit/home/karma/nonterminal/detail/generator_binder.hpp>
#include <boost/spirit/home/karma/nonterminal/detail/parameterized.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/karma/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/repository/home/support/subrule_context.hpp>
#include <boost/fusion/include/as_map.hpp>
#include <boost/fusion/include/at_key.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/has_key.hpp>
#include <boost/fusion/include/join.hpp>
#include <boost/fusion/include/make_map.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace repository { namespace karma
{
///////////////////////////////////////////////////////////////////////////
// subrule_group:
// - generator representing a group of subrule definitions (one or more),
// invokes first subrule on entry,
// - also a Proto terminal, so that a group behaves like any Spirit
// expression.
///////////////////////////////////////////////////////////////////////////
template <typename Defs>
struct subrule_group
: proto::extends<
typename proto::terminal<
spirit::karma::reference<subrule_group<Defs> const>
>::type
, subrule_group<Defs>
>
, spirit::karma::generator<subrule_group<Defs> >
{
struct properties
// Forward to first subrule.
: remove_reference<
typename fusion::result_of::front<Defs>::type
>::type::second_type::subject_type::properties {};
// Fusion associative sequence, associating each subrule ID in this
// group (as an MPL integral constant) with its definition
typedef Defs defs_type;
typedef subrule_group<Defs> this_type;
typedef spirit::karma::reference<this_type const> reference_;
typedef typename proto::terminal<reference_>::type terminal;
typedef proto::extends<terminal, this_type> base_type;
static size_t const params_size =
// Forward to first subrule.
remove_reference<
typename fusion::result_of::front<Defs>::type
>::type::second_type::params_size;
subrule_group(subrule_group const& rhs)
: base_type(terminal::make(reference_(*this)))
, defs(rhs.defs)
{
}
explicit subrule_group(Defs const& defs)
: base_type(terminal::make(reference_(*this)))
, defs(defs)
{
}
// from a subrule ID, get the type of a reference to its definition
template <int ID>
struct def_type
{
typedef mpl::int_<ID> id_type;
// If you are seeing a compilation error here, you are trying
// to use a subrule which was not defined in this group.
BOOST_SPIRIT_ASSERT_MSG(
(fusion::result_of::has_key<
defs_type const, id_type>::type::value)
, subrule_used_without_being_defined, (mpl::int_<ID>));
typedef typename
fusion::result_of::at_key<defs_type const, id_type>::type
type;
};
// from a subrule ID, get a reference to its definition
template <int ID>
typename def_type<ID>::type def() const
{
return fusion::at_key<mpl::int_<ID> >(defs);
}
template <typename Context, typename Iterator>
struct attribute
// Forward to first subrule.
: mpl::identity<
typename remove_reference<
typename fusion::result_of::front<Defs>::type
>::type::second_type::attr_type> {};
template <typename OutputIterator, typename Context
, typename Delimiter, typename Attribute>
bool generate(OutputIterator& sink, Context& context
, Delimiter const& delimiter, Attribute const& attr) const
{
// Forward to first subrule.
return generate_subrule(fusion::front(defs).second
, sink, context, delimiter, attr);
}
template <typename OutputIterator, typename Context
, typename Delimiter, typename Attribute
, typename Params>
bool generate(OutputIterator& sink, Context& context
, Delimiter const& delimiter, Attribute const& attr
, Params const& params) const
{
// Forward to first subrule.
return generate_subrule(fusion::front(defs).second
, sink, context, delimiter, attr, params);
}
template <int ID, typename OutputIterator, typename Context
, typename Delimiter, typename Attribute>
bool generate_subrule_id(OutputIterator& sink
, Context& context, Delimiter const& delimiter
, Attribute const& attr) const
{
return generate_subrule(def<ID>()
, sink, context, delimiter, attr);
}
template <int ID, typename OutputIterator, typename Context
, typename Delimiter, typename Attribute, typename Params>
bool generate_subrule_id(OutputIterator& sink
, Context& context, Delimiter const& delimiter
, Attribute const& attr, Params const& params) const
{
return generate_subrule(def<ID>()
, sink, context, delimiter, attr, params);
}
template <typename Def, typename OutputIterator, typename Context
, typename Delimiter, typename Attribute>
bool generate_subrule(Def const& def, OutputIterator& sink
, Context& /*caller_context*/, Delimiter const& delimiter
, Attribute const& attr) const
{
// compute context type for this subrule
typedef typename Def::locals_type subrule_locals_type;
typedef typename Def::attr_type subrule_attr_type;
typedef typename Def::attr_reference_type subrule_attr_reference_type;
typedef typename Def::parameter_types subrule_parameter_types;
typedef
subrule_context<
this_type
, fusion::cons<
subrule_attr_reference_type, subrule_parameter_types>
, subrule_locals_type
>
context_type;
// Create an attribute if none is supplied.
typedef traits::make_attribute<subrule_attr_type, Attribute>
make_attribute;
// If you are seeing a compilation error here, you are probably
// trying to use a subrule which has inherited attributes,
// without passing values for them.
context_type context(*this
, traits::pre_transform<spirit::karma::domain, subrule_attr_type>(
make_attribute::call(attr)));
return def.binder(sink, context, delimiter);
}
template <typename Def, typename OutputIterator, typename Context
, typename Delimiter, typename Attribute, typename Params>
bool generate_subrule(Def const& def, OutputIterator& sink
, Context& caller_context, Delimiter const& delimiter
, Attribute const& attr, Params const& params) const
{
// compute context type for this subrule
typedef typename Def::locals_type subrule_locals_type;
typedef typename Def::attr_type subrule_attr_type;
typedef typename Def::attr_reference_type subrule_attr_reference_type;
typedef typename Def::parameter_types subrule_parameter_types;
typedef
subrule_context<
this_type
, fusion::cons<
subrule_attr_reference_type, subrule_parameter_types>
, subrule_locals_type
>
context_type;
// Create an attribute if none is supplied.
typedef traits::make_attribute<subrule_attr_type, Attribute>
make_attribute;
// If you are seeing a compilation error here, you are probably
// trying to use a subrule which has inherited attributes,
// passing values of incompatible types for them.
context_type context(*this
, traits::pre_transform<spirit::karma::domain, subrule_attr_type>(
make_attribute::call(attr)), params, caller_context);
return def.binder(sink, context, delimiter);
}
template <typename Context>
info what(Context& context) const
{
// Forward to first subrule.
return fusion::front(defs).second.binder.g.what(context);
}
template <typename Defs2>
subrule_group<
typename fusion::result_of::as_map<
typename fusion::result_of::join<
Defs const, Defs2 const>::type>::type>
operator,(subrule_group<Defs2> const& other) const
{
typedef subrule_group<
typename fusion::result_of::as_map<
typename fusion::result_of::join<
Defs const, Defs2 const>::type>::type> result_type;
return result_type(fusion::as_map(fusion::join(defs, other.defs)));
}
// bring in the operator() overloads
this_type const& get_parameterized_subject() const { return *this; }
typedef this_type parameterized_subject_type;
#include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp>
Defs defs;
};
///////////////////////////////////////////////////////////////////////////
// subrule_definition: holds one particular definition of a subrule
///////////////////////////////////////////////////////////////////////////
template <
int ID_
, typename Locals
, typename Attr
, typename AttrRef
, typename Parameters
, size_t ParamsSize
, typename Subject
, bool Auto_
>
struct subrule_definition
{
typedef mpl::int_<ID_> id_type;
BOOST_STATIC_CONSTANT(int, ID = ID_);
typedef Locals locals_type;
typedef Attr attr_type;
typedef AttrRef attr_reference_type;
typedef Parameters parameter_types;
static size_t const params_size = ParamsSize;
typedef Subject subject_type;
typedef mpl::bool_<Auto_> auto_type;
BOOST_STATIC_CONSTANT(bool, Auto = Auto_);
typedef spirit::karma::detail::generator_binder<
Subject, auto_type> binder_type;
subrule_definition(Subject const& subject, std::string const& name)
: binder(subject), name(name)
{
}
binder_type const binder;
std::string const name;
};
///////////////////////////////////////////////////////////////////////////
// subrule placeholder:
// - on subrule definition: helper for creation of subrule_group,
// - on subrule invocation: Proto terminal and generator.
///////////////////////////////////////////////////////////////////////////
template <
int ID_
, typename T1 = unused_type
, typename T2 = unused_type
>
struct subrule
: proto::extends<
typename proto::terminal<
spirit::karma::reference<subrule<ID_, T1, T2> const>
>::type
, subrule<ID_, T1, T2>
>
, spirit::karma::generator<subrule<ID_, T1, T2> >
{
//FIXME should go fetch the real properties of this subrule's definition in the current context, but we don't
// have the context here (properties would need to be 'template<typename Context> struct properties' instead)
typedef mpl::int_<
spirit::karma::generator_properties::all_properties> properties;
typedef mpl::int_<ID_> id_type;
BOOST_STATIC_CONSTANT(int, ID = ID_);
typedef subrule<ID_, T1, T2> this_type;
typedef spirit::karma::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> template_params;
// locals_type is a sequence of types to be used as local variables
typedef typename
spirit::detail::extract_locals<template_params>::type
locals_type;
typedef typename
spirit::detail::extract_sig<template_params>::type
sig_type;
// This is the subrule's attribute type
typedef typename
spirit::detail::attr_from_sig<sig_type>::type
attr_type;
typedef typename add_reference<
typename add_const<attr_type>::type>::type attr_reference_type;
// parameter_types is a sequence of types passed as parameters to the subrule
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;
explicit subrule(std::string const& name_ = "unnamed-subrule")
: base_type(terminal::make(reference_(*this)))
, name_(name_)
{
}
// compute type of this subrule's definition for expr type Expr
template <typename Expr, bool Auto>
struct def_type_helper
{
// 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 karma expression.
BOOST_SPIRIT_ASSERT_MATCH(spirit::karma::domain, Expr);
typedef typename result_of::compile<
spirit::karma::domain, Expr>::type subject_type;
typedef subrule_definition<
ID_
, locals_type
, attr_type
, attr_reference_type
, parameter_types
, params_size
, subject_type
, Auto
> const type;
};
// compute type of subrule group containing only this
// subrule's definition for expr type Expr
template <typename Expr, bool Auto>
struct group_type_helper
{
typedef typename def_type_helper<Expr, Auto>::type def_type;
// create Defs map with only one entry: (ID -> def)
typedef typename
#ifndef BOOST_FUSION_HAS_VARIADIC_MAP
fusion::result_of::make_map<id_type, def_type>::type
#else
fusion::result_of::make_map<id_type>::template apply<def_type>::type
#endif
defs_type;
typedef subrule_group<defs_type> type;
};
template <typename Expr>
typename group_type_helper<Expr, false>::type
operator=(Expr const& expr) const
{
typedef group_type_helper<Expr, false> helper;
typedef typename helper::def_type def_type;
typedef typename helper::type result_type;
return result_type(fusion::make_map<id_type>(
def_type(compile<spirit::karma::domain>(expr), name_)));
}
template <typename Expr>
friend typename group_type_helper<Expr, true>::type
operator%=(subrule const& sr, Expr const& expr)
{
typedef group_type_helper<Expr, true> helper;
typedef typename helper::def_type def_type;
typedef typename helper::type result_type;
return result_type(fusion::make_map<id_type>(
def_type(compile<spirit::karma::domain>(expr), sr.name_)));
}
// non-const versions needed to suppress proto's %= kicking in
template <typename Expr>
friend typename group_type_helper<Expr, true>::type
operator%=(subrule const& sr, Expr& expr)
{
return operator%=(
sr
, static_cast<Expr const&>(expr));
}
template <typename Expr>
friend typename group_type_helper<Expr, true>::type
operator%=(subrule& sr, Expr const& expr)
{
return operator%=(
static_cast<subrule const&>(sr)
, expr);
}
template <typename Expr>
friend typename group_type_helper<Expr, true>::type
operator%=(subrule& sr, Expr& expr)
{
return operator%=(
static_cast<subrule const&>(sr)
, static_cast<Expr const&>(expr));
}
std::string const& name() const
{
return name_;
}
void name(std::string const& str)
{
name_ = str;
}
template <typename Context, typename Iterator>
struct attribute
{
typedef attr_type type;
};
template <typename OutputIterator, typename Group
, typename Attributes, typename Locals
, typename Delimiter, typename Attribute>
bool generate(OutputIterator& sink
, subrule_context<Group, Attributes, Locals>& context
, Delimiter const& delimiter, Attribute const& attr) const
{
return context.group.template generate_subrule_id<ID_>(
sink, context, delimiter, attr);
}
template <typename OutputIterator, typename Context
, typename Delimiter, typename Attribute>
bool generate(OutputIterator& /*sink*/
, Context& /*context*/
, Delimiter const& /*delimiter*/, Attribute const& /*attr*/) const
{
// If you are seeing a compilation error here, you are trying
// to use a subrule as a generator outside of a subrule group.
BOOST_SPIRIT_ASSERT_FAIL(OutputIterator
, subrule_used_outside_subrule_group, (id_type));
return false;
}
template <typename OutputIterator, typename Group
, typename Attributes, typename Locals
, typename Delimiter, typename Attribute
, typename Params>
bool generate(OutputIterator& sink
, subrule_context<Group, Attributes, Locals>& context
, Delimiter const& delimiter, Attribute const& attr
, Params const& params) const
{
return context.group.template generate_subrule_id<ID_>(
sink, context, delimiter, attr, params);
}
template <typename OutputIterator, typename Context
, typename Delimiter, typename Attribute
, typename Params>
bool generate(OutputIterator& /*sink*/
, Context& /*context*/
, Delimiter const& /*delimiter*/, Attribute const& /*attr*/
, Params const& /*params*/) const
{
// If you are seeing a compilation error here, you are trying
// to use a subrule as a generator outside of a subrule group.
BOOST_SPIRIT_ASSERT_FAIL(OutputIterator
, subrule_used_outside_subrule_group, (id_type));
return false;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info(name_);
}
// bring in the operator() overloads
this_type const& get_parameterized_subject() const { return *this; }
typedef this_type parameterized_subject_type;
#include <boost/spirit/home/karma/nonterminal/detail/fcall.hpp>
std::string name_;
};
}}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,20 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// 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(SPIRIT_REPOSITORY_QI_APR_28_2009_1258PM)
#define SPIRIT_REPOSITORY_QI_APR_28_2009_1258PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/repository/home/qi/primitive.hpp>
#include <boost/spirit/repository/home/qi/directive.hpp>
#include <boost/spirit/repository/home/qi/nonterminal.hpp>
#include <boost/spirit/repository/home/qi/operator.hpp>
#endif
@@ -0,0 +1,20 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// 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(SPIRIT_REPOSITORY_QI_DIRECTIVE_APR_28_2009_1258PM)
#define SPIRIT_REPOSITORY_QI_DIRECTIVE_APR_28_2009_1258PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/repository/home/qi/directive/distinct.hpp>
#include <boost/spirit/repository/home/qi/directive/confix.hpp>
#include <boost/spirit/repository/home/qi/directive/kwd.hpp>
#include <boost/spirit/repository/home/qi/directive/seek.hpp>
#endif
@@ -0,0 +1,150 @@
// Copyright (c) 2009 Chris Hoeppler
//
// 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_REPOSITORY_QI_CONFIX_JUN_22_2009_1041AM)
#define BOOST_SPIRIT_REPOSITORY_QI_CONFIX_JUN_22_2009_1041AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/repository/home/support/confix.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/mpl/or.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables confix(..., ...)[]
template <typename Prefix, typename Suffix>
struct use_directive<qi::domain
, terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> > >
: mpl::true_ {};
// enables *lazy* confix(..., ...)[]
template <>
struct use_lazy_directive<qi::domain, repository::tag::confix, 2>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace repository { namespace qi
{
using repository::confix_type;
using repository::confix;
///////////////////////////////////////////////////////////////////////////
// the confix() generated parser
template <typename Subject, typename Prefix, typename Suffix>
struct confix_parser
: spirit::qi::unary_parser<confix_parser<Subject, Prefix, Suffix> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<subject_type, Context, Iterator>
{};
confix_parser(Subject const& subject, Prefix const& prefix
, Suffix const& suffix)
: subject(subject), prefix(prefix), suffix(suffix) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
Iterator iter = first;
if (!(prefix.parse(iter, last, context, skipper, unused) &&
subject.parse(iter, last, context, skipper, attr) &&
suffix.parse(iter, last, context, skipper, unused)))
{
return false;
}
first = iter;
return true;
}
template <typename Context>
info what(Context const& ctx) const
{
return info("confix", subject.what(ctx));
}
Subject subject;
Prefix prefix;
Suffix suffix;
};
}}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
// creates confix(..., ...)[] directive
template <typename Prefix, typename Suffix, typename Subject
, typename Modifiers>
struct make_directive<
terminal_ex<repository::tag::confix, fusion::vector2<Prefix, Suffix> >
, Subject, Modifiers>
{
typedef typename
result_of::compile<qi::domain, Prefix, Modifiers>::type
prefix_type;
typedef typename
result_of::compile<qi::domain, Suffix, Modifiers>::type
suffix_type;
typedef repository::qi::confix_parser<
Subject, prefix_type, suffix_type> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<qi::domain>(fusion::at_c<0>(term.args), modifiers)
, compile<qi::domain>(fusion::at_c<1>(term.args), modifiers));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
template <typename Subject, typename Prefix, typename Suffix>
struct has_semantic_action<
repository::qi::confix_parser<Subject, Prefix, Suffix> >
: mpl::or_<
has_semantic_action<Subject>
, has_semantic_action<Prefix>
, has_semantic_action<Suffix>
> {};
}}}
#endif
@@ -0,0 +1,143 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// Copyright (c) 2001-2011 Joel de Guzman
// Copyright (c) 2003 Vaclav Vesely
//
// 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(SPIRIT_REPOSITORY_QI_DISTINCT_MAY_20_2009_0825M)
#define SPIRIT_REPOSITORY_QI_DISTINCT_MAY_20_2009_0825M
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/skip_over.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/make_component.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/string_traits.hpp>
#include <boost/spirit/home/qi/auxiliary/eps.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/qi/directive/lexeme.hpp>
#include <boost/spirit/home/qi/operator/not_predicate.hpp>
#include <boost/spirit/repository/home/support/distinct.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/vector.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables distinct(...)[...]
template <typename Tail>
struct use_directive<qi::domain
, terminal_ex<repository::tag::distinct, fusion::vector1<Tail> > >
: mpl::true_ {};
// enables *lazy* distinct(...)[...]
template <>
struct use_lazy_directive<qi::domain, repository::tag::distinct, 1>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace repository {namespace qi
{
using repository::distinct_type;
using repository::distinct;
template <typename Subject, typename Tail, typename Modifier>
struct distinct_parser
: spirit::qi::unary_parser<distinct_parser<Subject, Tail, Modifier> >
{
template <typename Context, typename Iterator>
struct attribute
: traits::attribute_of<Subject, Context, Iterator>
{};
distinct_parser(Subject const& subject, Tail const& tail)
: subject(subject), tail(tail) {}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, Attribute& attr) const
{
Iterator iter = first;
spirit::qi::skip_over(iter, last, skipper);
if (!subject.parse(iter, last, context
, spirit::qi::detail::unused_skipper<Skipper>(skipper), attr))
return false;
Iterator i = iter;
if (tail.parse(i, last, context, unused, unused))
return false;
first = iter;
return true;
}
template <typename Context>
info what(Context& /*ctx*/) const
{
return info("distinct");
}
Subject subject;
Tail tail;
};
}}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Tail, typename Subject, typename Modifiers>
struct make_directive<
terminal_ex<repository::tag::distinct, fusion::vector1<Tail> >
, Subject, Modifiers>
{
typedef typename result_of::compile<qi::domain, Tail, Modifiers>::type
tail_type;
typedef repository::qi::distinct_parser<
Subject, tail_type, Modifiers> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, Subject const& subject
, Modifiers const& modifiers) const
{
return result_type(subject
, compile<qi::domain>(fusion::at_c<0>(term.args), modifiers));
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
template <typename Subject, typename Tail, typename Modifier>
struct has_semantic_action<
repository::qi::distinct_parser<Subject, Tail, Modifier> >
: unary_has_semantic_action<Subject> {};
}}}
#endif
@@ -0,0 +1,134 @@
/*//////////////////////////////////////////////////////////////////////////////
Copyright (c) 2011 Jamboree
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_SPIRIT_REPOSITORY_QI_SEEK
#define BOOST_SPIRIT_REPOSITORY_QI_SEEK
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/has_semantic_action.hpp>
#include <boost/spirit/home/support/handles_container.hpp>
#include <boost/spirit/repository/home/support/seek.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables seek[...]
template <>
struct use_directive<qi::domain, repository::tag::seek>
: mpl::true_ {};
}} // namespace boost::spirit
namespace boost { namespace spirit { namespace repository {namespace qi
{
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
using repository::seek;
#endif
using repository::seek_type;
template <typename Subject>
struct seek_directive
: spirit::qi::unary_parser<seek_directive<Subject> >
{
typedef Subject subject_type;
template <typename Context, typename Iterator>
struct attribute
{
typedef typename
traits::attribute_of<subject_type, Context, Iterator>::type
type;
};
seek_directive(Subject const& subject)
: subject(subject)
{}
template
<
typename Iterator, typename Context
, typename Skipper, typename Attribute
>
bool parse
(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr
) const
{
for (Iterator it(first); ; ++it)
{
if (subject.parse(it, last, context, skipper, attr))
{
first = it;
return true;
}
// fail only after subject fails & no input
if (it == last)
return false;
}
}
template <typename Context>
info what(Context& context) const
{
return info("seek", subject.what(context));
}
Subject subject;
};
}}}} // namespace boost::spirit::repository::qi
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Modifiers>
struct make_directive<repository::tag::seek, Subject, Modifiers>
{
typedef repository::qi::seek_directive<Subject> result_type;
result_type operator()(unused_type, Subject const& subject, unused_type) const
{
return result_type(subject);
}
};
}}} // namespace boost::spirit::qi
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
template <typename Subject>
struct has_semantic_action<repository::qi::seek_directive<Subject> >
: unary_has_semantic_action<Subject> {};
///////////////////////////////////////////////////////////////////////////
template <typename Subject, typename Attribute, typename Context
, typename Iterator>
struct handles_container<repository::qi::seek_directive<Subject>, Attribute
, Context, Iterator>
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
}}} // namespace boost::spirit::traits
#endif
@@ -0,0 +1,18 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// 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(SPIRIT_REPOSITORY_QI_NONTERMINAL_AUG_12_2009_1140AM)
#define SPIRIT_REPOSITORY_QI_NONTERMINAL_AUG_12_2009_1140AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/repository/home/qi/nonterminal/subrule.hpp>
#endif
@@ -0,0 +1,590 @@
/*=============================================================================
Copyright (c) 2009 Francois Barel
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_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM)
#define BOOST_SPIRIT_REPOSITORY_QI_SUBRULE_AUGUST_06_2009_0239AM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/parser.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/support/argument.hpp>
#include <boost/spirit/home/support/assert_msg.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/repository/home/support/subrule_context.hpp>
#include <boost/fusion/include/as_map.hpp>
#include <boost/fusion/include/at_key.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/has_key.hpp>
#include <boost/fusion/include/join.hpp>
#include <boost/fusion/include/make_map.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace repository { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// subrule_group:
// - parser representing a group of subrule definitions (one or more),
// invokes first subrule on entry,
// - also a Proto terminal, so that a group behaves like any Spirit
// expression.
///////////////////////////////////////////////////////////////////////////
template <typename Defs>
struct subrule_group
: proto::extends<
typename proto::terminal<
spirit::qi::reference<subrule_group<Defs> const>
>::type
, subrule_group<Defs>
>
, spirit::qi::parser<subrule_group<Defs> >
{
// Fusion associative sequence, associating each subrule ID in this
// group (as an MPL integral constant) with its definition
typedef Defs defs_type;
typedef subrule_group<Defs> this_type;
typedef spirit::qi::reference<this_type const> reference_;
typedef typename proto::terminal<reference_>::type terminal;
typedef proto::extends<terminal, this_type> base_type;
static size_t const params_size =
// Forward to first subrule.
remove_reference<
typename fusion::result_of::front<Defs>::type
>::type::second_type::params_size;
subrule_group(subrule_group const& rhs)
: base_type(terminal::make(reference_(*this)))
, defs(rhs.defs)
{
}
explicit subrule_group(Defs const& defs)
: base_type(terminal::make(reference_(*this)))
, defs(defs)
{
}
// from a subrule ID, get the type of a reference to its definition
template <int ID>
struct def_type
{
typedef mpl::int_<ID> id_type;
// If you are seeing a compilation error here, you are trying
// to use a subrule which was not defined in this group.
BOOST_SPIRIT_ASSERT_MSG(
(fusion::result_of::has_key<
defs_type const, id_type>::type::value)
, subrule_used_without_being_defined, (mpl::int_<ID>));
typedef typename
fusion::result_of::at_key<defs_type const, id_type>::type
type;
};
// from a subrule ID, get a reference to its definition
template <int ID>
typename def_type<ID>::type def() const
{
return fusion::at_key<mpl::int_<ID> >(defs);
}
template <typename Context, typename Iterator>
struct attribute
// Forward to first subrule.
: mpl::identity<
typename remove_reference<
typename fusion::result_of::front<Defs>::type
>::type::second_type::attr_type> {};
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 first subrule.
return parse_subrule(fusion::front(defs).second
, first, last, context, skipper, attr);
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute, typename Params>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr, Params const& params) const
{
// Forward to first subrule.
return parse_subrule(fusion::front(defs).second
, first, last, context, skipper, attr, params);
}
template <int ID, typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse_subrule_id(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
return parse_subrule(def<ID>()
, first, last, context, skipper, attr);
}
template <int ID, typename Iterator, typename Context
, typename Skipper, typename Attribute, typename Params>
bool parse_subrule_id(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr, Params const& params) const
{
return parse_subrule(def<ID>()
, first, last, context, skipper, attr, params);
}
template <typename Def
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse_subrule(Def const& def
, Iterator& first, Iterator const& last
, Context& /*caller_context*/, Skipper const& skipper
, Attribute& attr) const
{
// compute context type for this subrule
typedef typename Def::locals_type subrule_locals_type;
typedef typename Def::attr_type subrule_attr_type;
typedef typename Def::attr_reference_type subrule_attr_reference_type;
typedef typename Def::parameter_types subrule_parameter_types;
typedef
subrule_context<
this_type
, fusion::cons<
subrule_attr_reference_type, subrule_parameter_types>
, subrule_locals_type
>
context_type;
// prepare attribute
typedef traits::make_attribute<
subrule_attr_type, Attribute> make_attribute;
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
typename make_attribute::type, subrule_attr_type, spirit::qi::domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr);
typename transform::type attr_ = transform::pre(made_attr);
// If you are seeing a compilation error here, you are probably
// trying to use a subrule which has inherited attributes,
// without passing values for them.
context_type context(*this, attr_);
if (def.binder(first, last, context, skipper))
{
// do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr, attr_);
return true;
}
// inform attribute transformation of failed rhs
traits::fail_transform(attr, attr_);
return false;
}
template <typename Def
, typename Iterator, typename Context
, typename Skipper, typename Attribute, typename Params>
bool parse_subrule(Def const& def
, Iterator& first, Iterator const& last
, Context& caller_context, Skipper const& skipper
, Attribute& attr, Params const& params) const
{
// compute context type for this subrule
typedef typename Def::locals_type subrule_locals_type;
typedef typename Def::attr_type subrule_attr_type;
typedef typename Def::attr_reference_type subrule_attr_reference_type;
typedef typename Def::parameter_types subrule_parameter_types;
typedef
subrule_context<
this_type
, fusion::cons<
subrule_attr_reference_type, subrule_parameter_types>
, subrule_locals_type
>
context_type;
// prepare attribute
typedef traits::make_attribute<
subrule_attr_type, Attribute> make_attribute;
// do down-stream transformation, provides attribute for
// rhs parser
typedef traits::transform_attribute<
typename make_attribute::type, subrule_attr_type, spirit::qi::domain>
transform;
typename make_attribute::type made_attr = make_attribute::call(attr);
typename transform::type attr_ = transform::pre(made_attr);
// If you are seeing a compilation error here, you are probably
// trying to use a subrule which has inherited attributes,
// passing values of incompatible types for them.
context_type context(*this, attr_, params, caller_context);
if (def.binder(first, last, context, skipper))
{
// do up-stream transformation, this integrates the results
// back into the original attribute value, if appropriate
traits::post_transform(attr, attr_);
return true;
}
// inform attribute transformation of failed rhs
traits::fail_transform(attr, attr_);
return false;
}
template <typename Context>
info what(Context& context) const
{
// Forward to first subrule.
return fusion::front(defs).second.binder.p.what(context);
}
template <typename Defs2>
subrule_group<
typename fusion::result_of::as_map<
typename fusion::result_of::join<
Defs const, Defs2 const>::type>::type>
operator,(subrule_group<Defs2> const& other) const
{
typedef subrule_group<
typename fusion::result_of::as_map<
typename fusion::result_of::join<
Defs const, Defs2 const>::type>::type> result_type;
return result_type(fusion::as_map(fusion::join(defs, other.defs)));
}
// bring in the operator() overloads
this_type const& get_parameterized_subject() const { return *this; }
typedef this_type parameterized_subject_type;
#include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
Defs defs;
};
///////////////////////////////////////////////////////////////////////////
// subrule_definition: holds one particular definition of a subrule
///////////////////////////////////////////////////////////////////////////
template <
int ID_
, typename Locals
, typename Attr
, typename AttrRef
, typename Parameters
, size_t ParamsSize
, typename Subject
, bool Auto_
>
struct subrule_definition
{
typedef mpl::int_<ID_> id_type;
BOOST_STATIC_CONSTANT(int, ID = ID_);
typedef Locals locals_type;
typedef Attr attr_type;
typedef AttrRef attr_reference_type;
typedef Parameters parameter_types;
static size_t const params_size = ParamsSize;
typedef Subject subject_type;
typedef mpl::bool_<Auto_> auto_type;
BOOST_STATIC_CONSTANT(bool, Auto = Auto_);
typedef spirit::qi::detail::parser_binder<
Subject, auto_type> binder_type;
subrule_definition(Subject const& subject, std::string const& name)
: binder(subject), name(name)
{
}
binder_type const binder;
std::string const name;
};
///////////////////////////////////////////////////////////////////////////
// subrule placeholder:
// - on subrule definition: helper for creation of subrule_group,
// - on subrule invocation: Proto terminal and parser.
///////////////////////////////////////////////////////////////////////////
template <
int ID_
, typename T1 = unused_type
, typename T2 = unused_type
>
struct subrule
: proto::extends<
typename proto::terminal<
spirit::qi::reference<subrule<ID_, T1, T2> const>
>::type
, subrule<ID_, T1, T2>
>
, spirit::qi::parser<subrule<ID_, T1, T2> >
{
typedef mpl::int_<ID_> id_type;
BOOST_STATIC_CONSTANT(int, ID = ID_);
typedef subrule<ID_, T1, T2> this_type;
typedef spirit::qi::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> template_params;
// locals_type is a sequence of types to be used as local variables
typedef typename
spirit::detail::extract_locals<template_params>::type
locals_type;
typedef typename
spirit::detail::extract_sig<template_params>::type
sig_type;
// This is the subrule'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 subrule
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;
explicit subrule(std::string const& name_ = "unnamed-subrule")
: base_type(terminal::make(reference_(*this)))
, name_(name_)
{
}
// compute type of this subrule's definition for expr type Expr
template <typename Expr, bool Auto>
struct def_type_helper
{
// 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(spirit::qi::domain, Expr);
typedef typename result_of::compile<
spirit::qi::domain, Expr>::type subject_type;
typedef subrule_definition<
ID_
, locals_type
, attr_type
, attr_reference_type
, parameter_types
, params_size
, subject_type
, Auto
> const type;
};
// compute type of subrule group containing only this
// subrule's definition for expr type Expr
template <typename Expr, bool Auto>
struct group_type_helper
{
typedef typename def_type_helper<Expr, Auto>::type def_type;
// create Defs map with only one entry: (ID -> def)
typedef typename
#ifndef BOOST_FUSION_HAS_VARIADIC_MAP
fusion::result_of::make_map<id_type, def_type>::type
#else
fusion::result_of::make_map<id_type>::template apply<def_type>::type
#endif
defs_type;
typedef subrule_group<defs_type> type;
};
template <typename Expr>
typename group_type_helper<Expr, false>::type
operator=(Expr const& expr) const
{
typedef group_type_helper<Expr, false> helper;
typedef typename helper::def_type def_type;
typedef typename helper::type result_type;
return result_type(fusion::make_map<id_type>(
def_type(compile<spirit::qi::domain>(expr), name_)));
}
template <typename Expr>
friend typename group_type_helper<Expr, true>::type
operator%=(subrule const& sr, Expr const& expr)
{
typedef group_type_helper<Expr, true> helper;
typedef typename helper::def_type def_type;
typedef typename helper::type result_type;
return result_type(fusion::make_map<id_type>(
def_type(compile<spirit::qi::domain>(expr), sr.name_)));
}
// non-const versions needed to suppress proto's %= kicking in
template <typename Expr>
friend typename group_type_helper<Expr, true>::type
operator%=(subrule const& sr, Expr& expr)
{
return operator%=(
sr
, static_cast<Expr const&>(expr));
}
template <typename Expr>
friend typename group_type_helper<Expr, true>::type
operator%=(subrule& sr, Expr const& expr)
{
return operator%=(
static_cast<subrule const&>(sr)
, expr);
}
template <typename Expr>
friend typename group_type_helper<Expr, true>::type
operator%=(subrule& sr, Expr& expr)
{
return operator%=(
static_cast<subrule const&>(sr)
, static_cast<Expr const&>(expr));
}
std::string const& name() const
{
return name_;
}
void name(std::string const& str)
{
name_ = str;
}
template <typename Context, typename Iterator>
struct attribute
{
typedef attr_type type;
};
template <typename Iterator, typename Group
, typename Attributes, typename Locals
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, subrule_context<Group, Attributes, Locals>& context
, Skipper const& skipper, Attribute& attr) const
{
return context.group.template parse_subrule_id<ID_>(
first, last, context, skipper, attr);
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& /*first*/, Iterator const& /*last*/
, Context& /*context*/
, Skipper const& /*skipper*/, Attribute& /*attr*/) const
{
// If you are seeing a compilation error here, you are trying
// to use a subrule as a parser outside of a subrule group.
BOOST_SPIRIT_ASSERT_FAIL(Iterator
, subrule_used_outside_subrule_group, (id_type));
return false;
}
template <typename Iterator, typename Group
, typename Attributes, typename Locals
, typename Skipper, typename Attribute
, typename Params>
bool parse(Iterator& first, Iterator const& last
, subrule_context<Group, Attributes, Locals>& context
, Skipper const& skipper, Attribute& attr
, Params const& params) const
{
return context.group.template parse_subrule_id<ID_>(
first, last, context, skipper, attr, params);
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute
, typename Params>
bool parse(Iterator& /*first*/, Iterator const& /*last*/
, Context& /*context*/
, Skipper const& /*skipper*/, Attribute& /*attr*/
, Params const& /*params*/) const
{
// If you are seeing a compilation error here, you are trying
// to use a subrule as a parser outside of a subrule group.
BOOST_SPIRIT_ASSERT_FAIL(Iterator
, subrule_used_outside_subrule_group, (id_type));
return false;
}
template <typename Context>
info what(Context& /*context*/) const
{
return info(name_);
}
// bring in the operator() overloads
this_type const& get_parameterized_subject() const { return *this; }
typedef this_type parameterized_subject_type;
#include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
std::string name_;
};
}}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,17 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// Copyright (c) 2001-2011 Joel de Guzman
// Copyright (c) 2011 Thomas Bernard
//
// 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(SPIRIT_REPOSITORY_QI_OPERATOR_OCT_20_2010_1258PM)
#define SPIRIT_REPOSITORY_QI_OPERATOR_OCT_20_2010_1258PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/repository/home/qi/operator/keywords.hpp>
#endif
@@ -0,0 +1,696 @@
/*=============================================================================
Copyright (c) 2011-2012 Thomas Bernard
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(SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM)
#define SPIRIT_KEYWORDS_DETAIL_MARCH_13_2007_1145PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/fusion/include/nview.hpp>
#include <boost/spirit/home/qi/string/lit.hpp>
#include <boost/fusion/include/at.hpp>
namespace boost { namespace spirit { namespace repository { namespace qi { namespace detail {
// Variant visitor class which handles dispatching the parsing to the selected parser
// This also handles passing the correct attributes and flags/counters to the subject parsers
template<typename T>
struct is_distinct : T::distinct { };
template<typename T, typename Action>
struct is_distinct< spirit::qi::action<T,Action> > : T::distinct { };
template<typename T>
struct is_distinct< spirit::qi::hold_directive<T> > : T::distinct { };
template < typename Elements, typename Iterator ,typename Context ,typename Skipper
,typename Flags ,typename Counters ,typename Attribute, typename NoCasePass>
struct parse_dispatcher
: public boost::static_visitor<bool>
{
typedef Iterator iterator_type;
typedef Context context_type;
typedef Skipper skipper_type;
typedef Elements elements_type;
typedef typename add_reference<Attribute>::type attr_reference;
public:
parse_dispatcher(const Elements &elements,Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Flags &flags, Counters &counters, attr_reference attr) :
elements(elements), first(first), last(last)
, context(context), skipper(skipper)
, flags(flags),counters(counters), attr(attr)
{}
template<typename T> bool operator()(T& idx) const
{
return call(idx,typename traits::not_is_unused<Attribute>::type());
}
template <typename Subject,typename Index>
bool call_subject_unused(
Subject const &subject, Iterator &first, Iterator const &last
, Context& context, Skipper const& skipper
, Index& idx ) const
{
Iterator save = first;
skipper_keyword_marker<Skipper,NoCasePass>
marked_skipper(skipper,flags[Index::value],counters[Index::value]);
if(subject.parse(first,last,context,marked_skipper,unused))
{
return true;
}
save = save;
return false;
}
template <typename Subject,typename Index>
bool call_subject(
Subject const &subject, Iterator &first, Iterator const &last
, Context& context, Skipper const& skipper
, Index& idx ) const
{
Iterator save = first;
skipper_keyword_marker<Skipper,NoCasePass>
marked_skipper(skipper,flags[Index::value],counters[Index::value]);
if(subject.parse(first,last,context,marked_skipper,fusion::at_c<Index::value>(attr)))
{
return true;
}
save = save;
return false;
}
// Handle unused attributes
template <typename T> bool call(T &idx, mpl::false_) const{
typedef typename mpl::at<Elements,T>::type ElementType;
if(
(!is_distinct<ElementType>::value)
|| skipper.parse(first,last,unused,unused,unused)
){
spirit::qi::skip_over(first, last, skipper);
return call_subject_unused(fusion::at_c<T::value>(elements), first, last, context, skipper, idx );
}
return false;
}
// Handle normal attributes
template <typename T> bool call(T &idx, mpl::true_) const{
typedef typename mpl::at<Elements,T>::type ElementType;
if(
(!is_distinct<ElementType>::value)
|| skipper.parse(first,last,unused,unused,unused)
){
return call_subject(fusion::at_c<T::value>(elements), first, last, context, skipper, idx);
}
return false;
}
const Elements &elements;
Iterator &first;
const Iterator &last;
Context & context;
const Skipper &skipper;
Flags &flags;
Counters &counters;
attr_reference attr;
};
// string keyword loop handler
template <typename Elements, typename StringKeywords, typename IndexList, typename FlagsType, typename Modifiers>
struct string_keywords
{
// Create a variant type to be able to store parser indexes in the embedded symbols parser
typedef typename
spirit::detail::as_variant<
IndexList >::type parser_index_type;
///////////////////////////////////////////////////////////////////////////
// build_char_type_sequence
//
// Build a fusion sequence from the kwd directive specified character type.
///////////////////////////////////////////////////////////////////////////
template <typename Sequence >
struct build_char_type_sequence
{
struct element_char_type
{
template <typename T>
struct result;
template <typename F, typename Element>
struct result<F(Element)>
{
typedef typename Element::char_type type;
};
template <typename F, typename Element,typename Action>
struct result<F(spirit::qi::action<Element,Action>) >
{
typedef typename Element::char_type type;
};
template <typename F, typename Element>
struct result<F(spirit::qi::hold_directive<Element>)>
{
typedef typename Element::char_type type;
};
// never called, but needed for decltype-based result_of (C++0x)
template <typename Element>
typename result<element_char_type(Element)>::type
operator()(Element&) const;
};
// Compute the list of character types of the child kwd directives
typedef typename
fusion::result_of::transform<Sequence, element_char_type>::type
type;
};
///////////////////////////////////////////////////////////////////////////
// get_keyword_char_type
//
// Collapses the character type comming from the subject kwd parsers and
// and checks that they are all identical (necessary in order to be able
// to build a tst parser to parse the keywords.
///////////////////////////////////////////////////////////////////////////
template <typename Sequence>
struct get_keyword_char_type
{
// Make sure each of the types occur only once in the type list
typedef typename
mpl::fold<
Sequence, mpl::vector<>,
mpl::if_<
mpl::contains<mpl::_1, mpl::_2>,
mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
>
>::type
no_duplicate_char_types;
// If the compiler traps here this means you mixed
// character type for the keywords specified in the
// kwd directive sequence.
BOOST_MPL_ASSERT_RELATION( mpl::size<no_duplicate_char_types>::value, ==, 1 );
typedef typename mpl::front<no_duplicate_char_types>::type type;
};
// Get the character type for the tst parser
typedef typename build_char_type_sequence< StringKeywords >::type char_types;
typedef typename get_keyword_char_type<
typename mpl::if_<
mpl::equal_to<
typename mpl::size < char_types >::type
, mpl::int_<0>
>
, mpl::vector< boost::spirit::standard::char_type >
, char_types >::type
>::type char_type;
// Our symbols container
typedef spirit::qi::tst< char_type, parser_index_type> keywords_type;
// Filter functor used for case insensitive parsing
template <typename CharEncoding>
struct no_case_filter
{
char_type operator()(char_type ch) const
{
return static_cast<char_type>(CharEncoding::tolower(ch));
}
};
///////////////////////////////////////////////////////////////////////////
// build_case_type_sequence
//
// Build a fusion sequence from the kwd/ikwd directives
// in order to determine if case sensitive and case insensitive
// keywords have been mixed.
///////////////////////////////////////////////////////////////////////////
template <typename Sequence >
struct build_case_type_sequence
{
struct element_case_type
{
template <typename T>
struct result;
template <typename F, typename Element>
struct result<F(Element)>
{
typedef typename Element::no_case_keyword type;
};
template <typename F, typename Element,typename Action>
struct result<F(spirit::qi::action<Element,Action>) >
{
typedef typename Element::no_case_keyword type;
};
template <typename F, typename Element>
struct result<F(spirit::qi::hold_directive<Element>)>
{
typedef typename Element::no_case_keyword type;
};
// never called, but needed for decltype-based result_of (C++0x)
template <typename Element>
typename result<element_case_type(Element)>::type
operator()(Element&) const;
};
// Compute the list of character types of the child kwd directives
typedef typename
fusion::result_of::transform<Sequence, element_case_type>::type
type;
};
///////////////////////////////////////////////////////////////////////////
// get_nb_case_types
//
// Counts the number of entries in the case type sequence matching the
// CaseType parameter (mpl::true_ -> case insensitve
// , mpl::false_ -> case sensitive
///////////////////////////////////////////////////////////////////////////
template <typename Sequence,typename CaseType>
struct get_nb_case_types
{
// Make sure each of the types occur only once in the type list
typedef typename
mpl::count_if<
Sequence, mpl::equal_to<mpl::_,CaseType>
>::type type;
};
// Build the case type sequence
typedef typename build_case_type_sequence< StringKeywords >::type case_type_sequence;
// Count the number of case sensitive entries and case insensitve entries
typedef typename get_nb_case_types<case_type_sequence,mpl::true_>::type ikwd_count;
typedef typename get_nb_case_types<case_type_sequence,mpl::false_>::type kwd_count;
// Get the size of the original sequence
typedef typename mpl::size<IndexList>::type nb_elements;
// Determine if all the kwd directive are case sensitive/insensitive
typedef typename mpl::and_<
typename mpl::greater< nb_elements, mpl::int_<0> >::type
, typename mpl::equal_to< ikwd_count, nb_elements>::type
>::type all_ikwd;
typedef typename mpl::and_<
typename mpl::greater< nb_elements, mpl::int_<0> >::type
, typename mpl::equal_to< kwd_count, nb_elements>::type
>::type all_kwd;
typedef typename mpl::or_< all_kwd, all_ikwd >::type all_directives_of_same_type;
// Do we have a no case modifier
typedef has_modifier<Modifiers, spirit::tag::char_code_base<spirit::tag::no_case> > no_case_modifier;
// Should the no_case filter always be used ?
typedef typename mpl::or_<
no_case_modifier,
mpl::and_<
all_directives_of_same_type
,all_ikwd
>
>::type
no_case;
typedef no_case_filter<
typename spirit::detail::get_encoding_with_case<
Modifiers
, char_encoding::standard
, no_case::value>::type>
nc_filter;
// Determine the standard case filter type
typedef typename mpl::if_<
no_case
, nc_filter
, spirit::qi::tst_pass_through >::type
first_pass_filter_type;
typedef typename mpl::or_<
all_directives_of_same_type
, no_case_modifier
>::type requires_one_pass;
// Functor which adds all the keywords/subject parser indexes
// collected from the subject kwd directives to the keyword tst parser
struct keyword_entry_adder
{
typedef int result_type;
keyword_entry_adder(shared_ptr<keywords_type> lookup,FlagsType &flags, Elements &elements) :
lookup(lookup)
,flags(flags)
,elements(elements)
{}
template <typename T>
int operator()(const T &index) const
{
return call(fusion::at_c<T::value>(elements),index);
}
template <typename T, typename Position, typename Action>
int call(const spirit::qi::action<T,Action> &parser, const Position position ) const
{
// Make the keyword/parse index entry in the tst parser
lookup->add(
traits::get_begin<char_type>(get_string(parser.subject.keyword)),
traits::get_end<char_type>(get_string(parser.subject.keyword)),
position
);
// Get the initial state of the flags array and store it in the flags initializer
flags[Position::value]=parser.subject.iter.flag_init();
return 0;
}
template <typename T, typename Position>
int call( const T & parser, const Position position) const
{
// Make the keyword/parse index entry in the tst parser
lookup->add(
traits::get_begin<char_type>(get_string(parser.keyword)),
traits::get_end<char_type>(get_string(parser.keyword)),
position
);
// Get the initial state of the flags array and store it in the flags initializer
flags[Position::value]=parser.iter.flag_init();
return 0;
}
template <typename T, typename Position>
int call( const spirit::qi::hold_directive<T> & parser, const Position position) const
{
// Make the keyword/parse index entry in the tst parser
lookup->add(
traits::get_begin<char_type>(get_string(parser.subject.keyword)),
traits::get_end<char_type>(get_string(parser.subject.keyword)),
position
);
// Get the initial state of the flags array and store it in the flags initializer
flags[Position::value]=parser.subject.iter.flag_init();
return 0;
}
template <typename String, bool no_attribute>
const String get_string(const boost::spirit::qi::literal_string<String,no_attribute> &parser) const
{
return parser.str;
}
template <typename String, bool no_attribute>
const typename boost::spirit::qi::no_case_literal_string<String,no_attribute>::string_type &
get_string(const boost::spirit::qi::no_case_literal_string<String,no_attribute> &parser) const
{
return parser.str_lo;
}
shared_ptr<keywords_type> lookup;
FlagsType & flags;
Elements &elements;
};
string_keywords(Elements &elements,FlagsType &flags_init) : lookup(new keywords_type())
{
// Loop through all the subject parsers to build the keyword parser symbol parser
IndexList indexes;
keyword_entry_adder f1(lookup,flags_init,elements);
fusion::for_each(indexes,f1);
}
template <typename Iterator,typename ParseVisitor, typename Skipper>
bool parse(
Iterator &first,
const Iterator &last,
const ParseVisitor &parse_visitor,
const Skipper &skipper) const
{
if(parser_index_type* val_ptr =
lookup->find(first,last,first_pass_filter_type()))
{
if(!apply_visitor(parse_visitor,*val_ptr)){
return false;
}
return true;
}
return false;
}
template <typename Iterator,typename ParseVisitor, typename NoCaseParseVisitor,typename Skipper>
bool parse(
Iterator &first,
const Iterator &last,
const ParseVisitor &parse_visitor,
const NoCaseParseVisitor &no_case_parse_visitor,
const Skipper &skipper) const
{
Iterator saved_first = first;
if(parser_index_type* val_ptr =
lookup->find(first,last,first_pass_filter_type()))
{
if(!apply_visitor(parse_visitor,*val_ptr)){
return false;
}
return true;
}
// Second pass case insensitive
else if(parser_index_type* val_ptr
= lookup->find(saved_first,last,nc_filter()))
{
first = saved_first;
if(!apply_visitor(no_case_parse_visitor,*val_ptr)){
return false;
}
return true;
}
return false;
}
shared_ptr<keywords_type> lookup;
};
struct empty_keywords_list
{
typedef mpl::true_ requires_one_pass;
empty_keywords_list()
{}
template<typename Elements>
empty_keywords_list(const Elements &)
{}
template<typename Elements, typename FlagsInit>
empty_keywords_list(const Elements &, const FlagsInit &)
{}
template <typename Iterator,typename ParseVisitor, typename NoCaseParseVisitor,typename Skipper>
bool parse(
Iterator &first,
const Iterator &last,
const ParseVisitor &parse_visitor,
const NoCaseParseVisitor &no_case_parse_visitor,
const Skipper &skipper) const
{
return false;
}
template <typename Iterator,typename ParseVisitor, typename Skipper>
bool parse(
Iterator &first,
const Iterator &last,
const ParseVisitor &parse_visitor,
const Skipper &skipper) const
{
return false;
}
template <typename ParseFunction>
bool parse( ParseFunction &function ) const
{
return false;
}
};
template<typename ComplexKeywords>
struct complex_keywords
{
// Functor which performs the flag initialization for the complex keyword parsers
template <typename FlagsType, typename Elements>
struct flag_init_value_setter
{
typedef int result_type;
flag_init_value_setter(Elements &elements,FlagsType &flags)
:flags(flags)
,elements(elements)
{}
template <typename T>
int operator()(const T &index) const
{
return call(fusion::at_c<T::value>(elements),index);
}
template <typename T, typename Position, typename Action>
int call(const spirit::qi::action<T,Action> &parser, const Position position ) const
{
// Get the initial state of the flags array and store it in the flags initializer
flags[Position::value]=parser.subject.iter.flag_init();
return 0;
}
template <typename T, typename Position>
int call( const T & parser, const Position position) const
{
// Get the initial state of the flags array and store it in the flags initializer
flags[Position::value]=parser.iter.flag_init();
return 0;
}
template <typename T, typename Position>
int call( const spirit::qi::hold_directive<T> & parser, const Position position) const
{
// Get the initial state of the flags array and store it in the flags initializer
flags[Position::value]=parser.subject.iter.flag_init();
return 0;
}
FlagsType & flags;
Elements &elements;
};
template <typename Elements, typename Flags>
complex_keywords(Elements &elements, Flags &flags)
{
flag_init_value_setter<Flags,Elements> flag_initializer(elements,flags);
fusion::for_each(complex_keywords_inst,flag_initializer);
}
template <typename ParseFunction>
bool parse( ParseFunction &function ) const
{
return fusion::any(complex_keywords_inst,function);
}
ComplexKeywords complex_keywords_inst;
};
// This helper class enables jumping over intermediate directives
// down the kwd parser iteration count checking policy
struct register_successful_parse
{
template <typename Subject>
static bool call(Subject const &subject,bool &flag, int &counter)
{
return subject.iter.register_successful_parse(flag,counter);
}
template <typename Subject, typename Action>
static bool call(spirit::qi::action<Subject, Action> const &subject,bool &flag, int &counter)
{
return subject.subject.iter.register_successful_parse(flag,counter);
}
template <typename Subject>
static bool call(spirit::qi::hold_directive<Subject> const &subject,bool &flag, int &counter)
{
return subject.subject.iter.register_successful_parse(flag,counter);
}
};
// This helper class enables jumping over intermediate directives
// down the kwd parser
struct extract_keyword
{
template <typename Subject>
static Subject const& call(Subject const &subject)
{
return subject;
}
template <typename Subject, typename Action>
static Subject const& call(spirit::qi::action<Subject, Action> const &subject)
{
return subject.subject;
}
template <typename Subject>
static Subject const& call(spirit::qi::hold_directive<Subject> const &subject)
{
return subject.subject;
}
};
template <typename ParseDispatcher>
struct complex_kwd_function
{
typedef typename ParseDispatcher::iterator_type Iterator;
typedef typename ParseDispatcher::context_type Context;
typedef typename ParseDispatcher::skipper_type Skipper;
complex_kwd_function(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, ParseDispatcher &dispatcher)
: first(first)
, last(last)
, context(context)
, skipper(skipper)
, dispatcher(dispatcher)
{
}
template <typename Component>
bool operator()(Component const& component)
{
Iterator save = first;
if(
extract_keyword::call(
fusion::at_c<
Component::value
,typename ParseDispatcher::elements_type
>(dispatcher.elements)
)
.keyword.parse(
first
,last
,context
,skipper
,unused)
)
{
if(!dispatcher(component)){
first = save;
return false;
}
return true;
}
return false;
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
ParseDispatcher const& dispatcher;
private:
// silence MSVC warning C4512: assignment operator could not be generated
complex_kwd_function& operator= (complex_kwd_function const&);
};
}}}}}
#endif
@@ -0,0 +1,436 @@
/*=============================================================================
Copyright (c) 2001-2011 Joel de Guzman
Copyright (c) 2011-2012 Thomas Bernard
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(SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM)
#define SPIRIT_KEYWORDS_OR_MARCH_13_2007_1145PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/detail/permute_function.hpp>
#include <boost/spirit/home/qi/detail/attributes.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/iter_fold.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/value_at.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/optional.hpp>
#include <boost/foreach.hpp>
#include <boost/array.hpp>
#include <boost/spirit/home/qi/string/symbols.hpp>
#include <boost/spirit/home/qi/string/lit.hpp>
#include <boost/spirit/home/qi/action/action.hpp>
#include <boost/spirit/home/qi/directive/hold.hpp>
#include <boost/mpl/count_if.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/filter_view.hpp>
#include <boost/fusion/include/zip_view.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/repository/home/qi/operator/detail/keywords.hpp>
#include <boost/fusion/include/any.hpp>
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
template <>
struct use_operator<qi::domain, proto::tag::divides > // enables /
: mpl::true_ {};
template <>
struct flatten_tree<qi::domain, proto::tag::divides> // flattens /
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace repository { namespace qi
{
// kwd directive parser type identification
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(kwd_parser_id)
BOOST_MPL_HAS_XXX_TRAIT_DEF(complex_kwd_parser_id)
}
// kwd directive type query
template <typename T>
struct is_kwd_parser : detail::has_kwd_parser_id<T> {};
template <typename Subject, typename Action>
struct is_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_kwd_parser_id<Subject> {};
template <typename Subject>
struct is_kwd_parser<spirit::qi::hold_directive<Subject> > : detail::has_kwd_parser_id<Subject> {};
template <typename T>
struct is_complex_kwd_parser : detail::has_complex_kwd_parser_id<T> {};
template <typename Subject, typename Action>
struct is_complex_kwd_parser<spirit::qi::action<Subject,Action> > : detail::has_complex_kwd_parser_id<Subject> {};
template <typename Subject>
struct is_complex_kwd_parser<spirit::qi::hold_directive<Subject> > : detail::has_complex_kwd_parser_id<Subject> {};
// Keywords operator
template <typename Elements, typename Modifiers>
struct keywords : spirit::qi::nary_parser<keywords<Elements,Modifiers> >
{
template <typename Context, typename Iterator>
struct attribute
{
// Put all the element attributes in a tuple
typedef typename traits::build_attribute_sequence<
Elements, Context, traits::sequence_attribute_transform, Iterator, spirit::qi::domain >::type
all_attributes;
// Now, build a fusion vector over the attributes. Note
// that build_fusion_vector 1) removes all unused attributes
// and 2) may return unused_type if all elements have
// unused_type(s).
typedef typename
traits::build_fusion_vector<all_attributes>::type
type;
};
/// Make sure that all subjects are of the kwd type
typedef typename mpl::count_if<
Elements,
mpl::not_<
mpl::or_<
is_kwd_parser<
mpl::_1
> ,
is_complex_kwd_parser<
mpl::_1
>
>
>
> non_kwd_subject_count;
/// If the assertion fails here then you probably forgot to wrap a
/// subject of the / operator in a kwd directive
BOOST_MPL_ASSERT_RELATION( non_kwd_subject_count::value, ==, 0 );
///////////////////////////////////////////////////////////////////////////
// build_parser_tags
//
// Builds a boost::variant from an mpl::range_c in order to "mark" every
// parser of the fusion sequence. The integer constant is used in the parser
// dispatcher functor in order to use the parser corresponding to the recognised
// keyword.
///////////////////////////////////////////////////////////////////////////
template <typename Sequence>
struct build_parser_tags
{
// Get the sequence size
typedef typename mpl::size< Sequence >::type sequence_size;
// Create an integer_c constant for every parser in the sequence
typedef typename mpl::range_c<int, 0, sequence_size::value>::type int_range;
// Transform the range_c to an mpl vector in order to be able to transform it into a variant
typedef typename mpl::copy<int_range, mpl::back_inserter<mpl::vector<> > >::type type;
};
// Build an index mpl vector
typedef typename build_parser_tags< Elements >::type parser_index_vector;
template <typename idx>
struct is_complex_kwd_parser_filter : is_complex_kwd_parser< typename mpl::at<Elements, idx>::type >
{};
template <typename idx>
struct is_kwd_parser_filter : is_kwd_parser< typename mpl::at<Elements, idx>::type >
{};
// filter out the string kwd directives
typedef typename mpl::filter_view< Elements, is_kwd_parser<mpl::_> >::type string_keywords;
typedef typename mpl::filter_view< parser_index_vector ,
is_kwd_parser_filter< mpl::_ >
>::type string_keyword_indexes;
// filter out the complex keywords
typedef typename mpl::filter_view< parser_index_vector ,
is_complex_kwd_parser_filter< mpl::_ >
>::type complex_keywords_indexes;
//typedef typename fusion::filter_view< Elements, is_complex_kwd_parser< mpl::_ > > complex_keywords_view;
typedef typename mpl::if_<
typename mpl::empty<complex_keywords_indexes>::type,
detail::empty_keywords_list,
detail::complex_keywords< complex_keywords_indexes >
>::type complex_keywords_type;
// build a bool array and an integer array which will be used to
// check that the repetition constraints of the kwd parsers are
// met and bail out a soon as possible
typedef boost::array<bool, fusion::result_of::size<Elements>::value> flags_type;
typedef boost::array<int, fusion::result_of::size<Elements>::value> counters_type;
typedef typename mpl::if_<
typename mpl::empty<string_keyword_indexes>::type,
detail::empty_keywords_list,
detail::string_keywords<
Elements,
string_keywords,
string_keyword_indexes,
flags_type,
Modifiers>
>::type string_keywords_type;
keywords(Elements const& elements_) :
elements(elements_)
, string_keywords_inst(elements,flags_init)
, complex_keywords_inst(elements,flags_init)
{
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_) const
{
// Select which parse function to call
// We need to handle the case where kwd / ikwd directives have been mixed
// This is where we decide which function should be called.
return parse_impl(first, last, context, skipper, attr_,
typename string_keywords_type::requires_one_pass()
);
}
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse_impl(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_,mpl::true_ /* one pass */) const
{
// wrap the attribute in a tuple if it is not a tuple
typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
flags_type flags(flags_init);
//flags.assign(false);
counters_type counters;
counters.assign(0);
typedef repository::qi::detail::parse_dispatcher<Elements,Iterator, Context, Skipper
, flags_type, counters_type
, typename traits::wrap_if_not_tuple<Attribute>::type
, mpl::false_ > parser_visitor_type;
parser_visitor_type parse_visitor(elements, first, last
, context, skipper, flags
, counters, attr);
typedef repository::qi::detail::complex_kwd_function< parser_visitor_type > complex_kwd_function_type;
complex_kwd_function_type
complex_function(first,last,context,skipper,parse_visitor);
// We have a bool array 'flags' with one flag for each parser as well as a 'counter'
// array.
// The kwd directive sets and increments the counter when a successeful parse occurred
// as well as the slot of the corresponding parser to true in the flags array as soon
// the minimum repetition requirement is met and keeps that value to true as long as
// the maximum repetition requirement is met.
// The parsing takes place here in two steps:
// 1) parse a keyword and fetch the parser index associated with that keyword
// 2) call the associated parser and store the parsed value in the matching attribute.
while(true)
{
spirit::qi::skip_over(first, last, skipper);
Iterator save = first;
if (string_keywords_inst.parse(first, last,parse_visitor,skipper))
{
save = first;
}
else {
// restore the position to the last successful keyword parse
first = save;
if(!complex_keywords_inst.parse(complex_function))
{
first = save;
// Check that we are leaving the keywords parser in a successfull state
BOOST_FOREACH(bool &valid,flags)
{
if(!valid)
{
return false;
}
}
return true;
}
else
save = first;
}
}
return false;
}
// Handle the mixed kwd and ikwd case
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse_impl(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_,mpl::false_ /* two passes */) const
{
// wrap the attribute in a tuple if it is not a tuple
typename traits::wrap_if_not_tuple<Attribute>::type attr(attr_);
flags_type flags(flags_init);
//flags.assign(false);
counters_type counters;
counters.assign(0);
typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
, flags_type, counters_type
, typename traits::wrap_if_not_tuple<Attribute>::type
, mpl::false_> parser_visitor_type;
typedef detail::parse_dispatcher<Elements, Iterator, Context, Skipper
, flags_type, counters_type
, typename traits::wrap_if_not_tuple<Attribute>::type
, mpl::true_> no_case_parser_visitor_type;
parser_visitor_type parse_visitor(elements,first,last
,context,skipper,flags,counters,attr);
no_case_parser_visitor_type no_case_parse_visitor(elements,first,last
,context,skipper,flags,counters,attr);
typedef repository::qi::detail::complex_kwd_function< parser_visitor_type > complex_kwd_function_type;
complex_kwd_function_type
complex_function(first,last,context,skipper,parse_visitor);
// We have a bool array 'flags' with one flag for each parser as well as a 'counter'
// array.
// The kwd directive sets and increments the counter when a successeful parse occurred
// as well as the slot of the corresponding parser to true in the flags array as soon
// the minimum repetition requirement is met and keeps that value to true as long as
// the maximum repetition requirement is met.
// The parsing takes place here in two steps:
// 1) parse a keyword and fetch the parser index associated with that keyword
// 2) call the associated parser and store the parsed value in the matching attribute.
while(true)
{
spirit::qi::skip_over(first, last, skipper);
Iterator save = first;
// String keywords pass
if (string_keywords_inst.parse(first,last,parse_visitor,no_case_parse_visitor,skipper))
{
save = first;
}
else {
first = save;
if(!complex_keywords_inst.parse(complex_function))
{
first = save;
// Check that we are leaving the keywords parser in a successfull state
BOOST_FOREACH(bool &valid,flags)
{
if(!valid)
{
return false;
}
}
return true;
}
else
{
save = first;
}
}
}
return false;
}
template <typename Context>
info what(Context& context) const
{
info result("keywords");
fusion::for_each(elements,
spirit::detail::what_function<Context>(result, context));
return result;
}
flags_type flags_init;
Elements elements;
string_keywords_type string_keywords_inst;
complex_keywords_type complex_keywords_inst;
};
}}}}
namespace boost { namespace spirit { namespace qi {
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Elements, typename Modifiers >
struct make_composite<proto::tag::divides, Elements, Modifiers >
{
typedef repository::qi::keywords<Elements,Modifiers> result_type;
result_type operator()(Elements ref, unused_type) const
{
return result_type(ref);
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
// We specialize this for keywords (see support/attributes.hpp).
// For keywords, we only wrap the attribute in a tuple IFF
// it is not already a fusion tuple.
template <typename Elements, typename Modifiers,typename Attribute>
struct pass_attribute<repository::qi::keywords<Elements,Modifiers>, Attribute>
: wrap_if_not_tuple<Attribute> {};
template <typename Elements, typename Modifiers>
struct has_semantic_action<repository::qi::keywords<Elements, Modifiers> >
: nary_has_semantic_action<Elements> {};
template <typename Elements, typename Attribute, typename Context
, typename Iterator, typename Modifiers>
struct handles_container<repository::qi::keywords<Elements,Modifiers>, Attribute
, Context, Iterator>
: nary_handles_container<Elements, Attribute, Context, Iterator> {};
}}}
#endif
@@ -0,0 +1,19 @@
// Copyright (c) 2001-2011 Hartmut Kaiser
// 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(SPIRIT_REPOSITORY_QI_PRIMITIVE_APR_28_2009_1258PM)
#define SPIRIT_REPOSITORY_QI_PRIMITIVE_APR_28_2009_1258PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/repository/home/qi/primitive/advance.hpp>
#include <boost/spirit/repository/home/qi/primitive/flush_multi_pass.hpp>
#include <boost/spirit/repository/home/qi/primitive/iter_pos.hpp>
#endif
@@ -0,0 +1,130 @@
// Copyright (c) 2011 Aaron Graham
//
// 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_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM)
#define BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM
#include <boost/spirit/include/qi_parse.hpp>
///////////////////////////////////////////////////////////////////////////////
// definition the place holder
namespace boost { namespace spirit { namespace repository { namespace qi
{
BOOST_SPIRIT_TERMINAL_EX(advance);
}}}}
///////////////////////////////////////////////////////////////////////////////
// implementation the enabler
namespace boost { namespace spirit
{
template <typename A0>
struct use_terminal<qi::domain
, terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> > >
: mpl::or_<is_integral<A0>, is_enum<A0> >
{};
template <>
struct use_lazy_terminal<qi::domain, repository::qi::tag::advance, 1>
: mpl::true_
{};
}}
///////////////////////////////////////////////////////////////////////////////
// implementation of the parser
namespace boost { namespace spirit { namespace repository { namespace qi
{
template <typename Int>
struct advance_parser
: boost::spirit::qi::primitive_parser< advance_parser<Int> >
{
// Define the attribute type exposed by this parser component
template <typename Context, typename Iterator>
struct attribute
{
typedef boost::spirit::unused_type type;
};
advance_parser(Int dist)
: dist(dist)
{}
// This function is called during the actual parsing process
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context&, Skipper&, Attribute&) const
{
// This series of checks is designed to fail parsing on negative
// values, without generating a "expression always evaluates true"
// warning on unsigned types.
if (dist == Int(0)) return true;
if (dist < Int(1)) return false;
typedef typename std::iterator_traits<Iterator>::iterator_category
iterator_category;
return advance(first, last, iterator_category());
}
// This function is called during error handling to create
// a human readable string for the error context.
template <typename Context>
boost::spirit::info what(Context&) const
{
return boost::spirit::info("advance");
}
private:
// this is the general implementation used by most iterator categories
template <typename Iterator, typename IteratorCategory>
bool advance(Iterator& first, Iterator const& last
, IteratorCategory) const
{
Int n = dist;
Iterator i = first;
while (n)
{
if (i == last) return false;
++i;
--n;
}
first = i;
return true;
}
// this is a specialization for random access iterators
template <typename Iterator>
bool advance(Iterator& first, Iterator const& last
, std::random_access_iterator_tag) const
{
Iterator const it = first + dist;
if (it > last) return false;
first = it;
return true;
}
Int const dist;
};
}}}}
///////////////////////////////////////////////////////////////////////////////
// instantiation of the parser
namespace boost { namespace spirit { namespace qi
{
template <typename Modifiers, typename A0>
struct make_primitive<
terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> >
, Modifiers>
{
typedef repository::qi::advance_parser<A0> result_type;
template <typename Terminal>
result_type operator()(Terminal const& term, unused_type) const
{
return result_type(fusion::at_c<0>(term.args));
}
};
}}}
#endif
@@ -0,0 +1,92 @@
// 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_REPOSITORY_QI_FLUSH_MULTI_PASS_JUL_10_2009_0535PM)
#define BOOST_SPIRIT_REPOSITORY_QI_FLUSH_MULTI_PASS_JUL_10_2009_0535PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/meta_compiler.hpp>
#include <boost/spirit/home/support/common_terminals.hpp>
#include <boost/spirit/home/support/info.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/attributes.hpp>
#include <boost/spirit/home/support/multi_pass.hpp>
#include <boost/spirit/repository/home/support/flush_multi_pass.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
///////////////////////////////////////////////////////////////////////////
// Enablers
///////////////////////////////////////////////////////////////////////////
// enables flush_multi_pass
template <>
struct use_terminal<qi::domain, repository::tag::flush_multi_pass>
: mpl::true_ {};
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace repository { namespace qi
{
using repository::flush_multi_pass_type;
using repository::flush_multi_pass;
///////////////////////////////////////////////////////////////////////////
// for a flush_multi_pass_parser generated parser
struct flush_multi_pass_parser
: spirit::qi::primitive_parser<flush_multi_pass_parser>
{
template <typename Context, typename Unused>
struct attribute
{
typedef unused_type type;
};
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr) const
{
spirit::traits::clear_queue(first, traits::clear_mode::clear_always);
return true;
}
template <typename Context>
info what(Context const& ctx) const
{
return info("flush_multi_pass");
}
};
}}}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// Parser generators: make_xxx function (objects)
///////////////////////////////////////////////////////////////////////////
template <typename Modifiers>
struct make_primitive<repository::tag::flush_multi_pass, Modifiers>
{
typedef repository::qi::flush_multi_pass_parser result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
}}}
#endif
@@ -0,0 +1,83 @@
// 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_REPOSITORY_QI_ITER_POS_NOV_20_2009_1245PM)
#define BOOST_SPIRIT_REPOSITORY_QI_ITER_POS_NOV_20_2009_1245PM
#include <boost/spirit/include/qi_parse.hpp>
///////////////////////////////////////////////////////////////////////////////
// definition the place holder
namespace boost { namespace spirit { namespace repository { namespace qi
{
BOOST_SPIRIT_TERMINAL(iter_pos);
}}}}
///////////////////////////////////////////////////////////////////////////////
// implementation the enabler
namespace boost { namespace spirit
{
// We want custom_parser::iter_pos to be usable as a terminal only,
// and only for parser expressions (qi::domain).
template <>
struct use_terminal<qi::domain, repository::qi::tag::iter_pos>
: mpl::true_
{};
}}
///////////////////////////////////////////////////////////////////////////////
// implementation of the parser
namespace boost { namespace spirit { namespace repository { namespace qi
{
struct iter_pos_parser
: boost::spirit::qi::primitive_parser<iter_pos_parser>
{
// Define the attribute type exposed by this parser component
template <typename Context, typename Iterator>
struct attribute
{
typedef Iterator type;
};
// This function is called during the actual parsing process
template <typename Iterator, typename Context
, typename Skipper, typename Attribute>
bool parse(Iterator& first, Iterator const& last
, Context&, Skipper const& skipper, Attribute& attr) const
{
boost::spirit::qi::skip_over(first, last, skipper);
boost::spirit::traits::assign_to(first, attr);
return true;
}
// This function is called during error handling to create
// a human readable string for the error context.
template <typename Context>
boost::spirit::info what(Context&) const
{
return boost::spirit::info("iter_pos");
}
};
}}}}
///////////////////////////////////////////////////////////////////////////////
// instantiation of the parser
namespace boost { namespace spirit { namespace qi
{
// This is the factory function object invoked in order to create
// an instance of our iter_pos_parser.
template <typename Modifiers>
struct make_primitive<repository::qi::tag::iter_pos, Modifiers>
{
typedef repository::qi::iter_pos_parser result_type;
result_type operator()(unused_type, unused_type) const
{
return result_type();
}
};
}}}
#endif
@@ -0,0 +1,22 @@
// 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_REPOSITORY_SUPPORT_CONFIX_APR_28_2009_0110PM)
#define BOOST_SPIRIT_REPOSITORY_SUPPORT_CONFIX_APR_28_2009_0110PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/terminal.hpp>
namespace boost { namespace spirit { namespace repository
{
// The confix extended terminal
BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(( confix, confix_type ))
}}}
#endif
@@ -0,0 +1,22 @@
// 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_REPOSITORY_SUPPORT_DISTINCT_APR_28_2009_0110PM)
#define BOOST_SPIRIT_REPOSITORY_SUPPORT_DISTINCT_APR_28_2009_0110PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/terminal.hpp>
namespace boost { namespace spirit { namespace repository
{
// The distinct extended terminal
BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(( distinct, distinct_type ))
}}}
#endif
@@ -0,0 +1,22 @@
// 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_REPOSITORY_SUPPORT_FLUSH_MULTI_PASS_JUL_11_2009_0823PM)
#define BOOST_SPIRIT_REPOSITORY_SUPPORT_FLUSH_MULTI_PASS_JUL_11_2009_0823PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/terminal.hpp>
namespace boost { namespace spirit { namespace repository
{
// The flush_multi_pass extended terminal
BOOST_SPIRIT_TERMINAL( flush_multi_pass )
}}}
#endif
@@ -0,0 +1,22 @@
// Copyright (c) 2001-2011 Thomas Bernard
//
// 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_REPOSITORY_SUPPORT_KWD_OCT_20_2010_0110PM)
#define BOOST_SPIRIT_REPOSITORY_SUPPORT_KWD_OCT_20_2010_0110PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/terminal.hpp>
namespace boost { namespace spirit { namespace repository
{
// The distinct extended terminal
BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(( kwd, kwd_type )( ikwd, ikwd_type )(dkwd, dkwd_type)(idkwd, idkwd_type) )
}}}
#endif
@@ -0,0 +1,25 @@
/*//////////////////////////////////////////////////////////////////////////////
Copyright (c) 2011 Jamboree
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_SPIRIT_REPOSITORY_SUPPORT_SEEK
#define BOOST_SPIRIT_REPOSITORY_SUPPORT_SEEK
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/terminal.hpp>
namespace boost { namespace spirit { namespace repository
{
// The seek terminal
BOOST_SPIRIT_DEFINE_TERMINALS_NAME(( seek, seek_type ))
}}}
#endif
@@ -0,0 +1,57 @@
/*=============================================================================
Copyright (c) 2009 Francois Barel
Copyright (c) 2001-2010 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_REPOSITORY_SUPPORT_SUBRULE_CONTEXT_AUGUST_12_2009_0539PM)
#define BOOST_SPIRIT_REPOSITORY_SUPPORT_SUBRULE_CONTEXT_AUGUST_12_2009_0539PM
#if defined(_MSC_VER)
#pragma once
#endif
#include <boost/spirit/home/support/context.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace repository
{
///////////////////////////////////////////////////////////////////////////
// subrule_context: special context used with subrules, to pass around
// the current set of subrule definitions (subrule_group)
///////////////////////////////////////////////////////////////////////////
template <typename Group, typename Attributes, typename Locals>
struct subrule_context
: context<Attributes, Locals>
{
typedef context<Attributes, Locals> base_type;
typedef Group group_type;
subrule_context(
Group const& group
, typename Attributes::car_type attribute
) : base_type(attribute), group(group)
{
}
template <typename Args, typename Context>
subrule_context(
Group const& group
, typename Attributes::car_type attribute
, Args const& args
, Context& caller_context
) : base_type(attribute, args, caller_context), group(group)
{
}
subrule_context(Group const& group, Attributes const& attributes)
: base_type(attributes), group(group)
{
}
Group const& group;
};
}}}
#endif