mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-25 08:38:10 +00:00
Added thirdparty: boost library
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2014 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)
|
||||
#define BOOST_SPIRIT_X3_DEBUG_HANDLER_STATE_APR_21_2010_0733PM
|
||||
|
||||
namespace boost { namespace spirit { namespace x3
|
||||
{
|
||||
enum debug_handler_state
|
||||
{
|
||||
pre_parse
|
||||
, successful_parse
|
||||
, failed_parse
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+347
@@ -0,0 +1,347 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2014 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM)
|
||||
#define BOOST_SPIRIT_X3_DETAIL_RULE_JAN_08_2012_0326PM
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/spirit/home/x3/auxiliary/guard.hpp>
|
||||
#include <boost/spirit/home/x3/core/parser.hpp>
|
||||
#include <boost/spirit/home/x3/core/skip_over.hpp>
|
||||
#include <boost/spirit/home/x3/directive/expect.hpp>
|
||||
#include <boost/spirit/home/x3/nonterminal/detail/transform_attribute.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
|
||||
#if defined(BOOST_SPIRIT_X3_DEBUG)
|
||||
#include <boost/spirit/home/x3/nonterminal/simple_trace.hpp>
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace spirit { namespace x3
|
||||
{
|
||||
template <typename ID>
|
||||
struct identity;
|
||||
|
||||
template <typename ID, typename Attribute = unused_type, bool force_attribute = false>
|
||||
struct rule;
|
||||
|
||||
struct parse_pass_context_tag;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename ID>
|
||||
struct rule_id {};
|
||||
|
||||
// we use this so we can detect if the default parse_rule
|
||||
// is the being called.
|
||||
struct default_parse_rule_result
|
||||
{
|
||||
default_parse_rule_result(bool r)
|
||||
: r(r) {}
|
||||
operator bool() const { return r; }
|
||||
bool r;
|
||||
};
|
||||
}
|
||||
|
||||
// default parse_rule implementation
|
||||
template <typename ID, typename Iterator
|
||||
, typename Context, typename ActualAttribute>
|
||||
inline detail::default_parse_rule_result
|
||||
parse_rule(
|
||||
detail::rule_id<ID>
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, ActualAttribute& attr);
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace x3 { namespace detail
|
||||
{
|
||||
#if defined(BOOST_SPIRIT_X3_DEBUG)
|
||||
template <typename Iterator, typename Attribute>
|
||||
struct context_debug
|
||||
{
|
||||
context_debug(
|
||||
char const* rule_name
|
||||
, Iterator const& first, Iterator const& last
|
||||
, Attribute const& attr
|
||||
, bool const& ok_parse //was parse successful?
|
||||
)
|
||||
: ok_parse(ok_parse), rule_name(rule_name)
|
||||
, first(first), last(last)
|
||||
, attr(attr)
|
||||
, f(detail::get_simple_trace())
|
||||
{
|
||||
f(first, last, attr, pre_parse, rule_name);
|
||||
}
|
||||
|
||||
~context_debug()
|
||||
{
|
||||
auto status = ok_parse ? successful_parse : failed_parse ;
|
||||
f(first, last, attr, status, rule_name);
|
||||
}
|
||||
|
||||
bool const& ok_parse;
|
||||
char const* rule_name;
|
||||
Iterator const& first;
|
||||
Iterator const& last;
|
||||
Attribute const& attr;
|
||||
detail::simple_trace_type& f;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename ID, typename Iterator, typename Context, typename Enable = void>
|
||||
struct has_on_error : mpl::false_ {};
|
||||
|
||||
template <typename ID, typename Iterator, typename Context>
|
||||
struct has_on_error<ID, Iterator, Context,
|
||||
decltype(void(
|
||||
std::declval<ID>().on_error(
|
||||
std::declval<Iterator&>()
|
||||
, std::declval<Iterator>()
|
||||
, std::declval<expectation_failure<Iterator>>()
|
||||
, std::declval<Context>()
|
||||
)
|
||||
))
|
||||
>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
template <typename ID, typename Iterator, typename Attribute, typename Context, typename Enable = void>
|
||||
struct has_on_success : mpl::false_ {};
|
||||
|
||||
template <typename ID, typename Iterator, typename Attribute, typename Context>
|
||||
struct has_on_success<ID, Iterator, Context, Attribute,
|
||||
decltype(void(
|
||||
std::declval<ID>().on_success(
|
||||
std::declval<Iterator&>()
|
||||
, std::declval<Iterator&>()
|
||||
, std::declval<Attribute&>()
|
||||
, std::declval<Context>()
|
||||
)
|
||||
))
|
||||
>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
template <typename ID>
|
||||
struct make_id
|
||||
{
|
||||
typedef identity<ID> type;
|
||||
};
|
||||
|
||||
template <typename ID>
|
||||
struct make_id<identity<ID>>
|
||||
{
|
||||
typedef identity<ID> type;
|
||||
};
|
||||
|
||||
template <typename ID, typename RHS, typename Context>
|
||||
Context const&
|
||||
make_rule_context(RHS const& /* rhs */, Context const& context
|
||||
, mpl::false_ /* is_default_parse_rule */)
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
template <typename ID, typename RHS, typename Context>
|
||||
auto make_rule_context(RHS const& rhs, Context const& context
|
||||
, mpl::true_ /* is_default_parse_rule */ )
|
||||
{
|
||||
return make_unique_context<ID>(rhs, context);
|
||||
}
|
||||
|
||||
template <typename Attribute, typename ID, bool skip_definition_injection = false>
|
||||
struct rule_parser
|
||||
{
|
||||
template <typename Iterator, typename Context, typename ActualAttribute>
|
||||
static bool call_on_success(
|
||||
Iterator& /* before */, Iterator& /* after */
|
||||
, Context const& /* context */, ActualAttribute& /* attr */
|
||||
, mpl::false_ /* No on_success handler */ )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context, typename ActualAttribute>
|
||||
static bool call_on_success(
|
||||
Iterator& before, Iterator& after
|
||||
, Context const& context, ActualAttribute& attr
|
||||
, mpl::true_ /* Has on_success handler */)
|
||||
{
|
||||
x3::skip_over(before, after, context);
|
||||
bool pass = true;
|
||||
ID().on_success(
|
||||
before
|
||||
, after
|
||||
, attr
|
||||
, make_context<parse_pass_context_tag>(pass, context)
|
||||
);
|
||||
return pass;
|
||||
}
|
||||
|
||||
template <typename RHS, typename Iterator, typename Context
|
||||
, typename RContext, typename ActualAttribute>
|
||||
static bool parse_rhs_main(
|
||||
RHS const& rhs
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, ActualAttribute& attr
|
||||
, mpl::false_)
|
||||
{
|
||||
// see if the user has a BOOST_SPIRIT_DEFINE for this rule
|
||||
typedef
|
||||
decltype(parse_rule(
|
||||
detail::rule_id<ID>{}, first, last
|
||||
, make_unique_context<ID>(rhs, context), std::declval<Attribute&>()))
|
||||
parse_rule_result;
|
||||
|
||||
// If there is no BOOST_SPIRIT_DEFINE for this rule,
|
||||
// we'll make a context for this rule tagged by its ID
|
||||
// so we can extract the rule later on in the default
|
||||
// (generic) parse_rule function.
|
||||
typedef
|
||||
is_same<parse_rule_result, default_parse_rule_result>
|
||||
is_default_parse_rule;
|
||||
|
||||
Iterator start = first;
|
||||
bool r = rhs.parse(
|
||||
first
|
||||
, last
|
||||
, make_rule_context<ID>(rhs, context, std::conditional_t<skip_definition_injection, mpl::false_, is_default_parse_rule>())
|
||||
, rcontext
|
||||
, attr
|
||||
);
|
||||
|
||||
if (r)
|
||||
{
|
||||
r = call_on_success(start, first, context, attr
|
||||
, has_on_success<ID, Iterator, Context, ActualAttribute>());
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename RHS, typename Iterator, typename Context
|
||||
, typename RContext, typename ActualAttribute>
|
||||
static bool parse_rhs_main(
|
||||
RHS const& rhs
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, ActualAttribute& attr
|
||||
, mpl::true_ /* on_error is found */)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
try
|
||||
{
|
||||
return parse_rhs_main(
|
||||
rhs, first, last, context, rcontext, attr, mpl::false_());
|
||||
}
|
||||
catch (expectation_failure<Iterator> const& x)
|
||||
{
|
||||
switch (ID().on_error(first, last, x, context))
|
||||
{
|
||||
case error_handler_result::fail:
|
||||
return false;
|
||||
case error_handler_result::retry:
|
||||
continue;
|
||||
case error_handler_result::accept:
|
||||
return true;
|
||||
case error_handler_result::rethrow:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RHS, typename Iterator
|
||||
, typename Context, typename RContext, typename ActualAttribute>
|
||||
static bool parse_rhs_main(
|
||||
RHS const& rhs
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, ActualAttribute& attr)
|
||||
{
|
||||
return parse_rhs_main(
|
||||
rhs, first, last, context, rcontext, attr
|
||||
, has_on_error<ID, Iterator, Context>()
|
||||
);
|
||||
}
|
||||
|
||||
template <typename RHS, typename Iterator
|
||||
, typename Context, typename RContext, typename ActualAttribute>
|
||||
static bool parse_rhs(
|
||||
RHS const& rhs
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, ActualAttribute& attr
|
||||
, mpl::false_)
|
||||
{
|
||||
return parse_rhs_main(rhs, first, last, context, rcontext, attr);
|
||||
}
|
||||
|
||||
template <typename RHS, typename Iterator
|
||||
, typename Context, typename RContext, typename ActualAttribute>
|
||||
static bool parse_rhs(
|
||||
RHS const& rhs
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, RContext& rcontext, ActualAttribute& /* attr */
|
||||
, mpl::true_)
|
||||
{
|
||||
return parse_rhs_main(rhs, first, last, context, rcontext, unused);
|
||||
}
|
||||
|
||||
template <typename RHS, typename Iterator, typename Context
|
||||
, typename ActualAttribute, typename ExplicitAttrPropagation>
|
||||
static bool call_rule_definition(
|
||||
RHS const& rhs
|
||||
, char const* rule_name
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, ActualAttribute& attr
|
||||
, ExplicitAttrPropagation)
|
||||
{
|
||||
boost::ignore_unused(rule_name);
|
||||
|
||||
// do down-stream transformation, provides attribute for
|
||||
// rhs parser
|
||||
typedef traits::transform_attribute<
|
||||
ActualAttribute, Attribute, parser_id>
|
||||
transform;
|
||||
|
||||
typedef typename transform::type transform_attr;
|
||||
transform_attr attr_ = transform::pre(attr);
|
||||
|
||||
bool ok_parse
|
||||
//Creates a place to hold the result of parse_rhs
|
||||
//called inside the following scope.
|
||||
;
|
||||
{
|
||||
// Create a scope to cause the dbg variable below (within
|
||||
// the #if...#endif) to call it's DTOR before any
|
||||
// modifications are made to the attribute, attr_ passed
|
||||
// to parse_rhs (such as might be done in
|
||||
// transform::post when, for example,
|
||||
// ActualAttribute is a recursive variant).
|
||||
#if defined(BOOST_SPIRIT_X3_DEBUG)
|
||||
context_debug<Iterator, transform_attr>
|
||||
dbg(rule_name, first, last, attr_, ok_parse);
|
||||
#endif
|
||||
ok_parse = parse_rhs(rhs, first, last, context, attr_, attr_
|
||||
, mpl::bool_
|
||||
< ( RHS::has_action
|
||||
&& !ExplicitAttrPropagation::value
|
||||
)
|
||||
>()
|
||||
);
|
||||
}
|
||||
if (ok_parse)
|
||||
{
|
||||
// do up-stream transformation, this integrates the results
|
||||
// back into the original attribute value, if appropriate
|
||||
transform::post(attr, std::forward<transform_attr>(attr_));
|
||||
}
|
||||
return ok_parse;
|
||||
}
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
Vendored
Executable
+92
@@ -0,0 +1,92 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2014 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#ifndef BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP
|
||||
#define BOOST_SPIRIT_X3_NONTERMINAL_DETAIL_TRANSFORM_ATTRIBUTE_HPP
|
||||
|
||||
#include <boost/spirit/home/x3/support/traits/transform_attribute.hpp>
|
||||
#include <boost/spirit/home/x3/support/traits/move_to.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace x3
|
||||
{
|
||||
struct parser_id;
|
||||
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct default_transform_attribute
|
||||
{
|
||||
typedef Transformed type;
|
||||
|
||||
static Transformed pre(Exposed&) { return Transformed(); }
|
||||
|
||||
static void post(Exposed& val, Transformed&& attribute)
|
||||
{
|
||||
traits::move_to(std::forward<Transformed>(attribute), val);
|
||||
}
|
||||
};
|
||||
|
||||
// handle case where no transformation is required as the types are the same
|
||||
template <typename Attribute>
|
||||
struct default_transform_attribute<Attribute, Attribute>
|
||||
{
|
||||
typedef Attribute& type;
|
||||
static Attribute& pre(Attribute& val) { return val; }
|
||||
static void post(Attribute&, Attribute const&) {}
|
||||
};
|
||||
|
||||
// main specialization for x3
|
||||
template <typename Exposed, typename Transformed, typename Enable = void>
|
||||
struct transform_attribute
|
||||
: default_transform_attribute<Exposed, Transformed> {};
|
||||
|
||||
// unused_type needs some special handling as well
|
||||
template <>
|
||||
struct transform_attribute<unused_type, unused_type>
|
||||
{
|
||||
typedef unused_type type;
|
||||
static unused_type pre(unused_type) { return unused; }
|
||||
static void post(unused_type, unused_type) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct transform_attribute<unused_type const, unused_type>
|
||||
: transform_attribute<unused_type, unused_type> {};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<unused_type, Attribute>
|
||||
: transform_attribute<unused_type, unused_type> {};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<unused_type const, Attribute>
|
||||
: transform_attribute<unused_type, unused_type> {};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute, unused_type>
|
||||
: transform_attribute<unused_type, unused_type> {};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute const, unused_type>
|
||||
: transform_attribute<unused_type, unused_type> {};
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace x3 { namespace traits
|
||||
{
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct transform_attribute<Exposed, Transformed, x3::parser_id>
|
||||
: x3::transform_attribute<Exposed, Transformed>
|
||||
{
|
||||
static_assert(!std::is_reference<Exposed>::value,
|
||||
"Exposed cannot be a reference type");
|
||||
static_assert(!std::is_reference<Transformed>::value,
|
||||
"Transformed cannot be a reference type");
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
+260
@@ -0,0 +1,260 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2014 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM)
|
||||
#define BOOST_SPIRIT_X3_RULE_JAN_08_2012_0326PM
|
||||
|
||||
#include <boost/spirit/home/x3/nonterminal/detail/rule.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/spirit/home/x3/support/context.hpp>
|
||||
#include <boost/preprocessor/variadic/to_seq.hpp>
|
||||
#include <boost/preprocessor/variadic/elem.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
|
||||
#include <typeinfo>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace x3
|
||||
{
|
||||
// default parse_rule implementation
|
||||
template <typename ID, typename Iterator
|
||||
, typename Context, typename ActualAttribute>
|
||||
inline detail::default_parse_rule_result
|
||||
parse_rule(
|
||||
detail::rule_id<ID>
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context const& context, ActualAttribute& attr)
|
||||
{
|
||||
static_assert(!is_same<decltype(x3::get<ID>(context)), unused_type>::value,
|
||||
"BOOST_SPIRIT_DEFINE undefined for this rule.");
|
||||
return x3::get<ID>(context).parse(first, last, context, unused, attr);
|
||||
}
|
||||
|
||||
template <typename ID, typename RHS, typename Attribute, bool force_attribute_, bool skip_definition_injection = false>
|
||||
struct rule_definition : parser<rule_definition<ID, RHS, Attribute, force_attribute_, skip_definition_injection>>
|
||||
{
|
||||
typedef rule_definition<ID, RHS, Attribute, force_attribute_, skip_definition_injection> this_type;
|
||||
typedef ID id;
|
||||
typedef RHS rhs_type;
|
||||
typedef rule<ID, Attribute, force_attribute_> lhs_type;
|
||||
typedef Attribute attribute_type;
|
||||
|
||||
static bool const has_attribute =
|
||||
!is_same<Attribute, unused_type>::value;
|
||||
static bool const handles_container =
|
||||
traits::is_container<Attribute>::value;
|
||||
static bool const force_attribute =
|
||||
force_attribute_;
|
||||
|
||||
constexpr rule_definition(RHS const& rhs, char const* name)
|
||||
: rhs(rhs), name(name) {}
|
||||
|
||||
template <typename Iterator, typename Context, typename Attribute_>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context const& context, unused_type, Attribute_& attr) const
|
||||
{
|
||||
return detail::rule_parser<attribute_type, ID, skip_definition_injection>
|
||||
::call_rule_definition(
|
||||
rhs, name, first, last
|
||||
, context
|
||||
, attr
|
||||
, mpl::bool_<force_attribute>());
|
||||
}
|
||||
|
||||
RHS rhs;
|
||||
char const* name;
|
||||
};
|
||||
|
||||
template <typename ID, typename Attribute, bool force_attribute_>
|
||||
struct rule : parser<rule<ID, Attribute, force_attribute_>>
|
||||
{
|
||||
static_assert(!std::is_reference<Attribute>::value,
|
||||
"Reference qualifier on rule attribute type is meaningless");
|
||||
|
||||
typedef ID id;
|
||||
typedef Attribute attribute_type;
|
||||
static bool const has_attribute =
|
||||
!std::is_same<std::remove_const_t<Attribute>, unused_type>::value;
|
||||
static bool const handles_container =
|
||||
traits::is_container<Attribute>::value;
|
||||
static bool const force_attribute = force_attribute_;
|
||||
|
||||
#if !defined(BOOST_SPIRIT_X3_NO_RTTI)
|
||||
rule() : name(typeid(rule).name()) {}
|
||||
#else
|
||||
constexpr rule() : name("unnamed") {}
|
||||
#endif
|
||||
|
||||
constexpr rule(char const* name)
|
||||
: name(name) {}
|
||||
|
||||
constexpr rule(rule const& r)
|
||||
: name(r.name)
|
||||
{
|
||||
// Assert that we are not copying an unitialized static rule. If
|
||||
// the static is in another TU, it may be initialized after we copy
|
||||
// it. If so, its name member will be nullptr.
|
||||
BOOST_ASSERT_MSG(r.name, "uninitialized rule"); // static initialization order fiasco
|
||||
}
|
||||
|
||||
template <typename RHS>
|
||||
constexpr rule_definition<
|
||||
ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_>
|
||||
operator=(RHS const& rhs) const&
|
||||
{
|
||||
return { as_parser(rhs), name };
|
||||
}
|
||||
|
||||
template <typename RHS>
|
||||
constexpr rule_definition<
|
||||
ID, typename extension::as_parser<RHS>::value_type, Attribute, true>
|
||||
operator%=(RHS const& rhs) const&
|
||||
{
|
||||
return { as_parser(rhs), name };
|
||||
}
|
||||
|
||||
// When a rule placeholder constructed and immediately consumed it cannot be used recursively,
|
||||
// that's why the rule definition injection into a parser context can be skipped.
|
||||
// This optimization has a huge impact on compile times because immediate rules are commonly
|
||||
// used to cast an attribute like `as`/`attr_cast` does in Qi.
|
||||
template <typename RHS>
|
||||
constexpr rule_definition<
|
||||
ID, typename extension::as_parser<RHS>::value_type, Attribute, force_attribute_, true>
|
||||
operator=(RHS const& rhs) const&&
|
||||
{
|
||||
return { as_parser(rhs), name };
|
||||
}
|
||||
|
||||
template <typename RHS>
|
||||
constexpr rule_definition<
|
||||
ID, typename extension::as_parser<RHS>::value_type, Attribute, true, true>
|
||||
operator%=(RHS const& rhs) const&&
|
||||
{
|
||||
return { as_parser(rhs), name };
|
||||
}
|
||||
|
||||
|
||||
template <typename Iterator, typename Context, typename Attribute_>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context const& context, unused_type, Attribute_& attr) const
|
||||
{
|
||||
static_assert(has_attribute,
|
||||
"The rule does not have an attribute. Check your parser.");
|
||||
|
||||
using transform = traits::transform_attribute<
|
||||
Attribute_, attribute_type, parser_id>;
|
||||
|
||||
using transform_attr = typename transform::type;
|
||||
transform_attr attr_ = transform::pre(attr);
|
||||
|
||||
if (parse_rule(detail::rule_id<ID>{}, first, last, context, attr_)) {
|
||||
transform::post(attr, std::forward<transform_attr>(attr_));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context const& context, unused_type, unused_type) const
|
||||
{
|
||||
// make sure we pass exactly the rule attribute type
|
||||
attribute_type no_attr{};
|
||||
return parse_rule(detail::rule_id<ID>{}, first, last, context, no_attr);
|
||||
}
|
||||
|
||||
char const* name;
|
||||
};
|
||||
|
||||
namespace traits
|
||||
{
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_rule : mpl::false_ {};
|
||||
|
||||
template <typename ID, typename Attribute, bool force_attribute>
|
||||
struct is_rule<rule<ID, Attribute, force_attribute>> : mpl::true_ {};
|
||||
|
||||
template <typename ID, typename Attribute, typename RHS, bool force_attribute, bool skip_definition_injection>
|
||||
struct is_rule<rule_definition<ID, RHS, Attribute, force_attribute, skip_definition_injection>> : mpl::true_ {};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct get_info<T, typename enable_if<traits::is_rule<T>>::type>
|
||||
{
|
||||
typedef std::string result_type;
|
||||
std::string operator()(T const& r) const
|
||||
{
|
||||
BOOST_ASSERT_MSG(r.name, "uninitialized rule"); // static initialization order fiasco
|
||||
return r.name? r.name : "uninitialized";
|
||||
}
|
||||
};
|
||||
|
||||
#define BOOST_SPIRIT_DECLARE_(r, data, rule_type) \
|
||||
template <typename Iterator, typename Context> \
|
||||
bool parse_rule( \
|
||||
::boost::spirit::x3::detail::rule_id<rule_type::id> \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, rule_type::attribute_type& attr); \
|
||||
/***/
|
||||
|
||||
#define BOOST_SPIRIT_DECLARE(...) BOOST_PP_SEQ_FOR_EACH( \
|
||||
BOOST_SPIRIT_DECLARE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
|
||||
/***/
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
#define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
|
||||
using BOOST_PP_CAT(rule_name, _synonym) = decltype(rule_name); \
|
||||
template <typename Iterator, typename Context> \
|
||||
inline bool parse_rule( \
|
||||
::boost::spirit::x3::detail::rule_id<BOOST_PP_CAT(rule_name, _synonym)::id> \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, BOOST_PP_CAT(rule_name, _synonym)::attribute_type& attr) \
|
||||
{ \
|
||||
using rule_t = BOOST_JOIN(rule_name, _synonym); \
|
||||
return ::boost::spirit::x3::detail \
|
||||
::rule_parser<typename rule_t::attribute_type, rule_t::id, true> \
|
||||
::call_rule_definition( \
|
||||
BOOST_JOIN(rule_name, _def), rule_name.name \
|
||||
, first, last, context, attr \
|
||||
, ::boost::mpl::bool_<rule_t::force_attribute>()); \
|
||||
} \
|
||||
/***/
|
||||
#else
|
||||
#define BOOST_SPIRIT_DEFINE_(r, data, rule_name) \
|
||||
template <typename Iterator, typename Context> \
|
||||
inline bool parse_rule( \
|
||||
::boost::spirit::x3::detail::rule_id<decltype(rule_name)::id> \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, decltype(rule_name)::attribute_type& attr) \
|
||||
{ \
|
||||
using rule_t = decltype(rule_name); \
|
||||
return ::boost::spirit::x3::detail \
|
||||
::rule_parser<typename rule_t::attribute_type, rule_t::id, true> \
|
||||
::call_rule_definition( \
|
||||
BOOST_JOIN(rule_name, _def), rule_name.name \
|
||||
, first, last, context, attr \
|
||||
, ::boost::mpl::bool_<rule_t::force_attribute>()); \
|
||||
} \
|
||||
/***/
|
||||
#endif
|
||||
|
||||
#define BOOST_SPIRIT_DEFINE(...) BOOST_PP_SEQ_FOR_EACH( \
|
||||
BOOST_SPIRIT_DEFINE_, _, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
|
||||
/***/
|
||||
|
||||
#define BOOST_SPIRIT_INSTANTIATE(rule_type, Iterator, Context) \
|
||||
template bool parse_rule<Iterator, Context>( \
|
||||
::boost::spirit::x3::detail::rule_id<rule_type::id> \
|
||||
, Iterator& first, Iterator const& last \
|
||||
, Context const& context, rule_type::attribute_type&); \
|
||||
/***/
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2014 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
|
||||
#define BOOST_SPIRIT_X3_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
|
||||
|
||||
#include <boost/spirit/home/x3/support/unused.hpp>
|
||||
#include <boost/spirit/home/x3/support/traits/print_token.hpp>
|
||||
#include <boost/spirit/home/x3/support/traits/print_attribute.hpp>
|
||||
#include <boost/spirit/home/x3/nonterminal/debug_handler_state.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <iostream>
|
||||
|
||||
// The stream to use for debug output
|
||||
#if !defined(BOOST_SPIRIT_X3_DEBUG_OUT)
|
||||
#define BOOST_SPIRIT_X3_DEBUG_OUT std::cerr
|
||||
#endif
|
||||
|
||||
// number of tokens to print while debugging
|
||||
#if !defined(BOOST_SPIRIT_X3_DEBUG_PRINT_SOME)
|
||||
#define BOOST_SPIRIT_X3_DEBUG_PRINT_SOME 20
|
||||
#endif
|
||||
|
||||
// number of spaces to indent
|
||||
#if !defined(BOOST_SPIRIT_X3_DEBUG_INDENT)
|
||||
#define BOOST_SPIRIT_X3_DEBUG_INDENT 2
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace x3
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <typename Char>
|
||||
inline void token_printer(std::ostream& o, Char c)
|
||||
{
|
||||
// allow customization of the token printer routine
|
||||
x3::traits::print_token(o, c);
|
||||
}
|
||||
}
|
||||
|
||||
template <int IndentSpaces = 2, int CharsToPrint = 20>
|
||||
struct simple_trace
|
||||
{
|
||||
simple_trace(std::ostream& out)
|
||||
: out(out), indent(0) {}
|
||||
|
||||
void print_indent(int n) const
|
||||
{
|
||||
n *= IndentSpaces;
|
||||
for (int i = 0; i != n; ++i)
|
||||
out << ' ';
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void print_some(
|
||||
char const* tag
|
||||
, Iterator first, Iterator const& last) const
|
||||
{
|
||||
print_indent(indent);
|
||||
out << '<' << tag << '>';
|
||||
int const n = CharsToPrint;
|
||||
for (int i = 0; first != last && i != n && *first; ++i, ++first)
|
||||
detail::token_printer(out, *first);
|
||||
out << "</" << tag << '>' << std::endl;
|
||||
|
||||
// $$$ FIXME convert invalid xml characters (e.g. '<') to valid
|
||||
// character entities. $$$
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute, typename State>
|
||||
void operator()(
|
||||
Iterator const& first
|
||||
, Iterator const& last
|
||||
, Attribute const& attr
|
||||
, State state
|
||||
, std::string const& rule_name) const
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case pre_parse:
|
||||
print_indent(indent++);
|
||||
out
|
||||
<< '<' << rule_name << '>'
|
||||
<< std::endl;
|
||||
print_some("try", first, last);
|
||||
break;
|
||||
|
||||
case successful_parse:
|
||||
print_some("success", first, last);
|
||||
if (!is_same<Attribute, unused_type>::value)
|
||||
{
|
||||
print_indent(indent);
|
||||
out
|
||||
<< "<attributes>";
|
||||
traits::print_attribute(out, attr);
|
||||
out
|
||||
<< "</attributes>";
|
||||
out << std::endl;
|
||||
}
|
||||
print_indent(--indent);
|
||||
out
|
||||
<< "</" << rule_name << '>'
|
||||
<< std::endl;
|
||||
break;
|
||||
|
||||
case failed_parse:
|
||||
print_indent(indent);
|
||||
out << "<fail/>" << std::endl;
|
||||
print_indent(--indent);
|
||||
out
|
||||
<< "</" << rule_name << '>'
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& out;
|
||||
mutable int indent;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
typedef simple_trace<
|
||||
BOOST_SPIRIT_X3_DEBUG_INDENT, BOOST_SPIRIT_X3_DEBUG_PRINT_SOME>
|
||||
simple_trace_type;
|
||||
|
||||
inline simple_trace_type&
|
||||
get_simple_trace()
|
||||
{
|
||||
static simple_trace_type tracer(BOOST_SPIRIT_X3_DEBUG_OUT);
|
||||
return tracer;
|
||||
}
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user