stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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_ACTION_DISPATCH_APRIL_18_2008_0720AM)
|
||||
#define BOOST_SPIRIT_ACTION_DISPATCH_APRIL_18_2008_0720AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include<boost/config.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <typename Component>
|
||||
struct action_dispatch
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_LAMBDAS) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
// omit function parameters without specializing for each possible
|
||||
// type of callable entity
|
||||
// many thanks to Eelis/##iso-c++ for this contribution
|
||||
|
||||
private:
|
||||
// this will be used to pass around POD types which are safe
|
||||
// to go through the ellipsis operator (if ever used)
|
||||
template <typename>
|
||||
struct fwd_tag {};
|
||||
|
||||
// the first parameter is a placeholder to obtain SFINAE when
|
||||
// doing overload resolution, the second one is the actual
|
||||
// forwarder, where we can apply our implementation
|
||||
template <typename, typename T>
|
||||
struct fwd_storage { typedef T type; };
|
||||
|
||||
// gcc should accept fake<T>() but it prints a sorry, needs
|
||||
// a check once the bug is sorted out, use a FAKE_CALL macro for now
|
||||
template <typename T>
|
||||
T fake_call();
|
||||
|
||||
#define BOOST_SPIRIT_FAKE_CALL(T) (*(T*)0)
|
||||
|
||||
// the forwarders, here we could tweak the implementation of
|
||||
// how parameters are passed to the functions, if needed
|
||||
struct fwd_none
|
||||
{
|
||||
template<typename F, typename... Rest>
|
||||
auto operator()(F && f, Rest&&...) -> decltype(f())
|
||||
{
|
||||
return f();
|
||||
}
|
||||
};
|
||||
|
||||
struct fwd_attrib
|
||||
{
|
||||
template<typename F, typename A, typename... Rest>
|
||||
auto operator()(F && f, A && a, Rest&&...) -> decltype(f(a))
|
||||
{
|
||||
return f(a);
|
||||
}
|
||||
};
|
||||
|
||||
struct fwd_attrib_context
|
||||
{
|
||||
template<typename F, typename A, typename B, typename... Rest>
|
||||
auto operator()(F && f, A && a, B && b, Rest&&...)
|
||||
-> decltype(f(a, b))
|
||||
{
|
||||
return f(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
struct fwd_attrib_context_pass
|
||||
{
|
||||
template<typename F, typename A, typename B, typename C
|
||||
, typename... Rest>
|
||||
auto operator()(F && f, A && a, B && b, C && c, Rest&&...)
|
||||
-> decltype(f(a, b, c))
|
||||
{
|
||||
return f(a, b, c);
|
||||
}
|
||||
};
|
||||
|
||||
// SFINAE for our calling syntax, the forwarders are stored based
|
||||
// on what function call gives a proper result
|
||||
// this code can probably be more generic once implementations are
|
||||
// steady
|
||||
template <typename F>
|
||||
static auto do_call(F && f, ...)
|
||||
-> typename fwd_storage<decltype(f()), fwd_none>::type
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename F, typename A>
|
||||
static auto do_call(F && f, fwd_tag<A>, ...)
|
||||
-> typename fwd_storage<decltype(f(BOOST_SPIRIT_FAKE_CALL(A)))
|
||||
, fwd_attrib>::type
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename F, typename A, typename B>
|
||||
static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, ...)
|
||||
-> typename fwd_storage<
|
||||
decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)))
|
||||
, fwd_attrib_context>::type
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename F, typename A, typename B, typename C>
|
||||
static auto do_call(F && f, fwd_tag<A>, fwd_tag<B>, fwd_tag<C>, ...)
|
||||
-> typename fwd_storage<
|
||||
decltype(f(BOOST_SPIRIT_FAKE_CALL(A), BOOST_SPIRIT_FAKE_CALL(B)
|
||||
, BOOST_SPIRIT_FAKE_CALL(C)))
|
||||
, fwd_attrib_context_pass>::type
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// this function calls the forwarder and is responsible for
|
||||
// stripping the tail of the parameters
|
||||
template <typename F, typename... A>
|
||||
static void caller(F && f, A && ... a)
|
||||
{
|
||||
do_call(f, fwd_tag<typename std::remove_reference<A>::type>()...)
|
||||
(std::forward<F>(f), std::forward<A>(a)...);
|
||||
}
|
||||
|
||||
#undef BOOST_SPIRIT_FAKE_CALL
|
||||
|
||||
public:
|
||||
template <typename F, typename Attribute, typename Context>
|
||||
bool operator()(F const& f, Attribute& attr, Context& context)
|
||||
{
|
||||
bool pass = true;
|
||||
caller(f, attr, context, pass);
|
||||
return pass;
|
||||
}
|
||||
#else
|
||||
// general handler for everything not explicitly specialized below
|
||||
template <typename F, typename Attribute, typename Context>
|
||||
bool operator()(F const& f, Attribute& attr, Context& context)
|
||||
{
|
||||
bool pass = true;
|
||||
f(attr, context, pass);
|
||||
return pass;
|
||||
}
|
||||
#endif
|
||||
|
||||
// handler for phoenix actors
|
||||
|
||||
// If the component this action has to be invoked for is a tuple, we
|
||||
// wrap any non-fusion tuple into a fusion tuple (done by pass_attribute)
|
||||
// and pass through any fusion tuple.
|
||||
template <typename Eval, typename Attribute, typename Context>
|
||||
bool operator()(phoenix::actor<Eval> const& f
|
||||
, Attribute& attr, Context& context)
|
||||
{
|
||||
bool pass = true;
|
||||
typename pass_attribute<Component, Attribute>::type attr_wrap(attr);
|
||||
f(attr_wrap, context, pass);
|
||||
return pass;
|
||||
}
|
||||
|
||||
// specializations for plain function pointers taking different number of
|
||||
// arguments
|
||||
template <typename RT, typename A0, typename A1, typename A2
|
||||
, typename Attribute, typename Context>
|
||||
bool operator()(RT(*f)(A0, A1, A2), Attribute& attr, Context& context)
|
||||
{
|
||||
bool pass = true;
|
||||
f(attr, context, pass);
|
||||
return pass;
|
||||
}
|
||||
|
||||
template <typename RT, typename A0, typename A1
|
||||
, typename Attribute, typename Context>
|
||||
bool operator()(RT(*f)(A0, A1), Attribute& attr, Context& context)
|
||||
{
|
||||
f(attr, context);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename RT, typename A0, typename Attribute, typename Context>
|
||||
bool operator()(RT(*f)(A0), Attribute& attr, Context&)
|
||||
{
|
||||
f(attr);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename RT, typename Attribute, typename Context>
|
||||
bool operator()(RT(*f)(), Attribute&, Context&)
|
||||
{
|
||||
f();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+406
@@ -0,0 +1,406 @@
|
||||
// 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_ADAPT_ADT_ATTRIBUTES_SEP_15_2010_1219PM)
|
||||
#define BOOST_SPIRIT_ADAPT_ADT_ATTRIBUTES_SEP_15_2010_1219PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/support/numeric_traits.hpp>
|
||||
#include <boost/fusion/include/adapt_adt.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// customization points allowing to use adapted classes with spirit
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, int N, bool Const, typename Domain>
|
||||
struct not_is_variant<
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const>, Domain>
|
||||
: not_is_variant<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
, Domain>
|
||||
{};
|
||||
|
||||
template <typename T, int N, bool Const, typename Domain>
|
||||
struct not_is_optional<
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const>, Domain>
|
||||
: not_is_optional<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
, Domain>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, int N, bool Const>
|
||||
struct is_container<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
: is_container<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct container_value<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
: container_value<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<
|
||||
T, N, Const
|
||||
>::type
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct container_value<
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const> const>
|
||||
: container_value<
|
||||
typename add_const<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<
|
||||
T, N, Const
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename T, int N, typename Val>
|
||||
struct push_back_container<
|
||||
fusion::extension::adt_attribute_proxy<T, N, false>
|
||||
, Val
|
||||
, typename enable_if<is_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, false>::type
|
||||
> >::type>
|
||||
{
|
||||
static bool call(
|
||||
fusion::extension::adt_attribute_proxy<T, N, false>& p
|
||||
, Val const& val)
|
||||
{
|
||||
typedef typename
|
||||
fusion::extension::adt_attribute_proxy<T, N, false>::type
|
||||
type;
|
||||
return push_back(type(p), val);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct container_iterator<
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
: container_iterator<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<
|
||||
T, N, Const
|
||||
>::type
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct container_iterator<
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const> const>
|
||||
: container_iterator<
|
||||
typename add_const<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<
|
||||
T, N, Const
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct begin_container<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
typedef typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>::type container_type;
|
||||
|
||||
static typename container_iterator<container_type>::type
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const>& c)
|
||||
{
|
||||
return c.get().begin();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct begin_container<fusion::extension::adt_attribute_proxy<T, N, Const> const>
|
||||
{
|
||||
typedef typename add_const<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>::type
|
||||
>::type container_type;
|
||||
|
||||
static typename container_iterator<container_type>::type
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& c)
|
||||
{
|
||||
return c.get().begin();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct end_container<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
typedef typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>::type container_type;
|
||||
|
||||
static typename container_iterator<container_type>::type
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const>& c)
|
||||
{
|
||||
return c.get().end();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct end_container<fusion::extension::adt_attribute_proxy<T, N, Const> const>
|
||||
{
|
||||
typedef typename add_const<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>::type
|
||||
>::type container_type;
|
||||
|
||||
static typename container_iterator<container_type>::type
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& c)
|
||||
{
|
||||
return c.get().end();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, int N, typename Val>
|
||||
struct assign_to_attribute_from_value<
|
||||
fusion::extension::adt_attribute_proxy<T, N, false>
|
||||
, Val>
|
||||
{
|
||||
static void
|
||||
call(Val const& val
|
||||
, fusion::extension::adt_attribute_proxy<T, N, false>& attr)
|
||||
{
|
||||
attr = val;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const, typename Exposed>
|
||||
struct extract_from_attribute<
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const>, Exposed>
|
||||
{
|
||||
typedef typename remove_const<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>::type
|
||||
>::type embedded_type;
|
||||
typedef
|
||||
typename spirit::result_of::extract_from<Exposed, embedded_type>::type
|
||||
type;
|
||||
|
||||
template <typename Context>
|
||||
static type
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val, Context& ctx)
|
||||
{
|
||||
return extract_from<Exposed>(val.get(), ctx);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, int N, bool Const>
|
||||
struct attribute_type<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
: fusion::extension::adt_attribute_proxy<T, N, Const>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, int N, bool Const>
|
||||
struct optional_attribute<
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
typedef typename result_of::optional_value<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>::type
|
||||
>::type type;
|
||||
|
||||
static type
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
|
||||
{
|
||||
return optional_value(val.get());
|
||||
}
|
||||
|
||||
static bool
|
||||
is_valid(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
|
||||
{
|
||||
return has_optional_value(val.get());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, int N, typename Attribute, typename Domain>
|
||||
struct transform_attribute<
|
||||
fusion::extension::adt_attribute_proxy<T, N, false>
|
||||
, Attribute
|
||||
, Domain
|
||||
, typename disable_if<is_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, false>::type
|
||||
> >::type>
|
||||
{
|
||||
typedef Attribute type;
|
||||
|
||||
static Attribute
|
||||
pre(fusion::extension::adt_attribute_proxy<T, N, false>& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
static void
|
||||
post(
|
||||
fusion::extension::adt_attribute_proxy<T, N, false>& val
|
||||
, Attribute const& attr)
|
||||
{
|
||||
val = attr;
|
||||
}
|
||||
static void
|
||||
fail(fusion::extension::adt_attribute_proxy<T, N, false>&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <
|
||||
typename T, int N, bool Const, typename Attribute, typename Domain>
|
||||
struct transform_attribute<
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const>
|
||||
, Attribute
|
||||
, Domain
|
||||
, typename enable_if<is_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<
|
||||
T, N, Const
|
||||
>::type
|
||||
> >::type>
|
||||
{
|
||||
typedef Attribute& type;
|
||||
|
||||
static Attribute&
|
||||
pre(fusion::extension::adt_attribute_proxy<T, N, Const>& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
static void
|
||||
post(
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const>&
|
||||
, Attribute const&)
|
||||
{
|
||||
}
|
||||
static void
|
||||
fail(fusion::extension::adt_attribute_proxy<T, N, Const>&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct clear_value<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
static void call(
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const>& val)
|
||||
{
|
||||
typedef typename
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
type;
|
||||
clear(type(val));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct attribute_size<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
typedef typename remove_const<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>::type
|
||||
>::type embedded_type;
|
||||
|
||||
typedef typename attribute_size<embedded_type>::type type;
|
||||
|
||||
static type
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
|
||||
{
|
||||
return attribute_size<embedded_type>::call(val.get());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// customization point specializations for numeric generators
|
||||
template <typename T, int N, bool Const>
|
||||
struct absolute_value<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
typedef typename
|
||||
fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
type;
|
||||
|
||||
static type
|
||||
call (fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
|
||||
{
|
||||
return get_absolute_value(val.get());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct is_negative<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
static bool
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
|
||||
{
|
||||
return test_negative(val.get());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct is_zero<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
static bool
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
|
||||
{
|
||||
return test_zero(val.get());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct is_nan<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
static bool
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
|
||||
{
|
||||
return test_nan(val.get());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, int N, bool Const>
|
||||
struct is_infinite<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
{
|
||||
static bool
|
||||
call(fusion::extension::adt_attribute_proxy<T, N, Const> const& val)
|
||||
{
|
||||
return test_infinite(val.get());
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace result_of
|
||||
{
|
||||
template <typename T, int N, bool Const>
|
||||
struct optional_value<fusion::extension::adt_attribute_proxy<T, N, Const> >
|
||||
: result_of::optional_value<
|
||||
typename remove_const<
|
||||
typename remove_reference<
|
||||
typename fusion::extension::adt_attribute_proxy<T, N, Const>::type
|
||||
>::type
|
||||
>::type>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/*=============================================================================
|
||||
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_ANY_APRIL_22_2006_1147AM)
|
||||
#define BOOST_SPIRIT_ANY_APRIL_22_2006_1147AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/fusion/include/equal_to.hpp>
|
||||
#include <boost/fusion/include/next.hpp>
|
||||
#include <boost/fusion/include/deref.hpp>
|
||||
#include <boost/fusion/include/begin.hpp>
|
||||
#include <boost/fusion/include/end.hpp>
|
||||
#include <boost/fusion/include/any.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
// This is the binary version of fusion::any. This might
|
||||
// be a good candidate for inclusion in fusion algorithm
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename First1, typename Last, typename First2, typename F>
|
||||
inline bool
|
||||
any(First1 const&, First2 const&, Last const&, F const&, mpl::true_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename First1, typename Last, typename First2, typename F>
|
||||
inline bool
|
||||
any(First1 const& first1, First2 const& first2, Last const& last, F& f, mpl::false_)
|
||||
{
|
||||
return f(*first1, *first2) ||
|
||||
detail::any(
|
||||
fusion::next(first1)
|
||||
, fusion::next(first2)
|
||||
, last
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::next<First1>::type, Last>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Sequence1, typename Sequence2, typename F>
|
||||
inline bool
|
||||
any(Sequence1 const& seq1, Sequence2& seq2, F f)
|
||||
{
|
||||
return detail::any(
|
||||
fusion::begin(seq1)
|
||||
, fusion::begin(seq2)
|
||||
, fusion::end(seq1)
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::begin<Sequence1>::type
|
||||
, typename fusion::result_of::end<Sequence1>::type>());
|
||||
}
|
||||
|
||||
template <typename Sequence, typename F>
|
||||
inline bool
|
||||
any(Sequence const& seq, unused_type, F f)
|
||||
{
|
||||
return fusion::any(seq, f);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
/*=============================================================================
|
||||
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(BOOST_SPIRIT_ANY_IF_MARCH_30_2007_1220PM)
|
||||
#define BOOST_SPIRIT_ANY_IF_MARCH_30_2007_1220PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/fusion/include/equal_to.hpp>
|
||||
#include <boost/fusion/include/next.hpp>
|
||||
#include <boost/fusion/include/deref.hpp>
|
||||
#include <boost/fusion/include/value_of.hpp>
|
||||
#include <boost/fusion/include/begin.hpp>
|
||||
#include <boost/fusion/include/end.hpp>
|
||||
#include <boost/fusion/include/is_sequence.hpp>
|
||||
#include <boost/fusion/include/any.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is a special version for a binary fusion::any. The predicate
|
||||
// is used to decide whether to advance the second iterator or not.
|
||||
// This is needed for sequences containing components with unused
|
||||
// attributes. The second iterator is advanced only if the attribute
|
||||
// of the corresponding component iterator is not unused.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Pred>
|
||||
struct apply_predicate
|
||||
: mpl::apply1<Pred, typename fusion::result_of::value_of<Iterator>::type>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// if the predicate is true, attribute_next returns next(Iterator2),
|
||||
// otherwise Iterator2
|
||||
namespace result_of
|
||||
{
|
||||
template <
|
||||
typename Iterator1, typename Iterator2, typename Last2
|
||||
, typename Pred>
|
||||
struct attribute_next
|
||||
{
|
||||
typedef mpl::and_<
|
||||
apply_predicate<Iterator1, Pred>
|
||||
, mpl::not_<fusion::result_of::equal_to<Iterator2, Last2> >
|
||||
> pred;
|
||||
|
||||
typedef typename
|
||||
mpl::eval_if<
|
||||
pred
|
||||
, fusion::result_of::next<Iterator2>
|
||||
, mpl::identity<Iterator2>
|
||||
>::type
|
||||
type;
|
||||
|
||||
template <typename Iterator>
|
||||
static type
|
||||
call(Iterator const& i, mpl::true_)
|
||||
{
|
||||
return fusion::next(i);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static type
|
||||
call(Iterator const& i, mpl::false_)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static type
|
||||
call(Iterator const& i)
|
||||
{
|
||||
return call(i, pred());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <
|
||||
typename Pred, typename Iterator1, typename Last2
|
||||
, typename Iterator2>
|
||||
inline typename
|
||||
result_of::attribute_next<Iterator1, Iterator2, Last2, Pred
|
||||
>::type const
|
||||
attribute_next(Iterator2 const& i)
|
||||
{
|
||||
return result_of::attribute_next<
|
||||
Iterator1, Iterator2, Last2, Pred>::call(i);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// if the predicate is true, attribute_value returns deref(Iterator2),
|
||||
// otherwise unused
|
||||
namespace result_of
|
||||
{
|
||||
template <
|
||||
typename Iterator1, typename Iterator2, typename Last2
|
||||
, typename Pred>
|
||||
struct attribute_value
|
||||
{
|
||||
typedef mpl::and_<
|
||||
apply_predicate<Iterator1, Pred>
|
||||
, mpl::not_<fusion::result_of::equal_to<Iterator2, Last2> >
|
||||
> pred;
|
||||
|
||||
typedef typename
|
||||
mpl::eval_if<
|
||||
pred
|
||||
, fusion::result_of::deref<Iterator2>
|
||||
, mpl::identity<unused_type const>
|
||||
>::type
|
||||
type;
|
||||
|
||||
template <typename Iterator>
|
||||
static type
|
||||
call(Iterator const& i, mpl::true_)
|
||||
{
|
||||
return fusion::deref(i);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static type
|
||||
call(Iterator const&, mpl::false_)
|
||||
{
|
||||
return unused;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static type
|
||||
call(Iterator const& i)
|
||||
{
|
||||
return call(i, pred());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <
|
||||
typename Pred, typename Iterator1, typename Last2
|
||||
, typename Iterator2>
|
||||
inline typename
|
||||
result_of::attribute_value<Iterator1, Iterator2, Last2, Pred
|
||||
>::type
|
||||
attribute_value(Iterator2 const& i)
|
||||
{
|
||||
return result_of::attribute_value<
|
||||
Iterator1, Iterator2, Last2, Pred>::call(i);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename Pred, typename First1, typename Last1, typename First2
|
||||
, typename Last2, typename F>
|
||||
inline bool
|
||||
any_if (First1 const&, First2 const&, Last1 const&, Last2 const&
|
||||
, F const&, mpl::true_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <
|
||||
typename Pred, typename First1, typename Last1, typename First2
|
||||
, typename Last2, typename F>
|
||||
inline bool
|
||||
any_if (First1 const& first1, First2 const& first2, Last1 const& last1
|
||||
, Last2 const& last2, F& f, mpl::false_)
|
||||
{
|
||||
typename result_of::attribute_value<First1, First2, Last2, Pred>::type
|
||||
attribute = spirit::detail::attribute_value<Pred, First1, Last2>(first2);
|
||||
|
||||
return f(*first1, attribute) ||
|
||||
detail::any_if<Pred>(
|
||||
fusion::next(first1)
|
||||
, attribute_next<Pred, First1, Last2>(first2)
|
||||
, last1, last2
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::next<First1>::type, Last1>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Pred, typename Sequence1, typename Sequence2, typename F>
|
||||
inline bool
|
||||
any_if(Sequence1 const& seq1, Sequence2& seq2, F f, Pred)
|
||||
{
|
||||
return detail::any_if<Pred>(
|
||||
fusion::begin(seq1), fusion::begin(seq2)
|
||||
, fusion::end(seq1), fusion::end(seq2)
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::begin<Sequence1>::type
|
||||
, typename fusion::result_of::end<Sequence1>::type>());
|
||||
}
|
||||
|
||||
template <typename Pred, typename Sequence, typename F>
|
||||
inline bool
|
||||
any_if(Sequence const& seq, unused_type const, F f, Pred)
|
||||
{
|
||||
return fusion::any(seq, f);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*=============================================================================
|
||||
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(BOOST_SPIRIT_ANY_IF_NS_NOVEMBER_04_2008_0906PM)
|
||||
#define BOOST_SPIRIT_ANY_IF_NS_NOVEMBER_04_2008_0906PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/algorithm/any_if.hpp>
|
||||
#include <boost/spirit/home/support/algorithm/any_ns.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is a special version for a binary fusion::any. The predicate
|
||||
// is used to decide whether to advance the second iterator or not.
|
||||
// This is needed for sequences containing components with unused
|
||||
// attributes. The second iterator is advanced only if the attribute
|
||||
// of the corresponding component iterator is not unused.
|
||||
//
|
||||
// This is a non-short circuiting (ns) version of the any_if algorithm.
|
||||
// see any_if.hpp (uses | instead of ||).
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
template <
|
||||
typename Pred, typename First1, typename Last1, typename First2
|
||||
, typename Last2, typename F
|
||||
>
|
||||
inline bool
|
||||
any_if_ns(First1 const&, First2 const&, Last1 const&, Last2 const&
|
||||
, F const&, mpl::true_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <
|
||||
typename Pred, typename First1, typename Last1, typename First2
|
||||
, typename Last2, typename F
|
||||
>
|
||||
inline bool
|
||||
any_if_ns(First1 const& first1, First2 const& first2
|
||||
, Last1 const& last1, Last2 const& last2, F& f, mpl::false_)
|
||||
{
|
||||
return (0 != (f(*first1, spirit::detail::attribute_value<Pred, First1, Last2>(first2)) |
|
||||
detail::any_if_ns<Pred>(
|
||||
fusion::next(first1)
|
||||
, attribute_next<Pred, First1, Last2>(first2)
|
||||
, last1, last2
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::next<First1>::type, Last1>())));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Pred, typename Sequence1, typename Sequence2, typename F>
|
||||
inline bool
|
||||
any_if_ns(Sequence1 const& seq1, Sequence2& seq2, F f, Pred)
|
||||
{
|
||||
return detail::any_if_ns<Pred>(
|
||||
fusion::begin(seq1), fusion::begin(seq2)
|
||||
, fusion::end(seq1), fusion::end(seq2)
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::begin<Sequence1>::type
|
||||
, typename fusion::result_of::end<Sequence1>::type>());
|
||||
}
|
||||
|
||||
template <typename Pred, typename Sequence, typename F>
|
||||
inline bool
|
||||
any_if_ns(Sequence const& seq, unused_type const, F f, Pred)
|
||||
{
|
||||
return detail::any_ns(
|
||||
fusion::begin(seq)
|
||||
, fusion::end(seq)
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::begin<Sequence>::type
|
||||
, typename fusion::result_of::end<Sequence>::type>());
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*=============================================================================
|
||||
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_ANY_NS_MARCH_13_2007_0827AM)
|
||||
#define BOOST_SPIRIT_ANY_NS_MARCH_13_2007_0827AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/fusion/include/equal_to.hpp>
|
||||
#include <boost/fusion/include/next.hpp>
|
||||
#include <boost/fusion/include/deref.hpp>
|
||||
#include <boost/fusion/include/begin.hpp>
|
||||
#include <boost/fusion/include/end.hpp>
|
||||
#include <boost/fusion/include/any.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
// A non-short circuiting (ns) version of the any algorithm (uses
|
||||
// | instead of ||.
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename First1, typename Last, typename First2, typename F>
|
||||
inline bool
|
||||
any_ns(First1 const&, First2 const&, Last const&, F const&, mpl::true_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename First1, typename Last, typename First2, typename F>
|
||||
inline bool
|
||||
any_ns(First1 const& first1, First2 const& first2, Last const& last, F& f, mpl::false_)
|
||||
{
|
||||
return (0 != (f(*first1, *first2) |
|
||||
detail::any_ns(
|
||||
fusion::next(first1)
|
||||
, fusion::next(first2)
|
||||
, last
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::next<First1>::type, Last>())));
|
||||
}
|
||||
|
||||
template <typename First, typename Last, typename F>
|
||||
inline bool
|
||||
any_ns(First const&, Last const&, F const&, mpl::true_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename First, typename Last, typename F>
|
||||
inline bool
|
||||
any_ns(First const& first, Last const& last, F& f, mpl::false_)
|
||||
{
|
||||
return (0 != (f(*first) |
|
||||
detail::any_ns(
|
||||
fusion::next(first)
|
||||
, last
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::next<First>::type, Last>())));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Sequence1, typename Sequence2, typename F>
|
||||
inline bool
|
||||
any_ns(Sequence1 const& seq1, Sequence2& seq2, F f)
|
||||
{
|
||||
return detail::any_ns(
|
||||
fusion::begin(seq1)
|
||||
, fusion::begin(seq2)
|
||||
, fusion::end(seq1)
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::begin<Sequence1>::type
|
||||
, typename fusion::result_of::end<Sequence1>::type>());
|
||||
}
|
||||
|
||||
template <typename Sequence, typename F>
|
||||
inline bool
|
||||
any_ns(Sequence const& seq, unused_type, F f)
|
||||
{
|
||||
return detail::any_ns(
|
||||
fusion::begin(seq)
|
||||
, fusion::end(seq)
|
||||
, f
|
||||
, fusion::result_of::equal_to<
|
||||
typename fusion::result_of::begin<Sequence>::type
|
||||
, typename fusion::result_of::end<Sequence>::type>());
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
Copyright (c) 2011 Thomas Heller
|
||||
|
||||
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_ARGUMENT_FEBRUARY_17_2007_0339PM)
|
||||
#define BOOST_SPIRIT_ARGUMENT_FEBRUARY_17_2007_0339PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/spirit/home/support/assert_msg.hpp>
|
||||
#include <boost/spirit/home/support/limits.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/fusion/include/size.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
|
||||
#define SPIRIT_DECLARE_ARG(z, n, data) \
|
||||
typedef phoenix::actor<argument<n> > \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \
|
||||
phoenix::actor<argument<n> > const \
|
||||
BOOST_PP_CAT(_, BOOST_PP_INC(n)) = \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type)(); \
|
||||
/***/
|
||||
|
||||
#define SPIRIT_USING_ARGUMENT(z, n, data) \
|
||||
using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \
|
||||
using spirit::BOOST_PP_CAT(_, n); \
|
||||
/***/
|
||||
|
||||
#else
|
||||
|
||||
#define SPIRIT_DECLARE_ARG(z, n, data) \
|
||||
typedef phoenix::actor<argument<n> > \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(_, BOOST_PP_INC(n)), _type); \
|
||||
/***/
|
||||
|
||||
#define SPIRIT_USING_ARGUMENT(z, n, data) \
|
||||
using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_, n), _type); \
|
||||
/***/
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
template <int N>
|
||||
struct argument;
|
||||
|
||||
template <typename Dummy>
|
||||
struct attribute_context;
|
||||
}}
|
||||
|
||||
BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
|
||||
template <int N>
|
||||
, boost::spirit::argument<N>
|
||||
, mpl::false_ // is not nullary
|
||||
, v2_eval(
|
||||
proto::make<
|
||||
boost::spirit::argument<N>()
|
||||
>
|
||||
, proto::call<
|
||||
functional::env(proto::_state)
|
||||
>
|
||||
)
|
||||
)
|
||||
|
||||
BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
|
||||
template <typename Dummy>
|
||||
, boost::spirit::attribute_context<Dummy>
|
||||
, mpl::false_ // is not nullary
|
||||
, v2_eval(
|
||||
proto::make<
|
||||
boost::spirit::attribute_context<Dummy>()
|
||||
>
|
||||
, proto::call<
|
||||
functional::env(proto::_state)
|
||||
>
|
||||
)
|
||||
)
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace result_of
|
||||
{
|
||||
template <typename Sequence, int N>
|
||||
struct get_arg
|
||||
{
|
||||
typedef typename
|
||||
fusion::result_of::size<Sequence>::type
|
||||
sequence_size;
|
||||
|
||||
// report invalid argument not found (N is out of bounds)
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
(N < sequence_size::value),
|
||||
index_is_out_of_bounds, ());
|
||||
|
||||
typedef typename
|
||||
fusion::result_of::at_c<Sequence, N>::type
|
||||
type;
|
||||
|
||||
static type call(Sequence& seq)
|
||||
{
|
||||
return fusion::at_c<N>(seq);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Sequence, int N>
|
||||
struct get_arg<Sequence&, N> : get_arg<Sequence, N>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
template <int N, typename T>
|
||||
typename result_of::get_arg<T, N>::type
|
||||
get_arg(T& val)
|
||||
{
|
||||
return result_of::get_arg<T, N>::call(val);
|
||||
}
|
||||
|
||||
template <typename>
|
||||
struct attribute_context
|
||||
{
|
||||
typedef mpl::true_ no_nullary;
|
||||
|
||||
template <typename Env>
|
||||
struct result
|
||||
{
|
||||
// FIXME: is this remove_const really necessary?
|
||||
typedef typename
|
||||
remove_const<
|
||||
typename mpl::at_c<typename Env::args_type, 0>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Env>
|
||||
typename result<Env>::type
|
||||
eval(Env const& env) const
|
||||
{
|
||||
return fusion::at_c<0>(env.args());
|
||||
}
|
||||
};
|
||||
|
||||
template <int N>
|
||||
struct argument
|
||||
{
|
||||
typedef mpl::true_ no_nullary;
|
||||
|
||||
template <typename Env>
|
||||
struct result
|
||||
{
|
||||
typedef typename
|
||||
mpl::at_c<typename Env::args_type, 0>::type
|
||||
arg_type;
|
||||
|
||||
typedef typename result_of::get_arg<arg_type, N>::type type;
|
||||
};
|
||||
|
||||
template <typename Env>
|
||||
typename result<Env>::type
|
||||
eval(Env const& env) const
|
||||
{
|
||||
return get_arg<N>(fusion::at_c<0>(env.args()));
|
||||
}
|
||||
};
|
||||
|
||||
// _0 refers to the whole attribute as generated by the lhs parser
|
||||
typedef phoenix::actor<attribute_context<void> > _0_type;
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
_0_type const _0 = _0_type();
|
||||
#endif
|
||||
|
||||
// _1, _2, ... refer to the attributes of the single components the lhs
|
||||
// parser is composed of
|
||||
typedef phoenix::actor<argument<0> > _1_type;
|
||||
typedef phoenix::actor<argument<1> > _2_type;
|
||||
typedef phoenix::actor<argument<2> > _3_type;
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
_1_type const _1 = _1_type();
|
||||
_2_type const _2 = _2_type();
|
||||
_3_type const _3 = _3_type();
|
||||
#endif
|
||||
|
||||
// '_pass' may be used to make a match fail in retrospective
|
||||
typedef phoenix::arg_names::_3_type _pass_type;
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
_pass_type const _pass = _pass_type();
|
||||
#endif
|
||||
|
||||
// Bring in the rest of the arguments and attributes (_4 .. _N+1), using PP
|
||||
BOOST_PP_REPEAT_FROM_TO(
|
||||
3, SPIRIT_ARGUMENTS_LIMIT, SPIRIT_DECLARE_ARG, _)
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
// You can bring these in with the using directive
|
||||
// without worrying about bringing in too much.
|
||||
namespace labels
|
||||
{
|
||||
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
|
||||
}
|
||||
#endif
|
||||
|
||||
}}
|
||||
|
||||
#undef SPIRIT_DECLARE_ARG
|
||||
#endif
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2011 Thomas Heller
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
Copyright (c) 2011 Thomas Heller
|
||||
|
||||
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_ARGUMENT_MARCH_22_2011_0939PM)
|
||||
#define BOOST_SPIRIT_ARGUMENT_MARCH_22_2011_0939PM
|
||||
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
template <int N>
|
||||
struct argument;
|
||||
|
||||
template <typename Dummy>
|
||||
struct attribute_context;
|
||||
|
||||
namespace expression
|
||||
{
|
||||
template <int N>
|
||||
struct argument
|
||||
: phoenix::expression::terminal<spirit::argument<N> >
|
||||
{
|
||||
typedef typename phoenix::expression::terminal<
|
||||
spirit::argument<N>
|
||||
>::type type;
|
||||
|
||||
static type make()
|
||||
{
|
||||
type const e = {{{}}};
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Dummy>
|
||||
struct attribute_context
|
||||
: phoenix::expression::terminal<spirit::attribute_context<Dummy> >
|
||||
{
|
||||
typedef typename phoenix::expression::terminal<
|
||||
spirit::attribute_context<Dummy>
|
||||
>::type type;
|
||||
|
||||
static type make()
|
||||
{
|
||||
type const e = {{{}}};
|
||||
return e;
|
||||
}
|
||||
};
|
||||
}
|
||||
}}
|
||||
|
||||
namespace boost { namespace phoenix
|
||||
{
|
||||
namespace result_of
|
||||
{
|
||||
template <typename Dummy>
|
||||
struct is_nullary<custom_terminal<spirit::attribute_context<Dummy> > >
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template <int N>
|
||||
struct is_nullary<custom_terminal<spirit::argument<N> > >
|
||||
: mpl::false_
|
||||
{};
|
||||
}
|
||||
|
||||
template <typename Dummy>
|
||||
struct is_custom_terminal<spirit::attribute_context<Dummy> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
template <int N>
|
||||
struct is_custom_terminal<spirit::argument<N> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
template <typename Dummy>
|
||||
struct custom_terminal<spirit::attribute_context<Dummy> >
|
||||
: proto::call<
|
||||
v2_eval(
|
||||
proto::make<spirit::attribute_context<Dummy>()>
|
||||
, proto::call<
|
||||
functional::env(proto::_state)
|
||||
>
|
||||
)
|
||||
>
|
||||
{};
|
||||
|
||||
template <int N>
|
||||
struct custom_terminal<spirit::argument<N> >
|
||||
: proto::call<
|
||||
v2_eval(
|
||||
proto::make<spirit::argument<N>()>
|
||||
, proto::call<
|
||||
functional::env(proto::_state)
|
||||
>
|
||||
)
|
||||
>
|
||||
{};
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2001-2013 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_ASSERT_MSG_JUN_23_2009_0836AM)
|
||||
#define BOOST_SPIRIT_ASSERT_MSG_JUN_23_2009_0836AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Work around the MPL problem in BOOST_MPL_ASSERT_MSG generating
|
||||
// multiple definition linker errors for certain compilers (VC++ 8).
|
||||
// BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG can also be defined by user.
|
||||
#if !defined(BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG)
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC < 1500
|
||||
# define BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) || BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG != 0
|
||||
#include <boost/static_assert.hpp>
|
||||
#define BOOST_SPIRIT_ASSERT_MSG(Cond, Msg, Types) \
|
||||
BOOST_STATIC_ASSERT_MSG(Cond, # Msg)
|
||||
#else
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#define BOOST_SPIRIT_ASSERT_MSG(Cond, Msg, Types) \
|
||||
BOOST_MPL_ASSERT_MSG(Cond, Msg, Types)
|
||||
#endif
|
||||
|
||||
#define BOOST_SPIRIT_ASSERT_MATCH(Domain, Expr) \
|
||||
BOOST_SPIRIT_ASSERT_MSG(( \
|
||||
boost::spirit::traits::matches< Domain, Expr >::value \
|
||||
), error_invalid_expression, (Expr))
|
||||
|
||||
// GCC 4.7 will overeagerly instantiate static_asserts in template functions,
|
||||
// if the assert condition does not depend on template parameters
|
||||
// (see https://svn.boost.org/trac/boost/ticket/8381).
|
||||
// There are places where we want to use constant false as the condition in
|
||||
// template functions to indicate that these function overloads should never
|
||||
// be called. This allows to generate better error messages. To solve this
|
||||
// problem we make the condition dependent on the template argument and use
|
||||
// the following macro in such places.
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#define BOOST_SPIRIT_ASSERT_FAIL(TemplateParam, Msg, Types) \
|
||||
BOOST_SPIRIT_ASSERT_MSG((!boost::is_same< \
|
||||
TemplateParam, TemplateParam >::value), Msg, Types)
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,297 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2010 Bryce Lelbach
|
||||
|
||||
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_ATTRIBUTES_FWD_OCT_01_2009_0715AM)
|
||||
#define BOOST_SPIRIT_ATTRIBUTES_FWD_OCT_01_2009_0715AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if (defined(__GNUC__) && (__GNUC__ < 4)) || \
|
||||
(defined(__APPLE__) && defined(__INTEL_COMPILER))
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#endif
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace result_of
|
||||
{
|
||||
// forward declaration only
|
||||
template <typename Exposed, typename Attribute>
|
||||
struct extract_from;
|
||||
|
||||
template <typename T, typename Attribute>
|
||||
struct attribute_as;
|
||||
|
||||
template <typename Exposed, typename Transformed, typename Domain>
|
||||
struct pre_transform;
|
||||
|
||||
template <typename T>
|
||||
struct optional_value;
|
||||
|
||||
template <typename Container>
|
||||
struct begin;
|
||||
|
||||
template <typename Container>
|
||||
struct end;
|
||||
|
||||
template <typename Iterator>
|
||||
struct deref;
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Find out if T can be a strong substitute for Expected attribute
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Expected, typename Enable = void>
|
||||
struct is_substitute;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Find out if T can be a weak substitute for Expected attribute
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Expected, typename Enable = void>
|
||||
struct is_weak_substitute;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Determine if T is a proxy
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_proxy;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Retrieve the attribute type to use from the given type
|
||||
//
|
||||
// This is needed to extract the correct attribute type from proxy classes
|
||||
// as utilized in FUSION_ADAPT_ADT et. al.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Attribute, typename Enable = void>
|
||||
struct attribute_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Retrieve the size of a fusion sequence (compile time)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct sequence_size;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Retrieve the size of an attribute (runtime)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Attribute, typename Enable = void>
|
||||
struct attribute_size;
|
||||
|
||||
template <typename Attribute>
|
||||
typename attribute_size<Attribute>::type
|
||||
size(Attribute const& attr);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Determines how we pass attributes to semantic actions. This
|
||||
// may be specialized. By default, all attributes are wrapped in
|
||||
// a fusion sequence, because the attribute has to be treated as being
|
||||
// a single value in any case (even if it actually already is a fusion
|
||||
// sequence in its own).
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Component, typename Attribute, typename Enable = void>
|
||||
struct pass_attribute;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Enable = void>
|
||||
struct optional_attribute;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Sometimes the user needs to transform the attribute types for certain
|
||||
// attributes. This template can be used as a customization point, where
|
||||
// the user is able specify specific transformation rules for any attribute
|
||||
// type.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Exposed, typename Transformed, typename Domain
|
||||
, typename Enable = void>
|
||||
struct transform_attribute;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Qi only
|
||||
template <typename Attribute, typename Iterator, typename Enable = void>
|
||||
struct assign_to_attribute_from_iterators;
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
void assign_to(Iterator const& first, Iterator const& last, Attribute& attr);
|
||||
|
||||
template <typename Iterator>
|
||||
void assign_to(Iterator const&, Iterator const&, unused_type);
|
||||
|
||||
template <typename Attribute, typename T, typename Enable = void>
|
||||
struct assign_to_attribute_from_value;
|
||||
|
||||
template <typename Attribute, typename T, typename Enable = void>
|
||||
struct assign_to_container_from_value;
|
||||
|
||||
template <typename T, typename Attribute>
|
||||
void assign_to(T const& val, Attribute& attr);
|
||||
|
||||
template <typename T>
|
||||
void assign_to(T const&, unused_type);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Karma only
|
||||
template <typename Attribute, typename Exposed, typename Enable = void>
|
||||
struct extract_from_attribute;
|
||||
|
||||
template <typename Attribute, typename Exposed, typename Enable = void>
|
||||
struct extract_from_container;
|
||||
|
||||
template <typename Exposed, typename Attribute, typename Context>
|
||||
typename spirit::result_of::extract_from<Exposed, Attribute>::type
|
||||
extract_from(Attribute const& attr, Context& ctx
|
||||
#if (defined(__GNUC__) && (__GNUC__ < 4)) || \
|
||||
(defined(__APPLE__) && defined(__INTEL_COMPILER))
|
||||
, typename enable_if<traits::not_is_unused<Attribute> >::type* = NULL
|
||||
#endif
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Karma only
|
||||
template <typename T, typename Attribute, typename Enable = void>
|
||||
struct attribute_as;
|
||||
|
||||
template <typename T, typename Attribute>
|
||||
typename spirit::result_of::attribute_as<T, Attribute>::type
|
||||
as(Attribute const& attr);
|
||||
|
||||
template <typename T, typename Attribute>
|
||||
bool valid_as(Attribute const& attr);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// return the type currently stored in the given variant
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Enable = void>
|
||||
struct variant_which;
|
||||
|
||||
template <typename T>
|
||||
int which(T const& v);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Determine, whether T is a variant like type
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Domain = unused_type, typename Enable = void>
|
||||
struct not_is_variant;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Determine, whether T is a variant like type
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Domain = unused_type, typename Enable = void>
|
||||
struct not_is_optional;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Clear data efficiently
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Enable = void>
|
||||
struct clear_value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Determine the value type of the given container type
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename Enable = void>
|
||||
struct container_value;
|
||||
|
||||
template <typename Container, typename Enable = void>
|
||||
struct container_iterator;
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_container;
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct is_iterator_range;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Attribute, typename Context = unused_type
|
||||
, typename Iterator = unused_type, typename Enable = void>
|
||||
struct handles_container;
|
||||
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence, typename Domain, typename Enable = void>
|
||||
struct pass_through_container;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Qi only
|
||||
template <typename Container, typename T, typename Enable = void>
|
||||
struct push_back_container;
|
||||
|
||||
template <typename Container, typename Enable = void>
|
||||
struct is_empty_container;
|
||||
|
||||
template <typename Container, typename Enable = void>
|
||||
struct make_container_attribute;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Determine the iterator type of the given container type
|
||||
// Karma only
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename Enable = void>
|
||||
struct begin_container;
|
||||
|
||||
template <typename Container, typename Enable = void>
|
||||
struct end_container;
|
||||
|
||||
template <typename Iterator, typename Enable = void>
|
||||
struct deref_iterator;
|
||||
|
||||
template <typename Iterator, typename Enable = void>
|
||||
struct next_iterator;
|
||||
|
||||
template <typename Iterator, typename Enable = void>
|
||||
struct compare_iterators;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Print the given attribute of type T to the stream given as Out
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Out, typename T, typename Enable = void>
|
||||
struct print_attribute_debug;
|
||||
|
||||
template <typename Out, typename T>
|
||||
void print_attribute(Out&, T const&);
|
||||
|
||||
template <typename Out>
|
||||
void print_attribute(Out&, unused_type);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char, typename Enable = void>
|
||||
struct token_printer_debug;
|
||||
|
||||
template<typename Out, typename T>
|
||||
void print_token(Out&, T const&);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Access attributes from a karma symbol table
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Attribute, typename Enable = void>
|
||||
struct symbols_lookup;
|
||||
|
||||
template <typename Attribute, typename T, typename Enable = void>
|
||||
struct symbols_value;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// transform attribute types exposed from compound operator components
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Attribute, typename Domain>
|
||||
struct alternative_attribute_transform;
|
||||
|
||||
template <typename Attribute, typename Domain>
|
||||
struct sequence_attribute_transform;
|
||||
|
||||
template <typename Attribute, typename Domain>
|
||||
struct permutation_attribute_transform;
|
||||
|
||||
template <typename Attribute, typename Domain>
|
||||
struct sequential_or_attribute_transform;
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2012 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_AUTO_FEBRUARY_7_2012_0159PM)
|
||||
#define BOOST_SPIRIT_AUTO_FEBRUARY_7_2012_0159PM
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/typeof/typeof.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
// Support for c++11 auto. See:
|
||||
// http://boost-spirit.com/home/articles/qi-example/zero-to-60-mph-in-2-seconds/
|
||||
// for more info
|
||||
|
||||
#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
|
||||
|
||||
#define BOOST_SPIRIT_AUTO(domain_, name, expr) \
|
||||
typedef boost::proto::result_of:: \
|
||||
deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
|
||||
BOOST_SPIRIT_ASSERT_MATCH( \
|
||||
boost::spirit::domain_::domain, name##_expr_type); \
|
||||
BOOST_AUTO(name, boost::proto::deep_copy(expr)); \
|
||||
/****/
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,212 @@
|
||||
// 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_SUPPORT_META_CREATE_NOV_21_2009_0327PM)
|
||||
#define BOOST_SPIRIT_SUPPORT_META_CREATE_NOV_21_2009_0327PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto
|
||||
#include <boost/proto/proto.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/fusion/include/fold.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
|
||||
// needed for workaround below
|
||||
#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is the main dispatch point for meta_create to the correct domain
|
||||
template <typename Domain, typename T, typename Enable = void>
|
||||
struct meta_create;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This allows to query whether a valid mapping exists for the given data
|
||||
// type to a component in the given domain
|
||||
template <typename Domain, typename T, typename Enable = void>
|
||||
struct meta_create_exists : mpl::false_ {};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
struct add_const_ref
|
||||
: add_reference<typename add_const<T>::type> {};
|
||||
|
||||
template <typename T>
|
||||
struct remove_const_ref
|
||||
: remove_const<typename remove_reference<T>::type> {};
|
||||
|
||||
// starting with Boost V1.42 fusion::fold has been changed to be compatible
|
||||
// with mpl::fold (the sequence of template parameters for the meta-function
|
||||
// object has been changed)
|
||||
#if BOOST_VERSION < 104200
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename OpTag, typename Domain>
|
||||
struct nary_proto_expr_function
|
||||
{
|
||||
template <typename T>
|
||||
struct result;
|
||||
|
||||
// this is a workaround for older versions of g++ (< V4.3) which apparently have
|
||||
// problems with the following template specialization
|
||||
#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
|
||||
template <typename F, typename T1, typename T2>
|
||||
struct result<F(T1, T2)>
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_same<F, nary_proto_expr_function>::value));
|
||||
#else
|
||||
template <typename T1, typename T2>
|
||||
struct result<nary_proto_expr_function(T1, T2)>
|
||||
{
|
||||
#endif
|
||||
typedef typename remove_const_ref<T2>::type left_type;
|
||||
typedef typename
|
||||
spirit::traits::meta_create<Domain, T1>::type
|
||||
right_type;
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
traits::not_is_unused<left_type>
|
||||
, proto::result_of::make_expr<OpTag, left_type, right_type>
|
||||
, mpl::identity<right_type>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
typename result<nary_proto_expr_function(T, unused_type const&)>::type
|
||||
operator()(T, unused_type const&) const
|
||||
{
|
||||
typedef spirit::traits::meta_create<Domain, T> right_type;
|
||||
return right_type::call();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
typename result<nary_proto_expr_function(T1, T2)>::type
|
||||
operator()(T1, T2 const& t2) const
|
||||
{
|
||||
// we variants to the alternative operator
|
||||
typedef spirit::traits::meta_create<Domain, T1> right_type;
|
||||
return proto::make_expr<OpTag>(t2, right_type::call());
|
||||
}
|
||||
};
|
||||
#else
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename OpTag, typename Domain>
|
||||
struct nary_proto_expr_function
|
||||
{
|
||||
template <typename T>
|
||||
struct result;
|
||||
|
||||
// this is a workaround for older versions of g++ (< V4.3) which apparently have
|
||||
// problems with the following template specialization
|
||||
#if defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ < 3))
|
||||
template <typename F, typename T1, typename T2>
|
||||
struct result<F(T1, T2)>
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_same<F, nary_proto_expr_function>::value));
|
||||
#else
|
||||
template <typename T1, typename T2>
|
||||
struct result<nary_proto_expr_function(T1, T2)>
|
||||
{
|
||||
#endif
|
||||
typedef typename remove_const_ref<T1>::type left_type;
|
||||
typedef typename
|
||||
spirit::traits::meta_create<Domain, T2>::type
|
||||
right_type;
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
traits::not_is_unused<left_type>
|
||||
, proto::result_of::make_expr<OpTag, left_type, right_type>
|
||||
, mpl::identity<right_type>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
typename result<nary_proto_expr_function(unused_type const&, T)>::type
|
||||
operator()(unused_type const&, T) const
|
||||
{
|
||||
typedef spirit::traits::meta_create<Domain, T> right_type;
|
||||
return right_type::call();
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
typename result<nary_proto_expr_function(T1, T2)>::type
|
||||
operator()(T1 const& t1, T2) const
|
||||
{
|
||||
// we variants to the alternative operator
|
||||
typedef spirit::traits::meta_create<Domain, T2> right_type;
|
||||
return proto::make_expr<OpTag>(t1, right_type::call());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename OpTag, typename Domain>
|
||||
struct make_unary_proto_expr
|
||||
{
|
||||
typedef spirit::traits::meta_create<Domain, T> subject_type;
|
||||
|
||||
typedef typename proto::result_of::make_expr<
|
||||
OpTag, typename subject_type::type
|
||||
>::type type;
|
||||
|
||||
static type call()
|
||||
{
|
||||
return proto::make_expr<OpTag>(subject_type::call());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Sequence, typename OpTag, typename Domain>
|
||||
struct make_nary_proto_expr
|
||||
{
|
||||
typedef detail::nary_proto_expr_function<OpTag, Domain>
|
||||
make_proto_expr;
|
||||
|
||||
typedef typename fusion::result_of::fold<
|
||||
Sequence, unused_type, make_proto_expr
|
||||
>::type type;
|
||||
|
||||
static type call()
|
||||
{
|
||||
return fusion::fold(Sequence(), unused, make_proto_expr());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
// Starting with newer versions of Proto, all Proto expressions are at
|
||||
// the same time Fusion sequences. This is the correct behavior, but
|
||||
// we need to distinguish between Fusion sequences and Proto
|
||||
// expressions. This meta-function does exactly that.
|
||||
template <typename T>
|
||||
struct is_fusion_sequence_but_not_proto_expr
|
||||
: mpl::and_<
|
||||
fusion::traits::is_sequence<T>
|
||||
, mpl::not_<proto::is_expr<T> > >
|
||||
{};
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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(SPIRIT_SUPPORT_ATTR_CAST_OCT_06_2009_00535PM)
|
||||
#define SPIRIT_SUPPORT_ATTR_CAST_OCT_06_2009_00535PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This one is the function that the user can call directly in order
|
||||
// to create a customized attr_cast component
|
||||
template <typename Expr>
|
||||
typename enable_if<proto::is_expr<Expr>
|
||||
, stateful_tag_type<Expr, tag::attr_cast> >::type
|
||||
attr_cast(Expr const& expr)
|
||||
{
|
||||
return stateful_tag_type<Expr, tag::attr_cast>(expr);
|
||||
}
|
||||
|
||||
template <typename Exposed, typename Expr>
|
||||
typename enable_if<proto::is_expr<Expr>
|
||||
, stateful_tag_type<Expr, tag::attr_cast, Exposed> >::type
|
||||
attr_cast(Expr const& expr)
|
||||
{
|
||||
return stateful_tag_type<Expr, tag::attr_cast, Exposed>(expr);
|
||||
}
|
||||
|
||||
template <typename Exposed, typename Transformed, typename Expr>
|
||||
typename enable_if<proto::is_expr<Expr>
|
||||
, stateful_tag_type<Expr, tag::attr_cast, Exposed, Transformed> >::type
|
||||
attr_cast(Expr const& expr)
|
||||
{
|
||||
return stateful_tag_type<Expr, tag::attr_cast, Exposed, Transformed>(expr);
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,798 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_CHAR_CLASS_NOVEMBER_10_2006_0907AM)
|
||||
#define BOOST_SPIRIT_CHAR_CLASS_NOVEMBER_10_2006_0907AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto
|
||||
#include <boost/proto/proto.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <boost/type_traits/make_signed.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
# pragma warning(disable: 4800) // 'int' : forcing value to bool 'true' or 'false' warning
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
// Here's the thing... typical encodings (except ASCII) deal with unsigned
|
||||
// integers > 127. ASCII uses only 127. Yet, most char and wchar_t are signed.
|
||||
// Thus, a char with value > 127 is negative (e.g. char 233 is -23). When you
|
||||
// cast this to an unsigned int with 32 bits, you get 4294967273!
|
||||
//
|
||||
// The trick is to cast to an unsigned version of the source char first
|
||||
// before casting to the target. {P.S. Don't worry about the code, the
|
||||
// optimizer will optimize the if-else branches}
|
||||
|
||||
template <typename TargetChar, typename SourceChar>
|
||||
TargetChar cast_char(SourceChar ch)
|
||||
{
|
||||
if (is_signed<TargetChar>::value != is_signed<SourceChar>::value)
|
||||
{
|
||||
if (is_signed<SourceChar>::value)
|
||||
{
|
||||
// source is signed, target is unsigned
|
||||
typedef typename make_unsigned<SourceChar>::type USourceChar;
|
||||
return TargetChar(USourceChar(ch));
|
||||
}
|
||||
else
|
||||
{
|
||||
// source is unsigned, target is signed
|
||||
typedef typename make_signed<SourceChar>::type SSourceChar;
|
||||
return TargetChar(SSourceChar(ch));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// source and target has same signedness
|
||||
return TargetChar(ch); // just cast
|
||||
}
|
||||
}
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace tag
|
||||
{
|
||||
struct char_ { BOOST_SPIRIT_IS_TAG() };
|
||||
struct string { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// classification tags
|
||||
struct alnum { BOOST_SPIRIT_IS_TAG() };
|
||||
struct alpha { BOOST_SPIRIT_IS_TAG() };
|
||||
struct digit { BOOST_SPIRIT_IS_TAG() };
|
||||
struct xdigit { BOOST_SPIRIT_IS_TAG() };
|
||||
struct cntrl { BOOST_SPIRIT_IS_TAG() };
|
||||
struct graph { BOOST_SPIRIT_IS_TAG() };
|
||||
struct print { BOOST_SPIRIT_IS_TAG() };
|
||||
struct punct { BOOST_SPIRIT_IS_TAG() };
|
||||
struct space { BOOST_SPIRIT_IS_TAG() };
|
||||
struct blank { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// classification/conversion tags
|
||||
struct no_case { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lower { BOOST_SPIRIT_IS_TAG() };
|
||||
struct upper { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lowernum { BOOST_SPIRIT_IS_TAG() };
|
||||
struct uppernum { BOOST_SPIRIT_IS_TAG() };
|
||||
struct ucs4 { BOOST_SPIRIT_IS_TAG() };
|
||||
struct encoding { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
#if defined(BOOST_SPIRIT_UNICODE)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Major Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct letter { BOOST_SPIRIT_IS_TAG() };
|
||||
struct mark { BOOST_SPIRIT_IS_TAG() };
|
||||
struct number { BOOST_SPIRIT_IS_TAG() };
|
||||
struct separator { BOOST_SPIRIT_IS_TAG() };
|
||||
struct other { BOOST_SPIRIT_IS_TAG() };
|
||||
struct punctuation { BOOST_SPIRIT_IS_TAG() };
|
||||
struct symbol { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode General Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct uppercase_letter { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lowercase_letter { BOOST_SPIRIT_IS_TAG() };
|
||||
struct titlecase_letter { BOOST_SPIRIT_IS_TAG() };
|
||||
struct modifier_letter { BOOST_SPIRIT_IS_TAG() };
|
||||
struct other_letter { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
struct nonspacing_mark { BOOST_SPIRIT_IS_TAG() };
|
||||
struct enclosing_mark { BOOST_SPIRIT_IS_TAG() };
|
||||
struct spacing_mark { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
struct decimal_number { BOOST_SPIRIT_IS_TAG() };
|
||||
struct letter_number { BOOST_SPIRIT_IS_TAG() };
|
||||
struct other_number { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
struct space_separator { BOOST_SPIRIT_IS_TAG() };
|
||||
struct line_separator { BOOST_SPIRIT_IS_TAG() };
|
||||
struct paragraph_separator { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
struct control { BOOST_SPIRIT_IS_TAG() };
|
||||
struct format { BOOST_SPIRIT_IS_TAG() };
|
||||
struct private_use { BOOST_SPIRIT_IS_TAG() };
|
||||
struct surrogate { BOOST_SPIRIT_IS_TAG() };
|
||||
struct unassigned { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
struct dash_punctuation { BOOST_SPIRIT_IS_TAG() };
|
||||
struct open_punctuation { BOOST_SPIRIT_IS_TAG() };
|
||||
struct close_punctuation { BOOST_SPIRIT_IS_TAG() };
|
||||
struct connector_punctuation { BOOST_SPIRIT_IS_TAG() };
|
||||
struct other_punctuation { BOOST_SPIRIT_IS_TAG() };
|
||||
struct initial_punctuation { BOOST_SPIRIT_IS_TAG() };
|
||||
struct final_punctuation { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
struct math_symbol { BOOST_SPIRIT_IS_TAG() };
|
||||
struct currency_symbol { BOOST_SPIRIT_IS_TAG() };
|
||||
struct modifier_symbol { BOOST_SPIRIT_IS_TAG() };
|
||||
struct other_symbol { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Derived Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct alphabetic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct uppercase { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lowercase { BOOST_SPIRIT_IS_TAG() };
|
||||
struct white_space { BOOST_SPIRIT_IS_TAG() };
|
||||
struct hex_digit { BOOST_SPIRIT_IS_TAG() };
|
||||
struct noncharacter_code_point { BOOST_SPIRIT_IS_TAG() };
|
||||
struct default_ignorable_code_point { BOOST_SPIRIT_IS_TAG() };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Scripts
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct arabic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct imperial_aramaic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct armenian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct avestan { BOOST_SPIRIT_IS_TAG() };
|
||||
struct balinese { BOOST_SPIRIT_IS_TAG() };
|
||||
struct bamum { BOOST_SPIRIT_IS_TAG() };
|
||||
struct bengali { BOOST_SPIRIT_IS_TAG() };
|
||||
struct bopomofo { BOOST_SPIRIT_IS_TAG() };
|
||||
struct braille { BOOST_SPIRIT_IS_TAG() };
|
||||
struct buginese { BOOST_SPIRIT_IS_TAG() };
|
||||
struct buhid { BOOST_SPIRIT_IS_TAG() };
|
||||
struct canadian_aboriginal { BOOST_SPIRIT_IS_TAG() };
|
||||
struct carian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct cham { BOOST_SPIRIT_IS_TAG() };
|
||||
struct cherokee { BOOST_SPIRIT_IS_TAG() };
|
||||
struct coptic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct cypriot { BOOST_SPIRIT_IS_TAG() };
|
||||
struct cyrillic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct devanagari { BOOST_SPIRIT_IS_TAG() };
|
||||
struct deseret { BOOST_SPIRIT_IS_TAG() };
|
||||
struct egyptian_hieroglyphs { BOOST_SPIRIT_IS_TAG() };
|
||||
struct ethiopic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct georgian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct glagolitic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct gothic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct greek { BOOST_SPIRIT_IS_TAG() };
|
||||
struct gujarati { BOOST_SPIRIT_IS_TAG() };
|
||||
struct gurmukhi { BOOST_SPIRIT_IS_TAG() };
|
||||
struct hangul { BOOST_SPIRIT_IS_TAG() };
|
||||
struct han { BOOST_SPIRIT_IS_TAG() };
|
||||
struct hanunoo { BOOST_SPIRIT_IS_TAG() };
|
||||
struct hebrew { BOOST_SPIRIT_IS_TAG() };
|
||||
struct hiragana { BOOST_SPIRIT_IS_TAG() };
|
||||
struct katakana_or_hiragana { BOOST_SPIRIT_IS_TAG() };
|
||||
struct old_italic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct javanese { BOOST_SPIRIT_IS_TAG() };
|
||||
struct kayah_li { BOOST_SPIRIT_IS_TAG() };
|
||||
struct katakana { BOOST_SPIRIT_IS_TAG() };
|
||||
struct kharoshthi { BOOST_SPIRIT_IS_TAG() };
|
||||
struct khmer { BOOST_SPIRIT_IS_TAG() };
|
||||
struct kannada { BOOST_SPIRIT_IS_TAG() };
|
||||
struct kaithi { BOOST_SPIRIT_IS_TAG() };
|
||||
struct tai_tham { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lao { BOOST_SPIRIT_IS_TAG() };
|
||||
struct latin { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lepcha { BOOST_SPIRIT_IS_TAG() };
|
||||
struct limbu { BOOST_SPIRIT_IS_TAG() };
|
||||
struct linear_b { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lisu { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lycian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct lydian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct malayalam { BOOST_SPIRIT_IS_TAG() };
|
||||
struct mongolian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct meetei_mayek { BOOST_SPIRIT_IS_TAG() };
|
||||
struct myanmar { BOOST_SPIRIT_IS_TAG() };
|
||||
struct nko { BOOST_SPIRIT_IS_TAG() };
|
||||
struct ogham { BOOST_SPIRIT_IS_TAG() };
|
||||
struct ol_chiki { BOOST_SPIRIT_IS_TAG() };
|
||||
struct old_turkic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct oriya { BOOST_SPIRIT_IS_TAG() };
|
||||
struct osmanya { BOOST_SPIRIT_IS_TAG() };
|
||||
struct phags_pa { BOOST_SPIRIT_IS_TAG() };
|
||||
struct inscriptional_pahlavi { BOOST_SPIRIT_IS_TAG() };
|
||||
struct phoenician { BOOST_SPIRIT_IS_TAG() };
|
||||
struct inscriptional_parthian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct rejang { BOOST_SPIRIT_IS_TAG() };
|
||||
struct runic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct samaritan { BOOST_SPIRIT_IS_TAG() };
|
||||
struct old_south_arabian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct saurashtra { BOOST_SPIRIT_IS_TAG() };
|
||||
struct shavian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct sinhala { BOOST_SPIRIT_IS_TAG() };
|
||||
struct sundanese { BOOST_SPIRIT_IS_TAG() };
|
||||
struct syloti_nagri { BOOST_SPIRIT_IS_TAG() };
|
||||
struct syriac { BOOST_SPIRIT_IS_TAG() };
|
||||
struct tagbanwa { BOOST_SPIRIT_IS_TAG() };
|
||||
struct tai_le { BOOST_SPIRIT_IS_TAG() };
|
||||
struct new_tai_lue { BOOST_SPIRIT_IS_TAG() };
|
||||
struct tamil { BOOST_SPIRIT_IS_TAG() };
|
||||
struct tai_viet { BOOST_SPIRIT_IS_TAG() };
|
||||
struct telugu { BOOST_SPIRIT_IS_TAG() };
|
||||
struct tifinagh { BOOST_SPIRIT_IS_TAG() };
|
||||
struct tagalog { BOOST_SPIRIT_IS_TAG() };
|
||||
struct thaana { BOOST_SPIRIT_IS_TAG() };
|
||||
struct thai { BOOST_SPIRIT_IS_TAG() };
|
||||
struct tibetan { BOOST_SPIRIT_IS_TAG() };
|
||||
struct ugaritic { BOOST_SPIRIT_IS_TAG() };
|
||||
struct vai { BOOST_SPIRIT_IS_TAG() };
|
||||
struct old_persian { BOOST_SPIRIT_IS_TAG() };
|
||||
struct cuneiform { BOOST_SPIRIT_IS_TAG() };
|
||||
struct yi { BOOST_SPIRIT_IS_TAG() };
|
||||
struct inherited { BOOST_SPIRIT_IS_TAG() };
|
||||
struct common { BOOST_SPIRIT_IS_TAG() };
|
||||
struct unknown { BOOST_SPIRIT_IS_TAG() };
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This composite tag type encodes both the character
|
||||
// set and the specific char tag (used for classification
|
||||
// or conversion). char_code_base and char_encoding_base
|
||||
// can be used to test for modifier membership (see modifier.hpp)
|
||||
template <typename CharClass>
|
||||
struct char_code_base {};
|
||||
|
||||
template <typename CharEncoding>
|
||||
struct char_encoding_base {};
|
||||
|
||||
template <typename CharClass, typename CharEncoding>
|
||||
struct char_code
|
||||
: char_code_base<CharClass>, char_encoding_base<CharEncoding>
|
||||
{
|
||||
BOOST_SPIRIT_IS_TAG()
|
||||
typedef CharEncoding char_encoding; // e.g. ascii
|
||||
typedef CharClass char_class; // e.g. tag::alnum
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace char_class
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test characters for classification
|
||||
template <typename CharEncoding>
|
||||
struct classify
|
||||
{
|
||||
typedef typename CharEncoding::char_type char_type;
|
||||
|
||||
#define BOOST_SPIRIT_CLASSIFY(name, isname) \
|
||||
template <typename Char> \
|
||||
static bool \
|
||||
is(tag::name, Char ch) \
|
||||
{ \
|
||||
return CharEncoding::isname \
|
||||
BOOST_PREVENT_MACRO_SUBSTITUTION \
|
||||
(detail::cast_char<char_type>(ch)); \
|
||||
} \
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_CLASSIFY(char_, ischar)
|
||||
BOOST_SPIRIT_CLASSIFY(alnum, isalnum)
|
||||
BOOST_SPIRIT_CLASSIFY(alpha, isalpha)
|
||||
BOOST_SPIRIT_CLASSIFY(digit, isdigit)
|
||||
BOOST_SPIRIT_CLASSIFY(xdigit, isxdigit)
|
||||
BOOST_SPIRIT_CLASSIFY(cntrl, iscntrl)
|
||||
BOOST_SPIRIT_CLASSIFY(graph, isgraph)
|
||||
BOOST_SPIRIT_CLASSIFY(lower, islower)
|
||||
BOOST_SPIRIT_CLASSIFY(print, isprint)
|
||||
BOOST_SPIRIT_CLASSIFY(punct, ispunct)
|
||||
BOOST_SPIRIT_CLASSIFY(space, isspace)
|
||||
BOOST_SPIRIT_CLASSIFY(blank, isblank)
|
||||
BOOST_SPIRIT_CLASSIFY(upper, isupper)
|
||||
|
||||
#undef BOOST_SPIRIT_CLASSIFY
|
||||
|
||||
template <typename Char>
|
||||
static bool
|
||||
is(tag::lowernum, Char ch)
|
||||
{
|
||||
return CharEncoding::islower(detail::cast_char<char_type>(ch)) ||
|
||||
CharEncoding::isdigit(detail::cast_char<char_type>(ch));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
static bool
|
||||
is(tag::uppernum, Char ch)
|
||||
{
|
||||
return CharEncoding::isupper(detail::cast_char<char_type>(ch)) ||
|
||||
CharEncoding::isdigit(detail::cast_char<char_type>(ch));
|
||||
}
|
||||
|
||||
#if defined(BOOST_SPIRIT_UNICODE)
|
||||
|
||||
#define BOOST_SPIRIT_UNICODE_CLASSIFY(name) \
|
||||
template <typename Char> \
|
||||
static bool \
|
||||
is(tag::name, Char ch) \
|
||||
{ \
|
||||
return CharEncoding::is_##name(detail::cast_char<char_type>(ch)); \
|
||||
} \
|
||||
/***/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Major Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(mark)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(number)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(separator)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(other)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(symbol)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode General Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(uppercase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(lowercase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(titlecase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(modifier_letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(other_letter)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(nonspacing_mark)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(enclosing_mark)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(spacing_mark)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(decimal_number)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(letter_number)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(other_number)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(space_separator)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(line_separator)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(paragraph_separator)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(control)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(format)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(private_use)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(surrogate)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(unassigned)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(dash_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(open_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(close_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(connector_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(other_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(initial_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(final_punctuation)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(math_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(currency_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(modifier_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(other_symbol)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Derived Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(alphabetic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(uppercase)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(lowercase)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(white_space)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(hex_digit)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(noncharacter_code_point)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(default_ignorable_code_point)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Scripts
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(arabic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(imperial_aramaic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(armenian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(avestan)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(balinese)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(bamum)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(bengali)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(bopomofo)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(braille)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(buginese)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(buhid)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(canadian_aboriginal)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(carian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(cham)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(cherokee)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(coptic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(cypriot)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(cyrillic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(devanagari)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(deseret)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(egyptian_hieroglyphs)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(ethiopic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(georgian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(glagolitic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(gothic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(greek)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(gujarati)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(gurmukhi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(hangul)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(han)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(hanunoo)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(hebrew)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(hiragana)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(katakana_or_hiragana)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(old_italic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(javanese)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(kayah_li)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(katakana)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(kharoshthi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(khmer)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(kannada)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(kaithi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(tai_tham)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(lao)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(latin)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(lepcha)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(limbu)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(linear_b)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(lisu)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(lycian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(lydian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(malayalam)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(mongolian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(meetei_mayek)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(myanmar)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(nko)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(ogham)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(ol_chiki)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(old_turkic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(oriya)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(osmanya)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(phags_pa)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(inscriptional_pahlavi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(phoenician)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(inscriptional_parthian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(rejang)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(runic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(samaritan)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(old_south_arabian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(saurashtra)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(shavian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(sinhala)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(sundanese)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(syloti_nagri)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(syriac)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(tagbanwa)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(tai_le)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(new_tai_lue)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(tamil)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(tai_viet)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(telugu)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(tifinagh)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(tagalog)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(thaana)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(thai)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(tibetan)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(ugaritic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(vai)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(old_persian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(cuneiform)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(yi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(inherited)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(common)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY(unknown)
|
||||
|
||||
#undef BOOST_SPIRIT_UNICODE_CLASSIFY
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Convert characters
|
||||
template <typename CharEncoding>
|
||||
struct convert
|
||||
{
|
||||
typedef typename CharEncoding::char_type char_type;
|
||||
|
||||
template <typename Char>
|
||||
static Char
|
||||
to(tag::lower, Char ch)
|
||||
{
|
||||
return static_cast<Char>(
|
||||
CharEncoding::tolower(detail::cast_char<char_type>(ch)));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
static Char
|
||||
to(tag::upper, Char ch)
|
||||
{
|
||||
return static_cast<Char>(
|
||||
CharEncoding::toupper(detail::cast_char<char_type>(ch)));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
static Char
|
||||
to(tag::ucs4, Char ch)
|
||||
{
|
||||
return static_cast<Char>(
|
||||
CharEncoding::toucs4(detail::cast_char<char_type>(ch)));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
static Char
|
||||
to(unused_type, Char ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Info on character classification
|
||||
template <typename CharEncoding>
|
||||
struct what
|
||||
{
|
||||
#define BOOST_SPIRIT_CLASSIFY_WHAT(name, isname) \
|
||||
static char const* is(tag::name) \
|
||||
{ \
|
||||
return isname; \
|
||||
} \
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(char_, "char")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(alnum, "alnum")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(alpha, "alpha")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(digit, "digit")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(xdigit, "xdigit")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(cntrl, "cntrl")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(graph, "graph")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(lower, "lower")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(lowernum, "lowernum")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(print, "print")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(punct, "punct")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(space, "space")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(blank, "blank")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(upper, "upper")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(uppernum, "uppernum")
|
||||
BOOST_SPIRIT_CLASSIFY_WHAT(ucs4, "ucs4")
|
||||
|
||||
#undef BOOST_SPIRIT_CLASSIFY_WHAT
|
||||
|
||||
#if defined(BOOST_SPIRIT_UNICODE)
|
||||
|
||||
#define BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(name) \
|
||||
static char const* is(tag::name) \
|
||||
{ \
|
||||
return BOOST_PP_STRINGIZE(name); \
|
||||
} \
|
||||
/***/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Major Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(mark)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(number)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(separator)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(symbol)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode General Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(uppercase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lowercase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(titlecase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(modifier_letter)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other_letter)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(nonspacing_mark)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(enclosing_mark)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(spacing_mark)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(decimal_number)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(letter_number)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other_number)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(space_separator)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(line_separator)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(paragraph_separator)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(control)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(format)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(private_use)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(surrogate)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(unassigned)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(dash_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(open_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(close_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(connector_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(initial_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(final_punctuation)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(math_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(currency_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(modifier_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(other_symbol)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Derived Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(alphabetic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(uppercase)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lowercase)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(white_space)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hex_digit)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(noncharacter_code_point)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(default_ignorable_code_point)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Scripts
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(arabic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(imperial_aramaic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(armenian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(avestan)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(balinese)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(bamum)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(bengali)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(bopomofo)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(braille)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(buginese)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(buhid)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(canadian_aboriginal)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(carian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cham)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cherokee)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(coptic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cypriot)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cyrillic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(devanagari)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(deseret)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(egyptian_hieroglyphs)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(ethiopic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(georgian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(glagolitic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(gothic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(greek)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(gujarati)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(gurmukhi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hangul)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(han)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hanunoo)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hebrew)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(hiragana)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(katakana_or_hiragana)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(old_italic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(javanese)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(kayah_li)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(katakana)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(kharoshthi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(khmer)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(kannada)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(kaithi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tai_tham)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lao)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(latin)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lepcha)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(limbu)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(linear_b)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lisu)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lycian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(lydian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(malayalam)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(mongolian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(meetei_mayek)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(myanmar)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(nko)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(ogham)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(ol_chiki)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(old_turkic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(oriya)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(osmanya)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(phags_pa)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(inscriptional_pahlavi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(phoenician)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(inscriptional_parthian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(rejang)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(runic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(samaritan)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(old_south_arabian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(saurashtra)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(shavian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(sinhala)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(sundanese)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(syloti_nagri)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(syriac)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tagbanwa)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tai_le)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(new_tai_lue)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tamil)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tai_viet)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(telugu)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tifinagh)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tagalog)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(thaana)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(thai)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(tibetan)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(ugaritic)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(vai)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(old_persian)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(cuneiform)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(yi)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(inherited)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(common)
|
||||
BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT(unknown)
|
||||
|
||||
#undef BOOST_SPIRIT_UNICODE_CLASSIFY_WHAT
|
||||
#endif
|
||||
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This meta-function evaluates to mpl::true_ if the function
|
||||
// char_encoding::ischar() needs to be called to ensure correct matching.
|
||||
// This happens mainly if the character type returned from the underlying
|
||||
// iterator is larger than the character type of the used character
|
||||
// encoding. Additionally, this meta-function provides a customization
|
||||
// point for the lexer library to enforce this behavior while parsing
|
||||
// a token stream.
|
||||
template <typename Char, typename BaseChar>
|
||||
struct mustcheck_ischar
|
||||
: mpl::bool_<(sizeof(Char) > sizeof(BaseChar)) ? true : false> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// The following template calls char_encoding::ischar, if necessary
|
||||
template <typename CharParam, typename CharEncoding
|
||||
, bool MustCheck = mustcheck_ischar<
|
||||
CharParam, typename CharEncoding::char_type>::value>
|
||||
struct ischar
|
||||
{
|
||||
static bool call(CharParam)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CharParam, typename CharEncoding>
|
||||
struct ischar<CharParam, CharEncoding, true>
|
||||
{
|
||||
static bool call(CharParam const& ch)
|
||||
{
|
||||
return CharEncoding::ischar(int(ch));
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+318
@@ -0,0 +1,318 @@
|
||||
/*=============================================================================
|
||||
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(BOOST_SPIRIT_ASCII_APRIL_26_2006_1106PM)
|
||||
#define BOOST_SPIRIT_ASCII_APRIL_26_2006_1106PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <climits>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// constants used to classify the single characters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_CC_DIGIT 0x0001
|
||||
#define BOOST_CC_XDIGIT 0x0002
|
||||
#define BOOST_CC_ALPHA 0x0004
|
||||
#define BOOST_CC_CTRL 0x0008
|
||||
#define BOOST_CC_LOWER 0x0010
|
||||
#define BOOST_CC_UPPER 0x0020
|
||||
#define BOOST_CC_SPACE 0x0040
|
||||
#define BOOST_CC_PUNCT 0x0080
|
||||
|
||||
namespace boost { namespace spirit { namespace char_encoding
|
||||
{
|
||||
// The detection of isgraph(), isprint() and isblank() is done programmatically
|
||||
// to keep the character type table small. Additionally, these functions are
|
||||
// rather seldom used and the programmatic detection is very simple.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ASCII character classification table
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
const unsigned char ascii_char_types[] =
|
||||
{
|
||||
/* NUL 0 0 */ BOOST_CC_CTRL,
|
||||
/* SOH 1 1 */ BOOST_CC_CTRL,
|
||||
/* STX 2 2 */ BOOST_CC_CTRL,
|
||||
/* ETX 3 3 */ BOOST_CC_CTRL,
|
||||
/* EOT 4 4 */ BOOST_CC_CTRL,
|
||||
/* ENQ 5 5 */ BOOST_CC_CTRL,
|
||||
/* ACK 6 6 */ BOOST_CC_CTRL,
|
||||
/* BEL 7 7 */ BOOST_CC_CTRL,
|
||||
/* BS 8 8 */ BOOST_CC_CTRL,
|
||||
/* HT 9 9 */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* NL 10 a */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* VT 11 b */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* NP 12 c */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* CR 13 d */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* SO 14 e */ BOOST_CC_CTRL,
|
||||
/* SI 15 f */ BOOST_CC_CTRL,
|
||||
/* DLE 16 10 */ BOOST_CC_CTRL,
|
||||
/* DC1 17 11 */ BOOST_CC_CTRL,
|
||||
/* DC2 18 12 */ BOOST_CC_CTRL,
|
||||
/* DC3 19 13 */ BOOST_CC_CTRL,
|
||||
/* DC4 20 14 */ BOOST_CC_CTRL,
|
||||
/* NAK 21 15 */ BOOST_CC_CTRL,
|
||||
/* SYN 22 16 */ BOOST_CC_CTRL,
|
||||
/* ETB 23 17 */ BOOST_CC_CTRL,
|
||||
/* CAN 24 18 */ BOOST_CC_CTRL,
|
||||
/* EM 25 19 */ BOOST_CC_CTRL,
|
||||
/* SUB 26 1a */ BOOST_CC_CTRL,
|
||||
/* ESC 27 1b */ BOOST_CC_CTRL,
|
||||
/* FS 28 1c */ BOOST_CC_CTRL,
|
||||
/* GS 29 1d */ BOOST_CC_CTRL,
|
||||
/* RS 30 1e */ BOOST_CC_CTRL,
|
||||
/* US 31 1f */ BOOST_CC_CTRL,
|
||||
/* SP 32 20 */ BOOST_CC_SPACE,
|
||||
/* ! 33 21 */ BOOST_CC_PUNCT,
|
||||
/* " 34 22 */ BOOST_CC_PUNCT,
|
||||
/* # 35 23 */ BOOST_CC_PUNCT,
|
||||
/* $ 36 24 */ BOOST_CC_PUNCT,
|
||||
/* % 37 25 */ BOOST_CC_PUNCT,
|
||||
/* & 38 26 */ BOOST_CC_PUNCT,
|
||||
/* ' 39 27 */ BOOST_CC_PUNCT,
|
||||
/* ( 40 28 */ BOOST_CC_PUNCT,
|
||||
/* ) 41 29 */ BOOST_CC_PUNCT,
|
||||
/* * 42 2a */ BOOST_CC_PUNCT,
|
||||
/* + 43 2b */ BOOST_CC_PUNCT,
|
||||
/* , 44 2c */ BOOST_CC_PUNCT,
|
||||
/* - 45 2d */ BOOST_CC_PUNCT,
|
||||
/* . 46 2e */ BOOST_CC_PUNCT,
|
||||
/* / 47 2f */ BOOST_CC_PUNCT,
|
||||
/* 0 48 30 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 1 49 31 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 2 50 32 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 3 51 33 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 4 52 34 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 5 53 35 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 6 54 36 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 7 55 37 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 8 56 38 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 9 57 39 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* : 58 3a */ BOOST_CC_PUNCT,
|
||||
/* ; 59 3b */ BOOST_CC_PUNCT,
|
||||
/* < 60 3c */ BOOST_CC_PUNCT,
|
||||
/* = 61 3d */ BOOST_CC_PUNCT,
|
||||
/* > 62 3e */ BOOST_CC_PUNCT,
|
||||
/* ? 63 3f */ BOOST_CC_PUNCT,
|
||||
/* @ 64 40 */ BOOST_CC_PUNCT,
|
||||
/* A 65 41 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* B 66 42 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* C 67 43 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* D 68 44 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* E 69 45 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* F 70 46 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* G 71 47 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* H 72 48 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* I 73 49 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* J 74 4a */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* K 75 4b */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* L 76 4c */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* M 77 4d */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* N 78 4e */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* O 79 4f */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* P 80 50 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Q 81 51 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* R 82 52 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* S 83 53 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* T 84 54 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* U 85 55 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* V 86 56 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* W 87 57 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* X 88 58 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Y 89 59 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Z 90 5a */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* [ 91 5b */ BOOST_CC_PUNCT,
|
||||
/* \ 92 5c */ BOOST_CC_PUNCT,
|
||||
/* ] 93 5d */ BOOST_CC_PUNCT,
|
||||
/* ^ 94 5e */ BOOST_CC_PUNCT,
|
||||
/* _ 95 5f */ BOOST_CC_PUNCT,
|
||||
/* ` 96 60 */ BOOST_CC_PUNCT,
|
||||
/* a 97 61 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* b 98 62 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* c 99 63 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* d 100 64 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* e 101 65 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* f 102 66 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* g 103 67 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* h 104 68 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* i 105 69 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* j 106 6a */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* k 107 6b */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* l 108 6c */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* m 109 6d */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* n 110 6e */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* o 111 6f */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* p 112 70 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* q 113 71 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* r 114 72 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* s 115 73 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* t 116 74 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* u 117 75 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* v 118 76 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* w 119 77 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* x 120 78 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* y 121 79 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* z 122 7a */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* { 123 7b */ BOOST_CC_PUNCT,
|
||||
/* | 124 7c */ BOOST_CC_PUNCT,
|
||||
/* } 125 7d */ BOOST_CC_PUNCT,
|
||||
/* ~ 126 7e */ BOOST_CC_PUNCT,
|
||||
/* DEL 127 7f */ BOOST_CC_CTRL,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test characters for specified conditions (using ASCII)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct ascii
|
||||
{
|
||||
typedef char char_type;
|
||||
|
||||
static bool
|
||||
isascii_(int ch)
|
||||
{
|
||||
return 0 == (ch & ~0x7f);
|
||||
}
|
||||
|
||||
static bool
|
||||
ischar(int ch)
|
||||
{
|
||||
return isascii_(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isalnum(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_ALPHA)
|
||||
|| (ascii_char_types[ch] & BOOST_CC_DIGIT);
|
||||
}
|
||||
|
||||
static bool
|
||||
isalpha(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_ALPHA) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isdigit(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_DIGIT) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isxdigit(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_XDIGIT) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
iscntrl(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_CTRL) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isgraph(int ch)
|
||||
{
|
||||
return ('\x21' <= ch && ch <= '\x7e');
|
||||
}
|
||||
|
||||
static bool
|
||||
islower(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_LOWER) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isprint(int ch)
|
||||
{
|
||||
return ('\x20' <= ch && ch <= '\x7e');
|
||||
}
|
||||
|
||||
static bool
|
||||
ispunct(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_PUNCT) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isspace(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_SPACE) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
|
||||
{
|
||||
return ('\x09' == ch || '\x20' == ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isupper(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (ascii_char_types[ch] & BOOST_CC_UPPER) ? true : false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Simple character conversions
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int
|
||||
tolower(int ch)
|
||||
{
|
||||
return isupper(ch) ? (ch - 'A' + 'a') : ch;
|
||||
}
|
||||
|
||||
static int
|
||||
toupper(int ch)
|
||||
{
|
||||
return islower(ch) ? (ch - 'a' + 'A') : ch;
|
||||
}
|
||||
|
||||
static ::boost::uint32_t
|
||||
toucs4(int ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// undefine macros
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef BOOST_CC_DIGIT
|
||||
#undef BOOST_CC_XDIGIT
|
||||
#undef BOOST_CC_ALPHA
|
||||
#undef BOOST_CC_CTRL
|
||||
#undef BOOST_CC_LOWER
|
||||
#undef BOOST_CC_UPPER
|
||||
#undef BOOST_CC_PUNCT
|
||||
#undef BOOST_CC_SPACE
|
||||
|
||||
#endif
|
||||
+711
@@ -0,0 +1,711 @@
|
||||
/*=============================================================================
|
||||
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(BOOST_SPIRIT_ISO8859_1_APRIL_26_2006_1106PM)
|
||||
#define BOOST_SPIRIT_ISO8859_1_APRIL_26_2006_1106PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <climits>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// constants used to classify the single characters
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_CC_DIGIT 0x0001
|
||||
#define BOOST_CC_XDIGIT 0x0002
|
||||
#define BOOST_CC_ALPHA 0x0004
|
||||
#define BOOST_CC_CTRL 0x0008
|
||||
#define BOOST_CC_LOWER 0x0010
|
||||
#define BOOST_CC_UPPER 0x0020
|
||||
#define BOOST_CC_SPACE 0x0040
|
||||
#define BOOST_CC_PUNCT 0x0080
|
||||
|
||||
namespace boost { namespace spirit { namespace char_encoding
|
||||
{
|
||||
// The detection of isgraph(), isprint() and isblank() is done programmatically
|
||||
// to keep the character type table small. Additionally, these functions are
|
||||
// rather seldom used and the programmatic detection is very simple.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ISO 8859-1 character classification table
|
||||
//
|
||||
// the comments intentionally contain non-ascii characters
|
||||
// boostinspect:noascii
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
const unsigned char iso8859_1_char_types[] =
|
||||
{
|
||||
/* NUL 0 0 */ BOOST_CC_CTRL,
|
||||
/* SOH 1 1 */ BOOST_CC_CTRL,
|
||||
/* STX 2 2 */ BOOST_CC_CTRL,
|
||||
/* ETX 3 3 */ BOOST_CC_CTRL,
|
||||
/* EOT 4 4 */ BOOST_CC_CTRL,
|
||||
/* ENQ 5 5 */ BOOST_CC_CTRL,
|
||||
/* ACK 6 6 */ BOOST_CC_CTRL,
|
||||
/* BEL 7 7 */ BOOST_CC_CTRL,
|
||||
/* BS 8 8 */ BOOST_CC_CTRL,
|
||||
/* HT 9 9 */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* NL 10 a */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* VT 11 b */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* NP 12 c */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* CR 13 d */ BOOST_CC_CTRL|BOOST_CC_SPACE,
|
||||
/* SO 14 e */ BOOST_CC_CTRL,
|
||||
/* SI 15 f */ BOOST_CC_CTRL,
|
||||
/* DLE 16 10 */ BOOST_CC_CTRL,
|
||||
/* DC1 17 11 */ BOOST_CC_CTRL,
|
||||
/* DC2 18 12 */ BOOST_CC_CTRL,
|
||||
/* DC3 19 13 */ BOOST_CC_CTRL,
|
||||
/* DC4 20 14 */ BOOST_CC_CTRL,
|
||||
/* NAK 21 15 */ BOOST_CC_CTRL,
|
||||
/* SYN 22 16 */ BOOST_CC_CTRL,
|
||||
/* ETB 23 17 */ BOOST_CC_CTRL,
|
||||
/* CAN 24 18 */ BOOST_CC_CTRL,
|
||||
/* EM 25 19 */ BOOST_CC_CTRL,
|
||||
/* SUB 26 1a */ BOOST_CC_CTRL,
|
||||
/* ESC 27 1b */ BOOST_CC_CTRL,
|
||||
/* FS 28 1c */ BOOST_CC_CTRL,
|
||||
/* GS 29 1d */ BOOST_CC_CTRL,
|
||||
/* RS 30 1e */ BOOST_CC_CTRL,
|
||||
/* US 31 1f */ BOOST_CC_CTRL,
|
||||
/* SP 32 20 */ BOOST_CC_SPACE,
|
||||
/* ! 33 21 */ BOOST_CC_PUNCT,
|
||||
/* " 34 22 */ BOOST_CC_PUNCT,
|
||||
/* # 35 23 */ BOOST_CC_PUNCT,
|
||||
/* $ 36 24 */ BOOST_CC_PUNCT,
|
||||
/* % 37 25 */ BOOST_CC_PUNCT,
|
||||
/* & 38 26 */ BOOST_CC_PUNCT,
|
||||
/* ' 39 27 */ BOOST_CC_PUNCT,
|
||||
/* ( 40 28 */ BOOST_CC_PUNCT,
|
||||
/* ) 41 29 */ BOOST_CC_PUNCT,
|
||||
/* * 42 2a */ BOOST_CC_PUNCT,
|
||||
/* + 43 2b */ BOOST_CC_PUNCT,
|
||||
/* , 44 2c */ BOOST_CC_PUNCT,
|
||||
/* - 45 2d */ BOOST_CC_PUNCT,
|
||||
/* . 46 2e */ BOOST_CC_PUNCT,
|
||||
/* / 47 2f */ BOOST_CC_PUNCT,
|
||||
/* 0 48 30 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 1 49 31 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 2 50 32 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 3 51 33 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 4 52 34 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 5 53 35 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 6 54 36 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 7 55 37 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 8 56 38 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* 9 57 39 */ BOOST_CC_DIGIT|BOOST_CC_XDIGIT,
|
||||
/* : 58 3a */ BOOST_CC_PUNCT,
|
||||
/* ; 59 3b */ BOOST_CC_PUNCT,
|
||||
/* < 60 3c */ BOOST_CC_PUNCT,
|
||||
/* = 61 3d */ BOOST_CC_PUNCT,
|
||||
/* > 62 3e */ BOOST_CC_PUNCT,
|
||||
/* ? 63 3f */ BOOST_CC_PUNCT,
|
||||
/* @ 64 40 */ BOOST_CC_PUNCT,
|
||||
/* A 65 41 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* B 66 42 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* C 67 43 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* D 68 44 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* E 69 45 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* F 70 46 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_UPPER,
|
||||
/* G 71 47 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* H 72 48 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* I 73 49 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* J 74 4a */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* K 75 4b */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* L 76 4c */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* M 77 4d */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* N 78 4e */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* O 79 4f */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* P 80 50 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Q 81 51 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* R 82 52 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* S 83 53 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* T 84 54 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* U 85 55 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* V 86 56 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* W 87 57 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* X 88 58 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Y 89 59 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Z 90 5a */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* [ 91 5b */ BOOST_CC_PUNCT,
|
||||
/* \ 92 5c */ BOOST_CC_PUNCT,
|
||||
/* ] 93 5d */ BOOST_CC_PUNCT,
|
||||
/* ^ 94 5e */ BOOST_CC_PUNCT,
|
||||
/* _ 95 5f */ BOOST_CC_PUNCT,
|
||||
/* ` 96 60 */ BOOST_CC_PUNCT,
|
||||
/* a 97 61 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* b 98 62 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* c 99 63 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* d 100 64 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* e 101 65 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* f 102 66 */ BOOST_CC_ALPHA|BOOST_CC_XDIGIT|BOOST_CC_LOWER,
|
||||
/* g 103 67 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* h 104 68 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* i 105 69 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* j 106 6a */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* k 107 6b */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* l 108 6c */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* m 109 6d */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* n 110 6e */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* o 111 6f */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* p 112 70 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* q 113 71 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* r 114 72 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* s 115 73 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* t 116 74 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* u 117 75 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* v 118 76 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* w 119 77 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* x 120 78 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* y 121 79 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* z 122 7a */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* { 123 7b */ BOOST_CC_PUNCT,
|
||||
/* | 124 7c */ BOOST_CC_PUNCT,
|
||||
/* } 125 7d */ BOOST_CC_PUNCT,
|
||||
/* ~ 126 7e */ BOOST_CC_PUNCT,
|
||||
/* DEL 127 7f */ BOOST_CC_CTRL,
|
||||
/* -- 128 80 */ BOOST_CC_CTRL,
|
||||
/* -- 129 81 */ BOOST_CC_CTRL,
|
||||
/* -- 130 82 */ BOOST_CC_CTRL,
|
||||
/* -- 131 83 */ BOOST_CC_CTRL,
|
||||
/* -- 132 84 */ BOOST_CC_CTRL,
|
||||
/* -- 133 85 */ BOOST_CC_CTRL,
|
||||
/* -- 134 86 */ BOOST_CC_CTRL,
|
||||
/* -- 135 87 */ BOOST_CC_CTRL,
|
||||
/* -- 136 88 */ BOOST_CC_CTRL,
|
||||
/* -- 137 89 */ BOOST_CC_CTRL,
|
||||
/* -- 138 8a */ BOOST_CC_CTRL,
|
||||
/* -- 139 8b */ BOOST_CC_CTRL,
|
||||
/* -- 140 8c */ BOOST_CC_CTRL,
|
||||
/* -- 141 8d */ BOOST_CC_CTRL,
|
||||
/* -- 142 8e */ BOOST_CC_CTRL,
|
||||
/* -- 143 8f */ BOOST_CC_CTRL,
|
||||
/* -- 144 90 */ BOOST_CC_CTRL,
|
||||
/* -- 145 91 */ BOOST_CC_CTRL,
|
||||
/* -- 146 92 */ BOOST_CC_CTRL,
|
||||
/* -- 147 93 */ BOOST_CC_CTRL,
|
||||
/* -- 148 94 */ BOOST_CC_CTRL,
|
||||
/* -- 149 95 */ BOOST_CC_CTRL,
|
||||
/* -- 150 96 */ BOOST_CC_CTRL,
|
||||
/* -- 151 97 */ BOOST_CC_CTRL,
|
||||
/* -- 152 98 */ BOOST_CC_CTRL,
|
||||
/* -- 153 99 */ BOOST_CC_CTRL,
|
||||
/* -- 154 9a */ BOOST_CC_CTRL,
|
||||
/* -- 155 9b */ BOOST_CC_CTRL,
|
||||
/* -- 156 9c */ BOOST_CC_CTRL,
|
||||
/* -- 157 9d */ BOOST_CC_CTRL,
|
||||
/* -- 158 9e */ BOOST_CC_CTRL,
|
||||
/* -- 159 9f */ BOOST_CC_CTRL,
|
||||
/* 160 a0 */ BOOST_CC_SPACE,
|
||||
/* ¡ 161 a1 */ BOOST_CC_PUNCT,
|
||||
/* ¢ 162 a2 */ BOOST_CC_PUNCT,
|
||||
/* £ 163 a3 */ BOOST_CC_PUNCT,
|
||||
/* ¤ 164 a4 */ BOOST_CC_PUNCT,
|
||||
/* ¥ 165 a5 */ BOOST_CC_PUNCT,
|
||||
/* ¦ 166 a6 */ BOOST_CC_PUNCT,
|
||||
/* § 167 a7 */ BOOST_CC_PUNCT,
|
||||
/* ¨ 168 a8 */ BOOST_CC_PUNCT,
|
||||
/* © 169 a9 */ BOOST_CC_PUNCT,
|
||||
/* ª 170 aa */ BOOST_CC_PUNCT,
|
||||
/* « 171 ab */ BOOST_CC_PUNCT,
|
||||
/* ¬ 172 ac */ BOOST_CC_PUNCT,
|
||||
/* 173 ad */ BOOST_CC_PUNCT,
|
||||
/* ® 174 ae */ BOOST_CC_PUNCT,
|
||||
/* ¯ 175 af */ BOOST_CC_PUNCT,
|
||||
/* ° 176 b0 */ BOOST_CC_PUNCT,
|
||||
/* ± 177 b1 */ BOOST_CC_PUNCT,
|
||||
/* ² 178 b2 */ BOOST_CC_DIGIT|BOOST_CC_PUNCT,
|
||||
/* ³ 179 b3 */ BOOST_CC_DIGIT|BOOST_CC_PUNCT,
|
||||
/* ´ 180 b4 */ BOOST_CC_PUNCT,
|
||||
/* µ 181 b5 */ BOOST_CC_PUNCT,
|
||||
/* ¶ 182 b6 */ BOOST_CC_PUNCT,
|
||||
/* · 183 b7 */ BOOST_CC_PUNCT,
|
||||
/* ¸ 184 b8 */ BOOST_CC_PUNCT,
|
||||
/* ¹ 185 b9 */ BOOST_CC_DIGIT|BOOST_CC_PUNCT,
|
||||
/* º 186 ba */ BOOST_CC_PUNCT,
|
||||
/* » 187 bb */ BOOST_CC_PUNCT,
|
||||
/* ¼ 188 bc */ BOOST_CC_PUNCT,
|
||||
/* ½ 189 bd */ BOOST_CC_PUNCT,
|
||||
/* ¾ 190 be */ BOOST_CC_PUNCT,
|
||||
/* ¿ 191 bf */ BOOST_CC_PUNCT,
|
||||
/* À 192 c0 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Á 193 c1 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Â 194 c2 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ã 195 c3 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ä 196 c4 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Å 197 c5 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Æ 198 c6 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ç 199 c7 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* È 200 c8 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* É 201 c9 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ê 202 ca */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ë 203 cb */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ì 204 cc */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Í 205 cd */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Î 206 ce */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ï 207 cf */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ð 208 d0 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ñ 209 d1 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ò 210 d2 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ó 211 d3 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ô 212 d4 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Õ 213 d5 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ö 214 d6 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* × 215 d7 */ BOOST_CC_PUNCT,
|
||||
/* Ø 216 d8 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ù 217 d9 */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ú 218 da */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Û 219 db */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ü 220 dc */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Ý 221 dd */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* Þ 222 de */ BOOST_CC_ALPHA|BOOST_CC_UPPER,
|
||||
/* ß 223 df */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* à 224 e0 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* á 225 e1 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* â 226 e2 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ã 227 e3 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ä 228 e4 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* å 229 e5 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* æ 230 e6 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ç 231 e7 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* è 232 e8 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* é 233 e9 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ê 234 ea */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ë 235 eb */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ì 236 ec */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* í 237 ed */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* î 238 ee */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ï 239 ef */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ð 240 f0 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ñ 241 f1 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ò 242 f2 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ó 243 f3 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ô 244 f4 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* õ 245 f5 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ö 246 f6 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ÷ 247 f7 */ BOOST_CC_PUNCT,
|
||||
/* ø 248 f8 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ù 249 f9 */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ú 250 fa */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* û 251 fb */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ü 252 fc */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ý 253 fd */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* þ 254 fe */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
/* ÿ 255 ff */ BOOST_CC_ALPHA|BOOST_CC_LOWER,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ISO 8859-1 character conversion table
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
const unsigned char iso8859_1_char_conversion[] =
|
||||
{
|
||||
/* NUL 0 0 */ '\0',
|
||||
/* SOH 1 1 */ '\0',
|
||||
/* STX 2 2 */ '\0',
|
||||
/* ETX 3 3 */ '\0',
|
||||
/* EOT 4 4 */ '\0',
|
||||
/* ENQ 5 5 */ '\0',
|
||||
/* ACK 6 6 */ '\0',
|
||||
/* BEL 7 7 */ '\0',
|
||||
/* BS 8 8 */ '\0',
|
||||
/* HT 9 9 */ '\0',
|
||||
/* NL 10 a */ '\0',
|
||||
/* VT 11 b */ '\0',
|
||||
/* NP 12 c */ '\0',
|
||||
/* CR 13 d */ '\0',
|
||||
/* SO 14 e */ '\0',
|
||||
/* SI 15 f */ '\0',
|
||||
/* DLE 16 10 */ '\0',
|
||||
/* DC1 17 11 */ '\0',
|
||||
/* DC2 18 12 */ '\0',
|
||||
/* DC3 19 13 */ '\0',
|
||||
/* DC4 20 14 */ '\0',
|
||||
/* NAK 21 15 */ '\0',
|
||||
/* SYN 22 16 */ '\0',
|
||||
/* ETB 23 17 */ '\0',
|
||||
/* CAN 24 18 */ '\0',
|
||||
/* EM 25 19 */ '\0',
|
||||
/* SUB 26 1a */ '\0',
|
||||
/* ESC 27 1b */ '\0',
|
||||
/* FS 28 1c */ '\0',
|
||||
/* GS 29 1d */ '\0',
|
||||
/* RS 30 1e */ '\0',
|
||||
/* US 31 1f */ '\0',
|
||||
/* SP 32 20 */ '\0',
|
||||
/* ! 33 21 */ '\0',
|
||||
/* " 34 22 */ '\0',
|
||||
/* # 35 23 */ '\0',
|
||||
/* $ 36 24 */ '\0',
|
||||
/* % 37 25 */ '\0',
|
||||
/* & 38 26 */ '\0',
|
||||
/* ' 39 27 */ '\0',
|
||||
/* ( 40 28 */ '\0',
|
||||
/* ) 41 29 */ '\0',
|
||||
/* * 42 2a */ '\0',
|
||||
/* + 43 2b */ '\0',
|
||||
/* , 44 2c */ '\0',
|
||||
/* - 45 2d */ '\0',
|
||||
/* . 46 2e */ '\0',
|
||||
/* / 47 2f */ '\0',
|
||||
/* 0 48 30 */ '\0',
|
||||
/* 1 49 31 */ '\0',
|
||||
/* 2 50 32 */ '\0',
|
||||
/* 3 51 33 */ '\0',
|
||||
/* 4 52 34 */ '\0',
|
||||
/* 5 53 35 */ '\0',
|
||||
/* 6 54 36 */ '\0',
|
||||
/* 7 55 37 */ '\0',
|
||||
/* 8 56 38 */ '\0',
|
||||
/* 9 57 39 */ '\0',
|
||||
/* : 58 3a */ '\0',
|
||||
/* ; 59 3b */ '\0',
|
||||
/* < 60 3c */ '\0',
|
||||
/* = 61 3d */ '\0',
|
||||
/* > 62 3e */ '\0',
|
||||
/* ? 63 3f */ '\0',
|
||||
/* @ 64 40 */ '\0',
|
||||
/* A 65 41 */ 'a',
|
||||
/* B 66 42 */ 'b',
|
||||
/* C 67 43 */ 'c',
|
||||
/* D 68 44 */ 'd',
|
||||
/* E 69 45 */ 'e',
|
||||
/* F 70 46 */ 'f',
|
||||
/* G 71 47 */ 'g',
|
||||
/* H 72 48 */ 'h',
|
||||
/* I 73 49 */ 'i',
|
||||
/* J 74 4a */ 'j',
|
||||
/* K 75 4b */ 'k',
|
||||
/* L 76 4c */ 'l',
|
||||
/* M 77 4d */ 'm',
|
||||
/* N 78 4e */ 'n',
|
||||
/* O 79 4f */ 'o',
|
||||
/* P 80 50 */ 'p',
|
||||
/* Q 81 51 */ 'q',
|
||||
/* R 82 52 */ 'r',
|
||||
/* S 83 53 */ 's',
|
||||
/* T 84 54 */ 't',
|
||||
/* U 85 55 */ 'u',
|
||||
/* V 86 56 */ 'v',
|
||||
/* W 87 57 */ 'w',
|
||||
/* X 88 58 */ 'x',
|
||||
/* Y 89 59 */ 'y',
|
||||
/* Z 90 5a */ 'z',
|
||||
/* [ 91 5b */ '\0',
|
||||
/* \ 92 5c */ '\0',
|
||||
/* ] 93 5d */ '\0',
|
||||
/* ^ 94 5e */ '\0',
|
||||
/* _ 95 5f */ '\0',
|
||||
/* ` 96 60 */ '\0',
|
||||
/* a 97 61 */ 'A',
|
||||
/* b 98 62 */ 'B',
|
||||
/* c 99 63 */ 'C',
|
||||
/* d 100 64 */ 'D',
|
||||
/* e 101 65 */ 'E',
|
||||
/* f 102 66 */ 'F',
|
||||
/* g 103 67 */ 'G',
|
||||
/* h 104 68 */ 'H',
|
||||
/* i 105 69 */ 'I',
|
||||
/* j 106 6a */ 'J',
|
||||
/* k 107 6b */ 'K',
|
||||
/* l 108 6c */ 'L',
|
||||
/* m 109 6d */ 'M',
|
||||
/* n 110 6e */ 'N',
|
||||
/* o 111 6f */ 'O',
|
||||
/* p 112 70 */ 'P',
|
||||
/* q 113 71 */ 'Q',
|
||||
/* r 114 72 */ 'R',
|
||||
/* s 115 73 */ 'S',
|
||||
/* t 116 74 */ 'T',
|
||||
/* u 117 75 */ 'U',
|
||||
/* v 118 76 */ 'V',
|
||||
/* w 119 77 */ 'W',
|
||||
/* x 120 78 */ 'X',
|
||||
/* y 121 79 */ 'Y',
|
||||
/* z 122 7a */ 'Z',
|
||||
/* { 123 7b */ '\0',
|
||||
/* | 124 7c */ '\0',
|
||||
/* } 125 7d */ '\0',
|
||||
/* ~ 126 7e */ '\0',
|
||||
/* DEL 127 7f */ '\0',
|
||||
/* -- 128 80 */ '\0',
|
||||
/* -- 129 81 */ '\0',
|
||||
/* -- 130 82 */ '\0',
|
||||
/* -- 131 83 */ '\0',
|
||||
/* -- 132 84 */ '\0',
|
||||
/* -- 133 85 */ '\0',
|
||||
/* -- 134 86 */ '\0',
|
||||
/* -- 135 87 */ '\0',
|
||||
/* -- 136 88 */ '\0',
|
||||
/* -- 137 89 */ '\0',
|
||||
/* -- 138 8a */ '\0',
|
||||
/* -- 139 8b */ '\0',
|
||||
/* -- 140 8c */ '\0',
|
||||
/* -- 141 8d */ '\0',
|
||||
/* -- 142 8e */ '\0',
|
||||
/* -- 143 8f */ '\0',
|
||||
/* -- 144 90 */ '\0',
|
||||
/* -- 145 91 */ '\0',
|
||||
/* -- 146 92 */ '\0',
|
||||
/* -- 147 93 */ '\0',
|
||||
/* -- 148 94 */ '\0',
|
||||
/* -- 149 95 */ '\0',
|
||||
/* -- 150 96 */ '\0',
|
||||
/* -- 151 97 */ '\0',
|
||||
/* -- 152 98 */ '\0',
|
||||
/* -- 153 99 */ '\0',
|
||||
/* -- 154 9a */ '\0',
|
||||
/* -- 155 9b */ '\0',
|
||||
/* -- 156 9c */ '\0',
|
||||
/* -- 157 9d */ '\0',
|
||||
/* -- 158 9e */ '\0',
|
||||
/* -- 159 9f */ '\0',
|
||||
/* 160 a0 */ '\0',
|
||||
/* ¡ 161 a1 */ '\0',
|
||||
/* ¢ 162 a2 */ '\0',
|
||||
/* £ 163 a3 */ '\0',
|
||||
/* ¤ 164 a4 */ '\0',
|
||||
/* ¥ 165 a5 */ '\0',
|
||||
/* ¦ 166 a6 */ '\0',
|
||||
/* § 167 a7 */ '\0',
|
||||
/* ¨ 168 a8 */ '\0',
|
||||
/* © 169 a9 */ '\0',
|
||||
/* ª 170 aa */ '\0',
|
||||
/* « 171 ab */ '\0',
|
||||
/* ¬ 172 ac */ '\0',
|
||||
/* 173 ad */ '\0',
|
||||
/* ® 174 ae */ '\0',
|
||||
/* ¯ 175 af */ '\0',
|
||||
/* ° 176 b0 */ '\0',
|
||||
/* ± 177 b1 */ '\0',
|
||||
/* ² 178 b2 */ '\0',
|
||||
/* ³ 179 b3 */ '\0',
|
||||
/* ´ 180 b4 */ '\0',
|
||||
/* µ 181 b5 */ '\0',
|
||||
/* ¶ 182 b6 */ '\0',
|
||||
/* · 183 b7 */ '\0',
|
||||
/* ¸ 184 b8 */ '\0',
|
||||
/* ¹ 185 b9 */ '\0',
|
||||
/* º 186 ba */ '\0',
|
||||
/* » 187 bb */ '\0',
|
||||
/* ¼ 188 bc */ '\0',
|
||||
/* ½ 189 bd */ '\0',
|
||||
/* ¾ 190 be */ '\0',
|
||||
/* ¿ 191 bf */ '\0',
|
||||
/* à 192 c0 */ 0xe0,
|
||||
/* á 193 c1 */ 0xe1,
|
||||
/* â 194 c2 */ 0xe2,
|
||||
/* ã 195 c3 */ 0xe3,
|
||||
/* ä 196 c4 */ 0xe4,
|
||||
/* å 197 c5 */ 0xe5,
|
||||
/* æ 198 c6 */ 0xe6,
|
||||
/* ç 199 c7 */ 0xe7,
|
||||
/* è 200 c8 */ 0xe8,
|
||||
/* é 201 c9 */ 0xe9,
|
||||
/* ê 202 ca */ 0xea,
|
||||
/* ë 203 cb */ 0xeb,
|
||||
/* ì 204 cc */ 0xec,
|
||||
/* í 205 cd */ 0xed,
|
||||
/* î 206 ce */ 0xee,
|
||||
/* ï 207 cf */ 0xef,
|
||||
/* ð 208 d0 */ 0xf0,
|
||||
/* ñ 209 d1 */ 0xf1,
|
||||
/* ò 210 d2 */ 0xf2,
|
||||
/* ó 211 d3 */ 0xf3,
|
||||
/* ô 212 d4 */ 0xf4,
|
||||
/* õ 213 d5 */ 0xf5,
|
||||
/* ö 214 d6 */ 0xf6,
|
||||
/* × 215 d7 */ '\0',
|
||||
/* ø 216 d8 */ 0xf8,
|
||||
/* ù 217 d9 */ 0xf9,
|
||||
/* ú 218 da */ 0xfa,
|
||||
/* û 219 db */ 0xfb,
|
||||
/* ü 220 dc */ 0xfc,
|
||||
/* ý 221 dd */ 0xfd,
|
||||
/* þ 222 de */ 0xfe,
|
||||
/* ß 223 df */ '\0',
|
||||
/* À 224 e0 */ 0xc0,
|
||||
/* Á 225 e1 */ 0xc1,
|
||||
/* Â 226 e2 */ 0xc2,
|
||||
/* Ã 227 e3 */ 0xc3,
|
||||
/* Ä 228 e4 */ 0xc4,
|
||||
/* Å 229 e5 */ 0xc5,
|
||||
/* Æ 230 e6 */ 0xc6,
|
||||
/* Ç 231 e7 */ 0xc7,
|
||||
/* È 232 e8 */ 0xc8,
|
||||
/* É 233 e9 */ 0xc9,
|
||||
/* Ê 234 ea */ 0xca,
|
||||
/* Ë 235 eb */ 0xcb,
|
||||
/* Ì 236 ec */ 0xcc,
|
||||
/* Í 237 ed */ 0xcd,
|
||||
/* Î 238 ee */ 0xce,
|
||||
/* Ï 239 ef */ 0xcf,
|
||||
/* Ð 240 f0 */ 0xd0,
|
||||
/* Ñ 241 f1 */ 0xd1,
|
||||
/* Ò 242 f2 */ 0xd2,
|
||||
/* Ó 243 f3 */ 0xd3,
|
||||
/* Ô 244 f4 */ 0xd4,
|
||||
/* Õ 245 f5 */ 0xd5,
|
||||
/* Ö 246 f6 */ 0xd6,
|
||||
/* ÷ 247 f7 */ '\0',
|
||||
/* Ø 248 f8 */ 0xd8,
|
||||
/* Ù 249 f9 */ 0xd9,
|
||||
/* Ú 250 fa */ 0xda,
|
||||
/* Û 251 fb */ 0xdb,
|
||||
/* Ü 252 fc */ 0xdc,
|
||||
/* Ý 253 fd */ 0xdd,
|
||||
/* Þ 254 fe */ 0xde,
|
||||
/* ÿ 255 ff */ '\0',
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test characters for specified conditions (using iso8859-1)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct iso8859_1
|
||||
{
|
||||
typedef unsigned char char_type;
|
||||
|
||||
static bool
|
||||
isascii_(int ch)
|
||||
{
|
||||
return 0 == (ch & ~0x7f);
|
||||
}
|
||||
|
||||
static bool
|
||||
ischar(int ch)
|
||||
{
|
||||
// iso8859.1 uses all 8 bits
|
||||
// we have to watch out for sign extensions
|
||||
return (0 == (ch & ~0xff) || ~0 == (ch | 0xff)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isalnum(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_ALPHA)
|
||||
|| (iso8859_1_char_types[ch] & BOOST_CC_DIGIT);
|
||||
}
|
||||
|
||||
static bool
|
||||
isalpha(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_ALPHA) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isdigit(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_DIGIT) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isxdigit(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_XDIGIT) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
iscntrl(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_CTRL) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isgraph(int ch)
|
||||
{
|
||||
return ('\x21' <= ch && ch <= '\x7e') || ('\xa1' <= ch && ch <= '\xff');
|
||||
}
|
||||
|
||||
static bool
|
||||
islower(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_LOWER) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isprint(int ch)
|
||||
{
|
||||
return ('\x20' <= ch && ch <= '\x7e') || ('\xa0' <= ch && ch <= '\xff');
|
||||
}
|
||||
|
||||
static bool
|
||||
ispunct(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_PUNCT) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isspace(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_SPACE) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
|
||||
{
|
||||
return ('\x09' == ch || '\x20' == ch || '\xa0' == ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isupper(int ch)
|
||||
{
|
||||
BOOST_ASSERT(0 == (ch & ~UCHAR_MAX));
|
||||
return (iso8859_1_char_types[ch] & BOOST_CC_UPPER) ? true : false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Simple character conversions
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int
|
||||
tolower(int ch)
|
||||
{
|
||||
return isupper(ch) && '\0' != iso8859_1_char_conversion[ch] ?
|
||||
iso8859_1_char_conversion[ch] : ch;
|
||||
}
|
||||
|
||||
static int
|
||||
toupper(int ch)
|
||||
{
|
||||
return islower(ch) && '\0' != iso8859_1_char_conversion[ch] ?
|
||||
iso8859_1_char_conversion[ch] : ch;
|
||||
}
|
||||
|
||||
static ::boost::uint32_t
|
||||
toucs4(int ch)
|
||||
{
|
||||
// The first 256 characters in Unicode and the UCS are
|
||||
// identical to those in ISO/IEC-8859-1.
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// undefine macros
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#undef BOOST_CC_DIGIT
|
||||
#undef BOOST_CC_XDIGIT
|
||||
#undef BOOST_CC_ALPHA
|
||||
#undef BOOST_CC_CTRL
|
||||
#undef BOOST_CC_LOWER
|
||||
#undef BOOST_CC_UPPER
|
||||
#undef BOOST_CC_PUNCT
|
||||
#undef BOOST_CC_SPACE
|
||||
|
||||
#endif
|
||||
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/*=============================================================================
|
||||
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(BOOST_SPIRIT_STANDARD_APRIL_26_2006_1106PM)
|
||||
#define BOOST_SPIRIT_STANDARD_APRIL_26_2006_1106PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cctype>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace char_encoding
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test characters for specified conditions (using std functions)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct standard
|
||||
{
|
||||
typedef char char_type;
|
||||
|
||||
static bool
|
||||
isascii_(int ch)
|
||||
{
|
||||
return 0 == (ch & ~0x7f);
|
||||
}
|
||||
|
||||
static bool
|
||||
ischar(int ch)
|
||||
{
|
||||
// uses all 8 bits
|
||||
// we have to watch out for sign extensions
|
||||
return (0 == (ch & ~0xff) || ~0 == (ch | 0xff)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isalnum(int ch)
|
||||
{
|
||||
return std::isalnum(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isalpha(int ch)
|
||||
{
|
||||
return std::isalpha(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isdigit(int ch)
|
||||
{
|
||||
return std::isdigit(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isxdigit(int ch)
|
||||
{
|
||||
return std::isxdigit(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
iscntrl(int ch)
|
||||
{
|
||||
return std::iscntrl(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isgraph(int ch)
|
||||
{
|
||||
return std::isgraph(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
islower(int ch)
|
||||
{
|
||||
return std::islower(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isprint(int ch)
|
||||
{
|
||||
return std::isprint(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
ispunct(int ch)
|
||||
{
|
||||
return std::ispunct(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isspace(int ch)
|
||||
{
|
||||
return std::isspace(ch) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (int ch)
|
||||
{
|
||||
return (ch == ' ' || ch == '\t');
|
||||
}
|
||||
|
||||
static bool
|
||||
isupper(int ch)
|
||||
{
|
||||
return std::isupper(ch) ? true : false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Simple character conversions
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int
|
||||
tolower(int ch)
|
||||
{
|
||||
return std::tolower(ch);
|
||||
}
|
||||
|
||||
static int
|
||||
toupper(int ch)
|
||||
{
|
||||
return std::toupper(ch);
|
||||
}
|
||||
|
||||
static ::boost::uint32_t
|
||||
toucs4(int ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/*=============================================================================
|
||||
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(BOOST_SPIRIT_STANDARD_WIDE_NOVEMBER_10_2006_0913AM)
|
||||
#define BOOST_SPIRIT_STANDARD_WIDE_NOVEMBER_10_2006_0913AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cwctype>
|
||||
#include <string>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/spirit/home/support/assert_msg.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <std::size_t N>
|
||||
struct wchar_t_size
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT_MSG(N == 1 || N == 2 || N == 4,
|
||||
not_supported_size_of_wchar_t, ());
|
||||
};
|
||||
|
||||
template <> struct wchar_t_size<1> { enum { mask = 0xff }; };
|
||||
template <> struct wchar_t_size<2> { enum { mask = 0xffff }; };
|
||||
template <> struct wchar_t_size<4> { enum { mask = 0xffffffff }; };
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace char_encoding
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test characters for specified conditions (using std wchar_t functions)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct standard_wide
|
||||
{
|
||||
typedef wchar_t char_type;
|
||||
|
||||
template <typename Char>
|
||||
static typename std::char_traits<Char>::int_type
|
||||
to_int_type(Char ch)
|
||||
{
|
||||
return std::char_traits<Char>::to_int_type(ch);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
static Char
|
||||
to_char_type(typename std::char_traits<Char>::int_type ch)
|
||||
{
|
||||
return std::char_traits<Char>::to_char_type(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
ischar(int ch)
|
||||
{
|
||||
// we have to watch out for sign extensions (casting is there to
|
||||
// silence certain compilers complaining about signed/unsigned
|
||||
// mismatch)
|
||||
return (
|
||||
std::size_t(0) ==
|
||||
std::size_t(ch & ~traits::wchar_t_size<sizeof(wchar_t)>::mask) ||
|
||||
std::size_t(~0) ==
|
||||
std::size_t(ch | traits::wchar_t_size<sizeof(wchar_t)>::mask)
|
||||
) ? true : false; // any wchar_t, but no other bits set
|
||||
}
|
||||
|
||||
static bool
|
||||
isalnum(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswalnum(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isalpha(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswalpha(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
iscntrl(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswcntrl(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isdigit(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswdigit(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isgraph(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswgraph(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
islower(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswlower(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isprint(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswprint(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
ispunct(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswpunct(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isspace(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswspace(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isupper(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswupper(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isxdigit(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return iswxdigit(to_int_type(ch)) ? true : false;
|
||||
}
|
||||
|
||||
static bool
|
||||
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (wchar_t ch)
|
||||
{
|
||||
return (ch == L' ' || ch == L'\t');
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Simple character conversions
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static wchar_t
|
||||
tolower(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return isupper(ch) ?
|
||||
to_char_type<wchar_t>(towlower(to_int_type(ch))) : ch;
|
||||
}
|
||||
|
||||
static wchar_t
|
||||
toupper(wchar_t ch)
|
||||
{
|
||||
using namespace std;
|
||||
return islower(ch) ?
|
||||
to_char_type<wchar_t>(towupper(to_int_type(ch))) : ch;
|
||||
}
|
||||
|
||||
static ::boost::uint32_t
|
||||
toucs4(int ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
+339
@@ -0,0 +1,339 @@
|
||||
/*=============================================================================
|
||||
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(BOOST_SPIRIT_UNICODE_1_JANUARY_12_2010_0728PM)
|
||||
#define BOOST_SPIRIT_UNICODE_1_JANUARY_12_2010_0728PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/spirit/home/support/char_encoding/unicode/query.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace char_encoding
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Test characters for specified conditions (using iso8859-1)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct unicode
|
||||
{
|
||||
typedef ::boost::uint32_t char_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Posix stuff
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
static bool
|
||||
isascii_(char_type ch)
|
||||
{
|
||||
return 0 == (ch & ~0x7f);
|
||||
}
|
||||
|
||||
static bool
|
||||
ischar(char_type ch)
|
||||
{
|
||||
// unicode code points in the range 0x00 to 0x10FFFF
|
||||
return ch <= 0x10FFFF;
|
||||
}
|
||||
|
||||
static bool
|
||||
isalnum(char_type ch)
|
||||
{
|
||||
return ucd::is_alphanumeric(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isalpha(char_type ch)
|
||||
{
|
||||
return ucd::is_alphabetic(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isdigit(char_type ch)
|
||||
{
|
||||
return ucd::is_decimal_number(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isxdigit(char_type ch)
|
||||
{
|
||||
return ucd::is_hex_digit(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
iscntrl(char_type ch)
|
||||
{
|
||||
return ucd::is_control(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isgraph(char_type ch)
|
||||
{
|
||||
return ucd::is_graph(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
islower(char_type ch)
|
||||
{
|
||||
return ucd::is_lowercase(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isprint(char_type ch)
|
||||
{
|
||||
return ucd::is_print(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
ispunct(char_type ch)
|
||||
{
|
||||
return ucd::is_punctuation(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isspace(char_type ch)
|
||||
{
|
||||
return ucd::is_white_space(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isblank BOOST_PREVENT_MACRO_SUBSTITUTION (char_type ch)
|
||||
{
|
||||
return ucd::is_blank(ch);
|
||||
}
|
||||
|
||||
static bool
|
||||
isupper(char_type ch)
|
||||
{
|
||||
return ucd::is_uppercase(ch);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Simple character conversions
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static char_type
|
||||
tolower(char_type ch)
|
||||
{
|
||||
return ucd::to_lowercase(ch);
|
||||
}
|
||||
|
||||
static char_type
|
||||
toupper(char_type ch)
|
||||
{
|
||||
return ucd::to_uppercase(ch);
|
||||
}
|
||||
|
||||
static ::boost::uint32_t
|
||||
toucs4(char_type ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Major Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_MAJOR_CATEGORY(name) \
|
||||
static bool \
|
||||
is_##name(char_type ch) \
|
||||
{ \
|
||||
return ucd::get_major_category(ch) == ucd::properties::name; \
|
||||
} \
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_MAJOR_CATEGORY(letter)
|
||||
BOOST_SPIRIT_MAJOR_CATEGORY(mark)
|
||||
BOOST_SPIRIT_MAJOR_CATEGORY(number)
|
||||
BOOST_SPIRIT_MAJOR_CATEGORY(separator)
|
||||
BOOST_SPIRIT_MAJOR_CATEGORY(other)
|
||||
BOOST_SPIRIT_MAJOR_CATEGORY(punctuation)
|
||||
BOOST_SPIRIT_MAJOR_CATEGORY(symbol)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// General Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_CATEGORY(name) \
|
||||
static bool \
|
||||
is_##name(char_type ch) \
|
||||
{ \
|
||||
return ucd::get_category(ch) == ucd::properties::name; \
|
||||
} \
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_CATEGORY(uppercase_letter)
|
||||
BOOST_SPIRIT_CATEGORY(lowercase_letter)
|
||||
BOOST_SPIRIT_CATEGORY(titlecase_letter)
|
||||
BOOST_SPIRIT_CATEGORY(modifier_letter)
|
||||
BOOST_SPIRIT_CATEGORY(other_letter)
|
||||
|
||||
BOOST_SPIRIT_CATEGORY(nonspacing_mark)
|
||||
BOOST_SPIRIT_CATEGORY(enclosing_mark)
|
||||
BOOST_SPIRIT_CATEGORY(spacing_mark)
|
||||
|
||||
BOOST_SPIRIT_CATEGORY(decimal_number)
|
||||
BOOST_SPIRIT_CATEGORY(letter_number)
|
||||
BOOST_SPIRIT_CATEGORY(other_number)
|
||||
|
||||
BOOST_SPIRIT_CATEGORY(space_separator)
|
||||
BOOST_SPIRIT_CATEGORY(line_separator)
|
||||
BOOST_SPIRIT_CATEGORY(paragraph_separator)
|
||||
|
||||
BOOST_SPIRIT_CATEGORY(control)
|
||||
BOOST_SPIRIT_CATEGORY(format)
|
||||
BOOST_SPIRIT_CATEGORY(private_use)
|
||||
BOOST_SPIRIT_CATEGORY(surrogate)
|
||||
BOOST_SPIRIT_CATEGORY(unassigned)
|
||||
|
||||
BOOST_SPIRIT_CATEGORY(dash_punctuation)
|
||||
BOOST_SPIRIT_CATEGORY(open_punctuation)
|
||||
BOOST_SPIRIT_CATEGORY(close_punctuation)
|
||||
BOOST_SPIRIT_CATEGORY(connector_punctuation)
|
||||
BOOST_SPIRIT_CATEGORY(other_punctuation)
|
||||
BOOST_SPIRIT_CATEGORY(initial_punctuation)
|
||||
BOOST_SPIRIT_CATEGORY(final_punctuation)
|
||||
|
||||
BOOST_SPIRIT_CATEGORY(math_symbol)
|
||||
BOOST_SPIRIT_CATEGORY(currency_symbol)
|
||||
BOOST_SPIRIT_CATEGORY(modifier_symbol)
|
||||
BOOST_SPIRIT_CATEGORY(other_symbol)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Derived Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_DERIVED_CATEGORY(name) \
|
||||
static bool \
|
||||
is_##name(char_type ch) \
|
||||
{ \
|
||||
return ucd::is_##name(ch); \
|
||||
} \
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_DERIVED_CATEGORY(alphabetic)
|
||||
BOOST_SPIRIT_DERIVED_CATEGORY(uppercase)
|
||||
BOOST_SPIRIT_DERIVED_CATEGORY(lowercase)
|
||||
BOOST_SPIRIT_DERIVED_CATEGORY(white_space)
|
||||
BOOST_SPIRIT_DERIVED_CATEGORY(hex_digit)
|
||||
BOOST_SPIRIT_DERIVED_CATEGORY(noncharacter_code_point)
|
||||
BOOST_SPIRIT_DERIVED_CATEGORY(default_ignorable_code_point)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Scripts
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_SCRIPT(name) \
|
||||
static bool \
|
||||
is_##name(char_type ch) \
|
||||
{ \
|
||||
return ucd::get_script(ch) == ucd::properties::name; \
|
||||
} \
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_SCRIPT(arabic)
|
||||
BOOST_SPIRIT_SCRIPT(imperial_aramaic)
|
||||
BOOST_SPIRIT_SCRIPT(armenian)
|
||||
BOOST_SPIRIT_SCRIPT(avestan)
|
||||
BOOST_SPIRIT_SCRIPT(balinese)
|
||||
BOOST_SPIRIT_SCRIPT(bamum)
|
||||
BOOST_SPIRIT_SCRIPT(bengali)
|
||||
BOOST_SPIRIT_SCRIPT(bopomofo)
|
||||
BOOST_SPIRIT_SCRIPT(braille)
|
||||
BOOST_SPIRIT_SCRIPT(buginese)
|
||||
BOOST_SPIRIT_SCRIPT(buhid)
|
||||
BOOST_SPIRIT_SCRIPT(canadian_aboriginal)
|
||||
BOOST_SPIRIT_SCRIPT(carian)
|
||||
BOOST_SPIRIT_SCRIPT(cham)
|
||||
BOOST_SPIRIT_SCRIPT(cherokee)
|
||||
BOOST_SPIRIT_SCRIPT(coptic)
|
||||
BOOST_SPIRIT_SCRIPT(cypriot)
|
||||
BOOST_SPIRIT_SCRIPT(cyrillic)
|
||||
BOOST_SPIRIT_SCRIPT(devanagari)
|
||||
BOOST_SPIRIT_SCRIPT(deseret)
|
||||
BOOST_SPIRIT_SCRIPT(egyptian_hieroglyphs)
|
||||
BOOST_SPIRIT_SCRIPT(ethiopic)
|
||||
BOOST_SPIRIT_SCRIPT(georgian)
|
||||
BOOST_SPIRIT_SCRIPT(glagolitic)
|
||||
BOOST_SPIRIT_SCRIPT(gothic)
|
||||
BOOST_SPIRIT_SCRIPT(greek)
|
||||
BOOST_SPIRIT_SCRIPT(gujarati)
|
||||
BOOST_SPIRIT_SCRIPT(gurmukhi)
|
||||
BOOST_SPIRIT_SCRIPT(hangul)
|
||||
BOOST_SPIRIT_SCRIPT(han)
|
||||
BOOST_SPIRIT_SCRIPT(hanunoo)
|
||||
BOOST_SPIRIT_SCRIPT(hebrew)
|
||||
BOOST_SPIRIT_SCRIPT(hiragana)
|
||||
BOOST_SPIRIT_SCRIPT(katakana_or_hiragana)
|
||||
BOOST_SPIRIT_SCRIPT(old_italic)
|
||||
BOOST_SPIRIT_SCRIPT(javanese)
|
||||
BOOST_SPIRIT_SCRIPT(kayah_li)
|
||||
BOOST_SPIRIT_SCRIPT(katakana)
|
||||
BOOST_SPIRIT_SCRIPT(kharoshthi)
|
||||
BOOST_SPIRIT_SCRIPT(khmer)
|
||||
BOOST_SPIRIT_SCRIPT(kannada)
|
||||
BOOST_SPIRIT_SCRIPT(kaithi)
|
||||
BOOST_SPIRIT_SCRIPT(tai_tham)
|
||||
BOOST_SPIRIT_SCRIPT(lao)
|
||||
BOOST_SPIRIT_SCRIPT(latin)
|
||||
BOOST_SPIRIT_SCRIPT(lepcha)
|
||||
BOOST_SPIRIT_SCRIPT(limbu)
|
||||
BOOST_SPIRIT_SCRIPT(linear_b)
|
||||
BOOST_SPIRIT_SCRIPT(lisu)
|
||||
BOOST_SPIRIT_SCRIPT(lycian)
|
||||
BOOST_SPIRIT_SCRIPT(lydian)
|
||||
BOOST_SPIRIT_SCRIPT(malayalam)
|
||||
BOOST_SPIRIT_SCRIPT(mongolian)
|
||||
BOOST_SPIRIT_SCRIPT(meetei_mayek)
|
||||
BOOST_SPIRIT_SCRIPT(myanmar)
|
||||
BOOST_SPIRIT_SCRIPT(nko)
|
||||
BOOST_SPIRIT_SCRIPT(ogham)
|
||||
BOOST_SPIRIT_SCRIPT(ol_chiki)
|
||||
BOOST_SPIRIT_SCRIPT(old_turkic)
|
||||
BOOST_SPIRIT_SCRIPT(oriya)
|
||||
BOOST_SPIRIT_SCRIPT(osmanya)
|
||||
BOOST_SPIRIT_SCRIPT(phags_pa)
|
||||
BOOST_SPIRIT_SCRIPT(inscriptional_pahlavi)
|
||||
BOOST_SPIRIT_SCRIPT(phoenician)
|
||||
BOOST_SPIRIT_SCRIPT(inscriptional_parthian)
|
||||
BOOST_SPIRIT_SCRIPT(rejang)
|
||||
BOOST_SPIRIT_SCRIPT(runic)
|
||||
BOOST_SPIRIT_SCRIPT(samaritan)
|
||||
BOOST_SPIRIT_SCRIPT(old_south_arabian)
|
||||
BOOST_SPIRIT_SCRIPT(saurashtra)
|
||||
BOOST_SPIRIT_SCRIPT(shavian)
|
||||
BOOST_SPIRIT_SCRIPT(sinhala)
|
||||
BOOST_SPIRIT_SCRIPT(sundanese)
|
||||
BOOST_SPIRIT_SCRIPT(syloti_nagri)
|
||||
BOOST_SPIRIT_SCRIPT(syriac)
|
||||
BOOST_SPIRIT_SCRIPT(tagbanwa)
|
||||
BOOST_SPIRIT_SCRIPT(tai_le)
|
||||
BOOST_SPIRIT_SCRIPT(new_tai_lue)
|
||||
BOOST_SPIRIT_SCRIPT(tamil)
|
||||
BOOST_SPIRIT_SCRIPT(tai_viet)
|
||||
BOOST_SPIRIT_SCRIPT(telugu)
|
||||
BOOST_SPIRIT_SCRIPT(tifinagh)
|
||||
BOOST_SPIRIT_SCRIPT(tagalog)
|
||||
BOOST_SPIRIT_SCRIPT(thaana)
|
||||
BOOST_SPIRIT_SCRIPT(thai)
|
||||
BOOST_SPIRIT_SCRIPT(tibetan)
|
||||
BOOST_SPIRIT_SCRIPT(ugaritic)
|
||||
BOOST_SPIRIT_SCRIPT(vai)
|
||||
BOOST_SPIRIT_SCRIPT(old_persian)
|
||||
BOOST_SPIRIT_SCRIPT(cuneiform)
|
||||
BOOST_SPIRIT_SCRIPT(yi)
|
||||
BOOST_SPIRIT_SCRIPT(inherited)
|
||||
BOOST_SPIRIT_SCRIPT(common)
|
||||
BOOST_SPIRIT_SCRIPT(unknown)
|
||||
|
||||
#undef BOOST_SPIRIT_MAJOR_CATEGORY
|
||||
#undef BOOST_SPIRIT_CATEGORY
|
||||
#undef BOOST_SPIRIT_DERIVED_CATEGORY
|
||||
#undef BOOST_SPIRIT_SCRIPT
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
+2216
File diff suppressed because it is too large
Load Diff
+620
@@ -0,0 +1,620 @@
|
||||
/*=============================================================================
|
||||
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)
|
||||
|
||||
AUTOGENERATED. DO NOT EDIT!!!
|
||||
==============================================================================*/
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace ucd { namespace detail
|
||||
{
|
||||
static const ::boost::uint8_t lowercase_stage1[] = {
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 9,
|
||||
6, 10, 6, 6, 11, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 13, 14, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 15,
|
||||
6, 6, 6, 6, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
|
||||
};
|
||||
|
||||
static const ::boost::uint32_t lowercase_stage2[] = {
|
||||
|
||||
// block 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
|
||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
|
||||
240, 241, 242, 243, 244, 245, 246, 0, 248, 249, 250, 251, 252, 253, 254, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 1
|
||||
257, 0, 259, 0, 261, 0, 263, 0, 265, 0, 267, 0, 269, 0, 271, 0,
|
||||
273, 0, 275, 0, 277, 0, 279, 0, 281, 0, 283, 0, 285, 0, 287, 0,
|
||||
289, 0, 291, 0, 293, 0, 295, 0, 297, 0, 299, 0, 301, 0, 303, 0,
|
||||
105, 0, 307, 0, 309, 0, 311, 0, 0, 314, 0, 316, 0, 318, 0, 320,
|
||||
0, 322, 0, 324, 0, 326, 0, 328, 0, 0, 331, 0, 333, 0, 335, 0,
|
||||
337, 0, 339, 0, 341, 0, 343, 0, 345, 0, 347, 0, 349, 0, 351, 0,
|
||||
353, 0, 355, 0, 357, 0, 359, 0, 361, 0, 363, 0, 365, 0, 367, 0,
|
||||
369, 0, 371, 0, 373, 0, 375, 0, 255, 378, 0, 380, 0, 382, 0, 0,
|
||||
0, 595, 387, 0, 389, 0, 596, 392, 0, 598, 599, 396, 0, 0, 477, 601,
|
||||
603, 402, 0, 608, 611, 0, 617, 616, 409, 0, 0, 0, 623, 626, 0, 629,
|
||||
417, 0, 419, 0, 421, 0, 640, 424, 0, 643, 0, 0, 429, 0, 648, 432,
|
||||
0, 650, 651, 436, 0, 438, 0, 658, 441, 0, 0, 0, 445, 0, 0, 0,
|
||||
0, 0, 0, 0, 454, 454, 0, 457, 457, 0, 460, 460, 0, 462, 0, 464,
|
||||
0, 466, 0, 468, 0, 470, 0, 472, 0, 474, 0, 476, 0, 0, 479, 0,
|
||||
481, 0, 483, 0, 485, 0, 487, 0, 489, 0, 491, 0, 493, 0, 495, 0,
|
||||
0, 499, 499, 0, 501, 0, 405, 447, 505, 0, 507, 0, 509, 0, 511, 0,
|
||||
|
||||
|
||||
// block 2
|
||||
513, 0, 515, 0, 517, 0, 519, 0, 521, 0, 523, 0, 525, 0, 527, 0,
|
||||
529, 0, 531, 0, 533, 0, 535, 0, 537, 0, 539, 0, 541, 0, 543, 0,
|
||||
414, 0, 547, 0, 549, 0, 551, 0, 553, 0, 555, 0, 557, 0, 559, 0,
|
||||
561, 0, 563, 0, 0, 0, 0, 0, 0, 0, 11365, 572, 0, 410, 11366, 0,
|
||||
0, 578, 0, 384, 649, 652, 583, 0, 585, 0, 587, 0, 589, 0, 591, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 3
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
881, 0, 883, 0, 0, 0, 887, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 940, 0, 941, 942, 943, 0, 972, 0, 973, 974,
|
||||
0, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959,
|
||||
960, 961, 0, 963, 964, 965, 966, 967, 968, 969, 970, 971, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 985, 0, 987, 0, 989, 0, 991, 0,
|
||||
993, 0, 995, 0, 997, 0, 999, 0, 1001, 0, 1003, 0, 1005, 0, 1007, 0,
|
||||
0, 0, 0, 0, 952, 0, 0, 1016, 0, 1010, 1019, 0, 0, 891, 892, 893,
|
||||
|
||||
|
||||
// block 4
|
||||
1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119,
|
||||
1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087,
|
||||
1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1121, 0, 1123, 0, 1125, 0, 1127, 0, 1129, 0, 1131, 0, 1133, 0, 1135, 0,
|
||||
1137, 0, 1139, 0, 1141, 0, 1143, 0, 1145, 0, 1147, 0, 1149, 0, 1151, 0,
|
||||
1153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1163, 0, 1165, 0, 1167, 0,
|
||||
1169, 0, 1171, 0, 1173, 0, 1175, 0, 1177, 0, 1179, 0, 1181, 0, 1183, 0,
|
||||
1185, 0, 1187, 0, 1189, 0, 1191, 0, 1193, 0, 1195, 0, 1197, 0, 1199, 0,
|
||||
1201, 0, 1203, 0, 1205, 0, 1207, 0, 1209, 0, 1211, 0, 1213, 0, 1215, 0,
|
||||
1231, 1218, 0, 1220, 0, 1222, 0, 1224, 0, 1226, 0, 1228, 0, 1230, 0, 0,
|
||||
1233, 0, 1235, 0, 1237, 0, 1239, 0, 1241, 0, 1243, 0, 1245, 0, 1247, 0,
|
||||
1249, 0, 1251, 0, 1253, 0, 1255, 0, 1257, 0, 1259, 0, 1261, 0, 1263, 0,
|
||||
1265, 0, 1267, 0, 1269, 0, 1271, 0, 1273, 0, 1275, 0, 1277, 0, 1279, 0,
|
||||
|
||||
|
||||
// block 5
|
||||
1281, 0, 1283, 0, 1285, 0, 1287, 0, 1289, 0, 1291, 0, 1293, 0, 1295, 0,
|
||||
1297, 0, 1299, 0, 1301, 0, 1303, 0, 1305, 0, 1307, 0, 1309, 0, 1311, 0,
|
||||
1313, 0, 1315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391,
|
||||
1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407,
|
||||
1408, 1409, 1410, 1411, 1412, 1413, 1414, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 6
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 7
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
11520, 11521, 11522, 11523, 11524, 11525, 11526, 11527, 11528, 11529, 11530, 11531, 11532, 11533, 11534, 11535,
|
||||
11536, 11537, 11538, 11539, 11540, 11541, 11542, 11543, 11544, 11545, 11546, 11547, 11548, 11549, 11550, 11551,
|
||||
11552, 11553, 11554, 11555, 11556, 11557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 8
|
||||
7681, 0, 7683, 0, 7685, 0, 7687, 0, 7689, 0, 7691, 0, 7693, 0, 7695, 0,
|
||||
7697, 0, 7699, 0, 7701, 0, 7703, 0, 7705, 0, 7707, 0, 7709, 0, 7711, 0,
|
||||
7713, 0, 7715, 0, 7717, 0, 7719, 0, 7721, 0, 7723, 0, 7725, 0, 7727, 0,
|
||||
7729, 0, 7731, 0, 7733, 0, 7735, 0, 7737, 0, 7739, 0, 7741, 0, 7743, 0,
|
||||
7745, 0, 7747, 0, 7749, 0, 7751, 0, 7753, 0, 7755, 0, 7757, 0, 7759, 0,
|
||||
7761, 0, 7763, 0, 7765, 0, 7767, 0, 7769, 0, 7771, 0, 7773, 0, 7775, 0,
|
||||
7777, 0, 7779, 0, 7781, 0, 7783, 0, 7785, 0, 7787, 0, 7789, 0, 7791, 0,
|
||||
7793, 0, 7795, 0, 7797, 0, 7799, 0, 7801, 0, 7803, 0, 7805, 0, 7807, 0,
|
||||
7809, 0, 7811, 0, 7813, 0, 7815, 0, 7817, 0, 7819, 0, 7821, 0, 7823, 0,
|
||||
7825, 0, 7827, 0, 7829, 0, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0,
|
||||
7841, 0, 7843, 0, 7845, 0, 7847, 0, 7849, 0, 7851, 0, 7853, 0, 7855, 0,
|
||||
7857, 0, 7859, 0, 7861, 0, 7863, 0, 7865, 0, 7867, 0, 7869, 0, 7871, 0,
|
||||
7873, 0, 7875, 0, 7877, 0, 7879, 0, 7881, 0, 7883, 0, 7885, 0, 7887, 0,
|
||||
7889, 0, 7891, 0, 7893, 0, 7895, 0, 7897, 0, 7899, 0, 7901, 0, 7903, 0,
|
||||
7905, 0, 7907, 0, 7909, 0, 7911, 0, 7913, 0, 7915, 0, 7917, 0, 7919, 0,
|
||||
7921, 0, 7923, 0, 7925, 0, 7927, 0, 7929, 0, 7931, 0, 7933, 0, 7935, 0,
|
||||
|
||||
|
||||
// block 9
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 7952, 7953, 7954, 7955, 7956, 7957, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8000, 8001, 8002, 8003, 8004, 8005, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 8017, 0, 8019, 0, 8021, 0, 8023,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8112, 8113, 8048, 8049, 8115, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8050, 8051, 8052, 8053, 8131, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8144, 8145, 8054, 8055, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8160, 8161, 8058, 8059, 8165, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 8056, 8057, 8060, 8061, 8179, 0, 0, 0,
|
||||
|
||||
|
||||
// block 10
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 969, 0, 0, 0, 107, 229, 0, 0, 0, 0,
|
||||
0, 0, 8526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8560, 8561, 8562, 8563, 8564, 8565, 8566, 8567, 8568, 8569, 8570, 8571, 8572, 8573, 8574, 8575,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 8580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 11
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 9424, 9425, 9426, 9427, 9428, 9429, 9430, 9431, 9432, 9433,
|
||||
9434, 9435, 9436, 9437, 9438, 9439, 9440, 9441, 9442, 9443, 9444, 9445, 9446, 9447, 9448, 9449,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 12
|
||||
11312, 11313, 11314, 11315, 11316, 11317, 11318, 11319, 11320, 11321, 11322, 11323, 11324, 11325, 11326, 11327,
|
||||
11328, 11329, 11330, 11331, 11332, 11333, 11334, 11335, 11336, 11337, 11338, 11339, 11340, 11341, 11342, 11343,
|
||||
11344, 11345, 11346, 11347, 11348, 11349, 11350, 11351, 11352, 11353, 11354, 11355, 11356, 11357, 11358, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
11361, 0, 619, 7549, 637, 0, 0, 11368, 0, 11370, 0, 11372, 0, 593, 625, 592,
|
||||
0, 0, 11379, 0, 0, 11382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
11393, 0, 11395, 0, 11397, 0, 11399, 0, 11401, 0, 11403, 0, 11405, 0, 11407, 0,
|
||||
11409, 0, 11411, 0, 11413, 0, 11415, 0, 11417, 0, 11419, 0, 11421, 0, 11423, 0,
|
||||
11425, 0, 11427, 0, 11429, 0, 11431, 0, 11433, 0, 11435, 0, 11437, 0, 11439, 0,
|
||||
11441, 0, 11443, 0, 11445, 0, 11447, 0, 11449, 0, 11451, 0, 11453, 0, 11455, 0,
|
||||
11457, 0, 11459, 0, 11461, 0, 11463, 0, 11465, 0, 11467, 0, 11469, 0, 11471, 0,
|
||||
11473, 0, 11475, 0, 11477, 0, 11479, 0, 11481, 0, 11483, 0, 11485, 0, 11487, 0,
|
||||
11489, 0, 11491, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 13
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
42561, 0, 42563, 0, 42565, 0, 42567, 0, 42569, 0, 42571, 0, 42573, 0, 42575, 0,
|
||||
42577, 0, 42579, 0, 42581, 0, 42583, 0, 42585, 0, 42587, 0, 42589, 0, 42591, 0,
|
||||
0, 0, 42595, 0, 42597, 0, 42599, 0, 42601, 0, 42603, 0, 42605, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
42625, 0, 42627, 0, 42629, 0, 42631, 0, 42633, 0, 42635, 0, 42637, 0, 42639, 0,
|
||||
42641, 0, 42643, 0, 42645, 0, 42647, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 14
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 42787, 0, 42789, 0, 42791, 0, 42793, 0, 42795, 0, 42797, 0, 42799, 0,
|
||||
0, 0, 42803, 0, 42805, 0, 42807, 0, 42809, 0, 42811, 0, 42813, 0, 42815, 0,
|
||||
42817, 0, 42819, 0, 42821, 0, 42823, 0, 42825, 0, 42827, 0, 42829, 0, 42831, 0,
|
||||
42833, 0, 42835, 0, 42837, 0, 42839, 0, 42841, 0, 42843, 0, 42845, 0, 42847, 0,
|
||||
42849, 0, 42851, 0, 42853, 0, 42855, 0, 42857, 0, 42859, 0, 42861, 0, 42863, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 42874, 0, 42876, 0, 7545, 42879, 0,
|
||||
42881, 0, 42883, 0, 42885, 0, 42887, 0, 0, 0, 0, 42892, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 15
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359,
|
||||
65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 16
|
||||
66600, 66601, 66602, 66603, 66604, 66605, 66606, 66607, 66608, 66609, 66610, 66611, 66612, 66613, 66614, 66615,
|
||||
66616, 66617, 66618, 66619, 66620, 66621, 66622, 66623, 66624, 66625, 66626, 66627, 66628, 66629, 66630, 66631,
|
||||
66632, 66633, 66634, 66635, 66636, 66637, 66638, 66639, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
inline ::boost::uint32_t lowercase_lookup(::boost::uint32_t ch)
|
||||
{
|
||||
::boost::uint32_t block_offset = lowercase_stage1[ch / 256] * 256;
|
||||
return lowercase_stage2[block_offset + ch % 256];
|
||||
}
|
||||
|
||||
}}}} // namespace boost::spirit::unicode::detail
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
/*=============================================================================
|
||||
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)
|
||||
|
||||
Autogenerated by MultiStageTable.py (Unicode multi-stage
|
||||
table builder) (c) Peter Kankowski, 2008
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_UNICODE_QUERY_FEBRUARY_2_2010)
|
||||
#define BOOST_SPIRIT_UNICODE_QUERY_FEBRUARY_2_2010
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
# include "category_table.hpp"
|
||||
# include "script_table.hpp"
|
||||
# include "lowercase_table.hpp"
|
||||
# include "uppercase_table.hpp"
|
||||
|
||||
namespace boost { namespace spirit { namespace ucd
|
||||
{
|
||||
// This header provides Basic (Level 1) Unicode Support
|
||||
// See http://unicode.org/reports/tr18/ for details
|
||||
|
||||
struct properties
|
||||
{
|
||||
// bit pattern: xxMMMCCC
|
||||
// MMM: major_category
|
||||
// CCC: category
|
||||
|
||||
enum major_category
|
||||
{
|
||||
letter,
|
||||
mark,
|
||||
number,
|
||||
separator,
|
||||
other,
|
||||
punctuation,
|
||||
symbol
|
||||
};
|
||||
|
||||
enum category
|
||||
{
|
||||
uppercase_letter = 0, // [Lu] an uppercase letter
|
||||
lowercase_letter, // [Ll] a lowercase letter
|
||||
titlecase_letter, // [Lt] a digraphic character, with first part uppercase
|
||||
modifier_letter, // [Lm] a modifier letter
|
||||
other_letter, // [Lo] other letters, including syllables and ideographs
|
||||
|
||||
nonspacing_mark = 8, // [Mn] a nonspacing combining mark (zero advance width)
|
||||
enclosing_mark, // [Me] an enclosing combining mark
|
||||
spacing_mark, // [Mc] a spacing combining mark (positive advance width)
|
||||
|
||||
decimal_number = 16, // [Nd] a decimal digit
|
||||
letter_number, // [Nl] a letterlike numeric character
|
||||
other_number, // [No] a numeric character of other type
|
||||
|
||||
space_separator = 24, // [Zs] a space character (of various non-zero widths)
|
||||
line_separator, // [Zl] U+2028 LINE SEPARATOR only
|
||||
paragraph_separator, // [Zp] U+2029 PARAGRAPH SEPARATOR only
|
||||
|
||||
control = 32, // [Cc] a C0 or C1 control code
|
||||
format, // [Cf] a format control character
|
||||
private_use, // [Co] a private-use character
|
||||
surrogate, // [Cs] a surrogate code point
|
||||
unassigned, // [Cn] a reserved unassigned code point or a noncharacter
|
||||
|
||||
dash_punctuation = 40, // [Pd] a dash or hyphen punctuation mark
|
||||
open_punctuation, // [Ps] an opening punctuation mark (of a pair)
|
||||
close_punctuation, // [Pe] a closing punctuation mark (of a pair)
|
||||
connector_punctuation, // [Pc] a connecting punctuation mark, like a tie
|
||||
other_punctuation, // [Po] a punctuation mark of other type
|
||||
initial_punctuation, // [Pi] an initial quotation mark
|
||||
final_punctuation, // [Pf] a final quotation mark
|
||||
|
||||
math_symbol = 48, // [Sm] a symbol of primarily mathematical use
|
||||
currency_symbol, // [Sc] a currency sign
|
||||
modifier_symbol, // [Sk] a non-letterlike modifier symbol
|
||||
other_symbol // [So] a symbol of other type
|
||||
};
|
||||
|
||||
enum derived_properties
|
||||
{
|
||||
alphabetic = 64,
|
||||
uppercase = 128,
|
||||
lowercase = 256,
|
||||
white_space = 512,
|
||||
hex_digit = 1024,
|
||||
noncharacter_code_point = 2048,
|
||||
default_ignorable_code_point = 4096
|
||||
};
|
||||
|
||||
enum script
|
||||
{
|
||||
arabic = 0,
|
||||
imperial_aramaic = 1,
|
||||
armenian = 2,
|
||||
avestan = 3,
|
||||
balinese = 4,
|
||||
bamum = 5,
|
||||
bengali = 6,
|
||||
bopomofo = 7,
|
||||
braille = 8,
|
||||
buginese = 9,
|
||||
buhid = 10,
|
||||
canadian_aboriginal = 11,
|
||||
carian = 12,
|
||||
cham = 13,
|
||||
cherokee = 14,
|
||||
coptic = 15,
|
||||
cypriot = 16,
|
||||
cyrillic = 17,
|
||||
devanagari = 18,
|
||||
deseret = 19,
|
||||
egyptian_hieroglyphs = 20,
|
||||
ethiopic = 21,
|
||||
georgian = 22,
|
||||
glagolitic = 23,
|
||||
gothic = 24,
|
||||
greek = 25,
|
||||
gujarati = 26,
|
||||
gurmukhi = 27,
|
||||
hangul = 28,
|
||||
han = 29,
|
||||
hanunoo = 30,
|
||||
hebrew = 31,
|
||||
hiragana = 32,
|
||||
katakana_or_hiragana = 33,
|
||||
old_italic = 34,
|
||||
javanese = 35,
|
||||
kayah_li = 36,
|
||||
katakana = 37,
|
||||
kharoshthi = 38,
|
||||
khmer = 39,
|
||||
kannada = 40,
|
||||
kaithi = 41,
|
||||
tai_tham = 42,
|
||||
lao = 43,
|
||||
latin = 44,
|
||||
lepcha = 45,
|
||||
limbu = 46,
|
||||
linear_b = 47,
|
||||
lisu = 48,
|
||||
lycian = 49,
|
||||
lydian = 50,
|
||||
malayalam = 51,
|
||||
mongolian = 52,
|
||||
meetei_mayek = 53,
|
||||
myanmar = 54,
|
||||
nko = 55,
|
||||
ogham = 56,
|
||||
ol_chiki = 57,
|
||||
old_turkic = 58,
|
||||
oriya = 59,
|
||||
osmanya = 60,
|
||||
phags_pa = 61,
|
||||
inscriptional_pahlavi = 62,
|
||||
phoenician = 63,
|
||||
inscriptional_parthian = 64,
|
||||
rejang = 65,
|
||||
runic = 66,
|
||||
samaritan = 67,
|
||||
old_south_arabian = 68,
|
||||
saurashtra = 69,
|
||||
shavian = 70,
|
||||
sinhala = 71,
|
||||
sundanese = 72,
|
||||
syloti_nagri = 73,
|
||||
syriac = 74,
|
||||
tagbanwa = 75,
|
||||
tai_le = 76,
|
||||
new_tai_lue = 77,
|
||||
tamil = 78,
|
||||
tai_viet = 79,
|
||||
telugu = 80,
|
||||
tifinagh = 81,
|
||||
tagalog = 82,
|
||||
thaana = 83,
|
||||
thai = 84,
|
||||
tibetan = 85,
|
||||
ugaritic = 86,
|
||||
vai = 87,
|
||||
old_persian = 88,
|
||||
cuneiform = 89,
|
||||
yi = 90,
|
||||
inherited = 91,
|
||||
common = 92,
|
||||
unknown = 93
|
||||
};
|
||||
};
|
||||
|
||||
inline properties::category get_category(::boost::uint32_t ch)
|
||||
{
|
||||
return static_cast<properties::category>(detail::category_lookup(ch) & 0x3F);
|
||||
}
|
||||
|
||||
inline properties::major_category get_major_category(::boost::uint32_t ch)
|
||||
{
|
||||
return static_cast<properties::major_category>(get_category(ch) >> 3);
|
||||
}
|
||||
|
||||
inline bool is_punctuation(::boost::uint32_t ch)
|
||||
{
|
||||
return get_major_category(ch) == properties::punctuation;
|
||||
}
|
||||
|
||||
inline bool is_decimal_number(::boost::uint32_t ch)
|
||||
{
|
||||
return get_category(ch) == properties::decimal_number;
|
||||
}
|
||||
|
||||
inline bool is_hex_digit(::boost::uint32_t ch)
|
||||
{
|
||||
return (detail::category_lookup(ch) & properties::hex_digit) != 0;
|
||||
}
|
||||
|
||||
inline bool is_control(::boost::uint32_t ch)
|
||||
{
|
||||
return get_category(ch) == properties::control;
|
||||
}
|
||||
|
||||
inline bool is_alphabetic(::boost::uint32_t ch)
|
||||
{
|
||||
return (detail::category_lookup(ch) & properties::alphabetic) != 0;
|
||||
}
|
||||
|
||||
inline bool is_alphanumeric(::boost::uint32_t ch)
|
||||
{
|
||||
return is_decimal_number(ch) || is_alphabetic(ch);
|
||||
}
|
||||
|
||||
inline bool is_uppercase(::boost::uint32_t ch)
|
||||
{
|
||||
return (detail::category_lookup(ch) & properties::uppercase) != 0;
|
||||
}
|
||||
|
||||
inline bool is_lowercase(::boost::uint32_t ch)
|
||||
{
|
||||
return (detail::category_lookup(ch) & properties::lowercase) != 0;
|
||||
}
|
||||
|
||||
inline bool is_white_space(::boost::uint32_t ch)
|
||||
{
|
||||
return (detail::category_lookup(ch) & properties::white_space) != 0;
|
||||
}
|
||||
|
||||
inline bool is_blank(::boost::uint32_t ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case '\n': case '\v': case '\f': case '\r':
|
||||
return false;
|
||||
default:
|
||||
return is_white_space(ch)
|
||||
&& !( get_category(ch) == properties::line_separator
|
||||
|| get_category(ch) == properties::paragraph_separator
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_graph(::boost::uint32_t ch)
|
||||
{
|
||||
return !( is_white_space(ch)
|
||||
|| get_category(ch) == properties::control
|
||||
|| get_category(ch) == properties::surrogate
|
||||
|| get_category(ch) == properties::unassigned
|
||||
);
|
||||
}
|
||||
|
||||
inline bool is_print(::boost::uint32_t ch)
|
||||
{
|
||||
return (is_graph(ch) || is_blank(ch)) && !is_control(ch);
|
||||
}
|
||||
|
||||
inline bool is_noncharacter_code_point(::boost::uint32_t ch)
|
||||
{
|
||||
return (detail::category_lookup(ch) & properties::noncharacter_code_point) != 0;
|
||||
}
|
||||
|
||||
inline bool is_default_ignorable_code_point(::boost::uint32_t ch)
|
||||
{
|
||||
return (detail::category_lookup(ch) & properties::default_ignorable_code_point) != 0;
|
||||
}
|
||||
|
||||
inline properties::script get_script(::boost::uint32_t ch)
|
||||
{
|
||||
return static_cast<properties::script>(detail::script_lookup(ch) & 0x7F);
|
||||
}
|
||||
|
||||
inline ::boost::uint32_t to_lowercase(::boost::uint32_t ch)
|
||||
{
|
||||
// The table returns 0 to signal that this code maps to itself
|
||||
::boost::uint32_t r = detail::lowercase_lookup(ch);
|
||||
return (r == 0)? ch : r;
|
||||
}
|
||||
|
||||
inline ::boost::uint32_t to_uppercase(::boost::uint32_t ch)
|
||||
{
|
||||
// The table returns 0 to signal that this code maps to itself
|
||||
::boost::uint32_t r = detail::uppercase_lookup(ch);
|
||||
return (r == 0)? ch : r;
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+2159
File diff suppressed because it is too large
Load Diff
+639
@@ -0,0 +1,639 @@
|
||||
/*=============================================================================
|
||||
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)
|
||||
|
||||
AUTOGENERATED. DO NOT EDIT!!!
|
||||
==============================================================================*/
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace ucd { namespace detail
|
||||
{
|
||||
static const ::boost::uint8_t uppercase_stage1[] = {
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8, 9,
|
||||
6, 10, 6, 6, 11, 6, 6, 6, 6, 6, 6, 6, 12, 13, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 14, 15, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 16,
|
||||
6, 6, 6, 6, 17, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
|
||||
};
|
||||
|
||||
static const ::boost::uint32_t uppercase_stage2[] = {
|
||||
|
||||
// block 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
|
||||
208, 209, 210, 211, 212, 213, 214, 0, 216, 217, 218, 219, 220, 221, 222, 376,
|
||||
|
||||
|
||||
// block 1
|
||||
0, 256, 0, 258, 0, 260, 0, 262, 0, 264, 0, 266, 0, 268, 0, 270,
|
||||
0, 272, 0, 274, 0, 276, 0, 278, 0, 280, 0, 282, 0, 284, 0, 286,
|
||||
0, 288, 0, 290, 0, 292, 0, 294, 0, 296, 0, 298, 0, 300, 0, 302,
|
||||
0, 73, 0, 306, 0, 308, 0, 310, 0, 0, 313, 0, 315, 0, 317, 0,
|
||||
319, 0, 321, 0, 323, 0, 325, 0, 327, 0, 0, 330, 0, 332, 0, 334,
|
||||
0, 336, 0, 338, 0, 340, 0, 342, 0, 344, 0, 346, 0, 348, 0, 350,
|
||||
0, 352, 0, 354, 0, 356, 0, 358, 0, 360, 0, 362, 0, 364, 0, 366,
|
||||
0, 368, 0, 370, 0, 372, 0, 374, 0, 0, 377, 0, 379, 0, 381, 83,
|
||||
579, 0, 0, 386, 0, 388, 0, 0, 391, 0, 0, 0, 395, 0, 0, 0,
|
||||
0, 0, 401, 0, 0, 502, 0, 0, 0, 408, 573, 0, 0, 0, 544, 0,
|
||||
0, 416, 0, 418, 0, 420, 0, 0, 423, 0, 0, 0, 0, 428, 0, 0,
|
||||
431, 0, 0, 0, 435, 0, 437, 0, 0, 440, 0, 0, 0, 444, 0, 503,
|
||||
0, 0, 0, 0, 0, 452, 452, 0, 455, 455, 0, 458, 458, 0, 461, 0,
|
||||
463, 0, 465, 0, 467, 0, 469, 0, 471, 0, 473, 0, 475, 398, 0, 478,
|
||||
0, 480, 0, 482, 0, 484, 0, 486, 0, 488, 0, 490, 0, 492, 0, 494,
|
||||
0, 0, 497, 497, 0, 500, 0, 0, 0, 504, 0, 506, 0, 508, 0, 510,
|
||||
|
||||
|
||||
// block 2
|
||||
0, 512, 0, 514, 0, 516, 0, 518, 0, 520, 0, 522, 0, 524, 0, 526,
|
||||
0, 528, 0, 530, 0, 532, 0, 534, 0, 536, 0, 538, 0, 540, 0, 542,
|
||||
0, 0, 0, 546, 0, 548, 0, 550, 0, 552, 0, 554, 0, 556, 0, 558,
|
||||
0, 560, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 0,
|
||||
0, 0, 577, 0, 0, 0, 0, 582, 0, 584, 0, 586, 0, 588, 0, 590,
|
||||
11375, 11373, 0, 385, 390, 0, 393, 394, 0, 399, 0, 400, 0, 0, 0, 0,
|
||||
403, 0, 0, 404, 0, 0, 0, 0, 407, 406, 0, 11362, 0, 0, 0, 412,
|
||||
0, 11374, 413, 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, 11364, 0, 0,
|
||||
422, 0, 0, 425, 0, 0, 0, 0, 430, 580, 433, 434, 581, 0, 0, 0,
|
||||
0, 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 3
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 880, 0, 882, 0, 0, 0, 886, 0, 0, 0, 1021, 1022, 1023, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 902, 904, 905, 906,
|
||||
0, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927,
|
||||
928, 929, 931, 931, 932, 933, 934, 935, 936, 937, 938, 939, 908, 910, 911, 0,
|
||||
914, 920, 0, 0, 0, 934, 928, 975, 0, 984, 0, 986, 0, 988, 0, 990,
|
||||
0, 992, 0, 994, 0, 996, 0, 998, 0, 1000, 0, 1002, 0, 1004, 0, 1006,
|
||||
922, 929, 1017, 0, 0, 917, 0, 0, 1015, 0, 0, 1018, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 4
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055,
|
||||
1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071,
|
||||
1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
|
||||
0, 1120, 0, 1122, 0, 1124, 0, 1126, 0, 1128, 0, 1130, 0, 1132, 0, 1134,
|
||||
0, 1136, 0, 1138, 0, 1140, 0, 1142, 0, 1144, 0, 1146, 0, 1148, 0, 1150,
|
||||
0, 1152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 1164, 0, 1166,
|
||||
0, 1168, 0, 1170, 0, 1172, 0, 1174, 0, 1176, 0, 1178, 0, 1180, 0, 1182,
|
||||
0, 1184, 0, 1186, 0, 1188, 0, 1190, 0, 1192, 0, 1194, 0, 1196, 0, 1198,
|
||||
0, 1200, 0, 1202, 0, 1204, 0, 1206, 0, 1208, 0, 1210, 0, 1212, 0, 1214,
|
||||
0, 0, 1217, 0, 1219, 0, 1221, 0, 1223, 0, 1225, 0, 1227, 0, 1229, 1216,
|
||||
0, 1232, 0, 1234, 0, 1236, 0, 1238, 0, 1240, 0, 1242, 0, 1244, 0, 1246,
|
||||
0, 1248, 0, 1250, 0, 1252, 0, 1254, 0, 1256, 0, 1258, 0, 1260, 0, 1262,
|
||||
0, 1264, 0, 1266, 0, 1268, 0, 1270, 0, 1272, 0, 1274, 0, 1276, 0, 1278,
|
||||
|
||||
|
||||
// block 5
|
||||
0, 1280, 0, 1282, 0, 1284, 0, 1286, 0, 1288, 0, 1290, 0, 1292, 0, 1294,
|
||||
0, 1296, 0, 1298, 0, 1300, 0, 1302, 0, 1304, 0, 1306, 0, 1308, 0, 1310,
|
||||
0, 1312, 0, 1314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343,
|
||||
1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359,
|
||||
1360, 1361, 1362, 1363, 1364, 1365, 1366, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 6
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 7
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 42877, 0, 0, 0, 11363, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 8
|
||||
0, 7680, 0, 7682, 0, 7684, 0, 7686, 0, 7688, 0, 7690, 0, 7692, 0, 7694,
|
||||
0, 7696, 0, 7698, 0, 7700, 0, 7702, 0, 7704, 0, 7706, 0, 7708, 0, 7710,
|
||||
0, 7712, 0, 7714, 0, 7716, 0, 7718, 0, 7720, 0, 7722, 0, 7724, 0, 7726,
|
||||
0, 7728, 0, 7730, 0, 7732, 0, 7734, 0, 7736, 0, 7738, 0, 7740, 0, 7742,
|
||||
0, 7744, 0, 7746, 0, 7748, 0, 7750, 0, 7752, 0, 7754, 0, 7756, 0, 7758,
|
||||
0, 7760, 0, 7762, 0, 7764, 0, 7766, 0, 7768, 0, 7770, 0, 7772, 0, 7774,
|
||||
0, 7776, 0, 7778, 0, 7780, 0, 7782, 0, 7784, 0, 7786, 0, 7788, 0, 7790,
|
||||
0, 7792, 0, 7794, 0, 7796, 0, 7798, 0, 7800, 0, 7802, 0, 7804, 0, 7806,
|
||||
0, 7808, 0, 7810, 0, 7812, 0, 7814, 0, 7816, 0, 7818, 0, 7820, 0, 7822,
|
||||
0, 7824, 0, 7826, 0, 7828, 0, 0, 0, 0, 0, 7776, 0, 0, 0, 0,
|
||||
0, 7840, 0, 7842, 0, 7844, 0, 7846, 0, 7848, 0, 7850, 0, 7852, 0, 7854,
|
||||
0, 7856, 0, 7858, 0, 7860, 0, 7862, 0, 7864, 0, 7866, 0, 7868, 0, 7870,
|
||||
0, 7872, 0, 7874, 0, 7876, 0, 7878, 0, 7880, 0, 7882, 0, 7884, 0, 7886,
|
||||
0, 7888, 0, 7890, 0, 7892, 0, 7894, 0, 7896, 0, 7898, 0, 7900, 0, 7902,
|
||||
0, 7904, 0, 7906, 0, 7908, 0, 7910, 0, 7912, 0, 7914, 0, 7916, 0, 7918,
|
||||
0, 7920, 0, 7922, 0, 7924, 0, 7926, 0, 7928, 0, 7930, 0, 7932, 0, 7934,
|
||||
|
||||
|
||||
// block 9
|
||||
7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
7960, 7961, 7962, 7963, 7964, 7965, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8008, 8009, 8010, 8011, 8012, 8013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 8025, 0, 8027, 0, 8029, 0, 8031, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8040, 8041, 8042, 8043, 8044, 8045, 8046, 8047, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8122, 8123, 8136, 8137, 8138, 8139, 8154, 8155, 8184, 8185, 8170, 8171, 8186, 8187, 0, 0,
|
||||
8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8088, 8089, 8090, 8091, 8092, 8093, 8094, 8095, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8104, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8120, 8121, 0, 8124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 921, 0,
|
||||
0, 0, 0, 8140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8152, 8153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8168, 8169, 0, 0, 0, 8172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 8188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 10
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8498, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8544, 8545, 8546, 8547, 8548, 8549, 8550, 8551, 8552, 8553, 8554, 8555, 8556, 8557, 8558, 8559,
|
||||
0, 0, 0, 0, 8579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 11
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
9398, 9399, 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 9408, 9409, 9410, 9411, 9412, 9413,
|
||||
9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, 9422, 9423, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 12
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
11264, 11265, 11266, 11267, 11268, 11269, 11270, 11271, 11272, 11273, 11274, 11275, 11276, 11277, 11278, 11279,
|
||||
11280, 11281, 11282, 11283, 11284, 11285, 11286, 11287, 11288, 11289, 11290, 11291, 11292, 11293, 11294, 11295,
|
||||
11296, 11297, 11298, 11299, 11300, 11301, 11302, 11303, 11304, 11305, 11306, 11307, 11308, 11309, 11310, 0,
|
||||
0, 11360, 0, 0, 0, 570, 574, 0, 11367, 0, 11369, 0, 11371, 0, 0, 0,
|
||||
0, 0, 0, 11378, 0, 0, 11381, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 11392, 0, 11394, 0, 11396, 0, 11398, 0, 11400, 0, 11402, 0, 11404, 0, 11406,
|
||||
0, 11408, 0, 11410, 0, 11412, 0, 11414, 0, 11416, 0, 11418, 0, 11420, 0, 11422,
|
||||
0, 11424, 0, 11426, 0, 11428, 0, 11430, 0, 11432, 0, 11434, 0, 11436, 0, 11438,
|
||||
0, 11440, 0, 11442, 0, 11444, 0, 11446, 0, 11448, 0, 11450, 0, 11452, 0, 11454,
|
||||
0, 11456, 0, 11458, 0, 11460, 0, 11462, 0, 11464, 0, 11466, 0, 11468, 0, 11470,
|
||||
0, 11472, 0, 11474, 0, 11476, 0, 11478, 0, 11480, 0, 11482, 0, 11484, 0, 11486,
|
||||
0, 11488, 0, 11490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 13
|
||||
4256, 4257, 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271,
|
||||
4272, 4273, 4274, 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282, 4283, 4284, 4285, 4286, 4287,
|
||||
4288, 4289, 4290, 4291, 4292, 4293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 14
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 42560, 0, 42562, 0, 42564, 0, 42566, 0, 42568, 0, 42570, 0, 42572, 0, 42574,
|
||||
0, 42576, 0, 42578, 0, 42580, 0, 42582, 0, 42584, 0, 42586, 0, 42588, 0, 42590,
|
||||
0, 0, 0, 42594, 0, 42596, 0, 42598, 0, 42600, 0, 42602, 0, 42604, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 42624, 0, 42626, 0, 42628, 0, 42630, 0, 42632, 0, 42634, 0, 42636, 0, 42638,
|
||||
0, 42640, 0, 42642, 0, 42644, 0, 42646, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 15
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 42786, 0, 42788, 0, 42790, 0, 42792, 0, 42794, 0, 42796, 0, 42798,
|
||||
0, 0, 0, 42802, 0, 42804, 0, 42806, 0, 42808, 0, 42810, 0, 42812, 0, 42814,
|
||||
0, 42816, 0, 42818, 0, 42820, 0, 42822, 0, 42824, 0, 42826, 0, 42828, 0, 42830,
|
||||
0, 42832, 0, 42834, 0, 42836, 0, 42838, 0, 42840, 0, 42842, 0, 42844, 0, 42846,
|
||||
0, 42848, 0, 42850, 0, 42852, 0, 42854, 0, 42856, 0, 42858, 0, 42860, 0, 42862,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42873, 0, 42875, 0, 0, 42878,
|
||||
0, 42880, 0, 42882, 0, 42884, 0, 42886, 0, 0, 0, 0, 42891, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 16
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 65313, 65314, 65315, 65316, 65317, 65318, 65319, 65320, 65321, 65322, 65323, 65324, 65325, 65326, 65327,
|
||||
65328, 65329, 65330, 65331, 65332, 65333, 65334, 65335, 65336, 65337, 65338, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
// block 17
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 66560, 66561, 66562, 66563, 66564, 66565, 66566, 66567,
|
||||
66568, 66569, 66570, 66571, 66572, 66573, 66574, 66575, 66576, 66577, 66578, 66579, 66580, 66581, 66582, 66583,
|
||||
66584, 66585, 66586, 66587, 66588, 66589, 66590, 66591, 66592, 66593, 66594, 66595, 66596, 66597, 66598, 66599,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
inline ::boost::uint32_t uppercase_lookup(::boost::uint32_t ch)
|
||||
{
|
||||
::boost::uint32_t block_offset = uppercase_stage1[ch / 256] * 256;
|
||||
return uppercase_stage2[block_offset + ch % 256];
|
||||
}
|
||||
|
||||
}}}} // namespace boost::spirit::unicode::detail
|
||||
+249
@@ -0,0 +1,249 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2009 Daniel Nuffer
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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_BASIC_CHSET_APRIL_17_2008
|
||||
#define BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <bitset>
|
||||
#include <climits>
|
||||
#include <boost/spirit/home/support/char_set/range_run.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace support { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: basic character set implementation using range_run
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct basic_chset
|
||||
{
|
||||
basic_chset() {}
|
||||
basic_chset(basic_chset const& arg_)
|
||||
: rr(arg_.rr) {}
|
||||
|
||||
bool
|
||||
test(Char v) const
|
||||
{
|
||||
return rr.test(v);
|
||||
}
|
||||
|
||||
void
|
||||
set(Char from, Char to)
|
||||
{
|
||||
rr.set(range<Char>(from, to));
|
||||
}
|
||||
|
||||
void
|
||||
set(Char c)
|
||||
{
|
||||
rr.set(range<Char>(c, c));
|
||||
}
|
||||
|
||||
void
|
||||
clear(Char from, Char to)
|
||||
{
|
||||
rr.clear(range<Char>(from, to));
|
||||
}
|
||||
|
||||
void
|
||||
clear(Char c)
|
||||
{
|
||||
rr.clear(range<Char>(c, c));
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
rr.clear();
|
||||
}
|
||||
|
||||
void
|
||||
inverse()
|
||||
{
|
||||
basic_chset inv;
|
||||
inv.set(
|
||||
(std::numeric_limits<Char>::min)(),
|
||||
(std::numeric_limits<Char>::max)()
|
||||
);
|
||||
inv -= *this;
|
||||
swap(inv);
|
||||
}
|
||||
|
||||
void
|
||||
swap(basic_chset& x)
|
||||
{
|
||||
rr.swap(x.rr);
|
||||
}
|
||||
|
||||
|
||||
basic_chset&
|
||||
operator|=(basic_chset const& x)
|
||||
{
|
||||
typedef typename range_run<Char>::const_iterator const_iterator;
|
||||
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
|
||||
rr.set(*iter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset&
|
||||
operator&=(basic_chset const& x)
|
||||
{
|
||||
basic_chset inv;
|
||||
inv.set(
|
||||
(std::numeric_limits<Char>::min)(),
|
||||
(std::numeric_limits<Char>::max)()
|
||||
);
|
||||
inv -= x;
|
||||
*this -= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset&
|
||||
operator-=(basic_chset const& x)
|
||||
{
|
||||
typedef typename range_run<Char>::const_iterator const_iterator;
|
||||
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
|
||||
rr.clear(*iter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset&
|
||||
operator^=(basic_chset const& x)
|
||||
{
|
||||
basic_chset bma = x;
|
||||
bma -= *this;
|
||||
*this -= x;
|
||||
*this |= bma;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private: range_run<Char> rr;
|
||||
};
|
||||
|
||||
#if (CHAR_BIT == 8)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: specializations for 8 bit chars using std::bitset
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct basic_chset_8bit
|
||||
{
|
||||
basic_chset_8bit() {}
|
||||
basic_chset_8bit(basic_chset_8bit const& arg_)
|
||||
: bset(arg_.bset) {}
|
||||
|
||||
bool
|
||||
test(Char v) const
|
||||
{
|
||||
return bset.test((unsigned char)v);
|
||||
}
|
||||
|
||||
void
|
||||
set(Char from, Char to)
|
||||
{
|
||||
for (int i = from; i <= to; ++i)
|
||||
bset.set((unsigned char)i);
|
||||
}
|
||||
|
||||
void
|
||||
set(Char c)
|
||||
{
|
||||
bset.set((unsigned char)c);
|
||||
}
|
||||
|
||||
void
|
||||
clear(Char from, Char to)
|
||||
{
|
||||
for (int i = from; i <= to; ++i)
|
||||
bset.reset((unsigned char)i);
|
||||
}
|
||||
|
||||
void
|
||||
clear(Char c)
|
||||
{
|
||||
bset.reset((unsigned char)c);
|
||||
}
|
||||
|
||||
void
|
||||
clear()
|
||||
{
|
||||
bset.reset();
|
||||
}
|
||||
|
||||
void
|
||||
inverse()
|
||||
{
|
||||
bset.flip();
|
||||
}
|
||||
|
||||
void
|
||||
swap(basic_chset_8bit& x)
|
||||
{
|
||||
std::swap(bset, x.bset);
|
||||
}
|
||||
|
||||
basic_chset_8bit&
|
||||
operator|=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset |= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset_8bit&
|
||||
operator&=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset &= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset_8bit&
|
||||
operator-=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset &= ~x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_chset_8bit&
|
||||
operator^=(basic_chset_8bit const& x)
|
||||
{
|
||||
bset ^= x.bset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private: std::bitset<256> bset;
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
struct basic_chset<char>
|
||||
: basic_chset_8bit<char> {};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
struct basic_chset<signed char>
|
||||
: basic_chset_8bit<signed char> {};
|
||||
|
||||
/////////////////////////////////
|
||||
template <>
|
||||
struct basic_chset<unsigned char>
|
||||
: basic_chset_8bit<unsigned char> {};
|
||||
|
||||
#endif // #if (CHAR_BIT == 8)
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_MAY_16_2006_0720_PM)
|
||||
#define BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace support { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// A closed range (first, last)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct range
|
||||
{
|
||||
typedef T value_type;
|
||||
|
||||
range() : first(), last() {}
|
||||
range(T first_, T last_) : first(first_), last(last_) {}
|
||||
|
||||
T first;
|
||||
T last;
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_FUNCTIONS_MAY_16_2006_0720_PM)
|
||||
#define BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/integer_traits.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace support { namespace detail
|
||||
{
|
||||
template <typename Range>
|
||||
inline bool
|
||||
is_valid(Range const& range)
|
||||
{
|
||||
// test for valid ranges
|
||||
return range.first <= range.last;
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline bool
|
||||
includes(Range const& range, Range const& other)
|
||||
{
|
||||
// see if two ranges intersect
|
||||
return (range.first <= other.first) && (range.last >= other.last);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline bool
|
||||
includes(Range const& range, typename Range::value_type val)
|
||||
{
|
||||
// see if val is in range
|
||||
return (range.first <= val) && (range.last >= val);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline bool
|
||||
can_merge(Range const& range, Range const& other)
|
||||
{
|
||||
// see if a 'range' overlaps, or is adjacent to
|
||||
// another range 'other', so we can merge them
|
||||
|
||||
typedef typename Range::value_type value_type;
|
||||
typedef integer_traits<value_type> integer_traits;
|
||||
|
||||
value_type decr_first =
|
||||
range.first == integer_traits::const_min
|
||||
? range.first : range.first-1;
|
||||
|
||||
value_type incr_last =
|
||||
range.last == integer_traits::const_max
|
||||
? range.last : range.last+1;
|
||||
|
||||
return (decr_first <= other.last) && (incr_last >= other.first);
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
inline void
|
||||
merge(Range& result, Range const& other)
|
||||
{
|
||||
// merge two ranges
|
||||
if (result.first > other.first)
|
||||
result.first = other.first;
|
||||
if (result.last < other.last)
|
||||
result.last = other.last;
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
struct range_compare
|
||||
{
|
||||
// compare functor with a value or another range
|
||||
|
||||
typedef typename Range::value_type value_type;
|
||||
|
||||
bool operator()(Range const& x, const value_type y) const
|
||||
{
|
||||
return x.first < y;
|
||||
}
|
||||
|
||||
bool operator()(value_type const x, Range const& y) const
|
||||
{
|
||||
return x < y.first;
|
||||
}
|
||||
|
||||
bool operator()(Range const& x, Range const& y) const
|
||||
{
|
||||
return x.first < y.first;
|
||||
}
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,56 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_RUN_MAY_16_2006_0801_PM)
|
||||
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/char_set/range.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace spirit { namespace support { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// range_run
|
||||
//
|
||||
// An implementation of a sparse bit (boolean) set. The set uses
|
||||
// a sorted vector of disjoint ranges. This class implements the
|
||||
// bare minimum essentials from which the full range of set
|
||||
// operators can be implemented. The set is constructed from
|
||||
// ranges. Internally, adjacent or overlapping ranges are
|
||||
// coalesced.
|
||||
//
|
||||
// range_runs are very space-economical in situations where there
|
||||
// are lots of ranges and a few individual disjoint values.
|
||||
// Searching is O(log n) where n is the number of ranges.
|
||||
//
|
||||
// { Low level interface }
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
class range_run
|
||||
{
|
||||
public:
|
||||
|
||||
typedef range<Char> range_type;
|
||||
typedef std::vector<range_type> storage_type;
|
||||
|
||||
void swap(range_run& other);
|
||||
bool test(Char v) const;
|
||||
void set(range_type const& range);
|
||||
void clear(range_type const& range);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
||||
storage_type run;
|
||||
};
|
||||
}}}}
|
||||
|
||||
#include <boost/spirit/home/support/char_set/range_run_impl.hpp>
|
||||
#endif
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/*=============================================================================
|
||||
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_RANGE_RUN_MAY_16_2006_0807_PM)
|
||||
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/char_set/range_functions.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost { namespace spirit { namespace support { namespace detail
|
||||
{
|
||||
template <typename Run, typename Iterator, typename Range>
|
||||
inline bool
|
||||
try_merge(Run& run, Iterator iter, Range const& range)
|
||||
{
|
||||
// if *iter intersects with, or is adjacent to, 'range'...
|
||||
if (can_merge(*iter, range))
|
||||
{
|
||||
// merge range and *iter
|
||||
merge(*iter, range);
|
||||
|
||||
// collapse all subsequent ranges that can merge with *iter:
|
||||
Iterator i = iter+1;
|
||||
// 1. skip subsequent ranges completely included in *iter
|
||||
while (i != run.end() && i->last <= iter->last)
|
||||
++i;
|
||||
// 2. collapse next range if adjacent or overlapping with *iter
|
||||
if (i != run.end() && i->first-1 <= iter->last)
|
||||
{
|
||||
iter->last = i->last;
|
||||
++i;
|
||||
}
|
||||
|
||||
// erase all ranges that were collapsed
|
||||
run.erase(iter+1, i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline bool
|
||||
range_run<Char>::test(Char val) const
|
||||
{
|
||||
if (run.empty())
|
||||
return false;
|
||||
|
||||
// search the ranges for one that potentially includes val
|
||||
typename storage_type::const_iterator iter =
|
||||
std::upper_bound(
|
||||
run.begin(), run.end(), val,
|
||||
range_compare<range_type>()
|
||||
);
|
||||
|
||||
// return true if *(iter-1) includes val
|
||||
return iter != run.begin() && includes(*(--iter), val);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void
|
||||
range_run<Char>::swap(range_run& other)
|
||||
{
|
||||
run.swap(other.run);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void
|
||||
range_run<Char>::set(range_type const& range)
|
||||
{
|
||||
BOOST_ASSERT(is_valid(range));
|
||||
if (run.empty())
|
||||
{
|
||||
// the vector is empty, insert 'range'
|
||||
run.push_back(range);
|
||||
return;
|
||||
}
|
||||
|
||||
// search the ranges for one that potentially includes 'range'
|
||||
typename storage_type::iterator iter =
|
||||
std::upper_bound(
|
||||
run.begin(), run.end(), range,
|
||||
range_compare<range_type>()
|
||||
);
|
||||
|
||||
if (iter != run.begin())
|
||||
{
|
||||
// if *(iter-1) includes 'range', return early
|
||||
if (includes(*(iter-1), range))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if *(iter-1) can merge with 'range', merge them and return
|
||||
if (try_merge(run, iter-1, range))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if *iter can merge with with 'range', merge them
|
||||
if (iter == run.end() || !try_merge(run, iter, range))
|
||||
{
|
||||
// no overlap, insert 'range'
|
||||
run.insert(iter, range);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
void
|
||||
range_run<Char>::clear(range_type const& range)
|
||||
{
|
||||
BOOST_ASSERT(is_valid(range));
|
||||
if (!run.empty())
|
||||
{
|
||||
// search the ranges for one that potentially includes 'range'
|
||||
typename storage_type::iterator iter =
|
||||
std::upper_bound(
|
||||
run.begin(), run.end(), range,
|
||||
range_compare<range_type>()
|
||||
);
|
||||
|
||||
// 'range' starts with or after another range:
|
||||
if (iter != run.begin())
|
||||
{
|
||||
typename storage_type::iterator const left_iter = iter-1;
|
||||
|
||||
// 'range' starts after '*left_iter':
|
||||
if (left_iter->first < range.first)
|
||||
{
|
||||
// if 'range' is completely included inside '*left_iter':
|
||||
// need to break it apart into two ranges (punch a hole),
|
||||
if (left_iter->last > range.last)
|
||||
{
|
||||
Char save_last = left_iter->last;
|
||||
left_iter->last = range.first-1;
|
||||
run.insert(iter, range_type(range.last+1, save_last));
|
||||
return;
|
||||
}
|
||||
// if 'range' contains 'left_iter->last':
|
||||
// truncate '*left_iter' (clip its right)
|
||||
else if (left_iter->last >= range.first)
|
||||
{
|
||||
left_iter->last = range.first-1;
|
||||
}
|
||||
}
|
||||
|
||||
// 'range' has the same left bound as '*left_iter': it
|
||||
// must be removed or truncated by the code below
|
||||
else
|
||||
{
|
||||
iter = left_iter;
|
||||
}
|
||||
}
|
||||
|
||||
// remove or truncate subsequent ranges that overlap with 'range':
|
||||
typename storage_type::iterator i = iter;
|
||||
// 1. skip subsequent ranges completely included in 'range'
|
||||
while (i != run.end() && i->last <= range.last)
|
||||
++i;
|
||||
// 2. clip left of next range if overlapping with 'range'
|
||||
if (i != run.end() && i->first <= range.last)
|
||||
i->first = range.last+1;
|
||||
|
||||
// erase all ranges that 'range' contained
|
||||
run.erase(iter, i);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline void
|
||||
range_run<Char>::clear()
|
||||
{
|
||||
run.clear();
|
||||
}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,437 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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_COMMON_PLACEHOLDERS_OCTOBER_16_2008_0102PM
|
||||
#define BOOST_SPIRIT_COMMON_PLACEHOLDERS_OCTOBER_16_2008_0102PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/terminal.hpp>
|
||||
#include <boost/spirit/home/support/char_encoding/standard.hpp>
|
||||
#include <boost/spirit/home/support/char_encoding/standard_wide.hpp>
|
||||
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
|
||||
#include <boost/spirit/home/support/char_encoding/iso8859_1.hpp>
|
||||
#include <boost/spirit/home/support/char_class.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
#if defined(BOOST_SPIRIT_UNICODE)
|
||||
# include <boost/spirit/home/support/char_encoding/unicode.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
typedef mpl::vector<
|
||||
spirit::char_encoding::ascii
|
||||
, spirit::char_encoding::iso8859_1
|
||||
, spirit::char_encoding::standard
|
||||
, spirit::char_encoding::standard_wide
|
||||
#if defined(BOOST_SPIRIT_UNICODE)
|
||||
, spirit::char_encoding::unicode
|
||||
#endif
|
||||
>
|
||||
char_encodings;
|
||||
|
||||
template <typename T>
|
||||
struct is_char_encoding : mpl::false_ {};
|
||||
|
||||
template <>
|
||||
struct is_char_encoding<spirit::char_encoding::ascii> : mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct is_char_encoding<spirit::char_encoding::iso8859_1> : mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct is_char_encoding<spirit::char_encoding::standard> : mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct is_char_encoding<spirit::char_encoding::standard_wide> : mpl::true_ {};
|
||||
|
||||
#if defined(BOOST_SPIRIT_UNICODE)
|
||||
template <>
|
||||
struct is_char_encoding<spirit::char_encoding::unicode> : mpl::true_ {};
|
||||
#endif
|
||||
|
||||
template <typename Encoding>
|
||||
struct encoding
|
||||
: proto::terminal<tag::char_code<tag::encoding, Encoding> >::type
|
||||
{};
|
||||
|
||||
// Our basic terminals
|
||||
BOOST_SPIRIT_DEFINE_TERMINALS_NAME(
|
||||
( verbatim, verbatim_type )
|
||||
( no_delimit, no_delimit_type )
|
||||
( lexeme, lexeme_type )
|
||||
( no_skip, no_skip_type )
|
||||
( omit, omit_type )
|
||||
( raw, raw_type )
|
||||
( as_string, as_string_type )
|
||||
( as_wstring, as_wstring_type )
|
||||
( inf, inf_type )
|
||||
( eol, eol_type )
|
||||
( eoi, eoi_type )
|
||||
( buffer, buffer_type )
|
||||
( true_, true_type )
|
||||
( false_, false_type )
|
||||
( matches, matches_type )
|
||||
( hold, hold_type )
|
||||
( strict, strict_type )
|
||||
( relaxed, relaxed_type )
|
||||
( duplicate, duplicate_type )
|
||||
)
|
||||
|
||||
// Our extended terminals
|
||||
BOOST_SPIRIT_DEFINE_TERMINALS_NAME_EX(
|
||||
( lit, lit_type )
|
||||
( bin, bin_type )
|
||||
( oct, oct_type )
|
||||
( hex, hex_type )
|
||||
( bool_, bool_type )
|
||||
( ushort_, ushort_type )
|
||||
( ulong_, ulong_type )
|
||||
( uint_, uint_type )
|
||||
( short_, short_type )
|
||||
( long_, long_type )
|
||||
( int_, int_type )
|
||||
( ulong_long, ulong_long_type )
|
||||
( long_long, long_long_type )
|
||||
( float_, float_type )
|
||||
( double_, double_type )
|
||||
( long_double, long_double_type )
|
||||
( repeat, repeat_type )
|
||||
( eps, eps_type )
|
||||
( pad, pad_type )
|
||||
( byte_, byte_type )
|
||||
( word, word_type )
|
||||
( big_word, big_word_type )
|
||||
( little_word, little_word_type )
|
||||
( dword, dword_type )
|
||||
( big_dword, big_dword_type )
|
||||
( little_dword, little_dword_type )
|
||||
( qword, qword_type )
|
||||
( big_qword, big_qword_type )
|
||||
( little_qword, little_qword_type )
|
||||
( bin_float, bin_float_type )
|
||||
( big_bin_float, big_bin_float_type )
|
||||
( little_bin_float, little_bin_float_type )
|
||||
( bin_double, bin_double_type )
|
||||
( big_bin_double, big_bin_double_type )
|
||||
( little_bin_double, little_bin_double_type )
|
||||
( skip, skip_type )
|
||||
( delimit, delimit_type )
|
||||
( stream, stream_type )
|
||||
( wstream, wstream_type )
|
||||
( left_align, left_align_type )
|
||||
( right_align, right_align_type )
|
||||
( center, center_type )
|
||||
( maxwidth, maxwidth_type )
|
||||
( set_state, set_state_type )
|
||||
( in_state, in_state_type )
|
||||
( token, token_type )
|
||||
( tokenid, tokenid_type )
|
||||
( raw_token, raw_token_type )
|
||||
( tokenid_mask, tokenid_mask_type )
|
||||
( attr, attr_type )
|
||||
( columns, columns_type )
|
||||
( auto_, auto_type )
|
||||
)
|
||||
|
||||
// special tags (used mainly for stateful tag types)
|
||||
namespace tag
|
||||
{
|
||||
struct attr_cast { BOOST_SPIRIT_IS_TAG() };
|
||||
struct as { BOOST_SPIRIT_IS_TAG() };
|
||||
}
|
||||
}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Here we place the character-set sensitive placeholders. We have one set
|
||||
// each for ascii, iso8859_1, standard and standard_wide and unicode. These
|
||||
// placeholders are placed in its char-set namespace. For example, there exist
|
||||
// a placeholder spirit::ascii::alnum for ascii versions of alnum.
|
||||
|
||||
#define BOOST_SPIRIT_TAG_CHAR_SPEC(charset) \
|
||||
typedef tag::char_code<tag::char_, charset> char_; \
|
||||
typedef tag::char_code<tag::string, charset> string; \
|
||||
/***/
|
||||
|
||||
#ifdef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
|
||||
#define BOOST_SPIRIT_CHAR_SPEC(charset) \
|
||||
typedef spirit::terminal<tag::charset::char_> char_type; \
|
||||
typedef spirit::terminal<tag::charset::string> string_type; \
|
||||
/***/
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_SPIRIT_CHAR_SPEC(charset) \
|
||||
typedef spirit::terminal<tag::charset::char_> char_type; \
|
||||
char_type const char_ = char_type(); \
|
||||
\
|
||||
inline void silence_unused_warnings_##char_() { (void) char_; } \
|
||||
\
|
||||
typedef spirit::terminal<tag::charset::string> string_type; \
|
||||
string_type const string = string_type(); \
|
||||
\
|
||||
inline void silence_unused_warnings_##string() { (void) string; } \
|
||||
/***/
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
|
||||
#define BOOST_SPIRIT_CHAR_CODE(name, charset) \
|
||||
typedef proto::terminal<tag::char_code<tag::name, charset> >::type \
|
||||
name##_type; \
|
||||
/***/
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_SPIRIT_CHAR_CODE(name, charset) \
|
||||
typedef proto::terminal<tag::char_code<tag::name, charset> >::type \
|
||||
name##_type; \
|
||||
name##_type const name = name##_type(); \
|
||||
\
|
||||
inline void silence_unused_warnings_##name() { (void) name; } \
|
||||
/***/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#define BOOST_SPIRIT_DEFINE_CHAR_CODES(charset) \
|
||||
namespace boost { namespace spirit { namespace tag { namespace charset \
|
||||
{ \
|
||||
BOOST_SPIRIT_TAG_CHAR_SPEC(spirit::char_encoding::charset) \
|
||||
}}}} \
|
||||
namespace boost { namespace spirit { namespace charset \
|
||||
{ \
|
||||
BOOST_SPIRIT_CHAR_SPEC(charset) \
|
||||
\
|
||||
BOOST_SPIRIT_CHAR_CODE(alnum, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(alpha, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(blank, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(cntrl, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(digit, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(graph, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(print, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(punct, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(space, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(xdigit, spirit::char_encoding::charset) \
|
||||
\
|
||||
BOOST_SPIRIT_CHAR_CODE(no_case, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(lower, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(upper, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(lowernum, spirit::char_encoding::charset) \
|
||||
BOOST_SPIRIT_CHAR_CODE(uppernum, spirit::char_encoding::charset) \
|
||||
}}} \
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_DEFINE_CHAR_CODES(ascii)
|
||||
BOOST_SPIRIT_DEFINE_CHAR_CODES(iso8859_1)
|
||||
BOOST_SPIRIT_DEFINE_CHAR_CODES(standard)
|
||||
BOOST_SPIRIT_DEFINE_CHAR_CODES(standard_wide)
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <typename Char>
|
||||
struct char_encoding_from_char;
|
||||
|
||||
template <>
|
||||
struct char_encoding_from_char<char>
|
||||
: mpl::identity<spirit::char_encoding::standard>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct char_encoding_from_char<wchar_t>
|
||||
: mpl::identity<spirit::char_encoding::standard_wide>
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct char_encoding_from_char<T const>
|
||||
: char_encoding_from_char<T>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#if defined(BOOST_SPIRIT_UNICODE)
|
||||
BOOST_SPIRIT_DEFINE_CHAR_CODES(unicode)
|
||||
|
||||
namespace boost { namespace spirit { namespace tag { namespace unicode
|
||||
{
|
||||
BOOST_SPIRIT_TAG_CHAR_SPEC(spirit::char_encoding::unicode)
|
||||
}}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace unicode
|
||||
{
|
||||
#define BOOST_SPIRIT_UNICODE_CHAR_CODE(name) \
|
||||
BOOST_SPIRIT_CHAR_CODE(name, spirit::char_encoding::unicode) \
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Major Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(letter)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(mark)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(number)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(separator)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(other)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(symbol)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode General Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(uppercase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(lowercase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(titlecase_letter)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(modifier_letter)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(other_letter)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(nonspacing_mark)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(enclosing_mark)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(spacing_mark)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(decimal_number)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(letter_number)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(other_number)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(space_separator)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(line_separator)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(paragraph_separator)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(control)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(format)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(private_use)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(surrogate)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(unassigned)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(dash_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(open_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(close_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(connector_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(other_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(initial_punctuation)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(final_punctuation)
|
||||
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(math_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(currency_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(modifier_symbol)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(other_symbol)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Derived Categories
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(alphabetic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(uppercase)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(lowercase)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(white_space)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(hex_digit)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(noncharacter_code_point)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(default_ignorable_code_point)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Unicode Scripts
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(arabic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(imperial_aramaic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(armenian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(avestan)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(balinese)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(bamum)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(bengali)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(bopomofo)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(braille)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(buginese)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(buhid)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(canadian_aboriginal)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(carian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(cham)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(cherokee)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(coptic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(cypriot)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(cyrillic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(devanagari)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(deseret)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(egyptian_hieroglyphs)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(ethiopic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(georgian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(glagolitic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(gothic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(greek)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(gujarati)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(gurmukhi)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(hangul)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(han)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(hanunoo)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(hebrew)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(hiragana)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(katakana_or_hiragana)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(old_italic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(javanese)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(kayah_li)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(katakana)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(kharoshthi)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(khmer)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(kannada)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(kaithi)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(tai_tham)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(lao)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(latin)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(lepcha)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(limbu)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(linear_b)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(lisu)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(lycian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(lydian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(malayalam)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(mongolian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(meetei_mayek)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(myanmar)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(nko)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(ogham)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(ol_chiki)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(old_turkic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(oriya)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(osmanya)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(phags_pa)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(inscriptional_pahlavi)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(phoenician)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(inscriptional_parthian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(rejang)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(runic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(samaritan)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(old_south_arabian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(saurashtra)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(shavian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(sinhala)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(sundanese)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(syloti_nagri)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(syriac)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(tagbanwa)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(tai_le)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(new_tai_lue)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(tamil)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(tai_viet)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(telugu)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(tifinagh)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(tagalog)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(thaana)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(thai)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(tibetan)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(ugaritic)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(vai)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(old_persian)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(cuneiform)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(yi)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(inherited)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(common)
|
||||
BOOST_SPIRIT_UNICODE_CHAR_CODE(unknown)
|
||||
|
||||
#undef BOOST_SPIRIT_UNICODE_CHAR_CODE
|
||||
}}}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,589 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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_CONTAINER_FEBRUARY_06_2007_1001AM)
|
||||
#define BOOST_SPIRIT_CONTAINER_FEBRUARY_06_2007_1001AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/attributes_fwd.hpp>
|
||||
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This file contains some container utils for stl containers. The
|
||||
// utilities provided also accept spirit's unused_type; all no-ops.
|
||||
// Compiler optimization will easily strip these away.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace detail
|
||||
{
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(size_type)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
|
||||
}
|
||||
|
||||
template <typename T, typename Enable/* = void*/>
|
||||
struct is_container
|
||||
: mpl::bool_<
|
||||
detail::has_value_type<T>::value &&
|
||||
detail::has_iterator<T>::value &&
|
||||
detail::has_size_type<T>::value &&
|
||||
detail::has_reference<T>::value>
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct is_container<T&>
|
||||
: is_container<T>
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct is_container<boost::optional<T> >
|
||||
: is_container<T>
|
||||
{};
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
template<typename T>
|
||||
struct is_container<boost::variant<T> >
|
||||
: is_container<T>
|
||||
{};
|
||||
|
||||
template<typename T0, typename T1, typename ...TN>
|
||||
struct is_container<boost::variant<T0, T1, TN...> >
|
||||
: mpl::bool_<is_container<T0>::value ||
|
||||
is_container<boost::variant<T1, TN...> >::value>
|
||||
{};
|
||||
|
||||
#else
|
||||
#define BOOST_SPIRIT_IS_CONTAINER(z, N, data) \
|
||||
is_container<BOOST_PP_CAT(T, N)>::value || \
|
||||
/***/
|
||||
|
||||
// make sure unused variant parameters do not affect the outcome
|
||||
template <>
|
||||
struct is_container<boost::detail::variant::void_>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct is_container<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
: mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
|
||||
, BOOST_SPIRIT_IS_CONTAINER, _) false>
|
||||
{};
|
||||
|
||||
#undef BOOST_SPIRIT_IS_CONTAINER
|
||||
#endif
|
||||
|
||||
template <typename T, typename Enable/* = void*/>
|
||||
struct is_iterator_range
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct is_iterator_range<iterator_range<T> >
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
struct remove_value_const
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct remove_value_const<T const>
|
||||
: remove_value_const<T>
|
||||
{};
|
||||
|
||||
template <typename F, typename S>
|
||||
struct remove_value_const<std::pair<F, S> >
|
||||
{
|
||||
typedef typename remove_value_const<F>::type first_type;
|
||||
typedef typename remove_value_const<S>::type second_type;
|
||||
typedef std::pair<first_type, second_type> type;
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//[customization_container_value_default
|
||||
template <typename Container, typename Enable/* = void*/>
|
||||
struct container_value
|
||||
: detail::remove_value_const<typename Container::value_type>
|
||||
{};
|
||||
//]
|
||||
|
||||
template <typename T>
|
||||
struct container_value<T&>
|
||||
: container_value<T>
|
||||
{};
|
||||
|
||||
// this will be instantiated if the optional holds a container
|
||||
template <typename T>
|
||||
struct container_value<boost::optional<T> >
|
||||
: container_value<T>
|
||||
{};
|
||||
|
||||
// this will be instantiated if the variant holds a container
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct container_value<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
typedef typename
|
||||
variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
|
||||
types;
|
||||
typedef typename
|
||||
mpl::find_if<types, is_container<mpl::_1> >::type
|
||||
iter;
|
||||
|
||||
typedef typename container_value<
|
||||
typename mpl::if_<
|
||||
is_same<iter, typename mpl::end<types>::type>
|
||||
, unused_type, typename mpl::deref<iter>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
//[customization_container_value_unused
|
||||
template <>
|
||||
struct container_value<unused_type>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
//]
|
||||
|
||||
template <>
|
||||
struct container_value<unused_type const>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename Enable/* = void*/>
|
||||
struct container_iterator
|
||||
{
|
||||
typedef typename Container::iterator type;
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
struct container_iterator<Container&>
|
||||
: container_iterator<Container>
|
||||
{};
|
||||
|
||||
template <typename Container>
|
||||
struct container_iterator<Container const>
|
||||
{
|
||||
typedef typename Container::const_iterator type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct container_iterator<optional<T> >
|
||||
: container_iterator<T>
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct container_iterator<optional<T> const>
|
||||
: container_iterator<T const>
|
||||
{};
|
||||
|
||||
template <typename Iterator>
|
||||
struct container_iterator<iterator_range<Iterator> >
|
||||
{
|
||||
typedef typename range_const_iterator<
|
||||
iterator_range<Iterator> >::type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct container_iterator<unused_type>
|
||||
{
|
||||
typedef unused_type const* type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct container_iterator<unused_type const>
|
||||
{
|
||||
typedef unused_type const* type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Enable/* = void*/>
|
||||
struct optional_attribute
|
||||
{
|
||||
typedef T const& type;
|
||||
|
||||
static type call(T const& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
static bool is_valid(T const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct optional_attribute<boost::optional<T> >
|
||||
{
|
||||
typedef T const& type;
|
||||
|
||||
static type call(boost::optional<T> const& val)
|
||||
{
|
||||
return boost::get<T>(val);
|
||||
}
|
||||
|
||||
static bool is_valid(boost::optional<T> const& val)
|
||||
{
|
||||
return !!val;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
typename optional_attribute<T>::type
|
||||
optional_value(T const& val)
|
||||
{
|
||||
return optional_attribute<T>::call(val);
|
||||
}
|
||||
|
||||
inline unused_type optional_value(unused_type)
|
||||
{
|
||||
return unused;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool has_optional_value(T const& val)
|
||||
{
|
||||
return optional_attribute<T>::is_valid(val);
|
||||
}
|
||||
|
||||
inline bool has_optional_value(unused_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename T>
|
||||
bool push_back(Container& c, T const& val);
|
||||
|
||||
//[customization_push_back_default
|
||||
template <typename Container, typename T, typename Enable/* = void*/>
|
||||
struct push_back_container
|
||||
{
|
||||
static bool call(Container& c, T const& val)
|
||||
{
|
||||
c.insert(c.end(), val);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
//]
|
||||
|
||||
template <typename Container, typename T>
|
||||
struct push_back_container<optional<Container>, T>
|
||||
{
|
||||
static bool call(boost::optional<Container>& c, T const& val)
|
||||
{
|
||||
if (!c)
|
||||
c = Container();
|
||||
return push_back(boost::get<Container>(c), val);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
struct push_back_visitor : public static_visitor<>
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
push_back_visitor(T const& t) : t_(t) {}
|
||||
|
||||
template <typename Container>
|
||||
bool push_back_impl(Container& c, mpl::true_) const
|
||||
{
|
||||
return push_back(c, t_);
|
||||
}
|
||||
|
||||
template <typename T_>
|
||||
bool push_back_impl(T_&, mpl::false_) const
|
||||
{
|
||||
// this variant doesn't hold a container
|
||||
BOOST_ASSERT(false && "This variant doesn't hold a container");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T_>
|
||||
bool operator()(T_& c) const
|
||||
{
|
||||
return push_back_impl(c, typename is_container<T_>::type());
|
||||
}
|
||||
|
||||
T const& t_;
|
||||
};
|
||||
}
|
||||
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T_), typename T>
|
||||
struct push_back_container<variant<BOOST_VARIANT_ENUM_PARAMS(T_)>, T>
|
||||
{
|
||||
static bool call(variant<BOOST_VARIANT_ENUM_PARAMS(T_)>& c, T const& val)
|
||||
{
|
||||
return apply_visitor(detail::push_back_visitor<T>(val), c);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Container, typename T>
|
||||
bool push_back(Container& c, T const& val)
|
||||
{
|
||||
return push_back_container<Container, T>::call(c, val);
|
||||
}
|
||||
|
||||
//[customization_push_back_unused
|
||||
template <typename Container>
|
||||
bool push_back(Container&, unused_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
//]
|
||||
|
||||
template <typename T>
|
||||
bool push_back(unused_type, T const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool push_back(unused_type, unused_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename Enable/* = void*/>
|
||||
struct is_empty_container
|
||||
{
|
||||
static bool call(Container const& c)
|
||||
{
|
||||
return c.empty();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
bool is_empty(Container const& c)
|
||||
{
|
||||
return is_empty_container<Container>::call(c);
|
||||
}
|
||||
|
||||
inline bool is_empty(unused_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Ensure the attribute is actually a container type
|
||||
template <typename Container, typename Enable/* = void*/>
|
||||
struct make_container_attribute
|
||||
{
|
||||
static void call(Container&)
|
||||
{
|
||||
// for static types this function does nothing
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void make_container(T& t)
|
||||
{
|
||||
make_container_attribute<T>::call(t);
|
||||
}
|
||||
|
||||
inline void make_container(unused_type)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename Enable/* = void*/>
|
||||
struct begin_container
|
||||
{
|
||||
static typename container_iterator<Container>::type call(Container& c)
|
||||
{
|
||||
return c.begin();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
typename spirit::result_of::begin<Container>::type
|
||||
begin(Container& c)
|
||||
{
|
||||
return begin_container<Container>::call(c);
|
||||
}
|
||||
|
||||
inline unused_type const*
|
||||
begin(unused_type)
|
||||
{
|
||||
return &unused;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename Enable/* = void*/>
|
||||
struct end_container
|
||||
{
|
||||
static typename container_iterator<Container>::type call(Container& c)
|
||||
{
|
||||
return c.end();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
inline typename spirit::result_of::end<Container>::type
|
||||
end(Container& c)
|
||||
{
|
||||
return end_container<Container>::call(c);
|
||||
}
|
||||
|
||||
inline unused_type const*
|
||||
end(unused_type)
|
||||
{
|
||||
return &unused;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Enable/* = void*/>
|
||||
struct deref_iterator
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference type;
|
||||
static type call(Iterator& it)
|
||||
{
|
||||
return *it;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
typename deref_iterator<Iterator>::type
|
||||
deref(Iterator& it)
|
||||
{
|
||||
return deref_iterator<Iterator>::call(it);
|
||||
}
|
||||
|
||||
inline unused_type
|
||||
deref(unused_type const*)
|
||||
{
|
||||
return unused;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Enable/* = void*/>
|
||||
struct next_iterator
|
||||
{
|
||||
static void call(Iterator& it)
|
||||
{
|
||||
++it;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
void next(Iterator& it)
|
||||
{
|
||||
next_iterator<Iterator>::call(it);
|
||||
}
|
||||
|
||||
inline void next(unused_type const*)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Enable/* = void*/>
|
||||
struct compare_iterators
|
||||
{
|
||||
static bool call(Iterator const& it1, Iterator const& it2)
|
||||
{
|
||||
return it1 == it2;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
bool compare(Iterator& it1, Iterator& it2)
|
||||
{
|
||||
return compare_iterators<Iterator>::call(it1, it2);
|
||||
}
|
||||
|
||||
inline bool compare(unused_type const*, unused_type const*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace result_of
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct optional_value
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct optional_value<boost::optional<T> >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct optional_value<boost::optional<T> const>
|
||||
{
|
||||
typedef T const type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct optional_value<unused_type>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct optional_value<unused_type const>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Container>
|
||||
struct begin
|
||||
: traits::container_iterator<Container>
|
||||
{};
|
||||
|
||||
template <typename Container>
|
||||
struct end
|
||||
: traits::container_iterator<Container>
|
||||
{};
|
||||
|
||||
template <typename Iterator>
|
||||
struct deref
|
||||
: traits::deref_iterator<Iterator>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct deref<unused_type const*>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,299 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
Copyright (c) 2011 Thomas Heller
|
||||
|
||||
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_CONTEXT_OCTOBER_31_2008_0654PM)
|
||||
#define BOOST_SPIRIT_CONTEXT_OCTOBER_31_2008_0654PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/spirit/home/support/nonterminal/expand_arg.hpp>
|
||||
#include <boost/spirit/home/support/assert_msg.hpp>
|
||||
#include <boost/spirit/home/support/argument.hpp>
|
||||
#include <boost/spirit/home/support/limits.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/fusion/include/size.hpp>
|
||||
#include <boost/fusion/include/as_list.hpp>
|
||||
#include <boost/fusion/include/transform.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/at.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
|
||||
#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \
|
||||
typedef phoenix::actor<attribute<n> > \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
|
||||
phoenix::actor<attribute<n> > const \
|
||||
BOOST_PP_CAT(_r, n) = BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type)();
|
||||
/***/
|
||||
#define SPIRIT_USING_ATTRIBUTE(z, n, data) \
|
||||
using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
|
||||
using spirit::BOOST_PP_CAT(_r, n); \
|
||||
/***/
|
||||
|
||||
#else
|
||||
|
||||
#define SPIRIT_DECLARE_ATTRIBUTE(z, n, data) \
|
||||
typedef phoenix::actor<attribute<n> > \
|
||||
BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
|
||||
/***/
|
||||
#define SPIRIT_USING_ATTRIBUTE(z, n, data) \
|
||||
using spirit::BOOST_PP_CAT(BOOST_PP_CAT(_r, n), _type); \
|
||||
/***/
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
template <int>
|
||||
struct attribute;
|
||||
|
||||
template <int>
|
||||
struct local_variable;
|
||||
}}
|
||||
|
||||
BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
|
||||
template <int N>
|
||||
, boost::spirit::attribute<N>
|
||||
, mpl::false_ // is not nullary
|
||||
, v2_eval(
|
||||
proto::make<
|
||||
boost::spirit::attribute<N>()
|
||||
>
|
||||
, proto::call<
|
||||
functional::env(proto::_state)
|
||||
>
|
||||
)
|
||||
)
|
||||
|
||||
BOOST_PHOENIX_DEFINE_CUSTOM_TERMINAL(
|
||||
template <int N>
|
||||
, boost::spirit::local_variable<N>
|
||||
, mpl::false_ // is not nullary
|
||||
, v2_eval(
|
||||
proto::make<
|
||||
boost::spirit::local_variable<N>()
|
||||
>
|
||||
, proto::call<
|
||||
functional::env(proto::_state)
|
||||
>
|
||||
)
|
||||
)
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
template <typename Attributes, typename Locals>
|
||||
struct context
|
||||
{
|
||||
typedef Attributes attributes_type;
|
||||
typedef Locals locals_type;
|
||||
|
||||
context(typename Attributes::car_type attribute)
|
||||
: attributes(attribute, fusion::nil_()), locals() {}
|
||||
|
||||
template <typename Args, typename Context>
|
||||
context(
|
||||
typename Attributes::car_type attribute
|
||||
, Args const& args
|
||||
, Context& caller_context
|
||||
) : attributes(
|
||||
attribute
|
||||
, fusion::as_list(
|
||||
fusion::transform(
|
||||
args
|
||||
, detail::expand_arg<Context>(caller_context)
|
||||
)
|
||||
)
|
||||
)
|
||||
, locals() {}
|
||||
|
||||
context(Attributes const& attributes_)
|
||||
: attributes(attributes_), locals() {}
|
||||
|
||||
Attributes attributes; // The attributes
|
||||
Locals locals; // Local variables
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct attributes_of
|
||||
{
|
||||
typedef typename Context::attributes_type type;
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct attributes_of<Context const>
|
||||
{
|
||||
typedef typename Context::attributes_type const type;
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct attributes_of<Context &>
|
||||
: attributes_of<Context>
|
||||
{};
|
||||
|
||||
template <typename Context>
|
||||
struct locals_of
|
||||
{
|
||||
typedef typename Context::locals_type type;
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct locals_of<Context const>
|
||||
{
|
||||
typedef typename Context::locals_type const type;
|
||||
};
|
||||
|
||||
template <typename Context>
|
||||
struct locals_of<Context &>
|
||||
{
|
||||
typedef typename Context::locals_type type;
|
||||
};
|
||||
|
||||
template <int N>
|
||||
struct attribute
|
||||
{
|
||||
typedef mpl::true_ no_nullary;
|
||||
|
||||
template <typename Env>
|
||||
struct result
|
||||
{
|
||||
typedef typename
|
||||
attributes_of<typename
|
||||
mpl::at_c<typename Env::args_type, 1>::type
|
||||
>::type
|
||||
attributes_type;
|
||||
|
||||
typedef typename
|
||||
fusion::result_of::size<attributes_type>::type
|
||||
attributes_size;
|
||||
|
||||
// report invalid argument not found (N is out of bounds)
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
(N < attributes_size::value),
|
||||
index_is_out_of_bounds, ());
|
||||
|
||||
typedef typename
|
||||
fusion::result_of::at_c<attributes_type, N>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Env>
|
||||
typename result<Env>::type
|
||||
eval(Env const& env) const
|
||||
{
|
||||
return fusion::at_c<N>((fusion::at_c<1>(env.args())).attributes);
|
||||
}
|
||||
};
|
||||
|
||||
template <int N>
|
||||
struct local_variable
|
||||
{
|
||||
typedef mpl::true_ no_nullary;
|
||||
|
||||
template <typename Env>
|
||||
struct result
|
||||
{
|
||||
typedef typename
|
||||
locals_of<typename
|
||||
mpl::at_c<typename Env::args_type, 1>::type
|
||||
>::type
|
||||
locals_type;
|
||||
|
||||
typedef typename
|
||||
fusion::result_of::size<locals_type>::type
|
||||
locals_size;
|
||||
|
||||
// report invalid argument not found (N is out of bounds)
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
(N < locals_size::value),
|
||||
index_is_out_of_bounds, ());
|
||||
|
||||
typedef typename
|
||||
fusion::result_of::at_c<locals_type, N>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Env>
|
||||
typename result<Env>::type
|
||||
eval(Env const& env) const
|
||||
{
|
||||
return get_arg<N>((fusion::at_c<1>(env.args())).locals);
|
||||
}
|
||||
};
|
||||
|
||||
typedef phoenix::actor<attribute<0> > _val_type;
|
||||
typedef phoenix::actor<attribute<0> > _r0_type;
|
||||
typedef phoenix::actor<attribute<1> > _r1_type;
|
||||
typedef phoenix::actor<attribute<2> > _r2_type;
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
// _val refers to the 'return' value of a rule (same as _r0)
|
||||
// _r1, _r2, ... refer to the rule arguments
|
||||
_val_type const _val = _val_type();
|
||||
_r0_type const _r0 = _r0_type();
|
||||
_r1_type const _r1 = _r1_type();
|
||||
_r2_type const _r2 = _r2_type();
|
||||
#endif
|
||||
|
||||
// Bring in the rest of the attributes (_r4 .. _rN+1), using PP
|
||||
BOOST_PP_REPEAT_FROM_TO(
|
||||
3, SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_DECLARE_ATTRIBUTE, _)
|
||||
|
||||
typedef phoenix::actor<local_variable<0> > _a_type;
|
||||
typedef phoenix::actor<local_variable<1> > _b_type;
|
||||
typedef phoenix::actor<local_variable<2> > _c_type;
|
||||
typedef phoenix::actor<local_variable<3> > _d_type;
|
||||
typedef phoenix::actor<local_variable<4> > _e_type;
|
||||
typedef phoenix::actor<local_variable<5> > _f_type;
|
||||
typedef phoenix::actor<local_variable<6> > _g_type;
|
||||
typedef phoenix::actor<local_variable<7> > _h_type;
|
||||
typedef phoenix::actor<local_variable<8> > _i_type;
|
||||
typedef phoenix::actor<local_variable<9> > _j_type;
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
// _a, _b, ... refer to the local variables of a rule
|
||||
_a_type const _a = _a_type();
|
||||
_b_type const _b = _b_type();
|
||||
_c_type const _c = _c_type();
|
||||
_d_type const _d = _d_type();
|
||||
_e_type const _e = _e_type();
|
||||
_f_type const _f = _f_type();
|
||||
_g_type const _g = _g_type();
|
||||
_h_type const _h = _h_type();
|
||||
_i_type const _i = _i_type();
|
||||
_j_type const _j = _j_type();
|
||||
#endif
|
||||
|
||||
// You can bring these in with the using directive
|
||||
// without worrying about bringing in too much.
|
||||
namespace labels
|
||||
{
|
||||
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
|
||||
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::_val;
|
||||
using spirit::_a;
|
||||
using spirit::_b;
|
||||
using spirit::_c;
|
||||
using spirit::_d;
|
||||
using spirit::_e;
|
||||
using spirit::_f;
|
||||
using spirit::_g;
|
||||
using spirit::_h;
|
||||
using spirit::_i;
|
||||
using spirit::_j;
|
||||
#endif
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,114 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
#if !defined(BOOST_SPIRIT_AS_VARIANT_NOVEMBER_16_2007_0420PM)
|
||||
#define BOOST_SPIRIT_AS_VARIANT_NOVEMBER_16_2007_0420PM
|
||||
|
||||
#include <boost/preprocessor/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
#include <boost/fusion/include/size.hpp>
|
||||
#include <boost/fusion/include/begin.hpp>
|
||||
#include <boost/fusion/include/next.hpp>
|
||||
#include <boost/fusion/include/value_of.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/mpl/limits/list.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
template <int size>
|
||||
struct as_variant_impl;
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
#else
|
||||
template <>
|
||||
struct as_variant_impl<0>
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct apply
|
||||
{
|
||||
typedef variant<> type;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
#define BOOST_FUSION_NEXT_ITERATOR(z, n, data) \
|
||||
typedef typename fusion::result_of::next<BOOST_PP_CAT(I, n)>::type \
|
||||
BOOST_PP_CAT(I, BOOST_PP_INC(n));
|
||||
|
||||
#define BOOST_FUSION_NEXT_CALL_ITERATOR(z, n, data) \
|
||||
typename gen::BOOST_PP_CAT(I, BOOST_PP_INC(n)) \
|
||||
BOOST_PP_CAT(i, BOOST_PP_INC(n)) = fusion::next(BOOST_PP_CAT(i, n));
|
||||
|
||||
#define BOOST_FUSION_VALUE_OF_ITERATOR(z, n, data) \
|
||||
typedef typename fusion::result_of::value_of<BOOST_PP_CAT(I, n)>::type \
|
||||
BOOST_PP_CAT(T, n);
|
||||
|
||||
#define BOOST_PP_FILENAME_1 <boost/spirit/home/support/detail/as_variant.hpp>
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
#define BOOST_PP_ITERATION_LIMITS (1, BOOST_MPL_LIMIT_LIST_SIZE)
|
||||
#else
|
||||
#define BOOST_PP_ITERATION_LIMITS (1, BOOST_VARIANT_LIMIT_TYPES)
|
||||
#endif
|
||||
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_FUSION_NEXT_ITERATOR
|
||||
#undef BOOST_FUSION_NEXT_CALL_ITERATOR
|
||||
#undef BOOST_FUSION_VALUE_OF_ITERATOR
|
||||
|
||||
template <typename Sequence>
|
||||
struct as_variant
|
||||
{
|
||||
// build a variant generator being able to generate a variant holding
|
||||
// all of the types as given in the typelist
|
||||
typedef typename
|
||||
detail::as_variant_impl<fusion::result_of::size<Sequence>::value>
|
||||
gen;
|
||||
|
||||
// use this generator to create the actual variant
|
||||
typedef typename gen::template apply<
|
||||
typename fusion::result_of::begin<Sequence>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
#else // defined(BOOST_PP_IS_ITERATING)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Preprocessor vertical repetition code
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template <>
|
||||
struct as_variant_impl<N>
|
||||
{
|
||||
template <typename I0>
|
||||
struct apply
|
||||
{
|
||||
BOOST_PP_REPEAT(N, BOOST_FUSION_NEXT_ITERATOR, _)
|
||||
BOOST_PP_REPEAT(N, BOOST_FUSION_VALUE_OF_ITERATOR, _)
|
||||
typedef variant<BOOST_PP_ENUM_PARAMS(N, T)> type;
|
||||
};
|
||||
};
|
||||
|
||||
#undef N
|
||||
#endif // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
// http://spirit.sourceforge.net/
|
||||
//
|
||||
// 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_ENDIAN_MAR_21_2009_0349PM)
|
||||
#define SPIRIT_ENDIAN_MAR_21_2009_0349PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// We need to treat the endian number types as PODs
|
||||
#if !defined(BOOST_ENDIAN_FORCE_PODNESS)
|
||||
#define BOOST_ENDIAN_FORCE_PODNESS 1
|
||||
#endif
|
||||
|
||||
// If Boost has the endian library, use it, otherwise use an adapted version
|
||||
// included with Spirit
|
||||
// #if BOOST_VERSION >= 105100
|
||||
// #include <boost/endian/integers.hpp>
|
||||
// #else
|
||||
#include <boost/spirit/home/support/detail/endian/endian.hpp>
|
||||
// #endif
|
||||
|
||||
#endif
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
// boost/integer/cover_operators.hpp ----------------------------------------//
|
||||
|
||||
// Copyright Darin Adler 2000
|
||||
// Copyright Beman Dawes 2008
|
||||
|
||||
// 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 the class being covered has a non-explicit conversion to an integer type
|
||||
// then a smaller number of cover operations are needed. Define the macro
|
||||
// BOOST_MINIMAL_INTEGER_COVER_OPERATORS to indicate this.
|
||||
|
||||
// Define BOOST_NO_IO_COVER_OPERATORS if I/O cover operations are not desired.
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_SPIRIT_INTEGER_COVER_OPERATORS_HPP
|
||||
#define BOOST_SPIRIT_INTEGER_COVER_OPERATORS_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
|
||||
# include <boost/operators.hpp>
|
||||
# endif
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
|
||||
// A class that adds integer operators to an integer cover class
|
||||
|
||||
template <typename T, typename IntegerType>
|
||||
class cover_operators
|
||||
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
|
||||
: boost::operators<T>
|
||||
# endif
|
||||
{
|
||||
// The other operations take advantage of the type conversion that's
|
||||
// built into unary +.
|
||||
|
||||
// Unary operations.
|
||||
friend IntegerType operator+(const T& x) { return x; }
|
||||
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
|
||||
friend IntegerType operator-(const T& x) { return -+x; }
|
||||
friend IntegerType operator~(const T& x) { return ~+x; }
|
||||
friend IntegerType operator!(const T& x) { return !+x; }
|
||||
|
||||
// The basic ordering operations.
|
||||
friend bool operator==(const T& x, IntegerType y) { return +x == y; }
|
||||
friend bool operator<(const T& x, IntegerType y) { return +x < y; }
|
||||
# endif
|
||||
|
||||
// The basic arithmetic operations.
|
||||
friend T& operator+=(T& x, IntegerType y) { return x = +x + y; }
|
||||
friend T& operator-=(T& x, IntegerType y) { return x = +x - y; }
|
||||
friend T& operator*=(T& x, IntegerType y) { return x = +x * y; }
|
||||
friend T& operator/=(T& x, IntegerType y) { return x = +x / y; }
|
||||
friend T& operator%=(T& x, IntegerType y) { return x = +x % y; }
|
||||
friend T& operator&=(T& x, IntegerType y) { return x = +x & y; }
|
||||
friend T& operator|=(T& x, IntegerType y) { return x = +x | y; }
|
||||
friend T& operator^=(T& x, IntegerType y) { return x = +x ^ y; }
|
||||
friend T& operator<<=(T& x, IntegerType y) { return x = +x << y; }
|
||||
friend T& operator>>=(T& x, IntegerType y) { return x = +x >> y; }
|
||||
|
||||
// A few binary arithmetic operations not covered by operators base class.
|
||||
friend IntegerType operator<<(const T& x, IntegerType y) { return +x << y; }
|
||||
friend IntegerType operator>>(const T& x, IntegerType y) { return +x >> y; }
|
||||
|
||||
// Auto-increment and auto-decrement can be defined in terms of the
|
||||
// arithmetic operations.
|
||||
friend T& operator++(T& x) { return x += 1; }
|
||||
friend T& operator--(T& x) { return x -= 1; }
|
||||
|
||||
# ifdef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
|
||||
friend T operator++(T& x, int)
|
||||
{
|
||||
T tmp(x);
|
||||
x += 1;
|
||||
return tmp;
|
||||
}
|
||||
friend T operator--(T& x, int)
|
||||
{
|
||||
T tmp(x);
|
||||
x -= 1;
|
||||
return tmp;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef BOOST_NO_IO_COVER_OPERATORS
|
||||
// TODO: stream I/O needs to be templatized on the stream type, so will
|
||||
// work with wide streams, etc.
|
||||
|
||||
// Stream input and output.
|
||||
friend std::ostream& operator<<(std::ostream& s, const T& x)
|
||||
{ return s << +x; }
|
||||
friend std::istream& operator>>(std::istream& s, T& x)
|
||||
{
|
||||
IntegerType i;
|
||||
if (s >> i)
|
||||
x = i;
|
||||
return s;
|
||||
}
|
||||
# endif
|
||||
};
|
||||
} // namespace endian
|
||||
}} // namespace boost::spirit
|
||||
|
||||
#endif // BOOST_SPIRIT_INTEGER_COVER_OPERATORS_HPP
|
||||
+569
@@ -0,0 +1,569 @@
|
||||
// Boost endian.hpp header file -------------------------------------------------------//
|
||||
|
||||
// (C) Copyright Darin Adler 2000
|
||||
// (C) Copyright Beman Dawes 2006, 2009
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// See library home page at http://www.boost.org/libs/endian
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
// Original design developed by Darin Adler based on classes developed by Mark
|
||||
// Borgerding. Four original class templates were combined into a single endian
|
||||
// class template by Beman Dawes, who also added the unrolled_byte_loops sign
|
||||
// partial specialization to correctly extend the sign when cover integer size
|
||||
// differs from endian representation size.
|
||||
|
||||
// TODO: When a compiler supporting constexpr becomes available, try possible uses.
|
||||
|
||||
#ifndef BOOST_SPIRIT_ENDIAN_HPP
|
||||
#define BOOST_SPIRIT_ENDIAN_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_ENDIAN_LOG
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
# pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
#define BOOST_MINIMAL_INTEGER_COVER_OPERATORS
|
||||
#define BOOST_NO_IO_COVER_OPERATORS
|
||||
#include <boost/spirit/home/support/detail/endian/cover_operators.hpp>
|
||||
#undef BOOST_NO_IO_COVER_OPERATORS
|
||||
#undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
|
||||
#include <iosfwd>
|
||||
#include <climits>
|
||||
|
||||
# if CHAR_BIT != 8
|
||||
# error Platforms with CHAR_BIT != 8 are not supported
|
||||
# endif
|
||||
|
||||
# define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03
|
||||
|
||||
# if defined(BOOST_ENDIAN_FORCE_PODNESS)
|
||||
# define BOOST_ENDIAN_NO_CTORS
|
||||
# endif
|
||||
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// Unrolled loops for loading and storing streams of bytes.
|
||||
|
||||
template <typename T, std::size_t n_bytes,
|
||||
bool sign=boost::is_signed<T>::value >
|
||||
struct unrolled_byte_loops
|
||||
{
|
||||
typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
|
||||
|
||||
static typename boost::make_unsigned<T>::type load_big(const unsigned char* bytes)
|
||||
{ return *(bytes - 1) | (next::load_big(bytes - 1) << 8); }
|
||||
static typename boost::make_unsigned<T>::type load_little(const unsigned char* bytes)
|
||||
{ return *bytes | (next::load_little(bytes + 1) << 8); }
|
||||
|
||||
static void store_big(char* bytes, T value)
|
||||
{
|
||||
*(bytes - 1) = static_cast<char>(value);
|
||||
next::store_big(bytes - 1, value >> 8);
|
||||
}
|
||||
static void store_little(char* bytes, T value)
|
||||
{
|
||||
*bytes = static_cast<char>(value);
|
||||
next::store_little(bytes + 1, value >> 8);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unrolled_byte_loops<T, 1, false>
|
||||
{
|
||||
static T load_big(const unsigned char* bytes)
|
||||
{ return *(bytes - 1); }
|
||||
static T load_little(const unsigned char* bytes)
|
||||
{ return *bytes; }
|
||||
static void store_big(char* bytes, T value)
|
||||
{ *(bytes - 1) = static_cast<char>(value); }
|
||||
static void store_little(char* bytes, T value)
|
||||
{ *bytes = static_cast<char>(value); }
|
||||
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unrolled_byte_loops<T, 1, true>
|
||||
{
|
||||
static typename boost::make_unsigned<T>::type load_big(const unsigned char* bytes)
|
||||
{ return *(bytes - 1); }
|
||||
static typename boost::make_unsigned<T>::type load_little(const unsigned char* bytes)
|
||||
{ return *bytes; }
|
||||
static void store_big(char* bytes, T value)
|
||||
{ *(bytes - 1) = static_cast<char>(value); }
|
||||
static void store_little(char* bytes, T value)
|
||||
{ *bytes = static_cast<char>(value); }
|
||||
};
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
T load_big_endian(const void* bytes)
|
||||
{
|
||||
return static_cast<T>(unrolled_byte_loops<T, n_bytes>::load_big
|
||||
(static_cast<const unsigned char*>(bytes) + n_bytes));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline
|
||||
float load_big_endian<float, 4>(const void* bytes)
|
||||
{
|
||||
const unsigned char *b = reinterpret_cast<const unsigned char *>(
|
||||
bytes);
|
||||
b += 3;
|
||||
|
||||
float value;
|
||||
unsigned char *v = reinterpret_cast<unsigned char *>(&value);
|
||||
|
||||
for(std::size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
*v++ = *b--;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline
|
||||
double load_big_endian<double, 8>(const void* bytes)
|
||||
{
|
||||
const unsigned char *b = reinterpret_cast<const unsigned char *>(
|
||||
bytes);
|
||||
b += 7;
|
||||
|
||||
double value;
|
||||
unsigned char *v = reinterpret_cast<unsigned char *>(&value);
|
||||
|
||||
for(std::size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
*v++ = *b--;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
T load_little_endian(const void* bytes)
|
||||
{
|
||||
return static_cast<T>(unrolled_byte_loops<T, n_bytes>::load_little
|
||||
(static_cast<const unsigned char*>(bytes)));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline
|
||||
float load_little_endian<float, 4>(const void* bytes)
|
||||
{
|
||||
const unsigned char *b = reinterpret_cast<const unsigned char *>(
|
||||
bytes);
|
||||
|
||||
float value;
|
||||
unsigned char *v = reinterpret_cast<unsigned char *>(&value);
|
||||
|
||||
for(std::size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
*v++ = *b++;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline
|
||||
double load_little_endian<double, 8>(const void* bytes)
|
||||
{
|
||||
const unsigned char *b = reinterpret_cast<const unsigned char *>(
|
||||
bytes);
|
||||
|
||||
double value;
|
||||
unsigned char *v = reinterpret_cast<unsigned char *>(&value);
|
||||
|
||||
for(std::size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
*v++ = *b++;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
void store_big_endian(void* bytes, T value)
|
||||
{
|
||||
unrolled_byte_loops<T, n_bytes>::store_big
|
||||
(static_cast<char*>(bytes) + n_bytes, value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline
|
||||
void store_big_endian<float, 4>(void* bytes, float value)
|
||||
{
|
||||
unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
|
||||
b += 3;
|
||||
|
||||
const unsigned char *v = reinterpret_cast<const unsigned char *>(
|
||||
&value);
|
||||
|
||||
for(std::size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
*b-- = *v++;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline
|
||||
void store_big_endian<double, 8>(void* bytes, double value)
|
||||
{
|
||||
unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
|
||||
b += 7;
|
||||
|
||||
const unsigned char *v = reinterpret_cast<const unsigned char *>(
|
||||
&value);
|
||||
|
||||
for(std::size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
*b-- = *v++;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, std::size_t n_bytes>
|
||||
inline
|
||||
void store_little_endian(void* bytes, T value)
|
||||
{
|
||||
unrolled_byte_loops<T, n_bytes>::store_little
|
||||
(static_cast<char*>(bytes), value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline
|
||||
void store_little_endian<float, 4>(void* bytes, float value)
|
||||
{
|
||||
unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
|
||||
|
||||
const unsigned char *v = reinterpret_cast<const unsigned char *>(
|
||||
&value);
|
||||
|
||||
for(std::size_t i = 0; i < 4; ++i)
|
||||
{
|
||||
*b++ = *v++;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline
|
||||
void store_little_endian<double, 8>(void* bytes, double value)
|
||||
{
|
||||
unsigned char *b = reinterpret_cast<unsigned char *>(bytes);
|
||||
|
||||
const unsigned char *v = reinterpret_cast<const unsigned char *>(
|
||||
&value);
|
||||
|
||||
for(std::size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
*b++ = *v++;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace endian
|
||||
{
|
||||
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
bool endian_log(true);
|
||||
# endif
|
||||
|
||||
|
||||
// endian class template and specializations ---------------------------------------//
|
||||
|
||||
BOOST_SCOPED_ENUM_START(endianness) { big, little, native }; BOOST_SCOPED_ENUM_END
|
||||
BOOST_SCOPED_ENUM_START(alignment) { unaligned, aligned }; BOOST_SCOPED_ENUM_END
|
||||
|
||||
template <BOOST_SCOPED_ENUM(endianness) E, typename T, std::size_t n_bits,
|
||||
BOOST_SCOPED_ENUM(alignment) A = alignment::unaligned>
|
||||
class endian;
|
||||
|
||||
// Specializations that represent unaligned bytes.
|
||||
// Taking an integer type as a parameter provides a nice way to pass both
|
||||
// the size and signedness of the desired integer and get the appropriate
|
||||
// corresponding integer type for the interface.
|
||||
|
||||
// unaligned big endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian< endianness::big, T, n_bits, alignment::unaligned >
|
||||
: cover_operators< endian< endianness::big, T, n_bits >, T >
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian(T val)
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::clog << "big, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
detail::store_big_endian<T, n_bits/8>(m_value, val);
|
||||
}
|
||||
# endif
|
||||
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::clog << "big, unaligned, " << n_bits << "-bits, convert(" << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n";
|
||||
# endif
|
||||
return detail::load_big_endian<T, n_bits/8>(m_value);
|
||||
}
|
||||
private:
|
||||
char m_value[n_bits/8];
|
||||
};
|
||||
|
||||
// unaligned little endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian< endianness::little, T, n_bits, alignment::unaligned >
|
||||
: cover_operators< endian< endianness::little, T, n_bits >, T >
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
explicit endian(T val)
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::clog << "little, unaligned, " << n_bits << "-bits, construct(" << val << ")\n";
|
||||
# endif
|
||||
detail::store_little_endian<T, n_bits/8>(m_value, val);
|
||||
}
|
||||
# endif
|
||||
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const
|
||||
{
|
||||
# ifdef BOOST_ENDIAN_LOG
|
||||
if ( endian_log )
|
||||
std::clog << "little, unaligned, " << n_bits << "-bits, convert(" << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n";
|
||||
# endif
|
||||
return detail::load_little_endian<T, n_bits/8>(m_value);
|
||||
}
|
||||
private:
|
||||
char m_value[n_bits/8];
|
||||
};
|
||||
|
||||
// unaligned native endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian< endianness::native, T, n_bits, alignment::unaligned >
|
||||
: cover_operators< endian< endianness::native, T, n_bits >, T >
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
explicit endian(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); }
|
||||
# else
|
||||
explicit endian(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); }
|
||||
# endif
|
||||
# endif
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const { return detail::load_big_endian<T, n_bits/8>(m_value); }
|
||||
# else
|
||||
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
|
||||
operator T() const { return detail::load_little_endian<T, n_bits/8>(m_value); }
|
||||
# endif
|
||||
private:
|
||||
char m_value[n_bits/8];
|
||||
};
|
||||
|
||||
// Specializations that mimic built-in integer types.
|
||||
// These typically have the same alignment as the underlying types.
|
||||
|
||||
// aligned big endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian< endianness::big, T, n_bits, alignment::aligned >
|
||||
: cover_operators< endian< endianness::big, T, n_bits, alignment::aligned >, T >
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
endian(T val) : m_value(val) { }
|
||||
# else
|
||||
explicit endian(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); }
|
||||
# endif
|
||||
# endif
|
||||
# ifdef BOOST_BIG_ENDIAN
|
||||
endian & operator=(T val) { m_value = val; return *this; }
|
||||
operator T() const { return m_value; }
|
||||
# else
|
||||
endian & operator=(T val) { detail::store_big_endian<T, sizeof(T)>(&m_value, val); return *this; }
|
||||
operator T() const { return detail::load_big_endian<T, sizeof(T)>(&m_value); }
|
||||
# endif
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
|
||||
// aligned little endian specialization
|
||||
template <typename T, std::size_t n_bits>
|
||||
class endian< endianness::little, T, n_bits, alignment::aligned >
|
||||
: cover_operators< endian< endianness::little, T, n_bits, alignment::aligned >, T >
|
||||
{
|
||||
BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
|
||||
BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
|
||||
public:
|
||||
typedef T value_type;
|
||||
# ifndef BOOST_ENDIAN_NO_CTORS
|
||||
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
endian(T val) : m_value(val) { }
|
||||
# else
|
||||
explicit endian(T val) { detail::store_little_endian<T, sizeof(T)>(&m_value, val); }
|
||||
# endif
|
||||
# endif
|
||||
# ifdef BOOST_LITTLE_ENDIAN
|
||||
endian & operator=(T val) { m_value = val; return *this; }
|
||||
operator T() const { return m_value; }
|
||||
#else
|
||||
endian & operator=(T val) { detail::store_little_endian<T, sizeof(T)>(&m_value, val); return *this; }
|
||||
operator T() const { return detail::load_little_endian<T, sizeof(T)>(&m_value); }
|
||||
#endif
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
|
||||
// naming convention typedefs ------------------------------------------------------//
|
||||
|
||||
// unaligned big endian signed integer types
|
||||
typedef endian< endianness::big, int_least8_t, 8 > big8_t;
|
||||
typedef endian< endianness::big, int_least16_t, 16 > big16_t;
|
||||
typedef endian< endianness::big, int_least32_t, 24 > big24_t;
|
||||
typedef endian< endianness::big, int_least32_t, 32 > big32_t;
|
||||
typedef endian< endianness::big, int_least64_t, 40 > big40_t;
|
||||
typedef endian< endianness::big, int_least64_t, 48 > big48_t;
|
||||
typedef endian< endianness::big, int_least64_t, 56 > big56_t;
|
||||
typedef endian< endianness::big, int_least64_t, 64 > big64_t;
|
||||
|
||||
// unaligned big endian unsigned integer types
|
||||
typedef endian< endianness::big, uint_least8_t, 8 > ubig8_t;
|
||||
typedef endian< endianness::big, uint_least16_t, 16 > ubig16_t;
|
||||
typedef endian< endianness::big, uint_least32_t, 24 > ubig24_t;
|
||||
typedef endian< endianness::big, uint_least32_t, 32 > ubig32_t;
|
||||
typedef endian< endianness::big, uint_least64_t, 40 > ubig40_t;
|
||||
typedef endian< endianness::big, uint_least64_t, 48 > ubig48_t;
|
||||
typedef endian< endianness::big, uint_least64_t, 56 > ubig56_t;
|
||||
typedef endian< endianness::big, uint_least64_t, 64 > ubig64_t;
|
||||
|
||||
// unaligned little endian signed integer types
|
||||
typedef endian< endianness::little, int_least8_t, 8 > little8_t;
|
||||
typedef endian< endianness::little, int_least16_t, 16 > little16_t;
|
||||
typedef endian< endianness::little, int_least32_t, 24 > little24_t;
|
||||
typedef endian< endianness::little, int_least32_t, 32 > little32_t;
|
||||
typedef endian< endianness::little, int_least64_t, 40 > little40_t;
|
||||
typedef endian< endianness::little, int_least64_t, 48 > little48_t;
|
||||
typedef endian< endianness::little, int_least64_t, 56 > little56_t;
|
||||
typedef endian< endianness::little, int_least64_t, 64 > little64_t;
|
||||
|
||||
// unaligned little endian unsigned integer types
|
||||
typedef endian< endianness::little, uint_least8_t, 8 > ulittle8_t;
|
||||
typedef endian< endianness::little, uint_least16_t, 16 > ulittle16_t;
|
||||
typedef endian< endianness::little, uint_least32_t, 24 > ulittle24_t;
|
||||
typedef endian< endianness::little, uint_least32_t, 32 > ulittle32_t;
|
||||
typedef endian< endianness::little, uint_least64_t, 40 > ulittle40_t;
|
||||
typedef endian< endianness::little, uint_least64_t, 48 > ulittle48_t;
|
||||
typedef endian< endianness::little, uint_least64_t, 56 > ulittle56_t;
|
||||
typedef endian< endianness::little, uint_least64_t, 64 > ulittle64_t;
|
||||
|
||||
// unaligned native endian signed integer types
|
||||
typedef endian< endianness::native, int_least8_t, 8 > native8_t;
|
||||
typedef endian< endianness::native, int_least16_t, 16 > native16_t;
|
||||
typedef endian< endianness::native, int_least32_t, 24 > native24_t;
|
||||
typedef endian< endianness::native, int_least32_t, 32 > native32_t;
|
||||
typedef endian< endianness::native, int_least64_t, 40 > native40_t;
|
||||
typedef endian< endianness::native, int_least64_t, 48 > native48_t;
|
||||
typedef endian< endianness::native, int_least64_t, 56 > native56_t;
|
||||
typedef endian< endianness::native, int_least64_t, 64 > native64_t;
|
||||
|
||||
// unaligned native endian unsigned integer types
|
||||
typedef endian< endianness::native, uint_least8_t, 8 > unative8_t;
|
||||
typedef endian< endianness::native, uint_least16_t, 16 > unative16_t;
|
||||
typedef endian< endianness::native, uint_least32_t, 24 > unative24_t;
|
||||
typedef endian< endianness::native, uint_least32_t, 32 > unative32_t;
|
||||
typedef endian< endianness::native, uint_least64_t, 40 > unative40_t;
|
||||
typedef endian< endianness::native, uint_least64_t, 48 > unative48_t;
|
||||
typedef endian< endianness::native, uint_least64_t, 56 > unative56_t;
|
||||
typedef endian< endianness::native, uint_least64_t, 64 > unative64_t;
|
||||
|
||||
#define BOOST_HAS_INT16_T
|
||||
#define BOOST_HAS_INT32_T
|
||||
#define BOOST_HAS_INT64_T
|
||||
|
||||
// These types only present if platform has exact size integers:
|
||||
// aligned big endian signed integer types
|
||||
// aligned big endian unsigned integer types
|
||||
// aligned little endian signed integer types
|
||||
// aligned little endian unsigned integer types
|
||||
|
||||
// aligned native endian typedefs are not provided because
|
||||
// <cstdint> types are superior for this use case
|
||||
|
||||
# if defined(BOOST_HAS_INT16_T)
|
||||
typedef endian< endianness::big, int16_t, 16, alignment::aligned > aligned_big16_t;
|
||||
typedef endian< endianness::big, uint16_t, 16, alignment::aligned > aligned_ubig16_t;
|
||||
typedef endian< endianness::little, int16_t, 16, alignment::aligned > aligned_little16_t;
|
||||
typedef endian< endianness::little, uint16_t, 16, alignment::aligned > aligned_ulittle16_t;
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_HAS_INT32_T)
|
||||
typedef endian< endianness::big, int32_t, 32, alignment::aligned > aligned_big32_t;
|
||||
typedef endian< endianness::big, uint32_t, 32, alignment::aligned > aligned_ubig32_t;
|
||||
typedef endian< endianness::little, int32_t, 32, alignment::aligned > aligned_little32_t;
|
||||
typedef endian< endianness::little, uint32_t, 32, alignment::aligned > aligned_ulittle32_t;
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_HAS_INT64_T)
|
||||
typedef endian< endianness::big, int64_t, 64, alignment::aligned > aligned_big64_t;
|
||||
typedef endian< endianness::big, uint64_t, 64, alignment::aligned > aligned_ubig64_t;
|
||||
typedef endian< endianness::little, int64_t, 64, alignment::aligned > aligned_little64_t;
|
||||
typedef endian< endianness::little, uint64_t, 64, alignment::aligned > aligned_ulittle64_t;
|
||||
# endif
|
||||
|
||||
} // namespace endian
|
||||
}} // namespace boost::spirit
|
||||
|
||||
// import the namespace above into boost::endian
|
||||
namespace boost { namespace endian
|
||||
{
|
||||
using namespace boost::spirit::endian;
|
||||
}}
|
||||
|
||||
#if defined(__BORLANDC__) || defined( __CODEGEARC__)
|
||||
# pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_SPIRIT_ENDIAN_HPP
|
||||
@@ -0,0 +1,75 @@
|
||||
// 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(BOOST_SPIRIT_GET_ENCODING_JANUARY_13_2009_1255PM)
|
||||
#define BOOST_SPIRIT_GET_ENCODING_JANUARY_13_2009_1255PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
template <typename Modifiers, typename Encoding>
|
||||
struct get_implicit_encoding
|
||||
{
|
||||
// Extract the implicit encoding from the Modifiers
|
||||
// If one is not found, Encoding is used. The explicit
|
||||
// encoding is the first viable encoding that can be
|
||||
// extracted from the Modifiers (there can be more than one).
|
||||
|
||||
typedef typename
|
||||
mpl::find_if<
|
||||
char_encodings,
|
||||
has_modifier<Modifiers, tag::char_encoding_base<mpl::_1> >
|
||||
>::type
|
||||
iter;
|
||||
|
||||
typedef typename
|
||||
mpl::eval_if<
|
||||
is_same<iter, typename mpl::end<char_encodings>::type>,
|
||||
mpl::identity<Encoding>,
|
||||
mpl::deref<iter>
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Modifiers, typename Encoding>
|
||||
struct get_encoding
|
||||
{
|
||||
// Extract the explicit encoding from the Modifiers
|
||||
// If one is not found, get implicit encoding (see above).
|
||||
// Explicit encoding is the encoding explicitly declared
|
||||
// using the encoding[c] directive.
|
||||
|
||||
typedef typename
|
||||
mpl::find_if<
|
||||
char_encodings,
|
||||
has_modifier<Modifiers, tag::char_code<tag::encoding, mpl::_1> >
|
||||
>::type
|
||||
iter;
|
||||
|
||||
typedef typename
|
||||
mpl::eval_if<
|
||||
is_same<iter, typename mpl::end<char_encodings>::type>,
|
||||
get_implicit_encoding<Modifiers, Encoding>,
|
||||
mpl::deref<iter>
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Modifiers, typename Encoding, bool case_modifier = false>
|
||||
struct get_encoding_with_case : mpl::identity<Encoding> {};
|
||||
|
||||
template <typename Modifiers, typename Encoding>
|
||||
struct get_encoding_with_case<Modifiers, Encoding, true>
|
||||
: get_encoding<Modifiers, Encoding> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,457 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2007-2011 Hartmut Kaiser
|
||||
Copyright (c) Christopher Diggins 2005
|
||||
Copyright (c) Pablo Aguilar 2005
|
||||
Copyright (c) Kevlin Henney 2001
|
||||
|
||||
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)
|
||||
|
||||
The class boost::spirit::hold_any is built based on the any class
|
||||
published here: http://www.codeproject.com/cpp/dynamic_typing.asp. It adds
|
||||
support for std streaming operator<<() and operator>>().
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_HOLD_ANY_MAY_02_2007_0857AM)
|
||||
#define BOOST_SPIRIT_HOLD_ANY_MAY_02_2007_0857AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/detail/sp_typeinfo.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
#include <algorithm>
|
||||
#include <iosfwd>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4100) // 'x': unreferenced formal parameter
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
struct bad_any_cast
|
||||
: std::bad_cast
|
||||
{
|
||||
bad_any_cast(boost::detail::sp_typeinfo const& src, boost::detail::sp_typeinfo const& dest)
|
||||
: from(src.name()), to(dest.name())
|
||||
{}
|
||||
|
||||
virtual const char* what() const throw() { return "bad any cast"; }
|
||||
|
||||
const char* from;
|
||||
const char* to;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// function pointer table
|
||||
template <typename Char>
|
||||
struct fxn_ptr_table
|
||||
{
|
||||
boost::detail::sp_typeinfo const& (*get_type)();
|
||||
void (*static_delete)(void**);
|
||||
void (*destruct)(void**);
|
||||
void (*clone)(void* const*, void**);
|
||||
void (*move)(void* const*, void**);
|
||||
std::basic_istream<Char>& (*stream_in)(std::basic_istream<Char>&, void**);
|
||||
std::basic_ostream<Char>& (*stream_out)(std::basic_ostream<Char>&, void* const*);
|
||||
};
|
||||
|
||||
// static functions for small value-types
|
||||
template <typename Small>
|
||||
struct fxns;
|
||||
|
||||
template <>
|
||||
struct fxns<mpl::true_>
|
||||
{
|
||||
template<typename T, typename Char>
|
||||
struct type
|
||||
{
|
||||
static boost::detail::sp_typeinfo const& get_type()
|
||||
{
|
||||
return BOOST_SP_TYPEID(T);
|
||||
}
|
||||
static void static_delete(void** x)
|
||||
{
|
||||
reinterpret_cast<T*>(x)->~T();
|
||||
}
|
||||
static void destruct(void** x)
|
||||
{
|
||||
reinterpret_cast<T*>(x)->~T();
|
||||
}
|
||||
static void clone(void* const* src, void** dest)
|
||||
{
|
||||
new (dest) T(*reinterpret_cast<T const*>(src));
|
||||
}
|
||||
static void move(void* const* src, void** dest)
|
||||
{
|
||||
*reinterpret_cast<T*>(dest) =
|
||||
*reinterpret_cast<T const*>(src);
|
||||
}
|
||||
static std::basic_istream<Char>&
|
||||
stream_in (std::basic_istream<Char>& i, void** obj)
|
||||
{
|
||||
i >> *reinterpret_cast<T*>(obj);
|
||||
return i;
|
||||
}
|
||||
static std::basic_ostream<Char>&
|
||||
stream_out(std::basic_ostream<Char>& o, void* const* obj)
|
||||
{
|
||||
o << *reinterpret_cast<T const*>(obj);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// static functions for big value-types (bigger than a void*)
|
||||
template <>
|
||||
struct fxns<mpl::false_>
|
||||
{
|
||||
template<typename T, typename Char>
|
||||
struct type
|
||||
{
|
||||
static boost::detail::sp_typeinfo const& get_type()
|
||||
{
|
||||
return BOOST_SP_TYPEID(T);
|
||||
}
|
||||
static void static_delete(void** x)
|
||||
{
|
||||
// destruct and free memory
|
||||
delete (*reinterpret_cast<T**>(x));
|
||||
}
|
||||
static void destruct(void** x)
|
||||
{
|
||||
// destruct only, we'll reuse memory
|
||||
(*reinterpret_cast<T**>(x))->~T();
|
||||
}
|
||||
static void clone(void* const* src, void** dest)
|
||||
{
|
||||
*dest = new T(**reinterpret_cast<T* const*>(src));
|
||||
}
|
||||
static void move(void* const* src, void** dest)
|
||||
{
|
||||
**reinterpret_cast<T**>(dest) =
|
||||
**reinterpret_cast<T* const*>(src);
|
||||
}
|
||||
static std::basic_istream<Char>&
|
||||
stream_in(std::basic_istream<Char>& i, void** obj)
|
||||
{
|
||||
i >> **reinterpret_cast<T**>(obj);
|
||||
return i;
|
||||
}
|
||||
static std::basic_ostream<Char>&
|
||||
stream_out(std::basic_ostream<Char>& o, void* const* obj)
|
||||
{
|
||||
o << **reinterpret_cast<T* const*>(obj);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct get_table
|
||||
{
|
||||
typedef mpl::bool_<(sizeof(T) <= sizeof(void*))> is_small;
|
||||
|
||||
template <typename Char>
|
||||
static fxn_ptr_table<Char>* get()
|
||||
{
|
||||
static fxn_ptr_table<Char> static_table =
|
||||
{
|
||||
fxns<is_small>::template type<T, Char>::get_type,
|
||||
fxns<is_small>::template type<T, Char>::static_delete,
|
||||
fxns<is_small>::template type<T, Char>::destruct,
|
||||
fxns<is_small>::template type<T, Char>::clone,
|
||||
fxns<is_small>::template type<T, Char>::move,
|
||||
fxns<is_small>::template type<T, Char>::stream_in,
|
||||
fxns<is_small>::template type<T, Char>::stream_out
|
||||
};
|
||||
return &static_table;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
struct empty {};
|
||||
|
||||
template <typename Char>
|
||||
inline std::basic_istream<Char>&
|
||||
operator>> (std::basic_istream<Char>& i, empty&)
|
||||
{
|
||||
// If this assertion fires you tried to insert from a std istream
|
||||
// into an empty hold_any instance. This simply can't work, because
|
||||
// there is no way to figure out what type to extract from the
|
||||
// stream.
|
||||
// The only way to make this work is to assign an arbitrary
|
||||
// value of the required type to the hold_any instance you want to
|
||||
// stream to. This assignment has to be executed before the actual
|
||||
// call to the operator>>().
|
||||
BOOST_ASSERT(false &&
|
||||
"Tried to insert from a std istream into an empty "
|
||||
"hold_any instance");
|
||||
return i;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline std::basic_ostream<Char>&
|
||||
operator<< (std::basic_ostream<Char>& o, empty const&)
|
||||
{
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
class basic_hold_any
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
template <typename T>
|
||||
explicit basic_hold_any(T const& x)
|
||||
: table(spirit::detail::get_table<T>::template get<Char>()), object(0)
|
||||
{
|
||||
if (spirit::detail::get_table<T>::is_small::value)
|
||||
new (&object) T(x);
|
||||
else
|
||||
object = new T(x);
|
||||
}
|
||||
|
||||
basic_hold_any()
|
||||
: table(spirit::detail::get_table<spirit::detail::empty>::template get<Char>()),
|
||||
object(0)
|
||||
{
|
||||
}
|
||||
|
||||
basic_hold_any(basic_hold_any const& x)
|
||||
: table(spirit::detail::get_table<spirit::detail::empty>::template get<Char>()),
|
||||
object(0)
|
||||
{
|
||||
assign(x);
|
||||
}
|
||||
|
||||
~basic_hold_any()
|
||||
{
|
||||
table->static_delete(&object);
|
||||
}
|
||||
|
||||
// assignment
|
||||
basic_hold_any& assign(basic_hold_any const& x)
|
||||
{
|
||||
if (&x != this) {
|
||||
// are we copying between the same type?
|
||||
if (table == x.table) {
|
||||
// if so, we can avoid reallocation
|
||||
table->move(&x.object, &object);
|
||||
}
|
||||
else {
|
||||
reset();
|
||||
x.table->clone(&x.object, &object);
|
||||
table = x.table;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
basic_hold_any& assign(T const& x)
|
||||
{
|
||||
// are we copying between the same type?
|
||||
spirit::detail::fxn_ptr_table<Char>* x_table =
|
||||
spirit::detail::get_table<T>::template get<Char>();
|
||||
if (table == x_table) {
|
||||
// if so, we can avoid deallocating and re-use memory
|
||||
table->destruct(&object); // first destruct the old content
|
||||
if (spirit::detail::get_table<T>::is_small::value) {
|
||||
// create copy on-top of object pointer itself
|
||||
new (&object) T(x);
|
||||
}
|
||||
else {
|
||||
// create copy on-top of old version
|
||||
new (object) T(x);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (spirit::detail::get_table<T>::is_small::value) {
|
||||
// create copy on-top of object pointer itself
|
||||
table->destruct(&object); // first destruct the old content
|
||||
new (&object) T(x);
|
||||
}
|
||||
else {
|
||||
reset(); // first delete the old content
|
||||
object = new T(x);
|
||||
}
|
||||
table = x_table; // update table pointer
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// assignment operator
|
||||
#ifdef BOOST_HAS_RVALUE_REFS
|
||||
template <typename T>
|
||||
basic_hold_any& operator=(T&& x)
|
||||
{
|
||||
return assign(std::forward<T>(x));
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
basic_hold_any& operator=(T& x)
|
||||
{
|
||||
return assign(x);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
basic_hold_any& operator=(T const& x)
|
||||
{
|
||||
return assign(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
// utility functions
|
||||
basic_hold_any& swap(basic_hold_any& x)
|
||||
{
|
||||
std::swap(table, x.table);
|
||||
std::swap(object, x.object);
|
||||
return *this;
|
||||
}
|
||||
|
||||
boost::detail::sp_typeinfo const& type() const
|
||||
{
|
||||
return table->get_type();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T const& cast() const
|
||||
{
|
||||
if (type() != BOOST_SP_TYPEID(T))
|
||||
throw bad_any_cast(type(), BOOST_SP_TYPEID(T));
|
||||
|
||||
return spirit::detail::get_table<T>::is_small::value ?
|
||||
*reinterpret_cast<T const*>(&object) :
|
||||
*reinterpret_cast<T const*>(object);
|
||||
}
|
||||
|
||||
// implicit casting is disabled by default for compatibility with boost::any
|
||||
#ifdef BOOST_SPIRIT_ANY_IMPLICIT_CASTING
|
||||
// automatic casting operator
|
||||
template <typename T>
|
||||
operator T const& () const { return cast<T>(); }
|
||||
#endif // implicit casting
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return table == spirit::detail::get_table<spirit::detail::empty>::template get<Char>();
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
if (!empty())
|
||||
{
|
||||
table->static_delete(&object);
|
||||
table = spirit::detail::get_table<spirit::detail::empty>::template get<Char>();
|
||||
object = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// these functions have been added in the assumption that the embedded
|
||||
// type has a corresponding operator defined, which is completely safe
|
||||
// because spirit::hold_any is used only in contexts where these operators
|
||||
// do exist
|
||||
template <typename Char_>
|
||||
friend inline std::basic_istream<Char_>&
|
||||
operator>> (std::basic_istream<Char_>& i, basic_hold_any<Char_>& obj)
|
||||
{
|
||||
return obj.table->stream_in(i, &obj.object);
|
||||
}
|
||||
|
||||
template <typename Char_>
|
||||
friend inline std::basic_ostream<Char_>&
|
||||
operator<< (std::basic_ostream<Char_>& o, basic_hold_any<Char_> const& obj)
|
||||
{
|
||||
return obj.table->stream_out(o, &obj.object);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
private: // types
|
||||
template <typename T, typename Char_>
|
||||
friend T* any_cast(basic_hold_any<Char_> *);
|
||||
#else
|
||||
public: // types (public so any_cast can be non-friend)
|
||||
#endif
|
||||
// fields
|
||||
spirit::detail::fxn_ptr_table<Char>* table;
|
||||
void* object;
|
||||
};
|
||||
|
||||
// boost::any-like casting
|
||||
template <typename T, typename Char>
|
||||
inline T* any_cast (basic_hold_any<Char>* operand)
|
||||
{
|
||||
if (operand && operand->type() == BOOST_SP_TYPEID(T)) {
|
||||
return spirit::detail::get_table<T>::is_small::value ?
|
||||
reinterpret_cast<T*>(&operand->object) :
|
||||
reinterpret_cast<T*>(operand->object);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline T const* any_cast(basic_hold_any<Char> const* operand)
|
||||
{
|
||||
return any_cast<T>(const_cast<basic_hold_any<Char>*>(operand));
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
T any_cast(basic_hold_any<Char>& operand)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
|
||||
|
||||
|
||||
nonref* result = any_cast<nonref>(&operand);
|
||||
if(!result)
|
||||
boost::throw_exception(bad_any_cast(operand.type(), BOOST_SP_TYPEID(T)));
|
||||
return *result;
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
T const& any_cast(basic_hold_any<Char> const& operand)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;
|
||||
|
||||
|
||||
return any_cast<nonref const&>(const_cast<basic_hold_any<Char> &>(operand));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// backwards compatibility
|
||||
typedef basic_hold_any<char> hold_any;
|
||||
typedef basic_hold_any<wchar_t> whold_any;
|
||||
|
||||
namespace traits
|
||||
{
|
||||
template <typename T>
|
||||
struct is_hold_any : mpl::false_ {};
|
||||
|
||||
template <typename Char>
|
||||
struct is_hold_any<basic_hold_any<Char> > : mpl::true_ {};
|
||||
}
|
||||
|
||||
}} // namespace boost::spirit
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*=============================================================================
|
||||
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_SUPPORT_DETAIL_IS_SPIRIT_TAG_MAR_28_2011_0341PM)
|
||||
#define BOOST_SPIRIT_SUPPORT_DETAIL_IS_SPIRIT_TAG_MAR_28_2011_0341PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define BOOST_SPIRIT_IS_TAG() typedef void is_spirit_tag;
|
||||
|
||||
#endif
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// char_traits.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_CHAR_TRAITS_H
|
||||
#define BOOST_LEXER_CHAR_TRAITS_H
|
||||
|
||||
// Make sure wchar_t is defined
|
||||
#include <string>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
template<typename CharT>
|
||||
struct char_traits
|
||||
{
|
||||
typedef CharT char_type;
|
||||
typedef CharT index_type;
|
||||
|
||||
static index_type call (CharT ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct char_traits<char>
|
||||
{
|
||||
typedef char char_type;
|
||||
typedef unsigned char index_type;
|
||||
|
||||
static index_type call (char ch)
|
||||
{
|
||||
return static_cast<index_type>(ch);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct char_traits<wchar_t>
|
||||
{
|
||||
typedef wchar_t char_type;
|
||||
typedef wchar_t index_type;
|
||||
|
||||
static index_type call (wchar_t ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
// consts.h
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_CONSTS_H
|
||||
#define BOOST_LEXER_CONSTS_H
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
#include "size_t.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
enum regex_flags {none = 0, icase = 1, dot_not_newline = 2};
|
||||
// 0 = end state, 1 = id, 2 = unique_id, 3 = lex state, 4 = bol, 5 = eol,
|
||||
// 6 = dead_state_index
|
||||
enum {end_state_index, id_index, unique_id_index, state_index, bol_index,
|
||||
eol_index, dead_state_index, dfa_offset};
|
||||
|
||||
const std::size_t max_macro_len = 30;
|
||||
const std::size_t num_chars = 256;
|
||||
// If sizeof(wchar_t) == sizeof(size_t) then don't overflow to 0
|
||||
// by adding one to comparison.
|
||||
const std::size_t num_wchar_ts =
|
||||
(boost::integer_traits<wchar_t>::const_max < 0x110000) ?
|
||||
boost::integer_traits<wchar_t>::const_max +
|
||||
static_cast<std::size_t> (1) : 0x110000;
|
||||
const std::size_t null_token = static_cast<std::size_t> (~0);
|
||||
const std::size_t bol_token = static_cast<std::size_t> (~1);
|
||||
const std::size_t eol_token = static_cast<std::size_t> (~2);
|
||||
const std::size_t end_state = 1;
|
||||
const std::size_t npos = static_cast<std::size_t> (~0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
// ptr_list.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_PTR_LIST_HPP
|
||||
#define BOOST_LEXER_PTR_LIST_HPP
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Type>
|
||||
class ptr_list
|
||||
{
|
||||
public:
|
||||
typedef std::list<Type *> list;
|
||||
|
||||
ptr_list ()
|
||||
{
|
||||
}
|
||||
|
||||
~ptr_list ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
list *operator -> ()
|
||||
{
|
||||
return &_list;
|
||||
}
|
||||
|
||||
const list *operator -> () const
|
||||
{
|
||||
return &_list;
|
||||
}
|
||||
|
||||
list &operator * ()
|
||||
{
|
||||
return _list;
|
||||
}
|
||||
|
||||
const list &operator * () const
|
||||
{
|
||||
return _list;
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
while (!_list.empty ())
|
||||
{
|
||||
delete _list.front ();
|
||||
_list.pop_front ();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
list _list;
|
||||
|
||||
ptr_list (const ptr_list &); // No copy construction.
|
||||
ptr_list &operator = (const ptr_list &); // No assignment.
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
// ptr_vector.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_PTR_VECTOR_HPP
|
||||
#define BOOST_LEXER_PTR_VECTOR_HPP
|
||||
|
||||
#include "../size_t.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Type>
|
||||
class ptr_vector
|
||||
{
|
||||
public:
|
||||
typedef std::vector<Type *> vector;
|
||||
|
||||
ptr_vector ()
|
||||
{
|
||||
}
|
||||
|
||||
~ptr_vector ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
vector *operator -> ()
|
||||
{
|
||||
return &_vector;
|
||||
}
|
||||
|
||||
const vector *operator -> () const
|
||||
{
|
||||
return &_vector;
|
||||
}
|
||||
|
||||
vector &operator * ()
|
||||
{
|
||||
return _vector;
|
||||
}
|
||||
|
||||
const vector &operator * () const
|
||||
{
|
||||
return _vector;
|
||||
}
|
||||
|
||||
Type * &operator [] (const std::size_t index_)
|
||||
{
|
||||
return _vector[index_];
|
||||
}
|
||||
|
||||
Type * const &operator [] (const std::size_t index_) const
|
||||
{
|
||||
return _vector[index_];
|
||||
}
|
||||
|
||||
bool operator == (const ptr_vector &rhs_) const
|
||||
{
|
||||
bool equal_ = _vector.size () == rhs_._vector.size ();
|
||||
|
||||
if (equal_)
|
||||
{
|
||||
typename vector::const_iterator lhs_iter_ = _vector.begin ();
|
||||
typename vector::const_iterator end_ = _vector.end ();
|
||||
typename vector::const_iterator rhs_iter_ = rhs_._vector.begin ();
|
||||
|
||||
for (; equal_ && lhs_iter_ != end_; ++lhs_iter_, ++rhs_iter_)
|
||||
{
|
||||
equal_ = **lhs_iter_ == **rhs_iter_;
|
||||
}
|
||||
}
|
||||
|
||||
return equal_;
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
if (!_vector.empty ())
|
||||
{
|
||||
Type **iter_ = &_vector.front ();
|
||||
Type **end_ = iter_ + _vector.size ();
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
delete *iter_;
|
||||
}
|
||||
}
|
||||
|
||||
_vector.clear ();
|
||||
}
|
||||
|
||||
private:
|
||||
vector _vector;
|
||||
|
||||
ptr_vector (const ptr_vector &); // No copy construction.
|
||||
ptr_vector &operator = (const ptr_vector &); // No assignment.
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
// char_state_machine.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_CHAR_STATE_MACHINE_HPP
|
||||
#define BOOST_LEXER_CHAR_STATE_MACHINE_HPP
|
||||
|
||||
#include "../consts.hpp"
|
||||
#include <map>
|
||||
#include "../size_t.hpp"
|
||||
#include "../string_token.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CharT>
|
||||
struct basic_char_state_machine
|
||||
{
|
||||
struct state
|
||||
{
|
||||
typedef basic_string_token<CharT> string_token;
|
||||
typedef std::map<std::size_t, string_token> size_t_string_token_map;
|
||||
typedef std::pair<std::size_t, string_token> size_t_string_token_pair;
|
||||
|
||||
bool _end_state;
|
||||
std::size_t _id;
|
||||
std::size_t _unique_id;
|
||||
std::size_t _state;
|
||||
std::size_t _bol_index;
|
||||
std::size_t _eol_index;
|
||||
size_t_string_token_map _transitions;
|
||||
|
||||
state () :
|
||||
_end_state (false),
|
||||
_id (0),
|
||||
_unique_id (npos),
|
||||
_state (0),
|
||||
_bol_index (npos),
|
||||
_eol_index (npos)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<state> state_vector;
|
||||
typedef std::vector<state_vector> state_vector_vector;
|
||||
|
||||
state_vector_vector _sm_vector;
|
||||
|
||||
bool empty () const
|
||||
{
|
||||
return _sm_vector.empty ();
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
_sm_vector.clear ();
|
||||
}
|
||||
|
||||
void swap (basic_char_state_machine &csm_)
|
||||
{
|
||||
_sm_vector.swap (csm_._sm_vector);
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_char_state_machine<char> char_state_machine;
|
||||
typedef basic_char_state_machine<wchar_t> wchar_state_machine;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,281 @@
|
||||
// debug.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_DEBUG_HPP
|
||||
#define BOOST_LEXER_DEBUG_HPP
|
||||
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include "rules.hpp"
|
||||
#include "size_t.hpp"
|
||||
#include "state_machine.hpp"
|
||||
#include "string_token.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
template<typename CharT>
|
||||
class basic_debug
|
||||
{
|
||||
public:
|
||||
typedef std::basic_ostream<CharT> ostream;
|
||||
typedef std::basic_string<CharT> string;
|
||||
typedef std::vector<std::size_t> size_t_vector;
|
||||
|
||||
static void escape_control_chars (const string &in_, string &out_)
|
||||
{
|
||||
const CharT *ptr_ = in_.c_str ();
|
||||
std::size_t size_ = in_.size ();
|
||||
|
||||
out_.clear ();
|
||||
|
||||
while (size_)
|
||||
{
|
||||
basic_string_token<CharT>::escape_char (*ptr_, out_);
|
||||
++ptr_;
|
||||
--size_;
|
||||
}
|
||||
}
|
||||
|
||||
static void dump (const basic_state_machine<CharT> &state_machine_,
|
||||
basic_rules<CharT> &rules_, ostream &stream_)
|
||||
{
|
||||
typename basic_state_machine<CharT>::iterator iter_ =
|
||||
state_machine_.begin ();
|
||||
typename basic_state_machine<CharT>::iterator end_ =
|
||||
state_machine_.end ();
|
||||
|
||||
for (std::size_t dfa_ = 0, dfas_ = state_machine_.size ();
|
||||
dfa_ < dfas_; ++dfa_)
|
||||
{
|
||||
lexer_state (stream_);
|
||||
stream_ << rules_.state (dfa_) << std::endl << std::endl;
|
||||
|
||||
dump_ex (iter_, stream_);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump (const basic_state_machine<CharT> &state_machine_,
|
||||
ostream &stream_)
|
||||
{
|
||||
typename basic_state_machine<CharT>::iterator iter_ =
|
||||
state_machine_.begin ();
|
||||
typename basic_state_machine<CharT>::iterator end_ =
|
||||
state_machine_.end ();
|
||||
|
||||
for (std::size_t dfa_ = 0, dfas_ = state_machine_.size ();
|
||||
dfa_ < dfas_; ++dfa_)
|
||||
{
|
||||
lexer_state (stream_);
|
||||
stream_ << dfa_ << std::endl << std::endl;
|
||||
|
||||
dump_ex (iter_, stream_);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef std::basic_stringstream<CharT> stringstream;
|
||||
|
||||
static void dump_ex (typename basic_state_machine<CharT>::iterator &iter_,
|
||||
ostream &stream_)
|
||||
{
|
||||
const std::size_t states_ = iter_->states;
|
||||
|
||||
for (std::size_t i_ = 0; i_ < states_; ++i_)
|
||||
{
|
||||
state (stream_);
|
||||
stream_ << i_ << std::endl;
|
||||
|
||||
if (iter_->end_state)
|
||||
{
|
||||
end_state (stream_);
|
||||
stream_ << iter_->id;
|
||||
unique_id (stream_);
|
||||
stream_ << iter_->unique_id;
|
||||
dfa (stream_);
|
||||
stream_ << iter_->goto_dfa;
|
||||
stream_ << std::endl;
|
||||
}
|
||||
|
||||
if (iter_->bol_index != npos)
|
||||
{
|
||||
bol (stream_);
|
||||
stream_ << iter_->bol_index << std::endl;
|
||||
}
|
||||
|
||||
if (iter_->eol_index != npos)
|
||||
{
|
||||
eol (stream_);
|
||||
stream_ << iter_->eol_index << std::endl;
|
||||
}
|
||||
|
||||
const std::size_t transitions_ = iter_->transitions;
|
||||
|
||||
if (transitions_ == 0)
|
||||
{
|
||||
++iter_;
|
||||
}
|
||||
|
||||
for (std::size_t t_ = 0; t_ < transitions_; ++t_)
|
||||
{
|
||||
std::size_t goto_state_ = iter_->goto_state;
|
||||
|
||||
if (iter_->token.any ())
|
||||
{
|
||||
any (stream_);
|
||||
}
|
||||
else
|
||||
{
|
||||
open_bracket (stream_);
|
||||
|
||||
if (iter_->token._negated)
|
||||
{
|
||||
negated (stream_);
|
||||
}
|
||||
|
||||
string charset_;
|
||||
CharT c_ = 0;
|
||||
|
||||
escape_control_chars (iter_->token._charset,
|
||||
charset_);
|
||||
c_ = *charset_.c_str ();
|
||||
|
||||
if (!iter_->token._negated &&
|
||||
(c_ == '^' || c_ == ']'))
|
||||
{
|
||||
stream_ << '\\';
|
||||
}
|
||||
|
||||
stream_ << charset_;
|
||||
close_bracket (stream_);
|
||||
}
|
||||
|
||||
stream_ << goto_state_ << std::endl;
|
||||
++iter_;
|
||||
}
|
||||
|
||||
stream_ << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void lexer_state (std::ostream &stream_)
|
||||
{
|
||||
stream_ << "Lexer state: ";
|
||||
}
|
||||
|
||||
static void lexer_state (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L"Lexer state: ";
|
||||
}
|
||||
|
||||
static void state (std::ostream &stream_)
|
||||
{
|
||||
stream_ << "State: ";
|
||||
}
|
||||
|
||||
static void state (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L"State: ";
|
||||
}
|
||||
|
||||
static void bol (std::ostream &stream_)
|
||||
{
|
||||
stream_ << " BOL -> ";
|
||||
}
|
||||
|
||||
static void bol (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L" BOL -> ";
|
||||
}
|
||||
|
||||
static void eol (std::ostream &stream_)
|
||||
{
|
||||
stream_ << " EOL -> ";
|
||||
}
|
||||
|
||||
static void eol (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L" EOL -> ";
|
||||
}
|
||||
|
||||
static void end_state (std::ostream &stream_)
|
||||
{
|
||||
stream_ << " END STATE, Id = ";
|
||||
}
|
||||
|
||||
static void end_state (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L" END STATE, Id = ";
|
||||
}
|
||||
|
||||
static void unique_id (std::ostream &stream_)
|
||||
{
|
||||
stream_ << ", Unique Id = ";
|
||||
}
|
||||
|
||||
static void unique_id (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L", Unique Id = ";
|
||||
}
|
||||
|
||||
static void any (std::ostream &stream_)
|
||||
{
|
||||
stream_ << " . -> ";
|
||||
}
|
||||
|
||||
static void any (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L" . -> ";
|
||||
}
|
||||
|
||||
static void open_bracket (std::ostream &stream_)
|
||||
{
|
||||
stream_ << " [";
|
||||
}
|
||||
|
||||
static void open_bracket (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L" [";
|
||||
}
|
||||
|
||||
static void negated (std::ostream &stream_)
|
||||
{
|
||||
stream_ << "^";
|
||||
}
|
||||
|
||||
static void negated (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L"^";
|
||||
}
|
||||
|
||||
static void close_bracket (std::ostream &stream_)
|
||||
{
|
||||
stream_ << "] -> ";
|
||||
}
|
||||
|
||||
static void close_bracket (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L"] -> ";
|
||||
}
|
||||
|
||||
static void dfa (std::ostream &stream_)
|
||||
{
|
||||
stream_ << ", dfa = ";
|
||||
}
|
||||
|
||||
static void dfa (std::wostream &stream_)
|
||||
{
|
||||
stream_ << L", dfa = ";
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_debug<char> debug;
|
||||
typedef basic_debug<wchar_t> wdebug;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+475
@@ -0,0 +1,475 @@
|
||||
// file_input.hpp
|
||||
// Copyright (c) 2008-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_FILE_INPUT
|
||||
#define BOOST_LEXER_FILE_INPUT
|
||||
|
||||
#include "char_traits.hpp"
|
||||
// memcpy
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include "size_t.hpp"
|
||||
#include "state_machine.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
template<typename CharT, typename Traits = char_traits<CharT> >
|
||||
class basic_file_input
|
||||
{
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
friend class basic_file_input;
|
||||
|
||||
struct data
|
||||
{
|
||||
std::size_t id;
|
||||
std::size_t unique_id;
|
||||
const CharT *start;
|
||||
const CharT *end;
|
||||
std::size_t state;
|
||||
|
||||
// Construct in end() state.
|
||||
data () :
|
||||
id (0),
|
||||
unique_id (npos),
|
||||
state (npos)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const data &rhs_) const
|
||||
{
|
||||
return id == rhs_.id && unique_id == rhs_.unique_id &&
|
||||
start == rhs_.start && end == rhs_.end &&
|
||||
state == rhs_.state;
|
||||
}
|
||||
};
|
||||
|
||||
iterator () :
|
||||
_input (0)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const iterator &rhs_) const
|
||||
{
|
||||
return _data == rhs_._data;
|
||||
}
|
||||
|
||||
bool operator != (const iterator &rhs_) const
|
||||
{
|
||||
return !(*this == rhs_);
|
||||
}
|
||||
|
||||
data &operator * ()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
data *operator -> ()
|
||||
{
|
||||
return &_data;
|
||||
}
|
||||
|
||||
// Let compiler generate operator = ().
|
||||
|
||||
// prefix version
|
||||
iterator &operator ++ ()
|
||||
{
|
||||
next_token ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// postfix version
|
||||
iterator operator ++ (int)
|
||||
{
|
||||
iterator iter_ = *this;
|
||||
|
||||
next_token ();
|
||||
return iter_;
|
||||
}
|
||||
|
||||
void next_token ()
|
||||
{
|
||||
const detail::internals &internals_ =
|
||||
_input->_state_machine->data ();
|
||||
|
||||
_data.start = _data.end;
|
||||
|
||||
if (internals_._dfa->size () == 1)
|
||||
{
|
||||
_data.id = _input->next (&internals_._lookup->front ()->
|
||||
front (), internals_._dfa_alphabet.front (),
|
||||
&internals_._dfa->front ()->front (), _data.start,
|
||||
_data.end, _data.unique_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data.id = _input->next (internals_, _data.state, _data.start,
|
||||
_data.end, _data.unique_id);
|
||||
}
|
||||
|
||||
if (_data.id == 0)
|
||||
{
|
||||
_data.start = 0;
|
||||
_data.end = 0;
|
||||
// Ensure current state matches that returned by end().
|
||||
_data.state = npos;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Not owner (obviously!)
|
||||
basic_file_input *_input;
|
||||
data _data;
|
||||
};
|
||||
|
||||
friend class iterator;
|
||||
|
||||
// Make it explict that we are NOT taking a copy of state_machine_!
|
||||
basic_file_input (const basic_state_machine<CharT> *state_machine_,
|
||||
std::basic_ifstream<CharT> *is_,
|
||||
const std::streamsize buffer_size_ = 4096,
|
||||
const std::streamsize buffer_increment_ = 1024) :
|
||||
_state_machine (state_machine_),
|
||||
_stream (is_),
|
||||
_buffer_size (buffer_size_),
|
||||
_buffer_increment (buffer_increment_),
|
||||
_buffer (_buffer_size, '!')
|
||||
{
|
||||
_start_buffer = &_buffer.front ();
|
||||
_end_buffer = _start_buffer + _buffer.size ();
|
||||
_start_token = _end_buffer;
|
||||
_end_token = _end_buffer;
|
||||
}
|
||||
|
||||
iterator begin ()
|
||||
{
|
||||
iterator iter_;
|
||||
|
||||
iter_._input = this;
|
||||
// Over-ride default of 0 (EOF)
|
||||
iter_._data.id = npos;
|
||||
iter_._data.start = 0;
|
||||
iter_._data.end = 0;
|
||||
iter_._data.state = 0;
|
||||
++iter_;
|
||||
return iter_;
|
||||
}
|
||||
|
||||
iterator end ()
|
||||
{
|
||||
iterator iter_;
|
||||
|
||||
iter_._input = this;
|
||||
iter_._data.start = 0;
|
||||
iter_._data.end = 0;
|
||||
return iter_;
|
||||
}
|
||||
|
||||
void flush ()
|
||||
{
|
||||
// This temporary is mandatory, otherwise the
|
||||
// pointer calculations won't work!
|
||||
const CharT *temp_ = _end_buffer;
|
||||
|
||||
_start_token = _end_token = _end_buffer;
|
||||
reload_buffer (temp_, true, _end_token);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::basic_istream<CharT> istream;
|
||||
typedef std::vector<CharT> buffer;
|
||||
|
||||
const basic_state_machine<CharT> *_state_machine;
|
||||
const std::streamsize _buffer_size;
|
||||
const std::streamsize _buffer_increment;
|
||||
|
||||
buffer _buffer;
|
||||
CharT *_start_buffer;
|
||||
istream *_stream;
|
||||
const CharT *_start_token;
|
||||
const CharT *_end_token;
|
||||
CharT *_end_buffer;
|
||||
|
||||
std::size_t next (const detail::internals &internals_,
|
||||
std::size_t &start_state_, const CharT * &start_, const CharT * &end_,
|
||||
std::size_t &unique_id_)
|
||||
{
|
||||
_start_token = _end_token;
|
||||
|
||||
again:
|
||||
const std::size_t * lookup_ = &internals_._lookup[start_state_]->
|
||||
front ();
|
||||
std::size_t dfa_alphabet_ = internals_._dfa_alphabet[start_state_];
|
||||
const std::size_t *dfa_ = &internals_._dfa[start_state_]->front ();
|
||||
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
|
||||
const CharT *curr_ = _start_token;
|
||||
bool end_state_ = *ptr_ != 0;
|
||||
std::size_t id_ = *(ptr_ + id_index);
|
||||
std::size_t uid_ = *(ptr_ + unique_id_index);
|
||||
const CharT *end_token_ = curr_;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (curr_ >= _end_buffer)
|
||||
{
|
||||
if (!reload_buffer (curr_, end_state_, end_token_))
|
||||
{
|
||||
// EOF
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const std::size_t BOL_state_ = ptr_[bol_index];
|
||||
const std::size_t EOL_state_ = ptr_[eol_index];
|
||||
|
||||
if (BOL_state_ && (_start_token == _start_buffer ||
|
||||
*(_start_token - 1) == '\n'))
|
||||
{
|
||||
ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
|
||||
}
|
||||
else if (EOL_state_ && *curr_ == '\n')
|
||||
{
|
||||
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::size_t state_ =
|
||||
ptr_[lookup_[static_cast<typename Traits::index_type>
|
||||
(*curr_++)]];
|
||||
|
||||
if (state_ == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ptr_ = &dfa_[state_ * dfa_alphabet_];
|
||||
}
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
start_state_ = *(ptr_ + state_index);
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
if (_start_token >= _end_buffer)
|
||||
{
|
||||
// No more tokens...
|
||||
unique_id_ = npos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::size_t EOL_state_ = ptr_[eol_index];
|
||||
|
||||
if (EOL_state_ && curr_ == end_)
|
||||
{
|
||||
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
start_state_ = *(ptr_ + state_index);
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
if (end_state_)
|
||||
{
|
||||
// return longest match
|
||||
_end_token = end_token_;
|
||||
|
||||
if (id_ == 0) goto again;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match causes char to be skipped
|
||||
_end_token = _start_token + 1;
|
||||
id_ = npos;
|
||||
uid_ = npos;
|
||||
}
|
||||
|
||||
start_ = _start_token;
|
||||
end_ = _end_token;
|
||||
unique_id_ = uid_;
|
||||
return id_;
|
||||
}
|
||||
|
||||
std::size_t next (const std::size_t * const lookup_,
|
||||
const std::size_t dfa_alphabet_, const std::size_t * const dfa_,
|
||||
const CharT * &start_, const CharT * &end_, std::size_t &unique_id_)
|
||||
{
|
||||
_start_token = _end_token;
|
||||
|
||||
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
|
||||
const CharT *curr_ = _start_token;
|
||||
bool end_state_ = *ptr_ != 0;
|
||||
std::size_t id_ = *(ptr_ + id_index);
|
||||
std::size_t uid_ = *(ptr_ + unique_id_index);
|
||||
const CharT *end_token_ = curr_;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (curr_ >= _end_buffer)
|
||||
{
|
||||
if (!reload_buffer (curr_, end_state_, end_token_))
|
||||
{
|
||||
// EOF
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const std::size_t BOL_state_ = ptr_[bol_index];
|
||||
const std::size_t EOL_state_ = ptr_[eol_index];
|
||||
|
||||
if (BOL_state_ && (_start_token == _start_buffer ||
|
||||
*(_start_token - 1) == '\n'))
|
||||
{
|
||||
ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
|
||||
}
|
||||
else if (EOL_state_ && *curr_ == '\n')
|
||||
{
|
||||
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::size_t state_ =
|
||||
ptr_[lookup_[static_cast<typename Traits::index_type>
|
||||
(*curr_++)]];
|
||||
|
||||
if (state_ == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ptr_ = &dfa_[state_ * dfa_alphabet_];
|
||||
}
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
if (_start_token >= _end_buffer)
|
||||
{
|
||||
// No more tokens...
|
||||
unique_id_ = npos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::size_t EOL_state_ = ptr_[eol_index];
|
||||
|
||||
if (EOL_state_ && curr_ == end_)
|
||||
{
|
||||
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
if (end_state_)
|
||||
{
|
||||
// return longest match
|
||||
_end_token = end_token_;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match causes char to be skipped
|
||||
_end_token = _start_token + 1;
|
||||
id_ = npos;
|
||||
uid_ = npos;
|
||||
}
|
||||
|
||||
start_ = _start_token;
|
||||
end_ = _end_token;
|
||||
unique_id_ = uid_;
|
||||
return id_;
|
||||
}
|
||||
|
||||
bool reload_buffer (const CharT * &curr_, const bool end_state_,
|
||||
const CharT * &end_token_)
|
||||
{
|
||||
bool success_ = !_stream->eof ();
|
||||
|
||||
if (success_)
|
||||
{
|
||||
const CharT *old_start_token_ = _start_token;
|
||||
std::size_t old_size_ = _buffer.size ();
|
||||
std::size_t count_ = 0;
|
||||
|
||||
if (_start_token - 1 == _start_buffer)
|
||||
{
|
||||
// Run out of buffer space, so increase.
|
||||
_buffer.resize (old_size_ + _buffer_increment, '!');
|
||||
_start_buffer = &_buffer.front ();
|
||||
_start_token = _start_buffer + 1;
|
||||
_stream->read (_start_buffer + old_size_,
|
||||
_buffer_increment);
|
||||
count_ = _stream->gcount ();
|
||||
_end_buffer = _start_buffer + old_size_ + count_;
|
||||
}
|
||||
else if (_start_token < _end_buffer)
|
||||
{
|
||||
const std::size_t len_ = _end_buffer - _start_token;
|
||||
// Some systems have memcpy in namespace std.
|
||||
using namespace std;
|
||||
|
||||
memcpy (_start_buffer, _start_token - 1, (len_ + 1) *
|
||||
sizeof (CharT));
|
||||
_stream->read (_start_buffer + len_ + 1,
|
||||
static_cast<std::streamsize> (_buffer.size () - len_ - 1));
|
||||
count_ = _stream->gcount ();
|
||||
_start_token = _start_buffer + 1;
|
||||
_end_buffer = _start_buffer + len_ + 1 + count_;
|
||||
}
|
||||
else
|
||||
{
|
||||
_stream->read (_start_buffer, static_cast<std::streamsize>
|
||||
(_buffer.size ()));
|
||||
count_ = _stream->gcount ();
|
||||
_start_token = _start_buffer;
|
||||
_end_buffer = _start_buffer + count_;
|
||||
}
|
||||
|
||||
if (end_state_)
|
||||
{
|
||||
end_token_ = _start_token +
|
||||
(end_token_ - old_start_token_);
|
||||
}
|
||||
|
||||
curr_ = _start_token + (curr_ - old_start_token_);
|
||||
}
|
||||
|
||||
return success_;
|
||||
}
|
||||
|
||||
// Disallow copying of buffer
|
||||
basic_file_input (const basic_file_input &);
|
||||
const basic_file_input &operator = (const basic_file_input &);
|
||||
};
|
||||
|
||||
typedef basic_file_input<char> file_input;
|
||||
typedef basic_file_input<wchar_t> wfile_input;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+577
@@ -0,0 +1,577 @@
|
||||
// generate_cpp.hpp
|
||||
// Copyright (c) 2008-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_GENERATE_CPP_HPP
|
||||
#define BOOST_LEXER_GENERATE_CPP_HPP
|
||||
|
||||
#include "char_traits.hpp"
|
||||
#include "consts.hpp"
|
||||
#include "internals.hpp"
|
||||
#include <iostream>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include "runtime_error.hpp"
|
||||
#include "size_t.hpp"
|
||||
#include "state_machine.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
template<typename CharT>
|
||||
void generate_cpp (const basic_state_machine<CharT> &state_machine_,
|
||||
std::ostream &os_, const bool use_pointers_ = false,
|
||||
const bool skip_unknown_ = true, const bool optimise_parameters_ = true,
|
||||
const char *name_ = "next_token")
|
||||
{
|
||||
const detail::internals &sm_ = state_machine_.data ();
|
||||
|
||||
if (sm_._lookup->size () == 0)
|
||||
{
|
||||
throw runtime_error ("Cannot generate code from an empty "
|
||||
"state machine");
|
||||
}
|
||||
|
||||
std::string upper_name_ (__DATE__);
|
||||
const std::size_t lookups_ = sm_._lookup->front ()->size ();
|
||||
const std::size_t dfas_ = sm_._dfa->size ();
|
||||
std::string::size_type pos_ = upper_name_.find (' ');
|
||||
const char *iterator_ = 0;
|
||||
|
||||
if (use_pointers_)
|
||||
{
|
||||
if (lookups_ == 256)
|
||||
{
|
||||
iterator_ = "const char *";
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator_ = "const wchar_t *";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator_ = "Iterator &";
|
||||
}
|
||||
|
||||
while (pos_ != std::string::npos)
|
||||
{
|
||||
upper_name_.replace (pos_, 1, "_");
|
||||
pos_ = upper_name_.find (' ', pos_);
|
||||
}
|
||||
|
||||
upper_name_ += '_';
|
||||
upper_name_ += __TIME__;
|
||||
|
||||
pos_ = upper_name_.find (':');
|
||||
|
||||
while (pos_ != std::string::npos)
|
||||
{
|
||||
upper_name_.erase (pos_, 1);
|
||||
pos_ = upper_name_.find (':', pos_);
|
||||
}
|
||||
|
||||
upper_name_ = '_' + upper_name_;
|
||||
upper_name_ = name_ + upper_name_;
|
||||
std::transform (upper_name_.begin (), upper_name_.end (),
|
||||
upper_name_.begin (), ::toupper);
|
||||
os_ << "#ifndef " << upper_name_ + '\n';
|
||||
os_ << "#define " << upper_name_ + '\n';
|
||||
os_ << "// Copyright (c) 2008-2009 Ben Hanson\n";
|
||||
os_ << "//\n";
|
||||
os_ << "// Distributed under the Boost Software License, "
|
||||
"Version 1.0. (See accompanying\n";
|
||||
os_ << "// file licence_1_0.txt or copy at "
|
||||
"http://www.boost.org/LICENSE_1_0.txt)\n\n";
|
||||
os_ << "// Auto-generated by boost::lexer\n";
|
||||
os_ << "template<typename Iterator>\n";
|
||||
os_ << "std::size_t " << name_ << " (";
|
||||
|
||||
if (dfas_ > 1 || !optimise_parameters_)
|
||||
{
|
||||
os_ << "std::size_t &start_state_, ";
|
||||
}
|
||||
|
||||
if (use_pointers_)
|
||||
{
|
||||
os_ << iterator_ << " &";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << iterator_;
|
||||
}
|
||||
|
||||
os_ << "start_token_, ";
|
||||
|
||||
if (use_pointers_)
|
||||
{
|
||||
os_ << iterator_ << " const ";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << "const " << iterator_;
|
||||
}
|
||||
|
||||
os_ << "end_, \n";
|
||||
os_ << " std::size_t &unique_id_";
|
||||
|
||||
if (sm_._seen_BOL_assertion || !optimise_parameters_)
|
||||
{
|
||||
os_ << ", bool &beg_of_line_";
|
||||
}
|
||||
|
||||
os_ << ")\n";
|
||||
os_ << "{\n";
|
||||
os_ << " enum {end_state_index, id_index, unique_id_index, state_index, bol_index,\n";
|
||||
os_ << " eol_index, dead_state_index, dfa_offset};\n";
|
||||
os_ << " static const std::size_t npos = static_cast"
|
||||
"<std::size_t>(~0);\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
std::size_t state_ = 0;
|
||||
|
||||
for (; state_ < dfas_; ++state_)
|
||||
{
|
||||
std::size_t i_ = 0;
|
||||
std::size_t j_ = 1;
|
||||
std::size_t count_ = lookups_ / 8;
|
||||
const std::size_t *lookup_ = &sm_._lookup[state_]->front ();
|
||||
const std::size_t *dfa_ = &sm_._dfa[state_]->front ();
|
||||
|
||||
os_ << " static const std::size_t lookup" << state_ << "_[" <<
|
||||
lookups_ << "] = {";
|
||||
|
||||
for (; i_ < count_; ++i_)
|
||||
{
|
||||
const std::size_t index_ = i_ * 8;
|
||||
|
||||
os_ << lookup_[index_];
|
||||
|
||||
for (; j_ < 8; ++j_)
|
||||
{
|
||||
os_ << ", " << lookup_[index_ + j_];
|
||||
}
|
||||
|
||||
if (i_ < count_ - 1)
|
||||
{
|
||||
os_ << "," << std::endl << " ";
|
||||
}
|
||||
|
||||
j_ = 1;
|
||||
}
|
||||
|
||||
os_ << "};\n";
|
||||
count_ = sm_._dfa[state_]->size ();
|
||||
os_ << " static const std::size_t dfa" << state_ << "_[" <<
|
||||
count_ << "] = {";
|
||||
count_ /= 8;
|
||||
|
||||
for (i_ = 0; i_ < count_; ++i_)
|
||||
{
|
||||
const std::size_t index_ = i_ * 8;
|
||||
|
||||
os_ << dfa_[index_];
|
||||
|
||||
for (j_ = 1; j_ < 8; ++j_)
|
||||
{
|
||||
os_ << ", " << dfa_[index_ + j_];
|
||||
}
|
||||
|
||||
if (i_ < count_ - 1)
|
||||
{
|
||||
os_ << "," << std::endl << " ";
|
||||
}
|
||||
}
|
||||
|
||||
const std::size_t mod_ = sm_._dfa[state_]->size () % 8;
|
||||
|
||||
if (mod_)
|
||||
{
|
||||
const std::size_t index_ = count_ * 8;
|
||||
|
||||
if (count_)
|
||||
{
|
||||
os_ << ",\n ";
|
||||
}
|
||||
|
||||
os_ << dfa_[index_];
|
||||
|
||||
for (j_ = 1; j_ < mod_; ++j_)
|
||||
{
|
||||
os_ << ", " << dfa_[index_ + j_];
|
||||
}
|
||||
}
|
||||
|
||||
os_ << "};\n";
|
||||
}
|
||||
|
||||
std::size_t count_ = sm_._dfa_alphabet.size ();
|
||||
std::size_t i_ = 1;
|
||||
|
||||
os_ << " static const std::size_t *lookup_arr_[" << count_ <<
|
||||
"] = {";
|
||||
os_ << "lookup0_";
|
||||
|
||||
for (i_ = 1; i_ < count_; ++i_)
|
||||
{
|
||||
os_ << ", " << "lookup" << i_ << "_";
|
||||
}
|
||||
|
||||
os_ << "};\n";
|
||||
os_ << " static const std::size_t dfa_alphabet_arr_[" << count_ <<
|
||||
"] = {";
|
||||
os_ << sm_._dfa_alphabet.front ();
|
||||
|
||||
for (i_ = 1; i_ < count_; ++i_)
|
||||
{
|
||||
os_ << ", " << sm_._dfa_alphabet[i_];
|
||||
}
|
||||
|
||||
os_ << "};\n";
|
||||
os_ << " static const std::size_t *dfa_arr_[" << count_ <<
|
||||
"] = {";
|
||||
os_ << "dfa0_";
|
||||
|
||||
for (i_ = 1; i_ < count_; ++i_)
|
||||
{
|
||||
os_ << ", " << "dfa" << i_ << "_";
|
||||
}
|
||||
|
||||
os_ << "};\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::size_t *lookup_ = &sm_._lookup->front ()->front ();
|
||||
const std::size_t *dfa_ = &sm_._dfa->front ()->front ();
|
||||
std::size_t i_ = 0;
|
||||
std::size_t j_ = 1;
|
||||
std::size_t count_ = lookups_ / 8;
|
||||
|
||||
os_ << " static const std::size_t lookup_[";
|
||||
os_ << sm_._lookup->front ()->size () << "] = {";
|
||||
|
||||
for (; i_ < count_; ++i_)
|
||||
{
|
||||
const std::size_t index_ = i_ * 8;
|
||||
|
||||
os_ << lookup_[index_];
|
||||
|
||||
for (; j_ < 8; ++j_)
|
||||
{
|
||||
os_ << ", " << lookup_[index_ + j_];
|
||||
}
|
||||
|
||||
if (i_ < count_ - 1)
|
||||
{
|
||||
os_ << "," << std::endl << " ";
|
||||
}
|
||||
|
||||
j_ = 1;
|
||||
}
|
||||
|
||||
os_ << "};\n";
|
||||
os_ << " static const std::size_t dfa_alphabet_ = " <<
|
||||
sm_._dfa_alphabet.front () << ";\n";
|
||||
os_ << " static const std::size_t dfa_[" <<
|
||||
sm_._dfa->front ()->size () << "] = {";
|
||||
count_ = sm_._dfa->front ()->size () / 8;
|
||||
|
||||
for (i_ = 0; i_ < count_; ++i_)
|
||||
{
|
||||
const std::size_t index_ = i_ * 8;
|
||||
|
||||
os_ << dfa_[index_];
|
||||
|
||||
for (j_ = 1; j_ < 8; ++j_)
|
||||
{
|
||||
os_ << ", " << dfa_[index_ + j_];
|
||||
}
|
||||
|
||||
if (i_ < count_ - 1)
|
||||
{
|
||||
os_ << "," << std::endl << " ";
|
||||
}
|
||||
}
|
||||
|
||||
const std::size_t mod_ = sm_._dfa->front ()->size () % 8;
|
||||
|
||||
if (mod_)
|
||||
{
|
||||
const std::size_t index_ = count_ * 8;
|
||||
|
||||
if (count_)
|
||||
{
|
||||
os_ << ",\n ";
|
||||
}
|
||||
|
||||
os_ << dfa_[index_];
|
||||
|
||||
for (j_ = 1; j_ < mod_; ++j_)
|
||||
{
|
||||
os_ << ", " << dfa_[index_ + j_];
|
||||
}
|
||||
}
|
||||
|
||||
os_ << "};\n";
|
||||
}
|
||||
|
||||
os_ << "\n if (start_token_ == end_)\n";
|
||||
os_ << " {\n";
|
||||
os_ << " unique_id_ = npos;\n";
|
||||
os_ << " return 0;\n";
|
||||
os_ << " }\n\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << "again:\n";
|
||||
os_ << " const std::size_t * lookup_ = "
|
||||
"lookup_arr_[start_state_];\n";
|
||||
os_ << " std::size_t dfa_alphabet_ = "
|
||||
"dfa_alphabet_arr_[start_state_];\n";
|
||||
os_ << " const std::size_t *dfa_ = dfa_arr_[start_state_];\n";
|
||||
}
|
||||
|
||||
os_ << " const std::size_t *ptr_ = dfa_ + dfa_alphabet_;\n";
|
||||
os_ << " Iterator curr_ = start_token_;\n";
|
||||
os_ << " bool end_state_ = *ptr_ != 0;\n";
|
||||
os_ << " std::size_t id_ = *(ptr_ + id_index);\n";
|
||||
os_ << " std::size_t uid_ = *(ptr_ + unique_id_index);\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << " std::size_t end_start_state_ = start_state_;\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " bool bol_ = beg_of_line_;\n";
|
||||
os_ << " bool end_bol_ = bol_;\n";
|
||||
}
|
||||
|
||||
os_ << " Iterator end_token_ = start_token_;\n";
|
||||
os_ << '\n';
|
||||
os_ << " while (curr_ != end_)\n";
|
||||
os_ << " {\n";
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " const std::size_t BOL_state_ = ptr_[bol_index];\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_EOL_assertion)
|
||||
{
|
||||
os_ << " const std::size_t EOL_state_ = ptr_[eol_index];\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion)
|
||||
{
|
||||
os_ << '\n';
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " if (BOL_state_ && bol_)\n";
|
||||
os_ << " {\n";
|
||||
os_ << " ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];\n";
|
||||
os_ << " }\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_EOL_assertion)
|
||||
{
|
||||
os_ << " ";
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << "else ";
|
||||
}
|
||||
|
||||
os_ << "if (EOL_state_ && *curr_ == '\\n')\n";
|
||||
os_ << " {\n";
|
||||
os_ << " ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
|
||||
os_ << " }\n";
|
||||
}
|
||||
|
||||
std::string tab_ (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion ? " " : "");
|
||||
|
||||
if (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion)
|
||||
{
|
||||
os_ << " else\n";
|
||||
os_ << " {\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " ";
|
||||
|
||||
if (lookups_ == 256)
|
||||
{
|
||||
os_ << "char";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << "wchar_t";
|
||||
}
|
||||
|
||||
os_ << " prev_char_ = *curr_++;\n\n";
|
||||
os_ << " bol_ = prev_char_ == '\\n';\n\n";
|
||||
}
|
||||
|
||||
os_ << tab_;
|
||||
os_ << " const std::size_t state_ =\n";
|
||||
os_ << tab_;
|
||||
os_ << " ptr_[lookup_[";
|
||||
|
||||
if (lookups_ == 256)
|
||||
{
|
||||
os_ << "static_cast<unsigned char>(";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << "prev_char";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << "*curr_++";
|
||||
}
|
||||
|
||||
|
||||
if (lookups_ == 256)
|
||||
{
|
||||
os_ << ')';
|
||||
}
|
||||
|
||||
os_ << "]];\n\n";
|
||||
|
||||
os_ << tab_;
|
||||
os_ << " if (state_ == 0) break;\n\n";
|
||||
os_ << tab_;
|
||||
os_ << " ptr_ = &dfa_[state_ * dfa_alphabet_];\n";
|
||||
|
||||
if (sm_._seen_BOL_assertion || sm_._seen_EOL_assertion)
|
||||
{
|
||||
os_ << " }\n";
|
||||
}
|
||||
|
||||
os_ << '\n';
|
||||
os_ << " if (*ptr_)\n";
|
||||
os_ << " {\n";
|
||||
os_ << " end_state_ = true;\n";
|
||||
os_ << " id_ = *(ptr_ + id_index);\n";
|
||||
os_ << " uid_ = *(ptr_ + unique_id_index);\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << " end_start_state_ = *(ptr_ + state_index);\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " end_bol_ = bol_;\n";
|
||||
}
|
||||
|
||||
os_ << " end_token_ = curr_;\n";
|
||||
os_ << " }\n";
|
||||
os_ << " }\n";
|
||||
os_ << '\n';
|
||||
|
||||
if (sm_._seen_EOL_assertion)
|
||||
{
|
||||
os_ << " const std::size_t EOL_state_ = ptr_[eol_index];\n";
|
||||
os_ << '\n';
|
||||
os_ << " if (EOL_state_ && curr_ == end_)\n";
|
||||
os_ << " {\n";
|
||||
os_ << " ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];\n";
|
||||
os_ << '\n';
|
||||
os_ << " if (*ptr_)\n";
|
||||
os_ << " {\n";
|
||||
os_ << " end_state_ = true;\n";
|
||||
os_ << " id_ = *(ptr_ + id_index);\n";
|
||||
os_ << " uid_ = *(ptr_ + unique_id_index);\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << " end_start_state_ = *(ptr_ + state_index);\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " end_bol_ = bol_;\n";
|
||||
}
|
||||
|
||||
os_ << " end_token_ = curr_;\n";
|
||||
os_ << " }\n";
|
||||
os_ << " }\n";
|
||||
os_ << '\n';
|
||||
}
|
||||
|
||||
os_ << " if (end_state_)\n";
|
||||
os_ << " {\n";
|
||||
os_ << " // return longest match\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << " start_state_ = end_start_state_;\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion && dfas_ < 2)
|
||||
{
|
||||
os_ << " beg_of_line_ = end_bol_;\n";
|
||||
}
|
||||
|
||||
os_ << " start_token_ = end_token_;\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << '\n';
|
||||
os_ << " if (id_ == 0)\n";
|
||||
os_ << " {\n";
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " bol_ = end_bol_;\n";
|
||||
}
|
||||
|
||||
os_ << " goto again;\n";
|
||||
os_ << " }\n";
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " else\n";
|
||||
os_ << " {\n";
|
||||
os_ << " beg_of_line_ = end_bol_;\n";
|
||||
os_ << " }\n";
|
||||
}
|
||||
}
|
||||
|
||||
os_ << " }\n";
|
||||
os_ << " else\n";
|
||||
os_ << " {\n";
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " beg_of_line_ = *start_token_ == '\\n';\n";
|
||||
}
|
||||
|
||||
if (skip_unknown_)
|
||||
{
|
||||
os_ << " // No match causes char to be skipped\n";
|
||||
os_ << " ++start_token_;\n";
|
||||
}
|
||||
|
||||
os_ << " id_ = npos;\n";
|
||||
os_ << " uid_ = npos;\n";
|
||||
os_ << " }\n";
|
||||
os_ << '\n';
|
||||
os_ << " unique_id_ = uid_;\n";
|
||||
os_ << " return id_;\n";
|
||||
os_ << "}\n";
|
||||
os_ << "\n#endif\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+440
@@ -0,0 +1,440 @@
|
||||
// generate_re2c.hpp
|
||||
// Copyright (c) 2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef LEXERTL_GENERATE_RE2C_HPP
|
||||
#define LEXERTL_GENERATE_RE2C_HPP
|
||||
|
||||
#include "char_traits.hpp"
|
||||
#include "consts.hpp"
|
||||
#include "internals.hpp"
|
||||
#include <iostream>
|
||||
#include "runtime_error.hpp"
|
||||
#include "size_t.hpp"
|
||||
#include "state_machine.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
// check whether state0_0 is referenced from any of the other states
|
||||
template <typename Char>
|
||||
bool need_label0_0(boost::lexer::basic_state_machine<Char> const &sm_)
|
||||
{
|
||||
typedef typename boost::lexer::basic_state_machine<Char>::iterator
|
||||
iterator_type;
|
||||
iterator_type iter_ = sm_.begin();
|
||||
std::size_t states_ = iter_->states;
|
||||
|
||||
for (std::size_t state_ = 0; state_ < states_; ++state_)
|
||||
{
|
||||
if (0 == iter_->bol_index || 0 == iter_->eol_index)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t const transitions_ = iter_->transitions;
|
||||
for (std::size_t t_ = 0; t_ < transitions_; ++t_)
|
||||
{
|
||||
if (0 == iter_->goto_state)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
++iter_;
|
||||
}
|
||||
if (transitions_ == 0) ++iter_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename CharT>
|
||||
void generate_re2c (const basic_state_machine<CharT> &state_machine_,
|
||||
std::ostream &os_, const bool use_pointers_ = false,
|
||||
const bool skip_unknown_ = true, const bool optimise_parameters_ = true,
|
||||
const char *name_ = "next_token")
|
||||
{
|
||||
typedef typename boost::lexer::basic_string_token<CharT> string_token;
|
||||
const detail::internals &sm_ = state_machine_.data ();
|
||||
|
||||
if (sm_._lookup->size () == 0)
|
||||
{
|
||||
throw runtime_error ("Cannot generate code from an empty "
|
||||
"state machine");
|
||||
}
|
||||
|
||||
std::string upper_name_ (__DATE__);
|
||||
const std::size_t lookups_ = sm_._lookup->front ()->size ();
|
||||
typename boost::lexer::basic_state_machine<CharT>::iterator iter_ =
|
||||
state_machine_.begin();
|
||||
typename boost::lexer::basic_state_machine<CharT>::iterator end_ =
|
||||
state_machine_.end();
|
||||
const std::size_t dfas_ = sm_._dfa->size ();
|
||||
std::string::size_type pos_ = upper_name_.find (' ');
|
||||
const char *iterator_ = 0;
|
||||
|
||||
if (use_pointers_)
|
||||
{
|
||||
if (lookups_ == 256)
|
||||
{
|
||||
iterator_ = "const char *";
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator_ = "const wchar_t *";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator_ = "Iterator &";
|
||||
}
|
||||
|
||||
while (pos_ != std::string::npos)
|
||||
{
|
||||
upper_name_.replace (pos_, 1, "_");
|
||||
pos_ = upper_name_.find (' ', pos_);
|
||||
}
|
||||
|
||||
upper_name_ += '_';
|
||||
upper_name_ += __TIME__;
|
||||
|
||||
pos_ = upper_name_.find (':');
|
||||
|
||||
while (pos_ != std::string::npos)
|
||||
{
|
||||
upper_name_.erase (pos_, 1);
|
||||
pos_ = upper_name_.find (':', pos_);
|
||||
}
|
||||
|
||||
upper_name_ = '_' + upper_name_;
|
||||
upper_name_ = name_ + upper_name_;
|
||||
std::transform (upper_name_.begin (), upper_name_.end (),
|
||||
upper_name_.begin (), ::toupper);
|
||||
os_ << "#ifndef " << upper_name_ + '\n';
|
||||
os_ << "#define " << upper_name_ + '\n';
|
||||
os_ << "// Copyright (c) 2008-2009 Ben Hanson\n";
|
||||
os_ << "//\n";
|
||||
os_ << "// Distributed under the Boost Software License, "
|
||||
"Version 1.0. (See accompanying\n";
|
||||
os_ << "// file licence_1_0.txt or copy at "
|
||||
"http://www.boost.org/LICENSE_1_0.txt)\n\n";
|
||||
os_ << "// Auto-generated by boost::lexer\n";
|
||||
os_ << "template<typename Iterator>\n";
|
||||
os_ << "std::size_t " << name_ << " (";
|
||||
|
||||
if (dfas_ > 1 || !optimise_parameters_)
|
||||
{
|
||||
os_ << "std::size_t &start_state_, ";
|
||||
}
|
||||
|
||||
if (use_pointers_)
|
||||
{
|
||||
os_ << iterator_ << " &";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << iterator_;
|
||||
}
|
||||
|
||||
os_ << "start_token_, ";
|
||||
|
||||
if (use_pointers_)
|
||||
{
|
||||
os_ << iterator_ << " const ";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << "const " << iterator_;
|
||||
}
|
||||
|
||||
os_ << "end_, \n";
|
||||
os_ << " std::size_t &unique_id_";
|
||||
|
||||
if (sm_._seen_BOL_assertion || !optimise_parameters_)
|
||||
{
|
||||
os_ << ", bool &beg_of_line_";
|
||||
}
|
||||
|
||||
os_ << ")\n";
|
||||
os_ << "{\n";
|
||||
os_ << " static const std::size_t npos = static_cast"
|
||||
"<std::size_t>(~0);\n";
|
||||
os_ << "\n if (start_token_ == end_)\n";
|
||||
os_ << " {\n";
|
||||
os_ << " unique_id_ = npos;\n";
|
||||
os_ << " return 0;\n";
|
||||
os_ << " }\n\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << "again:\n";
|
||||
}
|
||||
|
||||
os_ << " Iterator curr_ = start_token_;\n";
|
||||
os_ << " bool end_state_ = false;\n";
|
||||
os_ << " std::size_t id_ = npos;\n";
|
||||
os_ << " std::size_t uid_ = npos;\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << " std::size_t end_start_state_ = start_state_;\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " bool bol_ = beg_of_line_;\n";
|
||||
os_ << " bool end_bol_ = bol_;\n";
|
||||
}
|
||||
|
||||
os_ << " Iterator end_token_ = start_token_;\n";
|
||||
os_ << '\n';
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << " switch (start_state_)\n";
|
||||
os_ << " {\n";
|
||||
|
||||
for (std::size_t i_ = 0; i_ < dfas_; ++i_)
|
||||
{
|
||||
os_ << " case " << i_ << ":\n";
|
||||
os_ << " goto " << i_ << "_0;\n";
|
||||
os_ << " // Not needed, but to prevent warnings\n";
|
||||
os_ << " break;\n";
|
||||
}
|
||||
|
||||
os_ << " default:\n";
|
||||
os_ << " throw std::runtime_error (\"Invalid start state!\")\n";
|
||||
os_ << " break;\n";
|
||||
os_ << " }\n\n";
|
||||
}
|
||||
|
||||
os_ << " ";
|
||||
|
||||
if (lookups_ == 256)
|
||||
{
|
||||
os_ << "char";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << "wchar_t";
|
||||
}
|
||||
|
||||
os_ << " ch_ = 0;\n\n";
|
||||
|
||||
bool need_state0_0_label = need_label0_0(state_machine_);
|
||||
|
||||
for (std::size_t dfa_ = 0; dfa_ < dfas_; ++dfa_)
|
||||
{
|
||||
const std::size_t states_ = iter_->states;
|
||||
|
||||
for (std::size_t state_ = 0; state_ < states_; ++state_)
|
||||
{
|
||||
const std::size_t transitions_ = iter_->transitions;
|
||||
std::size_t t_ = 0;
|
||||
|
||||
if (dfas_ > 1 || dfa_ != 0 || state_ != 0 || need_state0_0_label)
|
||||
{
|
||||
os_ << "state" << dfa_ << '_' << state_ << ":\n";
|
||||
}
|
||||
|
||||
if (iter_->end_state)
|
||||
{
|
||||
os_ << " end_state_ = true;\n";
|
||||
os_ << " id_ = " << iter_->id << ";\n";
|
||||
os_ << " uid_ = " << iter_->unique_id << ";\n";
|
||||
os_ << " end_token_ = curr_;\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << " end_start_state_ = " << iter_->goto_dfa <<
|
||||
";\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " end_bol_ = bol_;\n";
|
||||
}
|
||||
|
||||
if (transitions_) os_ << '\n';
|
||||
}
|
||||
|
||||
if (t_ < transitions_ || iter_->bol_index != boost::lexer::npos ||
|
||||
iter_->eol_index != boost::lexer::npos)
|
||||
{
|
||||
os_ << " if (curr_ == end_) goto end;\n\n";
|
||||
os_ << " ch_ = *curr_;\n";
|
||||
|
||||
if (iter_->bol_index != boost::lexer::npos)
|
||||
{
|
||||
os_ << "\n if (bol_) goto state" << dfa_ << '_' <<
|
||||
iter_->bol_index << ";\n\n";
|
||||
}
|
||||
|
||||
if (iter_->eol_index != boost::lexer::npos)
|
||||
{
|
||||
os_ << "\n if (ch_ == '\n') goto state" << dfa_ << '_' <<
|
||||
iter_->eol_index << ";\n\n";
|
||||
}
|
||||
|
||||
os_ << " ++curr_;\n";
|
||||
}
|
||||
|
||||
for (; t_ < transitions_; ++t_)
|
||||
{
|
||||
const char *ptr_ = iter_->token._charset.c_str();
|
||||
const char *end_ = ptr_ + iter_->token._charset.size();
|
||||
char start_char_ = 0;
|
||||
char curr_char_ = 0;
|
||||
bool range_ = false;
|
||||
bool first_char_ = true;
|
||||
|
||||
os_ << "\n if (";
|
||||
|
||||
while (ptr_ != end_)
|
||||
{
|
||||
curr_char_ = *ptr_++;
|
||||
|
||||
if (*ptr_ == curr_char_ + 1)
|
||||
{
|
||||
if (!range_)
|
||||
{
|
||||
start_char_ = curr_char_;
|
||||
}
|
||||
|
||||
range_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!first_char_)
|
||||
{
|
||||
if (iter_->token._negated)
|
||||
{
|
||||
os_ << " && ";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << " || ";
|
||||
}
|
||||
}
|
||||
|
||||
first_char_ = false;
|
||||
|
||||
if (range_)
|
||||
{
|
||||
typename string_token::string temp_;
|
||||
|
||||
if (iter_->token._negated)
|
||||
{
|
||||
os_ << "!";
|
||||
}
|
||||
|
||||
string_token::escape_char (start_char_, temp_);
|
||||
os_ << "(ch_ >= '" << temp_;
|
||||
temp_.clear ();
|
||||
string_token::escape_char (curr_char_, temp_);
|
||||
os_ << "' && ch_ <= '" << temp_ << "')";
|
||||
range_ = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
typename string_token::string temp_;
|
||||
|
||||
os_ << "ch_ ";
|
||||
|
||||
if (iter_->token._negated)
|
||||
{
|
||||
os_ << "!=";
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << "==";
|
||||
}
|
||||
|
||||
string_token::escape_char (curr_char_, temp_);
|
||||
os_ << " '" << temp_ << "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os_ << ") goto state" << dfa_ << '_' << iter_->goto_state <<
|
||||
";\n\n";
|
||||
++iter_;
|
||||
}
|
||||
|
||||
if (!(dfa_ == dfas_ - 1 && state_ == states_ - 1))
|
||||
{
|
||||
os_ << " goto end;\n";
|
||||
}
|
||||
|
||||
if (transitions_ == 0) ++iter_;
|
||||
}
|
||||
}
|
||||
|
||||
os_ << "end:\n";
|
||||
os_ << " if (end_state_)\n";
|
||||
os_ << " {\n";
|
||||
os_ << " // return longest match\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << " start_state_ = end_start_state_;\n";
|
||||
}
|
||||
|
||||
if (sm_._seen_BOL_assertion && dfas_ < 2)
|
||||
{
|
||||
os_ << " beg_of_line_ = end_bol_;\n";
|
||||
}
|
||||
|
||||
os_ << " start_token_ = end_token_;\n";
|
||||
|
||||
if (dfas_ > 1)
|
||||
{
|
||||
os_ << '\n';
|
||||
os_ << " if (id_ == 0)\n";
|
||||
os_ << " {\n";
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " bol_ = end_bol_;\n";
|
||||
}
|
||||
|
||||
os_ << " goto again;\n";
|
||||
os_ << " }\n";
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " else\n";
|
||||
os_ << " {\n";
|
||||
os_ << " beg_of_line_ = end_bol_;\n";
|
||||
os_ << " }\n";
|
||||
}
|
||||
}
|
||||
|
||||
os_ << " }\n";
|
||||
os_ << " else\n";
|
||||
os_ << " {\n";
|
||||
|
||||
if (sm_._seen_BOL_assertion)
|
||||
{
|
||||
os_ << " beg_of_line_ = *start_token_ == '\\n';\n";
|
||||
}
|
||||
|
||||
if (skip_unknown_)
|
||||
{
|
||||
os_ << " // No match causes char to be skipped\n";
|
||||
os_ << " ++start_token_;\n";
|
||||
}
|
||||
|
||||
os_ << " id_ = npos;\n";
|
||||
os_ << " uid_ = npos;\n";
|
||||
os_ << " }\n";
|
||||
os_ << '\n';
|
||||
os_ << " unique_id_ = uid_;\n";
|
||||
os_ << " return id_;\n";
|
||||
os_ << "}\n";
|
||||
os_ << "\n#endif\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+864
@@ -0,0 +1,864 @@
|
||||
// generator.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_GENERATOR_HPP
|
||||
#define BOOST_LEXER_GENERATOR_HPP
|
||||
|
||||
#include "char_traits.hpp"
|
||||
// memcmp()
|
||||
#include <cstring>
|
||||
#include "partition/charset.hpp"
|
||||
#include "partition/equivset.hpp"
|
||||
#include <memory>
|
||||
#include <limits>
|
||||
#include "parser/tree/node.hpp"
|
||||
#include "parser/parser.hpp"
|
||||
#include "containers/ptr_list.hpp"
|
||||
#include "rules.hpp"
|
||||
#include "state_machine.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
template<typename CharT, typename Traits = char_traits<CharT> >
|
||||
class basic_generator
|
||||
{
|
||||
public:
|
||||
typedef typename detail::internals::size_t_vector size_t_vector;
|
||||
typedef basic_rules<CharT> rules;
|
||||
|
||||
static void build (const rules &rules_,
|
||||
basic_state_machine<CharT> &state_machine_)
|
||||
{
|
||||
std::size_t index_ = 0;
|
||||
std::size_t size_ = rules_.statemap ().size ();
|
||||
node_ptr_vector node_ptr_vector_;
|
||||
detail::internals &internals_ = const_cast<detail::internals &>
|
||||
(state_machine_.data ());
|
||||
bool seen_BOL_assertion_ = false;
|
||||
bool seen_EOL_assertion_ = false;
|
||||
|
||||
state_machine_.clear ();
|
||||
|
||||
for (; index_ < size_; ++index_)
|
||||
{
|
||||
internals_._lookup->push_back (static_cast<size_t_vector *>(0));
|
||||
internals_._lookup->back () = new size_t_vector;
|
||||
internals_._dfa_alphabet.push_back (0);
|
||||
internals_._dfa->push_back (static_cast<size_t_vector *>(0));
|
||||
internals_._dfa->back () = new size_t_vector;
|
||||
}
|
||||
|
||||
for (index_ = 0, size_ = internals_._lookup->size ();
|
||||
index_ < size_; ++index_)
|
||||
{
|
||||
internals_._lookup[index_]->resize (sizeof (CharT) == 1 ?
|
||||
num_chars : num_wchar_ts, dead_state_index);
|
||||
|
||||
if (!rules_.regexes ()[index_].empty ())
|
||||
{
|
||||
// vector mapping token indexes to partitioned token index sets
|
||||
index_set_vector set_mapping_;
|
||||
// syntax tree
|
||||
detail::node *root_ = build_tree (rules_, index_,
|
||||
node_ptr_vector_, internals_, set_mapping_);
|
||||
|
||||
build_dfa (root_, set_mapping_,
|
||||
internals_._dfa_alphabet[index_],
|
||||
*internals_._dfa[index_]);
|
||||
|
||||
if (internals_._seen_BOL_assertion)
|
||||
{
|
||||
seen_BOL_assertion_ = true;
|
||||
}
|
||||
|
||||
if (internals_._seen_EOL_assertion)
|
||||
{
|
||||
seen_EOL_assertion_ = true;
|
||||
}
|
||||
|
||||
internals_._seen_BOL_assertion = false;
|
||||
internals_._seen_EOL_assertion = false;
|
||||
}
|
||||
}
|
||||
|
||||
internals_._seen_BOL_assertion = seen_BOL_assertion_;
|
||||
internals_._seen_EOL_assertion = seen_EOL_assertion_;
|
||||
}
|
||||
|
||||
static void minimise (basic_state_machine<CharT> &state_machine_)
|
||||
{
|
||||
detail::internals &internals_ = const_cast<detail::internals &>
|
||||
(state_machine_.data ());
|
||||
const std::size_t machines_ = internals_._dfa->size ();
|
||||
|
||||
for (std::size_t i_ = 0; i_ < machines_; ++i_)
|
||||
{
|
||||
const std::size_t dfa_alphabet_ = internals_._dfa_alphabet[i_];
|
||||
size_t_vector *dfa_ = internals_._dfa[i_];
|
||||
|
||||
if (dfa_alphabet_ != 0)
|
||||
{
|
||||
std::size_t size_ = 0;
|
||||
|
||||
do
|
||||
{
|
||||
size_ = dfa_->size ();
|
||||
minimise_dfa (dfa_alphabet_, *dfa_, size_);
|
||||
} while (dfa_->size () != size_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef detail::basic_charset<CharT> charset;
|
||||
typedef detail::ptr_list<charset> charset_list;
|
||||
typedef std::auto_ptr<charset> charset_ptr;
|
||||
typedef detail::equivset equivset;
|
||||
typedef detail::ptr_list<equivset> equivset_list;
|
||||
typedef std::auto_ptr<equivset> equivset_ptr;
|
||||
typedef typename charset::index_set index_set;
|
||||
typedef std::vector<index_set> index_set_vector;
|
||||
typedef detail::basic_parser<CharT> parser;
|
||||
typedef typename parser::node_ptr_vector node_ptr_vector;
|
||||
typedef std::set<const detail::node *> node_set;
|
||||
typedef detail::ptr_vector<node_set> node_set_vector;
|
||||
typedef std::vector<const detail::node *> node_vector;
|
||||
typedef detail::ptr_vector<node_vector> node_vector_vector;
|
||||
typedef typename parser::string string;
|
||||
typedef std::pair<string, string> string_pair;
|
||||
typedef typename parser::tokeniser::string_token string_token;
|
||||
typedef std::deque<string_pair> macro_deque;
|
||||
typedef std::pair<string, const detail::node *> macro_pair;
|
||||
typedef typename parser::macro_map::iterator macro_iter;
|
||||
typedef std::pair<macro_iter, bool> macro_iter_pair;
|
||||
typedef typename parser::tokeniser::token_map token_map;
|
||||
|
||||
static detail::node *build_tree (const rules &rules_,
|
||||
const std::size_t state_, node_ptr_vector &node_ptr_vector_,
|
||||
detail::internals &internals_, index_set_vector &set_mapping_)
|
||||
{
|
||||
size_t_vector *lookup_ = internals_._lookup[state_];
|
||||
const typename rules::string_deque_deque ®exes_ =
|
||||
rules_.regexes ();
|
||||
const typename rules::id_vector_deque &ids_ = rules_.ids ();
|
||||
const typename rules::id_vector_deque &unique_ids_ =
|
||||
rules_.unique_ids ();
|
||||
const typename rules::id_vector_deque &states_ = rules_.states ();
|
||||
typename rules::string_deque::const_iterator regex_iter_ =
|
||||
regexes_[state_].begin ();
|
||||
typename rules::string_deque::const_iterator regex_iter_end_ =
|
||||
regexes_[state_].end ();
|
||||
typename rules::id_vector::const_iterator ids_iter_ =
|
||||
ids_[state_].begin ();
|
||||
typename rules::id_vector::const_iterator unique_ids_iter_ =
|
||||
unique_ids_[state_].begin ();
|
||||
typename rules::id_vector::const_iterator states_iter_ =
|
||||
states_[state_].begin ();
|
||||
const typename rules::string ®ex_ = *regex_iter_;
|
||||
// map of regex charset tokens (strings) to index
|
||||
token_map token_map_;
|
||||
const typename rules::string_pair_deque ¯odeque_ =
|
||||
rules_.macrodeque ();
|
||||
typename parser::macro_map macromap_;
|
||||
typename detail::node::node_vector tree_vector_;
|
||||
|
||||
build_macros (token_map_, macrodeque_, macromap_,
|
||||
rules_.flags (), rules_.locale (), node_ptr_vector_,
|
||||
internals_._seen_BOL_assertion, internals_._seen_EOL_assertion);
|
||||
|
||||
detail::node *root_ = parser::parse (regex_.c_str (),
|
||||
regex_.c_str () + regex_.size (), *ids_iter_, *unique_ids_iter_,
|
||||
*states_iter_, rules_.flags (), rules_.locale (), node_ptr_vector_,
|
||||
macromap_, token_map_, internals_._seen_BOL_assertion,
|
||||
internals_._seen_EOL_assertion);
|
||||
|
||||
++regex_iter_;
|
||||
++ids_iter_;
|
||||
++unique_ids_iter_;
|
||||
++states_iter_;
|
||||
tree_vector_.push_back (root_);
|
||||
|
||||
// build syntax trees
|
||||
while (regex_iter_ != regex_iter_end_)
|
||||
{
|
||||
// re-declare var, otherwise we perform an assignment..!
|
||||
const typename rules::string ®ex2_ = *regex_iter_;
|
||||
|
||||
root_ = parser::parse (regex2_.c_str (),
|
||||
regex2_.c_str () + regex2_.size (), *ids_iter_,
|
||||
*unique_ids_iter_, *states_iter_, rules_.flags (),
|
||||
rules_.locale (), node_ptr_vector_, macromap_, token_map_,
|
||||
internals_._seen_BOL_assertion,
|
||||
internals_._seen_EOL_assertion);
|
||||
tree_vector_.push_back (root_);
|
||||
++regex_iter_;
|
||||
++ids_iter_;
|
||||
++unique_ids_iter_;
|
||||
++states_iter_;
|
||||
}
|
||||
|
||||
if (internals_._seen_BOL_assertion)
|
||||
{
|
||||
// Fixup BOLs
|
||||
typename detail::node::node_vector::iterator iter_ =
|
||||
tree_vector_.begin ();
|
||||
typename detail::node::node_vector::iterator end_ =
|
||||
tree_vector_.end ();
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
fixup_bol (*iter_, node_ptr_vector_);
|
||||
}
|
||||
}
|
||||
|
||||
// join trees
|
||||
{
|
||||
typename detail::node::node_vector::iterator iter_ =
|
||||
tree_vector_.begin ();
|
||||
typename detail::node::node_vector::iterator end_ =
|
||||
tree_vector_.end ();
|
||||
|
||||
if (iter_ != end_)
|
||||
{
|
||||
root_ = *iter_;
|
||||
++iter_;
|
||||
}
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
node_ptr_vector_->push_back (static_cast<detail::selection_node *>(0));
|
||||
node_ptr_vector_->back () = new detail::selection_node
|
||||
(root_, *iter_);
|
||||
root_ = node_ptr_vector_->back ();
|
||||
}
|
||||
}
|
||||
|
||||
// partitioned token list
|
||||
charset_list token_list_;
|
||||
|
||||
set_mapping_.resize (token_map_.size ());
|
||||
partition_tokens (token_map_, token_list_);
|
||||
|
||||
typename charset_list::list::const_iterator iter_ =
|
||||
token_list_->begin ();
|
||||
typename charset_list::list::const_iterator end_ =
|
||||
token_list_->end ();
|
||||
std::size_t index_ = 0;
|
||||
|
||||
for (; iter_ != end_; ++iter_, ++index_)
|
||||
{
|
||||
const charset *cs_ = *iter_;
|
||||
typename charset::index_set::const_iterator set_iter_ =
|
||||
cs_->_index_set.begin ();
|
||||
typename charset::index_set::const_iterator set_end_ =
|
||||
cs_->_index_set.end ();
|
||||
|
||||
fill_lookup (cs_->_token, lookup_, index_);
|
||||
|
||||
for (; set_iter_ != set_end_; ++set_iter_)
|
||||
{
|
||||
set_mapping_[*set_iter_].insert (index_);
|
||||
}
|
||||
}
|
||||
|
||||
internals_._dfa_alphabet[state_] = token_list_->size () + dfa_offset;
|
||||
return root_;
|
||||
}
|
||||
|
||||
static void build_macros (token_map &token_map_,
|
||||
const macro_deque ¯odeque_,
|
||||
typename parser::macro_map ¯omap_, const regex_flags flags_,
|
||||
const std::locale &locale_, node_ptr_vector &node_ptr_vector_,
|
||||
bool &seen_BOL_assertion_, bool &seen_EOL_assertion_)
|
||||
{
|
||||
for (typename macro_deque::const_iterator iter_ =
|
||||
macrodeque_.begin (), end_ = macrodeque_.end ();
|
||||
iter_ != end_; ++iter_)
|
||||
{
|
||||
const typename rules::string &name_ = iter_->first;
|
||||
const typename rules::string ®ex_ = iter_->second;
|
||||
detail::node *node_ = parser::parse (regex_.c_str (),
|
||||
regex_.c_str () + regex_.size (), 0, 0, 0, flags_,
|
||||
locale_, node_ptr_vector_, macromap_, token_map_,
|
||||
seen_BOL_assertion_, seen_EOL_assertion_);
|
||||
macro_iter_pair map_iter_ = macromap_.
|
||||
insert (macro_pair (name_, static_cast<const detail::node *>
|
||||
(0)));
|
||||
|
||||
map_iter_.first->second = node_;
|
||||
}
|
||||
}
|
||||
|
||||
static void build_dfa (detail::node *root_,
|
||||
const index_set_vector &set_mapping_, const std::size_t dfa_alphabet_,
|
||||
size_t_vector &dfa_)
|
||||
{
|
||||
typename detail::node::node_vector *followpos_ =
|
||||
&root_->firstpos ();
|
||||
node_set_vector seen_sets_;
|
||||
node_vector_vector seen_vectors_;
|
||||
size_t_vector hash_vector_;
|
||||
|
||||
// 'jam' state
|
||||
dfa_.resize (dfa_alphabet_, 0);
|
||||
closure (followpos_, seen_sets_, seen_vectors_,
|
||||
hash_vector_, dfa_alphabet_, dfa_);
|
||||
|
||||
std::size_t *ptr_ = 0;
|
||||
|
||||
for (std::size_t index_ = 0; index_ < seen_vectors_->size (); ++index_)
|
||||
{
|
||||
equivset_list equiv_list_;
|
||||
|
||||
build_equiv_list (seen_vectors_[index_], set_mapping_, equiv_list_);
|
||||
|
||||
for (typename equivset_list::list::const_iterator iter_ =
|
||||
equiv_list_->begin (), end_ = equiv_list_->end ();
|
||||
iter_ != end_; ++iter_)
|
||||
{
|
||||
equivset *equivset_ = *iter_;
|
||||
const std::size_t transition_ = closure
|
||||
(&equivset_->_followpos, seen_sets_, seen_vectors_,
|
||||
hash_vector_, dfa_alphabet_, dfa_);
|
||||
|
||||
if (transition_ != npos)
|
||||
{
|
||||
ptr_ = &dfa_.front () + ((index_ + 1) * dfa_alphabet_);
|
||||
|
||||
// Prune abstemious transitions from end states.
|
||||
if (*ptr_ && !equivset_->_greedy) continue;
|
||||
|
||||
for (typename detail::equivset::index_vector::const_iterator
|
||||
equiv_iter_ = equivset_->_index_vector.begin (),
|
||||
equiv_end_ = equivset_->_index_vector.end ();
|
||||
equiv_iter_ != equiv_end_; ++equiv_iter_)
|
||||
{
|
||||
const std::size_t equiv_index_ = *equiv_iter_;
|
||||
|
||||
if (equiv_index_ == bol_token)
|
||||
{
|
||||
if (ptr_[eol_index] == 0)
|
||||
{
|
||||
ptr_[bol_index] = transition_;
|
||||
}
|
||||
}
|
||||
else if (equiv_index_ == eol_token)
|
||||
{
|
||||
if (ptr_[bol_index] == 0)
|
||||
{
|
||||
ptr_[eol_index] = transition_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_[equiv_index_ + dfa_offset] = transition_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::size_t closure (typename detail::node::node_vector *followpos_,
|
||||
node_set_vector &seen_sets_, node_vector_vector &seen_vectors_,
|
||||
size_t_vector &hash_vector_, const std::size_t size_,
|
||||
size_t_vector &dfa_)
|
||||
{
|
||||
bool end_state_ = false;
|
||||
std::size_t id_ = 0;
|
||||
std::size_t unique_id_ = npos;
|
||||
std::size_t state_ = 0;
|
||||
std::size_t hash_ = 0;
|
||||
|
||||
if (followpos_->empty ()) return npos;
|
||||
|
||||
std::size_t index_ = 0;
|
||||
std::auto_ptr<node_set> set_ptr_ (new node_set);
|
||||
std::auto_ptr<node_vector> vector_ptr_ (new node_vector);
|
||||
|
||||
for (typename detail::node::node_vector::const_iterator iter_ =
|
||||
followpos_->begin (), end_ = followpos_->end ();
|
||||
iter_ != end_; ++iter_)
|
||||
{
|
||||
closure_ex (*iter_, end_state_, id_, unique_id_, state_,
|
||||
set_ptr_.get (), vector_ptr_.get (), hash_);
|
||||
}
|
||||
|
||||
bool found_ = false;
|
||||
typename size_t_vector::const_iterator hash_iter_ =
|
||||
hash_vector_.begin ();
|
||||
typename size_t_vector::const_iterator hash_end_ =
|
||||
hash_vector_.end ();
|
||||
typename node_set_vector::vector::const_iterator set_iter_ =
|
||||
seen_sets_->begin ();
|
||||
|
||||
for (; hash_iter_ != hash_end_; ++hash_iter_, ++set_iter_)
|
||||
{
|
||||
found_ = *hash_iter_ == hash_ && *(*set_iter_) == *set_ptr_;
|
||||
++index_;
|
||||
|
||||
if (found_) break;
|
||||
}
|
||||
|
||||
if (!found_)
|
||||
{
|
||||
seen_sets_->push_back (static_cast<node_set *>(0));
|
||||
seen_sets_->back () = set_ptr_.release ();
|
||||
seen_vectors_->push_back (static_cast<node_vector *>(0));
|
||||
seen_vectors_->back () = vector_ptr_.release ();
|
||||
hash_vector_.push_back (hash_);
|
||||
// State 0 is the jam state...
|
||||
index_ = seen_sets_->size ();
|
||||
|
||||
const std::size_t old_size_ = dfa_.size ();
|
||||
|
||||
dfa_.resize (old_size_ + size_, 0);
|
||||
|
||||
if (end_state_)
|
||||
{
|
||||
dfa_[old_size_] |= end_state;
|
||||
dfa_[old_size_ + id_index] = id_;
|
||||
dfa_[old_size_ + unique_id_index] = unique_id_;
|
||||
dfa_[old_size_ + state_index] = state_;
|
||||
}
|
||||
}
|
||||
|
||||
return index_;
|
||||
}
|
||||
|
||||
static void closure_ex (detail::node *node_, bool &end_state_,
|
||||
std::size_t &id_, std::size_t &unique_id_, std::size_t &state_,
|
||||
node_set *set_ptr_, node_vector *vector_ptr_, std::size_t &hash_)
|
||||
{
|
||||
const bool temp_end_state_ = node_->end_state ();
|
||||
|
||||
if (temp_end_state_)
|
||||
{
|
||||
if (!end_state_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = node_->id ();
|
||||
unique_id_ = node_->unique_id ();
|
||||
state_ = node_->lexer_state ();
|
||||
}
|
||||
}
|
||||
|
||||
if (set_ptr_->insert (node_).second)
|
||||
{
|
||||
vector_ptr_->push_back (node_);
|
||||
hash_ += reinterpret_cast<std::size_t> (node_);
|
||||
}
|
||||
}
|
||||
|
||||
static void partition_tokens (const token_map &map_,
|
||||
charset_list &lhs_)
|
||||
{
|
||||
charset_list rhs_;
|
||||
|
||||
fill_rhs_list (map_, rhs_);
|
||||
|
||||
if (!rhs_->empty ())
|
||||
{
|
||||
typename charset_list::list::iterator iter_;
|
||||
typename charset_list::list::iterator end_;
|
||||
charset_ptr overlap_ (new charset);
|
||||
|
||||
lhs_->push_back (static_cast<charset *>(0));
|
||||
lhs_->back () = rhs_->front ();
|
||||
rhs_->pop_front ();
|
||||
|
||||
while (!rhs_->empty ())
|
||||
{
|
||||
charset_ptr r_ (rhs_->front ());
|
||||
|
||||
rhs_->pop_front ();
|
||||
iter_ = lhs_->begin ();
|
||||
end_ = lhs_->end ();
|
||||
|
||||
while (!r_->empty () && iter_ != end_)
|
||||
{
|
||||
typename charset_list::list::iterator l_iter_ = iter_;
|
||||
|
||||
(*l_iter_)->intersect (*r_.get (), *overlap_.get ());
|
||||
|
||||
if (overlap_->empty ())
|
||||
{
|
||||
++iter_;
|
||||
}
|
||||
else if ((*l_iter_)->empty ())
|
||||
{
|
||||
delete *l_iter_;
|
||||
*l_iter_ = overlap_.release ();
|
||||
|
||||
// VC++ 6 Hack:
|
||||
charset_ptr temp_overlap_ (new charset);
|
||||
|
||||
overlap_ = temp_overlap_;
|
||||
++iter_;
|
||||
}
|
||||
else if (r_->empty ())
|
||||
{
|
||||
delete r_.release ();
|
||||
r_ = overlap_;
|
||||
|
||||
// VC++ 6 Hack:
|
||||
charset_ptr temp_overlap_ (new charset);
|
||||
|
||||
overlap_ = temp_overlap_;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter_ = lhs_->insert (++iter_,
|
||||
static_cast<charset *>(0));
|
||||
*iter_ = overlap_.release ();
|
||||
|
||||
// VC++ 6 Hack:
|
||||
charset_ptr temp_overlap_ (new charset);
|
||||
|
||||
overlap_ = temp_overlap_;
|
||||
++iter_;
|
||||
end_ = lhs_->end ();
|
||||
}
|
||||
}
|
||||
|
||||
if (!r_->empty ())
|
||||
{
|
||||
lhs_->push_back (static_cast<charset *>(0));
|
||||
lhs_->back () = r_.release ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_rhs_list (const token_map &map_,
|
||||
charset_list &list_)
|
||||
{
|
||||
typename parser::tokeniser::token_map::const_iterator iter_ =
|
||||
map_.begin ();
|
||||
typename parser::tokeniser::token_map::const_iterator end_ =
|
||||
map_.end ();
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
list_->push_back (static_cast<charset *>(0));
|
||||
list_->back () = new charset (iter_->first, iter_->second);
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_lookup (const string_token &token_,
|
||||
size_t_vector *lookup_, const std::size_t index_)
|
||||
{
|
||||
const CharT *curr_ = token_._charset.c_str ();
|
||||
const CharT *chars_end_ = curr_ + token_._charset.size ();
|
||||
std::size_t *ptr_ = &lookup_->front ();
|
||||
const std::size_t max_ = sizeof (CharT) == 1 ?
|
||||
num_chars : num_wchar_ts;
|
||||
|
||||
if (token_._negated)
|
||||
{
|
||||
// $$$ FIXME JDG July 2014 $$$
|
||||
// this code is problematic on platforms where wchar_t is signed
|
||||
// with min generating negative numbers. This crashes with BAD_ACCESS
|
||||
// because of the vector index below:
|
||||
// ptr_[static_cast<typename Traits::index_type>(curr_char_)]
|
||||
CharT curr_char_ = 0; // (std::numeric_limits<CharT>::min)();
|
||||
std::size_t i_ = 0;
|
||||
|
||||
while (curr_ < chars_end_)
|
||||
{
|
||||
while (*curr_ > curr_char_)
|
||||
{
|
||||
ptr_[static_cast<typename Traits::index_type>
|
||||
(curr_char_)] = index_ + dfa_offset;
|
||||
++curr_char_;
|
||||
++i_;
|
||||
}
|
||||
|
||||
++curr_char_;
|
||||
++curr_;
|
||||
++i_;
|
||||
}
|
||||
|
||||
for (; i_ < max_; ++i_)
|
||||
{
|
||||
ptr_[static_cast<typename Traits::index_type>(curr_char_)] =
|
||||
index_ + dfa_offset;
|
||||
++curr_char_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (curr_ < chars_end_)
|
||||
{
|
||||
ptr_[static_cast<typename Traits::index_type>(*curr_)] =
|
||||
index_ + dfa_offset;
|
||||
++curr_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void build_equiv_list (const node_vector *vector_,
|
||||
const index_set_vector &set_mapping_, equivset_list &lhs_)
|
||||
{
|
||||
equivset_list rhs_;
|
||||
|
||||
fill_rhs_list (vector_, set_mapping_, rhs_);
|
||||
|
||||
if (!rhs_->empty ())
|
||||
{
|
||||
typename equivset_list::list::iterator iter_;
|
||||
typename equivset_list::list::iterator end_;
|
||||
equivset_ptr overlap_ (new equivset);
|
||||
|
||||
lhs_->push_back (static_cast<equivset *>(0));
|
||||
lhs_->back () = rhs_->front ();
|
||||
rhs_->pop_front ();
|
||||
|
||||
while (!rhs_->empty ())
|
||||
{
|
||||
equivset_ptr r_ (rhs_->front ());
|
||||
|
||||
rhs_->pop_front ();
|
||||
iter_ = lhs_->begin ();
|
||||
end_ = lhs_->end ();
|
||||
|
||||
while (!r_->empty () && iter_ != end_)
|
||||
{
|
||||
typename equivset_list::list::iterator l_iter_ = iter_;
|
||||
|
||||
(*l_iter_)->intersect (*r_.get (), *overlap_.get ());
|
||||
|
||||
if (overlap_->empty ())
|
||||
{
|
||||
++iter_;
|
||||
}
|
||||
else if ((*l_iter_)->empty ())
|
||||
{
|
||||
delete *l_iter_;
|
||||
*l_iter_ = overlap_.release ();
|
||||
|
||||
// VC++ 6 Hack:
|
||||
equivset_ptr temp_overlap_ (new equivset);
|
||||
|
||||
overlap_ = temp_overlap_;
|
||||
++iter_;
|
||||
}
|
||||
else if (r_->empty ())
|
||||
{
|
||||
delete r_.release ();
|
||||
r_ = overlap_;
|
||||
|
||||
// VC++ 6 Hack:
|
||||
equivset_ptr temp_overlap_ (new equivset);
|
||||
|
||||
overlap_ = temp_overlap_;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter_ = lhs_->insert (++iter_,
|
||||
static_cast<equivset *>(0));
|
||||
*iter_ = overlap_.release ();
|
||||
|
||||
// VC++ 6 Hack:
|
||||
equivset_ptr temp_overlap_ (new equivset);
|
||||
|
||||
overlap_ = temp_overlap_;
|
||||
++iter_;
|
||||
end_ = lhs_->end ();
|
||||
}
|
||||
}
|
||||
|
||||
if (!r_->empty ())
|
||||
{
|
||||
lhs_->push_back (static_cast<equivset *>(0));
|
||||
lhs_->back () = r_.release ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_rhs_list (const node_vector *vector_,
|
||||
const index_set_vector &set_mapping_, equivset_list &list_)
|
||||
{
|
||||
typename node_vector::const_iterator iter_ =
|
||||
vector_->begin ();
|
||||
typename node_vector::const_iterator end_ =
|
||||
vector_->end ();
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
const detail::node *node_ = *iter_;
|
||||
|
||||
if (!node_->end_state ())
|
||||
{
|
||||
const std::size_t token_ = node_->token ();
|
||||
|
||||
if (token_ != null_token)
|
||||
{
|
||||
list_->push_back (static_cast<equivset *>(0));
|
||||
|
||||
if (token_ == bol_token || token_ == eol_token)
|
||||
{
|
||||
std::set<std::size_t> index_set_;
|
||||
|
||||
index_set_.insert (token_);
|
||||
list_->back () = new equivset (index_set_,
|
||||
node_->greedy (), token_, node_->followpos ());
|
||||
}
|
||||
else
|
||||
{
|
||||
list_->back () = new equivset (set_mapping_[token_],
|
||||
node_->greedy (), token_, node_->followpos ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void fixup_bol (detail::node * &root_,
|
||||
node_ptr_vector &node_ptr_vector_)
|
||||
{
|
||||
typename detail::node::node_vector *first_ = &root_->firstpos ();
|
||||
bool found_ = false;
|
||||
typename detail::node::node_vector::const_iterator iter_ =
|
||||
first_->begin ();
|
||||
typename detail::node::node_vector::const_iterator end_ =
|
||||
first_->end ();
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
const detail::node *node_ = *iter_;
|
||||
|
||||
found_ = !node_->end_state () && node_->token () == bol_token;
|
||||
|
||||
if (found_) break;
|
||||
}
|
||||
|
||||
if (!found_)
|
||||
{
|
||||
node_ptr_vector_->push_back (static_cast<detail::leaf_node *>(0));
|
||||
node_ptr_vector_->back () = new detail::leaf_node
|
||||
(bol_token, true);
|
||||
|
||||
detail::node *lhs_ = node_ptr_vector_->back ();
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<detail::leaf_node *>(0));
|
||||
node_ptr_vector_->back () = new detail::leaf_node
|
||||
(null_token, true);
|
||||
|
||||
detail::node *rhs_ = node_ptr_vector_->back ();
|
||||
|
||||
node_ptr_vector_->push_back
|
||||
(static_cast<detail::selection_node *>(0));
|
||||
node_ptr_vector_->back () =
|
||||
new detail::selection_node (lhs_, rhs_);
|
||||
lhs_ = node_ptr_vector_->back ();
|
||||
|
||||
node_ptr_vector_->push_back
|
||||
(static_cast<detail::sequence_node *>(0));
|
||||
node_ptr_vector_->back () =
|
||||
new detail::sequence_node (lhs_, root_);
|
||||
root_ = node_ptr_vector_->back ();
|
||||
}
|
||||
}
|
||||
|
||||
static void minimise_dfa (const std::size_t dfa_alphabet_,
|
||||
size_t_vector &dfa_, std::size_t size_)
|
||||
{
|
||||
const std::size_t *first_ = &dfa_.front ();
|
||||
const std::size_t *second_ = 0;
|
||||
const std::size_t *end_ = first_ + size_;
|
||||
std::size_t index_ = 1;
|
||||
std::size_t new_index_ = 1;
|
||||
std::size_t curr_index_ = 0;
|
||||
index_set index_set_;
|
||||
size_t_vector lookup_;
|
||||
std::size_t *lookup_ptr_ = 0;
|
||||
|
||||
lookup_.resize (size_ / dfa_alphabet_, null_token);
|
||||
lookup_ptr_ = &lookup_.front ();
|
||||
*lookup_ptr_ = 0;
|
||||
// Only one 'jam' state, so skip it.
|
||||
first_ += dfa_alphabet_;
|
||||
|
||||
for (; first_ < end_; first_ += dfa_alphabet_, ++index_)
|
||||
{
|
||||
for (second_ = first_ + dfa_alphabet_, curr_index_ = index_ + 1;
|
||||
second_ < end_; second_ += dfa_alphabet_, ++curr_index_)
|
||||
{
|
||||
if (index_set_.find (curr_index_) != index_set_.end ())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Some systems have memcmp in namespace std.
|
||||
using namespace std;
|
||||
|
||||
if (memcmp (first_, second_, sizeof (std::size_t) *
|
||||
dfa_alphabet_) == 0)
|
||||
{
|
||||
index_set_.insert (curr_index_);
|
||||
lookup_ptr_[curr_index_] = new_index_;
|
||||
}
|
||||
}
|
||||
|
||||
if (lookup_ptr_[index_] == null_token)
|
||||
{
|
||||
lookup_ptr_[index_] = new_index_;
|
||||
++new_index_;
|
||||
}
|
||||
}
|
||||
|
||||
if (!index_set_.empty ())
|
||||
{
|
||||
const std::size_t *front_ = &dfa_.front ();
|
||||
size_t_vector new_dfa_ (front_, front_ + dfa_alphabet_);
|
||||
typename index_set::iterator set_end_ =
|
||||
index_set_.end ();
|
||||
const std::size_t *ptr_ = front_ + dfa_alphabet_;
|
||||
std::size_t *new_ptr_ = 0;
|
||||
|
||||
new_dfa_.resize (size_ - index_set_.size () * dfa_alphabet_, 0);
|
||||
new_ptr_ = &new_dfa_.front () + dfa_alphabet_;
|
||||
size_ /= dfa_alphabet_;
|
||||
|
||||
for (index_ = 1; index_ < size_; ++index_)
|
||||
{
|
||||
if (index_set_.find (index_) != set_end_)
|
||||
{
|
||||
ptr_ += dfa_alphabet_;
|
||||
continue;
|
||||
}
|
||||
|
||||
new_ptr_[end_state_index] = ptr_[end_state_index];
|
||||
new_ptr_[id_index] = ptr_[id_index];
|
||||
new_ptr_[unique_id_index] = ptr_[unique_id_index];
|
||||
new_ptr_[state_index] = ptr_[state_index];
|
||||
new_ptr_[bol_index] = lookup_ptr_[ptr_[bol_index]];
|
||||
new_ptr_[eol_index] = lookup_ptr_[ptr_[eol_index]];
|
||||
new_ptr_ += dfa_offset;
|
||||
ptr_ += dfa_offset;
|
||||
|
||||
for (std::size_t i_ = dfa_offset; i_ < dfa_alphabet_; ++i_)
|
||||
{
|
||||
*new_ptr_++ = lookup_ptr_[*ptr_++];
|
||||
}
|
||||
}
|
||||
|
||||
dfa_.swap (new_dfa_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_generator<char> generator;
|
||||
typedef basic_generator<wchar_t> wgenerator;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,529 @@
|
||||
// input.hpp
|
||||
// Copyright (c) 2008-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_INPUT
|
||||
#define BOOST_LEXER_INPUT
|
||||
|
||||
#include "char_traits.hpp"
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include "size_t.hpp"
|
||||
#include "state_machine.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
template<typename FwdIter, typename Traits =
|
||||
char_traits<typename boost::detail::iterator_traits<FwdIter>::value_type> >
|
||||
class basic_input
|
||||
{
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
friend class basic_input;
|
||||
|
||||
struct data
|
||||
{
|
||||
std::size_t id;
|
||||
std::size_t unique_id;
|
||||
FwdIter start;
|
||||
FwdIter end;
|
||||
bool bol;
|
||||
std::size_t state;
|
||||
|
||||
// Construct in end() state.
|
||||
data () :
|
||||
id (0),
|
||||
unique_id (npos),
|
||||
bol (false),
|
||||
state (npos)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const data &rhs_) const
|
||||
{
|
||||
return id == rhs_.id && unique_id == rhs_.unique_id &&
|
||||
start == rhs_.start && end == rhs_.end &&
|
||||
bol == rhs_.bol && state == rhs_.state;
|
||||
}
|
||||
};
|
||||
|
||||
iterator () :
|
||||
_input (0)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const iterator &rhs_) const
|
||||
{
|
||||
return _data == rhs_._data;
|
||||
}
|
||||
|
||||
bool operator != (const iterator &rhs_) const
|
||||
{
|
||||
return !(*this == rhs_);
|
||||
}
|
||||
|
||||
data &operator * ()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
data *operator -> ()
|
||||
{
|
||||
return &_data;
|
||||
}
|
||||
|
||||
// Let compiler generate operator = ().
|
||||
|
||||
// prefix version
|
||||
iterator &operator ++ ()
|
||||
{
|
||||
next_token ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// postfix version
|
||||
iterator operator ++ (int)
|
||||
{
|
||||
iterator iter_ = *this;
|
||||
|
||||
next_token ();
|
||||
return iter_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Not owner (obviously!)
|
||||
const basic_input *_input;
|
||||
data _data;
|
||||
|
||||
void next_token ()
|
||||
{
|
||||
const detail::internals &internals_ =
|
||||
_input->_state_machine->data ();
|
||||
|
||||
_data.start = _data.end;
|
||||
|
||||
if (internals_._dfa->size () == 1)
|
||||
{
|
||||
if (internals_._seen_BOL_assertion ||
|
||||
internals_._seen_EOL_assertion)
|
||||
{
|
||||
_data.id = next
|
||||
(&internals_._lookup->front ()->front (),
|
||||
internals_._dfa_alphabet.front (),
|
||||
&internals_._dfa->front ()->front (),
|
||||
_data.bol, _data.end, _input->_end, _data.unique_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data.id = next (&internals_._lookup->front ()->front (),
|
||||
internals_._dfa_alphabet.front (), &internals_.
|
||||
_dfa->front ()->front (), _data.end, _input->_end,
|
||||
_data.unique_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (internals_._seen_BOL_assertion ||
|
||||
internals_._seen_EOL_assertion)
|
||||
{
|
||||
_data.id = next (internals_, _data.state,
|
||||
_data.bol, _data.end, _input->_end, _data.unique_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data.id = next (internals_, _data.state,
|
||||
_data.end, _input->_end, _data.unique_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (_data.end == _input->_end && _data.start == _data.end)
|
||||
{
|
||||
// Ensure current state matches that returned by end().
|
||||
_data.state = npos;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t next (const detail::internals &internals_,
|
||||
std::size_t &start_state_, bool bol_,
|
||||
FwdIter &start_token_, const FwdIter &end_,
|
||||
std::size_t &unique_id_)
|
||||
{
|
||||
if (start_token_ == end_)
|
||||
{
|
||||
unique_id_ = npos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
again:
|
||||
const std::size_t * lookup_ = &internals_._lookup[start_state_]->
|
||||
front ();
|
||||
std::size_t dfa_alphabet_ = internals_._dfa_alphabet[start_state_];
|
||||
const std::size_t *dfa_ = &internals_._dfa[start_state_]->front ();
|
||||
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
|
||||
FwdIter curr_ = start_token_;
|
||||
bool end_state_ = *ptr_ != 0;
|
||||
std::size_t id_ = *(ptr_ + id_index);
|
||||
std::size_t uid_ = *(ptr_ + unique_id_index);
|
||||
std::size_t end_start_state_ = start_state_;
|
||||
bool end_bol_ = bol_;
|
||||
FwdIter end_token_ = start_token_;
|
||||
|
||||
while (curr_ != end_)
|
||||
{
|
||||
const std::size_t BOL_state_ = ptr_[bol_index];
|
||||
const std::size_t EOL_state_ = ptr_[eol_index];
|
||||
|
||||
if (BOL_state_ && bol_)
|
||||
{
|
||||
ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
|
||||
}
|
||||
else if (EOL_state_ && *curr_ == '\n')
|
||||
{
|
||||
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
|
||||
}
|
||||
else
|
||||
{
|
||||
typename Traits::char_type prev_char_ = *curr_++;
|
||||
|
||||
bol_ = prev_char_ == '\n';
|
||||
|
||||
const std::size_t state_ =
|
||||
ptr_[lookup_[static_cast<typename Traits::index_type>
|
||||
(prev_char_)]];
|
||||
|
||||
if (state_ == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ptr_ = &dfa_[state_ * dfa_alphabet_];
|
||||
}
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
end_start_state_ = *(ptr_ + state_index);
|
||||
end_bol_ = bol_;
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
const std::size_t EOL_state_ = ptr_[eol_index];
|
||||
|
||||
if (EOL_state_ && curr_ == end_)
|
||||
{
|
||||
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
end_start_state_ = *(ptr_ + state_index);
|
||||
end_bol_ = bol_;
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
if (end_state_)
|
||||
{
|
||||
// return longest match
|
||||
start_state_ = end_start_state_;
|
||||
start_token_ = end_token_;
|
||||
|
||||
if (id_ == 0)
|
||||
{
|
||||
bol_ = end_bol_;
|
||||
goto again;
|
||||
}
|
||||
else
|
||||
{
|
||||
_data.bol = end_bol_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match causes char to be skipped
|
||||
_data.bol = *start_token_ == '\n';
|
||||
++start_token_;
|
||||
id_ = npos;
|
||||
uid_ = npos;
|
||||
}
|
||||
|
||||
unique_id_ = uid_;
|
||||
return id_;
|
||||
}
|
||||
|
||||
std::size_t next (const detail::internals &internals_,
|
||||
std::size_t &start_state_, FwdIter &start_token_,
|
||||
FwdIter const &end_, std::size_t &unique_id_)
|
||||
{
|
||||
if (start_token_ == end_)
|
||||
{
|
||||
unique_id_ = npos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
again:
|
||||
const std::size_t * lookup_ = &internals_._lookup[start_state_]->
|
||||
front ();
|
||||
std::size_t dfa_alphabet_ = internals_._dfa_alphabet[start_state_];
|
||||
const std::size_t *dfa_ = &internals_._dfa[start_state_]->front ();
|
||||
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
|
||||
FwdIter curr_ = start_token_;
|
||||
bool end_state_ = *ptr_ != 0;
|
||||
std::size_t id_ = *(ptr_ + id_index);
|
||||
std::size_t uid_ = *(ptr_ + unique_id_index);
|
||||
std::size_t end_start_state_ = start_state_;
|
||||
FwdIter end_token_ = start_token_;
|
||||
|
||||
while (curr_ != end_)
|
||||
{
|
||||
const std::size_t state_ = ptr_[lookup_[static_cast
|
||||
<typename Traits::index_type>(*curr_++)]];
|
||||
|
||||
if (state_ == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ptr_ = &dfa_[state_ * dfa_alphabet_];
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
end_start_state_ = *(ptr_ + state_index);
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
if (end_state_)
|
||||
{
|
||||
// return longest match
|
||||
start_state_ = end_start_state_;
|
||||
start_token_ = end_token_;
|
||||
|
||||
if (id_ == 0) goto again;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match causes char to be skipped
|
||||
++start_token_;
|
||||
id_ = npos;
|
||||
uid_ = npos;
|
||||
}
|
||||
|
||||
unique_id_ = uid_;
|
||||
return id_;
|
||||
}
|
||||
|
||||
std::size_t next (const std::size_t * const lookup_,
|
||||
const std::size_t dfa_alphabet_, const std::size_t * const dfa_,
|
||||
bool bol_, FwdIter &start_token_, FwdIter const &end_,
|
||||
std::size_t &unique_id_)
|
||||
{
|
||||
if (start_token_ == end_)
|
||||
{
|
||||
unique_id_ = npos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
|
||||
FwdIter curr_ = start_token_;
|
||||
bool end_state_ = *ptr_ != 0;
|
||||
std::size_t id_ = *(ptr_ + id_index);
|
||||
std::size_t uid_ = *(ptr_ + unique_id_index);
|
||||
bool end_bol_ = bol_;
|
||||
FwdIter end_token_ = start_token_;
|
||||
|
||||
while (curr_ != end_)
|
||||
{
|
||||
const std::size_t BOL_state_ = ptr_[bol_index];
|
||||
const std::size_t EOL_state_ = ptr_[eol_index];
|
||||
|
||||
if (BOL_state_ && bol_)
|
||||
{
|
||||
ptr_ = &dfa_[BOL_state_ * dfa_alphabet_];
|
||||
}
|
||||
else if (EOL_state_ && *curr_ == '\n')
|
||||
{
|
||||
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
|
||||
}
|
||||
else
|
||||
{
|
||||
typename Traits::char_type prev_char_ = *curr_++;
|
||||
|
||||
bol_ = prev_char_ == '\n';
|
||||
|
||||
const std::size_t state_ =
|
||||
ptr_[lookup_[static_cast<typename Traits::index_type>
|
||||
(prev_char_)]];
|
||||
|
||||
if (state_ == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ptr_ = &dfa_[state_ * dfa_alphabet_];
|
||||
}
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
end_bol_ = bol_;
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
const std::size_t EOL_state_ = ptr_[eol_index];
|
||||
|
||||
if (EOL_state_ && curr_ == end_)
|
||||
{
|
||||
ptr_ = &dfa_[EOL_state_ * dfa_alphabet_];
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
end_bol_ = bol_;
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
if (end_state_)
|
||||
{
|
||||
// return longest match
|
||||
_data.bol = end_bol_;
|
||||
start_token_ = end_token_;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match causes char to be skipped
|
||||
_data.bol = *start_token_ == '\n';
|
||||
++start_token_;
|
||||
id_ = npos;
|
||||
uid_ = npos;
|
||||
}
|
||||
|
||||
unique_id_ = uid_;
|
||||
return id_;
|
||||
}
|
||||
|
||||
std::size_t next (const std::size_t * const lookup_,
|
||||
const std::size_t dfa_alphabet_, const std::size_t * const dfa_,
|
||||
FwdIter &start_token_, FwdIter const &end_,
|
||||
std::size_t &unique_id_)
|
||||
{
|
||||
if (start_token_ == end_)
|
||||
{
|
||||
unique_id_ = npos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const std::size_t *ptr_ = dfa_ + dfa_alphabet_;
|
||||
FwdIter curr_ = start_token_;
|
||||
bool end_state_ = *ptr_ != 0;
|
||||
std::size_t id_ = *(ptr_ + id_index);
|
||||
std::size_t uid_ = *(ptr_ + unique_id_index);
|
||||
FwdIter end_token_ = start_token_;
|
||||
|
||||
while (curr_ != end_)
|
||||
{
|
||||
const std::size_t state_ = ptr_[lookup_[static_cast
|
||||
<typename Traits::index_type>(*curr_++)]];
|
||||
|
||||
if (state_ == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ptr_ = &dfa_[state_ * dfa_alphabet_];
|
||||
|
||||
if (*ptr_)
|
||||
{
|
||||
end_state_ = true;
|
||||
id_ = *(ptr_ + id_index);
|
||||
uid_ = *(ptr_ + unique_id_index);
|
||||
end_token_ = curr_;
|
||||
}
|
||||
}
|
||||
|
||||
if (end_state_)
|
||||
{
|
||||
// return longest match
|
||||
start_token_ = end_token_;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No match causes char to be skipped
|
||||
++start_token_;
|
||||
id_ = npos;
|
||||
uid_ = npos;
|
||||
}
|
||||
|
||||
unique_id_ = uid_;
|
||||
return id_;
|
||||
}
|
||||
};
|
||||
|
||||
friend class iterator;
|
||||
|
||||
// Make it explict that we are NOT taking a copy of state_machine_!
|
||||
basic_input (const basic_state_machine<typename Traits::char_type>
|
||||
*state_machine_, const FwdIter &begin_, const FwdIter &end_) :
|
||||
_state_machine (state_machine_),
|
||||
_begin (begin_),
|
||||
_end (end_)
|
||||
{
|
||||
}
|
||||
|
||||
iterator begin () const
|
||||
{
|
||||
iterator iter_;
|
||||
|
||||
iter_._input = this;
|
||||
// Over-ride default of 0 (EOI)
|
||||
iter_._data.id = npos;
|
||||
iter_._data.start = _begin;
|
||||
iter_._data.end = _begin;
|
||||
iter_._data.bol = _state_machine->data ()._seen_BOL_assertion;
|
||||
iter_._data.state = 0;
|
||||
++iter_;
|
||||
return iter_;
|
||||
}
|
||||
|
||||
iterator end () const
|
||||
{
|
||||
iterator iter_;
|
||||
|
||||
iter_._input = this;
|
||||
iter_._data.start = _end;
|
||||
iter_._data.end = _end;
|
||||
return iter_;
|
||||
}
|
||||
|
||||
private:
|
||||
const basic_state_machine<typename Traits::char_type> *_state_machine;
|
||||
FwdIter _begin;
|
||||
FwdIter _end;
|
||||
};
|
||||
|
||||
typedef basic_input<std::string::iterator> iter_input;
|
||||
typedef basic_input<std::basic_string<wchar_t>::iterator> iter_winput;
|
||||
typedef basic_input<const char *> ptr_input;
|
||||
typedef basic_input<const wchar_t *> ptr_winput;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
// internals.hpp
|
||||
// Copyright (c) 2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_INTERNALS_HPP
|
||||
#define BOOST_LEXER_INTERNALS_HPP
|
||||
|
||||
#include "containers/ptr_vector.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct internals
|
||||
{
|
||||
typedef std::vector<std::size_t> size_t_vector;
|
||||
typedef ptr_vector<size_t_vector> size_t_vector_vector;
|
||||
|
||||
size_t_vector_vector _lookup;
|
||||
size_t_vector _dfa_alphabet;
|
||||
size_t_vector_vector _dfa;
|
||||
bool _seen_BOL_assertion;
|
||||
bool _seen_EOL_assertion;
|
||||
|
||||
internals () :
|
||||
_seen_BOL_assertion (false),
|
||||
_seen_EOL_assertion (false)
|
||||
{
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
_lookup.clear ();
|
||||
_dfa_alphabet.clear ();
|
||||
_dfa.clear ();
|
||||
_seen_BOL_assertion = false;
|
||||
_seen_EOL_assertion = false;
|
||||
}
|
||||
|
||||
void swap (internals &internals_)
|
||||
{
|
||||
_lookup->swap (*internals_._lookup);
|
||||
_dfa_alphabet.swap (internals_._dfa_alphabet);
|
||||
_dfa->swap (*internals_._dfa);
|
||||
std::swap (_seen_BOL_assertion, internals_._seen_BOL_assertion);
|
||||
std::swap (_seen_EOL_assertion, internals_._seen_EOL_assertion);
|
||||
}
|
||||
|
||||
private:
|
||||
internals (const internals &); // No copy construction.
|
||||
internals &operator = (const internals &); // No assignment.
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+511
@@ -0,0 +1,511 @@
|
||||
// parser.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_PARSER_HPP
|
||||
#define BOOST_LEXER_PARSER_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include "tree/end_node.hpp"
|
||||
#include "tree/iteration_node.hpp"
|
||||
#include "tree/leaf_node.hpp"
|
||||
#include "../runtime_error.hpp"
|
||||
#include "tree/selection_node.hpp"
|
||||
#include "tree/sequence_node.hpp"
|
||||
#include "../size_t.hpp"
|
||||
#include "tokeniser/re_tokeniser.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CharT>
|
||||
class basic_parser
|
||||
{
|
||||
public:
|
||||
typedef basic_re_tokeniser<CharT> tokeniser;
|
||||
typedef typename tokeniser::string string;
|
||||
typedef std::map<string, const node *> macro_map;
|
||||
typedef node::node_ptr_vector node_ptr_vector;
|
||||
typedef typename tokeniser::num_token token;
|
||||
|
||||
/*
|
||||
General principles of regex parsing:
|
||||
- Every regex is a sequence of sub-regexes.
|
||||
- Regexes consist of operands and operators
|
||||
- All operators decompose to sequence, selection ('|') and iteration ('*')
|
||||
- Regex tokens are stored on the stack.
|
||||
- When a complete sequence of regex tokens is on the stack it is processed.
|
||||
|
||||
Grammar:
|
||||
|
||||
<REGEX> -> <OREXP>
|
||||
<OREXP> -> <SEQUENCE> | <OREXP>'|'<SEQUENCE>
|
||||
<SEQUENCE> -> <SUB>
|
||||
<SUB> -> <EXPRESSION> | <SUB><EXPRESSION>
|
||||
<EXPRESSION> -> <REPEAT>
|
||||
<REPEAT> -> charset | macro | '('<REGEX>')' | <REPEAT><DUPLICATE>
|
||||
<DUPLICATE> -> '?' | '*' | '+' | '{n[,[m]]}'
|
||||
*/
|
||||
static node *parse (const CharT *start_, const CharT * const end_,
|
||||
const std::size_t id_, const std::size_t unique_id_,
|
||||
const std::size_t dfa_state_, const regex_flags flags_,
|
||||
const std::locale &locale_, node_ptr_vector &node_ptr_vector_,
|
||||
const macro_map ¯omap_, typename tokeniser::token_map &map_,
|
||||
bool &seen_BOL_assertion_, bool &seen_EOL_assertion_)
|
||||
{
|
||||
node *root_ = 0;
|
||||
state state_ (start_, end_, flags_, locale_);
|
||||
token lhs_token_;
|
||||
token rhs_token_;
|
||||
token_stack token_stack_;
|
||||
tree_node_stack tree_node_stack_;
|
||||
char action_ = 0;
|
||||
|
||||
token_stack_.push (rhs_token_);
|
||||
tokeniser::next (state_, map_, rhs_token_);
|
||||
|
||||
do
|
||||
{
|
||||
lhs_token_ = token_stack_.top ();
|
||||
action_ = lhs_token_.precedence (rhs_token_._type);
|
||||
|
||||
switch (action_)
|
||||
{
|
||||
case '<':
|
||||
case '=':
|
||||
token_stack_.push (rhs_token_);
|
||||
tokeniser::next (state_, map_, rhs_token_);
|
||||
break;
|
||||
case '>':
|
||||
reduce (token_stack_, macromap_, node_ptr_vector_,
|
||||
tree_node_stack_);
|
||||
break;
|
||||
default:
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "A syntax error occurred: '" <<
|
||||
lhs_token_.precedence_string () <<
|
||||
"' against '" << rhs_token_.precedence_string () <<
|
||||
"' at index " << state_.index () << ".";
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
break;
|
||||
}
|
||||
} while (!token_stack_.empty ());
|
||||
|
||||
if (tree_node_stack_.empty ())
|
||||
{
|
||||
throw runtime_error ("Empty rules are not allowed.");
|
||||
}
|
||||
|
||||
BOOST_ASSERT(tree_node_stack_.size () == 1);
|
||||
|
||||
node *lhs_node_ = tree_node_stack_.top ();
|
||||
|
||||
tree_node_stack_.pop ();
|
||||
|
||||
if (id_ == 0)
|
||||
{
|
||||
// Macros have no end state...
|
||||
root_ = lhs_node_;
|
||||
}
|
||||
else
|
||||
{
|
||||
node_ptr_vector_->push_back (static_cast<end_node *>(0));
|
||||
|
||||
node *rhs_node_ = new end_node (id_, unique_id_, dfa_state_);
|
||||
|
||||
node_ptr_vector_->back () = rhs_node_;
|
||||
node_ptr_vector_->push_back (static_cast<sequence_node *>(0));
|
||||
node_ptr_vector_->back () = new sequence_node
|
||||
(lhs_node_, rhs_node_);
|
||||
root_ = node_ptr_vector_->back ();
|
||||
}
|
||||
|
||||
// Done this way as bug in VC++ 6 prevents |= operator working
|
||||
// properly!
|
||||
if (state_._seen_BOL_assertion) seen_BOL_assertion_ = true;
|
||||
|
||||
if (state_._seen_EOL_assertion) seen_EOL_assertion_ = true;
|
||||
|
||||
return root_;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef typename tokeniser::state state;
|
||||
typedef std::stack<token> token_stack;
|
||||
typedef node::node_stack tree_node_stack;
|
||||
|
||||
static void reduce (token_stack &token_stack_,
|
||||
const macro_map ¯omap_, node_ptr_vector &node_vector_ptr_,
|
||||
tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
typename tokeniser::num_token lhs_;
|
||||
typename tokeniser::num_token rhs_;
|
||||
token_stack handle_;
|
||||
char action_ = 0;
|
||||
|
||||
do
|
||||
{
|
||||
rhs_ = token_stack_.top ();
|
||||
token_stack_.pop ();
|
||||
handle_.push (rhs_);
|
||||
|
||||
if (!token_stack_.empty ())
|
||||
{
|
||||
lhs_ = token_stack_.top ();
|
||||
action_ = lhs_.precedence (rhs_._type);
|
||||
}
|
||||
} while (!token_stack_.empty () && action_ == '=');
|
||||
|
||||
BOOST_ASSERT(token_stack_.empty () || action_ == '<');
|
||||
|
||||
switch (rhs_._type)
|
||||
{
|
||||
case token::BEGIN:
|
||||
// finished processing so exit
|
||||
break;
|
||||
case token::REGEX:
|
||||
// finished parsing, nothing to do
|
||||
break;
|
||||
case token::OREXP:
|
||||
orexp (handle_, token_stack_, node_vector_ptr_, tree_node_stack_);
|
||||
break;
|
||||
case token::SEQUENCE:
|
||||
token_stack_.push (token::OREXP);
|
||||
break;
|
||||
case token::SUB:
|
||||
sub (handle_, token_stack_, node_vector_ptr_, tree_node_stack_);
|
||||
break;
|
||||
case token::EXPRESSION:
|
||||
token_stack_.push (token::SUB);
|
||||
break;
|
||||
case token::REPEAT:
|
||||
repeat (handle_, token_stack_);
|
||||
break;
|
||||
case token::CHARSET:
|
||||
charset (handle_, token_stack_, node_vector_ptr_,
|
||||
tree_node_stack_);
|
||||
break;
|
||||
case token::MACRO:
|
||||
macro (handle_, token_stack_, macromap_, node_vector_ptr_,
|
||||
tree_node_stack_);
|
||||
break;
|
||||
case token::OPENPAREN:
|
||||
openparen (handle_, token_stack_);
|
||||
break;
|
||||
case token::OPT:
|
||||
case token::AOPT:
|
||||
optional (rhs_._type == token::OPT, node_vector_ptr_,
|
||||
tree_node_stack_);
|
||||
token_stack_.push (token::DUP);
|
||||
break;
|
||||
case token::ZEROORMORE:
|
||||
case token::AZEROORMORE:
|
||||
zero_or_more (rhs_._type == token::ZEROORMORE, node_vector_ptr_,
|
||||
tree_node_stack_);
|
||||
token_stack_.push (token::DUP);
|
||||
break;
|
||||
case token::ONEORMORE:
|
||||
case token::AONEORMORE:
|
||||
one_or_more (rhs_._type == token::ONEORMORE, node_vector_ptr_,
|
||||
tree_node_stack_);
|
||||
token_stack_.push (token::DUP);
|
||||
break;
|
||||
case token::REPEATN:
|
||||
case token::AREPEATN:
|
||||
repeatn (rhs_._type == token::REPEATN, handle_.top (),
|
||||
node_vector_ptr_, tree_node_stack_);
|
||||
token_stack_.push (token::DUP);
|
||||
break;
|
||||
default:
|
||||
throw runtime_error
|
||||
("Internal error regex_parser::reduce");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void orexp (token_stack &handle_, token_stack &token_stack_,
|
||||
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
BOOST_ASSERT(handle_.top ()._type == token::OREXP &&
|
||||
(handle_.size () == 1 || handle_.size () == 3));
|
||||
|
||||
if (handle_.size () == 1)
|
||||
{
|
||||
token_stack_.push (token::REGEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_.pop ();
|
||||
BOOST_ASSERT(handle_.top ()._type == token::OR);
|
||||
handle_.pop ();
|
||||
BOOST_ASSERT(handle_.top ()._type == token::SEQUENCE);
|
||||
perform_or (node_ptr_vector_, tree_node_stack_);
|
||||
token_stack_.push (token::OREXP);
|
||||
}
|
||||
}
|
||||
|
||||
static void sub (token_stack &handle_, token_stack &token_stack_,
|
||||
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
BOOST_ASSERT(handle_.top ()._type == token::SUB &&
|
||||
(handle_.size () == 1 || handle_.size () == 2));
|
||||
|
||||
if (handle_.size () == 1)
|
||||
{
|
||||
token_stack_.push (token::SEQUENCE);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_.pop ();
|
||||
BOOST_ASSERT(handle_.top ()._type == token::EXPRESSION);
|
||||
// perform join
|
||||
sequence (node_ptr_vector_, tree_node_stack_);
|
||||
token_stack_.push (token::SUB);
|
||||
}
|
||||
}
|
||||
|
||||
static void repeat (token_stack &handle_, token_stack &token_stack_)
|
||||
{
|
||||
BOOST_ASSERT(handle_.top ()._type == token::REPEAT &&
|
||||
handle_.size () >= 1 && handle_.size () <= 3);
|
||||
|
||||
if (handle_.size () == 1)
|
||||
{
|
||||
token_stack_.push (token::EXPRESSION);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_.pop ();
|
||||
BOOST_ASSERT(handle_.top ()._type == token::DUP);
|
||||
token_stack_.push (token::REPEAT);
|
||||
}
|
||||
}
|
||||
|
||||
static void charset (token_stack &handle_, token_stack &token_stack_,
|
||||
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
BOOST_ASSERT(handle_.top ()._type == token::CHARSET &&
|
||||
handle_.size () == 1);
|
||||
// store charset
|
||||
node_ptr_vector_->push_back (static_cast<leaf_node *>(0));
|
||||
|
||||
const size_t id_ = handle_.top ()._id;
|
||||
|
||||
node_ptr_vector_->back () = new leaf_node (id_, true);
|
||||
tree_node_stack_.push (node_ptr_vector_->back ());
|
||||
token_stack_.push (token::REPEAT);
|
||||
}
|
||||
|
||||
static void macro (token_stack &handle_, token_stack &token_stack_,
|
||||
const macro_map ¯omap_, node_ptr_vector &node_ptr_vector_,
|
||||
tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
token &top_ = handle_.top ();
|
||||
|
||||
BOOST_ASSERT(top_._type == token::MACRO && handle_.size () == 1);
|
||||
|
||||
typename macro_map::const_iterator iter_ =
|
||||
macromap_.find (top_._macro);
|
||||
|
||||
if (iter_ == macromap_.end ())
|
||||
{
|
||||
const CharT *name_ = top_._macro;
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "Unknown MACRO name '";
|
||||
|
||||
while (*name_)
|
||||
{
|
||||
os_ << ss_.narrow (*name_++, ' ');
|
||||
}
|
||||
|
||||
os_ << "'.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
|
||||
tree_node_stack_.push (iter_->second->copy (node_ptr_vector_));
|
||||
token_stack_.push (token::REPEAT);
|
||||
}
|
||||
|
||||
static void openparen (token_stack &handle_, token_stack &token_stack_)
|
||||
{
|
||||
BOOST_ASSERT(handle_.top ()._type == token::OPENPAREN &&
|
||||
handle_.size () == 3);
|
||||
handle_.pop ();
|
||||
BOOST_ASSERT(handle_.top ()._type == token::REGEX);
|
||||
handle_.pop ();
|
||||
BOOST_ASSERT(handle_.top ()._type == token::CLOSEPAREN);
|
||||
token_stack_.push (token::REPEAT);
|
||||
}
|
||||
|
||||
static void perform_or (node_ptr_vector &node_ptr_vector_,
|
||||
tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
// perform or
|
||||
node *rhs_ = tree_node_stack_.top ();
|
||||
|
||||
tree_node_stack_.pop ();
|
||||
|
||||
node *lhs_ = tree_node_stack_.top ();
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<selection_node *>(0));
|
||||
node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
|
||||
tree_node_stack_.top () = node_ptr_vector_->back ();
|
||||
}
|
||||
|
||||
static void sequence (node_ptr_vector &node_ptr_vector_,
|
||||
tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
node *rhs_ = tree_node_stack_.top ();
|
||||
|
||||
tree_node_stack_.pop ();
|
||||
|
||||
node *lhs_ = tree_node_stack_.top ();
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<sequence_node *>(0));
|
||||
node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
|
||||
tree_node_stack_.top () = node_ptr_vector_->back ();
|
||||
}
|
||||
|
||||
static void optional (const bool greedy_,
|
||||
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
// perform ?
|
||||
node *lhs_ = tree_node_stack_.top ();
|
||||
// You don't know if lhs_ is a leaf_node, so get firstpos.
|
||||
node::node_vector &firstpos_ = lhs_->firstpos ();
|
||||
|
||||
for (node::node_vector::iterator iter_ = firstpos_.begin (),
|
||||
end_ = firstpos_.end (); iter_ != end_; ++iter_)
|
||||
{
|
||||
// These are leaf_nodes!
|
||||
(*iter_)->greedy (greedy_);
|
||||
}
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<leaf_node *>(0));
|
||||
|
||||
node *rhs_ = new leaf_node (null_token, greedy_);
|
||||
|
||||
node_ptr_vector_->back () = rhs_;
|
||||
node_ptr_vector_->push_back (static_cast<selection_node *>(0));
|
||||
node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
|
||||
tree_node_stack_.top () = node_ptr_vector_->back ();
|
||||
}
|
||||
|
||||
static void zero_or_more (const bool greedy_,
|
||||
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
// perform *
|
||||
node *ptr_ = tree_node_stack_.top ();
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<iteration_node *>(0));
|
||||
node_ptr_vector_->back () = new iteration_node (ptr_, greedy_);
|
||||
tree_node_stack_.top () = node_ptr_vector_->back ();
|
||||
}
|
||||
|
||||
static void one_or_more (const bool greedy_,
|
||||
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
// perform +
|
||||
node *lhs_ = tree_node_stack_.top ();
|
||||
node *copy_ = lhs_->copy (node_ptr_vector_);
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<iteration_node *>(0));
|
||||
|
||||
node *rhs_ = new iteration_node (copy_, greedy_);
|
||||
|
||||
node_ptr_vector_->back () = rhs_;
|
||||
node_ptr_vector_->push_back (static_cast<sequence_node *>(0));
|
||||
node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
|
||||
tree_node_stack_.top () = node_ptr_vector_->back ();
|
||||
}
|
||||
|
||||
// This is one of the most mind bending routines in this code...
|
||||
static void repeatn (const bool greedy_, const token &token_,
|
||||
node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
|
||||
{
|
||||
// perform {n[,[m]]}
|
||||
// Semantic checks have already been performed.
|
||||
// {0,} = *
|
||||
// {0,1} = ?
|
||||
// {1,} = +
|
||||
// therefore we do not check for these cases.
|
||||
if (!(token_._min == 1 && !token_._comma))
|
||||
{
|
||||
const std::size_t top_ = token_._min > 0 ?
|
||||
token_._min : token_._max;
|
||||
|
||||
if (token_._min == 0)
|
||||
{
|
||||
optional (greedy_, node_ptr_vector_, tree_node_stack_);
|
||||
}
|
||||
|
||||
node *prev_ = tree_node_stack_.top ()->copy (node_ptr_vector_);
|
||||
node *curr_ = 0;
|
||||
|
||||
for (std::size_t i_ = 2; i_ < top_; ++i_)
|
||||
{
|
||||
curr_ = prev_->copy (node_ptr_vector_);
|
||||
tree_node_stack_.push (static_cast<node *>(0));
|
||||
tree_node_stack_.top () = prev_;
|
||||
sequence (node_ptr_vector_, tree_node_stack_);
|
||||
prev_ = curr_;
|
||||
}
|
||||
|
||||
if (token_._comma && token_._min > 0)
|
||||
{
|
||||
if (token_._min > 1)
|
||||
{
|
||||
curr_ = prev_->copy (node_ptr_vector_);
|
||||
tree_node_stack_.push (static_cast<node *>(0));
|
||||
tree_node_stack_.top () = prev_;
|
||||
sequence (node_ptr_vector_, tree_node_stack_);
|
||||
prev_ = curr_;
|
||||
}
|
||||
|
||||
if (token_._comma && token_._max)
|
||||
{
|
||||
tree_node_stack_.push (static_cast<node *>(0));
|
||||
tree_node_stack_.top () = prev_;
|
||||
optional (greedy_, node_ptr_vector_, tree_node_stack_);
|
||||
prev_ = tree_node_stack_.top ();
|
||||
tree_node_stack_.pop ();
|
||||
|
||||
const std::size_t count_ = token_._max - token_._min;
|
||||
|
||||
for (std::size_t i_ = 1; i_ < count_; ++i_)
|
||||
{
|
||||
curr_ = prev_->copy (node_ptr_vector_);
|
||||
tree_node_stack_.push (static_cast<node *>(0));
|
||||
tree_node_stack_.top () = prev_;
|
||||
sequence (node_ptr_vector_, tree_node_stack_);
|
||||
prev_ = curr_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tree_node_stack_.push (static_cast<node *>(0));
|
||||
tree_node_stack_.top () = prev_;
|
||||
zero_or_more (greedy_, node_ptr_vector_, tree_node_stack_);
|
||||
prev_ = tree_node_stack_.top ();
|
||||
tree_node_stack_.pop ();
|
||||
}
|
||||
}
|
||||
|
||||
tree_node_stack_.push (static_cast<node *>(0));
|
||||
tree_node_stack_.top () = prev_;
|
||||
sequence (node_ptr_vector_, tree_node_stack_);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
// num_token.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_NUM_TOKEN_HPP
|
||||
#define BOOST_LEXER_NUM_TOKEN_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include "../../consts.hpp" // null_token
|
||||
#include "../../size_t.hpp"
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CharT>
|
||||
struct basic_num_token
|
||||
{
|
||||
enum type {BEGIN, REGEX, OREXP, SEQUENCE, SUB, EXPRESSION, REPEAT,
|
||||
DUP, OR, CHARSET, MACRO, OPENPAREN, CLOSEPAREN, OPT, AOPT,
|
||||
ZEROORMORE, AZEROORMORE, ONEORMORE, AONEORMORE, REPEATN, AREPEATN,
|
||||
END};
|
||||
|
||||
type _type;
|
||||
std::size_t _id;
|
||||
std::size_t _min;
|
||||
bool _comma;
|
||||
std::size_t _max;
|
||||
CharT _macro[max_macro_len + 1];
|
||||
static const char _precedence_table[END + 1][END + 1];
|
||||
static const char *_precedence_strings[END + 1];
|
||||
|
||||
basic_num_token (const type type_ = BEGIN,
|
||||
const std::size_t id_ = null_token) :
|
||||
_type (type_),
|
||||
_id (id_),
|
||||
_min (0),
|
||||
_comma (false),
|
||||
_max (0)
|
||||
{
|
||||
*_macro = 0;
|
||||
}
|
||||
|
||||
basic_num_token &operator = (const basic_num_token &rhs_)
|
||||
{
|
||||
_type = rhs_._type;
|
||||
_id = rhs_._id;
|
||||
_min = rhs_._min;
|
||||
_comma = rhs_._comma;
|
||||
_max = rhs_._max;
|
||||
|
||||
if (_type == MACRO)
|
||||
{
|
||||
const CharT *read_ = rhs_._macro;
|
||||
CharT *write_ = _macro;
|
||||
|
||||
while (*read_)
|
||||
{
|
||||
*write_++ = *read_++;
|
||||
}
|
||||
|
||||
*write_ = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void set (const type type_)
|
||||
{
|
||||
_type = type_;
|
||||
_id = null_token;
|
||||
}
|
||||
|
||||
void set (const type type_, const std::size_t id_)
|
||||
{
|
||||
_type = type_;
|
||||
_id = id_;
|
||||
}
|
||||
|
||||
void min_max (const std::size_t min_, const bool comma_,
|
||||
const std::size_t max_)
|
||||
{
|
||||
_min = min_;
|
||||
_comma = comma_;
|
||||
_max = max_;
|
||||
}
|
||||
|
||||
char precedence (const type type_) const
|
||||
{
|
||||
return _precedence_table[_type][type_];
|
||||
}
|
||||
|
||||
const char *precedence_string () const
|
||||
{
|
||||
return _precedence_strings[_type];
|
||||
}
|
||||
};
|
||||
|
||||
template<typename CharT>
|
||||
const char basic_num_token<CharT>::_precedence_table[END + 1][END + 1] = {
|
||||
// BEG, REG, ORE, SEQ, SUB, EXP, RPT, DUP, | , CHR, MCR, ( , ) , ? , ?? , * , *? , + , +?, {n}?, {n}, END
|
||||
/*BEGIN*/{' ', '<', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/*REGEX*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/*OREXP*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* SEQ */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', ' ', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* SUB */{' ', ' ', ' ', ' ', ' ', '=', '<', ' ', '>', '<', '<', '<', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/*EXPRE*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* RPT */{' ', ' ', ' ', ' ', ' ', ' ', ' ', '=', '>', '>', '>', '>', '>', '<', '<', '<', '<', '<', '<', '<', '<', '>'},
|
||||
/*DUPLI*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* | */{' ', ' ', ' ', '=', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
|
||||
/*CHARA*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
|
||||
/*MACRO*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
|
||||
/* ( */{' ', '=', '<', '<', '<', '<', '<', ' ', ' ', '<', '<', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
|
||||
/* ) */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>', '>'},
|
||||
/* ? */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* ?? */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* * */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* *? */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* + */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* +? */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/*{n,m}*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', '<', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/*{nm}?*/{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>', '>', '>', '>', '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '>'},
|
||||
/* END */{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}
|
||||
};
|
||||
|
||||
template<typename CharT>
|
||||
const char *basic_num_token<CharT>::_precedence_strings[END + 1] =
|
||||
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(910))
|
||||
{{"BEGIN"}, {"REGEX"}, {"OREXP"}, {"SEQUENCE"}, {"SUB"}, {"EXPRESSION"},
|
||||
{"REPEAT"}, {"DUPLICATE"}, {"|"}, {"CHARSET"}, {"MACRO"},
|
||||
{"("}, {")"}, {"?"}, {"??"}, {"*"}, {"*?"}, {"+"}, {"+?"}, {"{n[,[m]]}"},
|
||||
{"{n[,[m]]}?"}, {"END"}};
|
||||
#else
|
||||
{"BEGIN", "REGEX", "OREXP", "SEQUENCE", "SUB", "EXPRESSION", "REPEAT",
|
||||
"DUPLICATE", "|", "CHARSET", "MACRO", "(", ")", "?", "??", "*", "*?",
|
||||
"+", "+?", "{n[,[m]]}", "{n[,[m]]}?", "END"};
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+574
@@ -0,0 +1,574 @@
|
||||
// tokeniser.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_RE_TOKENISER_HPP
|
||||
#define BOOST_LEXER_RE_TOKENISER_HPP
|
||||
|
||||
// memcpy()
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include "num_token.hpp"
|
||||
#include "../../runtime_error.hpp"
|
||||
#include "../../size_t.hpp"
|
||||
#include <sstream>
|
||||
#include "../../string_token.hpp"
|
||||
#include "re_tokeniser_helper.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CharT>
|
||||
class basic_re_tokeniser
|
||||
{
|
||||
public:
|
||||
typedef basic_num_token<CharT> num_token;
|
||||
typedef basic_re_tokeniser_state<CharT> state;
|
||||
typedef basic_string_token<CharT> string_token;
|
||||
typedef typename string_token::string string;
|
||||
typedef std::map<string_token, std::size_t> token_map;
|
||||
typedef std::pair<string_token, std::size_t> token_pair;
|
||||
|
||||
static void next (state &state_, token_map &map_, num_token &token_)
|
||||
{
|
||||
CharT ch_ = 0;
|
||||
bool eos_ = state_.next (ch_);
|
||||
|
||||
token_.min_max (0, false, 0);
|
||||
|
||||
while (!eos_ && ch_ == '"')
|
||||
{
|
||||
state_._in_string ^= 1;
|
||||
eos_ = state_.next (ch_);
|
||||
}
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
if (state_._in_string)
|
||||
{
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing '\"').");
|
||||
}
|
||||
|
||||
if (state_._paren_count)
|
||||
{
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing ')').");
|
||||
}
|
||||
|
||||
token_.set (num_token::END, null_token);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ch_ == '\\')
|
||||
{
|
||||
// Even if we are in a string, respect escape sequences...
|
||||
escape (state_, map_, token_);
|
||||
}
|
||||
else if (state_._in_string)
|
||||
{
|
||||
// All other meta characters lose their special meaning
|
||||
// inside a string.
|
||||
create_charset_token (string (1, ch_), false, map_, token_);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not an escape sequence and not inside a string, so
|
||||
// check for meta characters.
|
||||
switch (ch_)
|
||||
{
|
||||
case '(':
|
||||
token_.set (num_token::OPENPAREN, null_token);
|
||||
++state_._paren_count;
|
||||
read_options (state_);
|
||||
break;
|
||||
case ')':
|
||||
--state_._paren_count;
|
||||
|
||||
if (state_._paren_count < 0)
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Number of open parenthesis < 0 at index " <<
|
||||
state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
token_.set (num_token::CLOSEPAREN, null_token);
|
||||
|
||||
if (!state_._flags_stack.empty ())
|
||||
{
|
||||
state_._flags = state_._flags_stack.top ();
|
||||
state_._flags_stack.pop ();
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
if (!state_.eos () && *state_._curr == '?')
|
||||
{
|
||||
token_.set (num_token::AOPT, null_token);
|
||||
state_.increment ();
|
||||
}
|
||||
else
|
||||
{
|
||||
token_.set (num_token::OPT, null_token);
|
||||
}
|
||||
|
||||
break;
|
||||
case '*':
|
||||
if (!state_.eos () && *state_._curr == '?')
|
||||
{
|
||||
token_.set (num_token::AZEROORMORE, null_token);
|
||||
state_.increment ();
|
||||
}
|
||||
else
|
||||
{
|
||||
token_.set (num_token::ZEROORMORE, null_token);
|
||||
}
|
||||
|
||||
break;
|
||||
case '+':
|
||||
if (!state_.eos () && *state_._curr == '?')
|
||||
{
|
||||
token_.set (num_token::AONEORMORE, null_token);
|
||||
state_.increment ();
|
||||
}
|
||||
else
|
||||
{
|
||||
token_.set (num_token::ONEORMORE, null_token);
|
||||
}
|
||||
|
||||
break;
|
||||
case '{':
|
||||
open_curly (state_, token_);
|
||||
break;
|
||||
case '|':
|
||||
token_.set (num_token::OR, null_token);
|
||||
break;
|
||||
case '^':
|
||||
if (state_._curr - 1 == state_._start)
|
||||
{
|
||||
token_.set (num_token::CHARSET, bol_token);
|
||||
state_._seen_BOL_assertion = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
create_charset_token (string (1, ch_), false,
|
||||
map_, token_);
|
||||
}
|
||||
|
||||
break;
|
||||
case '$':
|
||||
if (state_._curr == state_._end)
|
||||
{
|
||||
token_.set (num_token::CHARSET, eol_token);
|
||||
state_._seen_EOL_assertion = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
create_charset_token (string (1, ch_), false,
|
||||
map_, token_);
|
||||
}
|
||||
|
||||
break;
|
||||
case '.':
|
||||
{
|
||||
string dot_;
|
||||
|
||||
if (state_._flags & dot_not_newline)
|
||||
{
|
||||
dot_ = '\n';
|
||||
}
|
||||
|
||||
create_charset_token (dot_, true, map_, token_);
|
||||
break;
|
||||
}
|
||||
case '[':
|
||||
{
|
||||
charset (state_, map_, token_);
|
||||
break;
|
||||
}
|
||||
case '/':
|
||||
throw runtime_error("Lookahead ('/') is not supported yet.");
|
||||
break;
|
||||
default:
|
||||
if ((state_._flags & icase) &&
|
||||
(std::isupper (ch_, state_._locale) ||
|
||||
std::islower (ch_, state_._locale)))
|
||||
{
|
||||
CharT upper_ = std::toupper (ch_, state_._locale);
|
||||
CharT lower_ = std::tolower (ch_, state_._locale);
|
||||
|
||||
string str_ (1, upper_);
|
||||
|
||||
str_ += lower_;
|
||||
create_charset_token (str_, false, map_, token_);
|
||||
}
|
||||
else
|
||||
{
|
||||
create_charset_token (string (1, ch_), false,
|
||||
map_, token_);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef basic_re_tokeniser_helper<CharT> tokeniser_helper;
|
||||
|
||||
static void read_options (state &state_)
|
||||
{
|
||||
if (!state_.eos () && *state_._curr == '?')
|
||||
{
|
||||
CharT ch_ = 0;
|
||||
bool eos_ = false;
|
||||
bool negate_ = false;
|
||||
|
||||
state_.increment ();
|
||||
eos_ = state_.next (ch_);
|
||||
state_._flags_stack.push (state_._flags);
|
||||
|
||||
while (!eos_ && ch_ != ':')
|
||||
{
|
||||
switch (ch_)
|
||||
{
|
||||
case '-':
|
||||
negate_ ^= 1;
|
||||
break;
|
||||
case 'i':
|
||||
if (negate_)
|
||||
{
|
||||
state_._flags = static_cast<regex_flags>
|
||||
(state_._flags & ~icase);
|
||||
}
|
||||
else
|
||||
{
|
||||
state_._flags = static_cast<regex_flags>
|
||||
(state_._flags | icase);
|
||||
}
|
||||
|
||||
negate_ = false;
|
||||
break;
|
||||
case 's':
|
||||
if (negate_)
|
||||
{
|
||||
state_._flags = static_cast<regex_flags>
|
||||
(state_._flags | dot_not_newline);
|
||||
}
|
||||
else
|
||||
{
|
||||
state_._flags = static_cast<regex_flags>
|
||||
(state_._flags & ~dot_not_newline);
|
||||
}
|
||||
|
||||
negate_ = false;
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Unknown option at index " <<
|
||||
state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
}
|
||||
|
||||
eos_ = state_.next (ch_);
|
||||
}
|
||||
|
||||
// End of string handler will handle early termination
|
||||
}
|
||||
else if (!state_._flags_stack.empty ())
|
||||
{
|
||||
state_._flags_stack.push (state_._flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void escape (state &state_, token_map &map_, num_token &token_)
|
||||
{
|
||||
CharT ch_ = 0;
|
||||
std::size_t str_len_ = 0;
|
||||
const CharT *str_ = tokeniser_helper::escape_sequence (state_,
|
||||
ch_, str_len_);
|
||||
|
||||
if (str_)
|
||||
{
|
||||
state state2_ (str_ + 1, str_ + str_len_, state_._flags,
|
||||
state_._locale);
|
||||
|
||||
charset (state2_, map_, token_);
|
||||
}
|
||||
else
|
||||
{
|
||||
create_charset_token (string (1, ch_), false, map_, token_);
|
||||
}
|
||||
}
|
||||
|
||||
static void charset (state &state_, token_map &map_, num_token &token_)
|
||||
{
|
||||
string chars_;
|
||||
bool negated_ = false;
|
||||
|
||||
tokeniser_helper::charset (state_, chars_, negated_);
|
||||
create_charset_token (chars_, negated_, map_, token_);
|
||||
}
|
||||
|
||||
static void create_charset_token (const string &charset_,
|
||||
const bool negated_, token_map &map_, num_token &token_)
|
||||
{
|
||||
std::size_t id_ = null_token;
|
||||
string_token stok_ (negated_, charset_);
|
||||
|
||||
stok_.remove_duplicates ();
|
||||
stok_.normalise ();
|
||||
|
||||
typename token_map::const_iterator iter_ = map_.find (stok_);
|
||||
|
||||
if (iter_ == map_.end ())
|
||||
{
|
||||
id_ = map_.size ();
|
||||
map_.insert (token_pair (stok_, id_));
|
||||
}
|
||||
else
|
||||
{
|
||||
id_ = iter_->second;
|
||||
}
|
||||
|
||||
token_.set (num_token::CHARSET, id_);
|
||||
}
|
||||
|
||||
static void open_curly (state &state_, num_token &token_)
|
||||
{
|
||||
if (state_.eos ())
|
||||
{
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing '}').");
|
||||
}
|
||||
else if (*state_._curr >= '0' && *state_._curr <= '9')
|
||||
{
|
||||
repeat_n (state_, token_);
|
||||
|
||||
if (!state_.eos () && *state_._curr == '?')
|
||||
{
|
||||
token_._type = num_token::AREPEATN;
|
||||
state_.increment ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
macro (state_, token_);
|
||||
}
|
||||
}
|
||||
|
||||
// SYNTAX:
|
||||
// {n[,[n]]}
|
||||
// SEMANTIC RULES:
|
||||
// {0} - INVALID (throw exception)
|
||||
// {0,} = *
|
||||
// {0,0} - INVALID (throw exception)
|
||||
// {0,1} = ?
|
||||
// {1,} = +
|
||||
// {min,max} where min == max - {min}
|
||||
// {min,max} where max < min - INVALID (throw exception)
|
||||
static void repeat_n (state &state_, num_token &token_)
|
||||
{
|
||||
CharT ch_ = 0;
|
||||
bool eos_ = state_.next (ch_);
|
||||
|
||||
while (!eos_ && ch_ >= '0' && ch_ <= '9')
|
||||
{
|
||||
token_._min *= 10;
|
||||
token_._min += ch_ - '0';
|
||||
eos_ = state_.next (ch_);
|
||||
}
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing '}').");
|
||||
}
|
||||
|
||||
bool min_max_ = false;
|
||||
bool repeatn_ = true;
|
||||
|
||||
token_._comma = ch_ == ',';
|
||||
|
||||
if (token_._comma)
|
||||
{
|
||||
eos_ = state_.next (ch_);
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing '}').");
|
||||
}
|
||||
|
||||
if (ch_ == '}')
|
||||
{
|
||||
// Small optimisation: Check for '*' equivalency.
|
||||
if (token_._min == 0)
|
||||
{
|
||||
token_.set (num_token::ZEROORMORE, null_token);
|
||||
repeatn_ = false;
|
||||
}
|
||||
// Small optimisation: Check for '+' equivalency.
|
||||
else if (token_._min == 1)
|
||||
{
|
||||
token_.set (num_token::ONEORMORE, null_token);
|
||||
repeatn_ = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ch_ < '0' || ch_ > '9')
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Missing '}' at index " <<
|
||||
state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
min_max_ = true;
|
||||
|
||||
do
|
||||
{
|
||||
token_._max *= 10;
|
||||
token_._max += ch_ - '0';
|
||||
eos_ = state_.next (ch_);
|
||||
} while (!eos_ && ch_ >= '0' && ch_ <= '9');
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing '}').");
|
||||
}
|
||||
|
||||
// Small optimisation: Check for '?' equivalency.
|
||||
if (token_._min == 0 && token_._max == 1)
|
||||
{
|
||||
token_.set (num_token::OPT, null_token);
|
||||
repeatn_ = false;
|
||||
}
|
||||
// Small optimisation: if min == max, then min.
|
||||
else if (token_._min == token_._max)
|
||||
{
|
||||
token_._comma = false;
|
||||
min_max_ = false;
|
||||
token_._max = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ch_ != '}')
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Missing '}' at index " << state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
if (repeatn_)
|
||||
{
|
||||
// SEMANTIC VALIDATION follows:
|
||||
// NOTE: {0,} has already become *
|
||||
// therefore we don't check for a comma.
|
||||
if (token_._min == 0 && token_._max == 0)
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Cannot have exactly zero repeats preceding index " <<
|
||||
state_.index () << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
if (min_max_ && token_._max < token_._min)
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Max less than min preceding index " <<
|
||||
state_.index () << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
token_.set (num_token::REPEATN, null_token);
|
||||
}
|
||||
}
|
||||
|
||||
static void macro (state &state_, num_token &token_)
|
||||
{
|
||||
CharT ch_ = 0;
|
||||
bool eos_ = false;
|
||||
const CharT *start_ = state_._curr;
|
||||
|
||||
state_.next (ch_);
|
||||
|
||||
if (ch_ != '_' && !(ch_ >= 'A' && ch_ <= 'Z') &&
|
||||
!(ch_ >= 'a' && ch_ <= 'z'))
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Invalid MACRO name at index " <<
|
||||
state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
eos_ = state_.next (ch_);
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing '}').");
|
||||
}
|
||||
} while (ch_ == '_' || ch_ == '-' || (ch_ >= 'A' && ch_ <= 'Z') ||
|
||||
(ch_ >= 'a' && ch_ <= 'z') || (ch_ >= '0' && ch_ <= '9'));
|
||||
|
||||
if (ch_ != '}')
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Missing '}' at index " << state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
std::size_t len_ = state_._curr - 1 - start_;
|
||||
|
||||
if (len_ > max_macro_len)
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "MACRO name '";
|
||||
|
||||
while (len_)
|
||||
{
|
||||
os_ << ss_.narrow (*start_++, ' ');
|
||||
--len_;
|
||||
}
|
||||
|
||||
os_ << "' too long.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
|
||||
token_.set (num_token::MACRO, null_token);
|
||||
|
||||
// Some systems have memcpy in namespace std.
|
||||
using namespace std;
|
||||
|
||||
memcpy (token_._macro, start_, len_ * sizeof (CharT));
|
||||
token_._macro[len_] = 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+549
@@ -0,0 +1,549 @@
|
||||
// tokeniser_helper.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_RE_TOKENISER_HELPER_H
|
||||
#define BOOST_LEXER_RE_TOKENISER_HELPER_H
|
||||
|
||||
#include "../../char_traits.hpp"
|
||||
// strlen()
|
||||
#include <cstring>
|
||||
#include "../../size_t.hpp"
|
||||
#include "re_tokeniser_state.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CharT, typename Traits = char_traits<CharT> >
|
||||
class basic_re_tokeniser_helper
|
||||
{
|
||||
public:
|
||||
typedef basic_re_tokeniser_state<CharT> state;
|
||||
typedef std::basic_string<CharT> string;
|
||||
|
||||
static const CharT *escape_sequence (state &state_, CharT &ch_,
|
||||
std::size_t &str_len_)
|
||||
{
|
||||
bool eos_ = state_.eos ();
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"following '\\'.");
|
||||
}
|
||||
|
||||
const CharT *str_ = charset_shortcut (*state_._curr, str_len_);
|
||||
|
||||
if (str_)
|
||||
{
|
||||
state_.increment ();
|
||||
}
|
||||
else
|
||||
{
|
||||
ch_ = chr (state_);
|
||||
}
|
||||
|
||||
return str_;
|
||||
}
|
||||
|
||||
// This function can call itself.
|
||||
static void charset (state &state_, string &chars_, bool &negated_)
|
||||
{
|
||||
CharT ch_ = 0;
|
||||
bool eos_ = state_.next (ch_);
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
// Pointless returning index if at end of string
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"following '['.");
|
||||
}
|
||||
|
||||
negated_ = ch_ == '^';
|
||||
|
||||
if (negated_)
|
||||
{
|
||||
eos_ = state_.next (ch_);
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
// Pointless returning index if at end of string
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"following '^'.");
|
||||
}
|
||||
}
|
||||
|
||||
bool chset_ = false;
|
||||
CharT prev_ = 0;
|
||||
|
||||
while (ch_ != ']')
|
||||
{
|
||||
if (ch_ == '\\')
|
||||
{
|
||||
std::size_t str_len_ = 0;
|
||||
const CharT *str_ = escape_sequence (state_, prev_, str_len_);
|
||||
|
||||
chset_ = str_ != 0;
|
||||
|
||||
if (chset_)
|
||||
{
|
||||
state temp_state_ (str_ + 1, str_ + str_len_,
|
||||
state_._flags, state_._locale);
|
||||
string temp_chars_;
|
||||
bool temp_negated_ = false;
|
||||
|
||||
charset (temp_state_, temp_chars_, temp_negated_);
|
||||
|
||||
if (negated_ != temp_negated_)
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Mismatch in charset negation preceding "
|
||||
"index " << state_.index () << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
chars_ += temp_chars_;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if (ch_ == '[' && !state_.eos () && *state_._curr == ':')
|
||||
{
|
||||
// TODO: POSIX charsets
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
chset_ = false;
|
||||
prev_ = ch_;
|
||||
}
|
||||
|
||||
eos_ = state_.next (ch_);
|
||||
|
||||
// Covers preceding if, else if and else
|
||||
if (eos_)
|
||||
{
|
||||
// Pointless returning index if at end of string
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing ']').");
|
||||
}
|
||||
|
||||
if (ch_ == '-')
|
||||
{
|
||||
charset_range (chset_, state_, eos_, ch_, prev_, chars_);
|
||||
}
|
||||
else if (!chset_)
|
||||
{
|
||||
if ((state_._flags & icase) &&
|
||||
(std::isupper (prev_, state_._locale) ||
|
||||
std::islower (prev_, state_._locale)))
|
||||
{
|
||||
CharT upper_ = std::toupper (prev_, state_._locale);
|
||||
CharT lower_ = std::tolower (prev_, state_._locale);
|
||||
|
||||
chars_ += upper_;
|
||||
chars_ += lower_;
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_ += prev_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!negated_ && chars_.empty ())
|
||||
{
|
||||
throw runtime_error ("Empty charsets not allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
static CharT chr (state &state_)
|
||||
{
|
||||
CharT ch_ = 0;
|
||||
|
||||
// eos_ has already been checked for.
|
||||
switch (*state_._curr)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
ch_ = decode_octal (state_);
|
||||
break;
|
||||
case 'a':
|
||||
ch_ = '\a';
|
||||
state_.increment ();
|
||||
break;
|
||||
case 'b':
|
||||
ch_ = '\b';
|
||||
state_.increment ();
|
||||
break;
|
||||
case 'c':
|
||||
ch_ = decode_control_char (state_);
|
||||
break;
|
||||
case 'e':
|
||||
ch_ = 27; // '\e' not recognised by compiler
|
||||
state_.increment ();
|
||||
break;
|
||||
case 'f':
|
||||
ch_ = '\f';
|
||||
state_.increment ();
|
||||
break;
|
||||
case 'n':
|
||||
ch_ = '\n';
|
||||
state_.increment ();
|
||||
break;
|
||||
case 'r':
|
||||
ch_ = '\r';
|
||||
state_.increment ();
|
||||
break;
|
||||
case 't':
|
||||
ch_ = '\t';
|
||||
state_.increment ();
|
||||
break;
|
||||
case 'v':
|
||||
ch_ = '\v';
|
||||
state_.increment ();
|
||||
break;
|
||||
case 'x':
|
||||
ch_ = decode_hex (state_);
|
||||
break;
|
||||
default:
|
||||
ch_ = *state_._curr;
|
||||
state_.increment ();
|
||||
break;
|
||||
}
|
||||
|
||||
return ch_;
|
||||
}
|
||||
|
||||
private:
|
||||
static const char *charset_shortcut (const char ch_,
|
||||
std::size_t &str_len_)
|
||||
{
|
||||
const char *str_ = 0;
|
||||
|
||||
switch (ch_)
|
||||
{
|
||||
case 'd':
|
||||
str_ = "[0-9]";
|
||||
break;
|
||||
case 'D':
|
||||
str_ = "[^0-9]";
|
||||
break;
|
||||
case 's':
|
||||
str_ = "[ \t\n\r\f\v]";
|
||||
break;
|
||||
case 'S':
|
||||
str_ = "[^ \t\n\r\f\v]";
|
||||
break;
|
||||
case 'w':
|
||||
str_ = "[_0-9A-Za-z]";
|
||||
break;
|
||||
case 'W':
|
||||
str_ = "[^_0-9A-Za-z]";
|
||||
break;
|
||||
}
|
||||
|
||||
if (str_)
|
||||
{
|
||||
// Some systems have strlen in namespace std.
|
||||
using namespace std;
|
||||
|
||||
str_len_ = strlen (str_);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_len_ = 0;
|
||||
}
|
||||
|
||||
return str_;
|
||||
}
|
||||
|
||||
static const wchar_t *charset_shortcut (const wchar_t ch_,
|
||||
std::size_t &str_len_)
|
||||
{
|
||||
const wchar_t *str_ = 0;
|
||||
|
||||
switch (ch_)
|
||||
{
|
||||
case 'd':
|
||||
str_ = L"[0-9]";
|
||||
break;
|
||||
case 'D':
|
||||
str_ = L"[^0-9]";
|
||||
break;
|
||||
case 's':
|
||||
str_ = L"[ \t\n\r\f\v]";
|
||||
break;
|
||||
case 'S':
|
||||
str_ = L"[^ \t\n\r\f\v]";
|
||||
break;
|
||||
case 'w':
|
||||
str_ = L"[_0-9A-Za-z]";
|
||||
break;
|
||||
case 'W':
|
||||
str_ = L"[^_0-9A-Za-z]";
|
||||
break;
|
||||
}
|
||||
|
||||
if (str_)
|
||||
{
|
||||
// Some systems have wcslen in namespace std.
|
||||
using namespace std;
|
||||
|
||||
str_len_ = wcslen (str_);
|
||||
}
|
||||
else
|
||||
{
|
||||
str_len_ = 0;
|
||||
}
|
||||
|
||||
return str_;
|
||||
}
|
||||
|
||||
static CharT decode_octal (state &state_)
|
||||
{
|
||||
std::size_t accumulator_ = 0;
|
||||
CharT ch_ = *state_._curr;
|
||||
unsigned short count_ = 3;
|
||||
bool eos_ = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
accumulator_ *= 8;
|
||||
accumulator_ += ch_ - '0';
|
||||
--count_;
|
||||
state_.increment ();
|
||||
eos_ = state_.eos ();
|
||||
|
||||
if (!count_ || eos_) break;
|
||||
|
||||
ch_ = *state_._curr;
|
||||
|
||||
// Don't consume invalid chars!
|
||||
if (ch_ < '0' || ch_ > '7')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<CharT> (accumulator_);
|
||||
}
|
||||
|
||||
static CharT decode_control_char (state &state_)
|
||||
{
|
||||
// Skip over 'c'
|
||||
state_.increment ();
|
||||
|
||||
CharT ch_ = 0;
|
||||
bool eos_ = state_.next (ch_);
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
// Pointless returning index if at end of string
|
||||
throw runtime_error ("Unexpected end of regex following \\c.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ch_ >= 'a' && ch_ <= 'z')
|
||||
{
|
||||
ch_ -= 'a' - 1;
|
||||
}
|
||||
else if (ch_ >= 'A' && ch_ <= 'Z')
|
||||
{
|
||||
ch_ -= 'A' - 1;
|
||||
}
|
||||
else if (ch_ == '@')
|
||||
{
|
||||
// Apparently...
|
||||
ch_ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Invalid control char at index " <<
|
||||
state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
}
|
||||
|
||||
return ch_;
|
||||
}
|
||||
|
||||
static CharT decode_hex (state &state_)
|
||||
{
|
||||
// Skip over 'x'
|
||||
state_.increment ();
|
||||
|
||||
CharT ch_ = 0;
|
||||
bool eos_ = state_.next (ch_);
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
// Pointless returning index if at end of string
|
||||
throw runtime_error ("Unexpected end of regex following \\x.");
|
||||
}
|
||||
|
||||
if (!((ch_ >= '0' && ch_ <= '9') || (ch_ >= 'a' && ch_ <= 'f') ||
|
||||
(ch_ >= 'A' && ch_ <= 'F')))
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Illegal char following \\x at index " <<
|
||||
state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
std::size_t hex_ = 0;
|
||||
|
||||
do
|
||||
{
|
||||
hex_ *= 16;
|
||||
|
||||
if (ch_ >= '0' && ch_ <= '9')
|
||||
{
|
||||
hex_ += ch_ - '0';
|
||||
}
|
||||
else if (ch_ >= 'a' && ch_ <= 'f')
|
||||
{
|
||||
hex_ += 10 + (ch_ - 'a');
|
||||
}
|
||||
else
|
||||
{
|
||||
hex_ += 10 + (ch_ - 'A');
|
||||
}
|
||||
|
||||
eos_ = state_.eos ();
|
||||
|
||||
if (!eos_)
|
||||
{
|
||||
ch_ = *state_._curr;
|
||||
|
||||
// Don't consume invalid chars!
|
||||
if (((ch_ >= '0' && ch_ <= '9') ||
|
||||
(ch_ >= 'a' && ch_ <= 'f') || (ch_ >= 'A' && ch_ <= 'F')))
|
||||
{
|
||||
state_.increment ();
|
||||
}
|
||||
else
|
||||
{
|
||||
eos_ = true;
|
||||
}
|
||||
}
|
||||
} while (!eos_);
|
||||
|
||||
return static_cast<CharT> (hex_);
|
||||
}
|
||||
|
||||
static void charset_range (const bool chset_, state &state_, bool &eos_,
|
||||
CharT &ch_, const CharT prev_, string &chars_)
|
||||
{
|
||||
if (chset_)
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Charset cannot form start of range preceding "
|
||||
"index " << state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
eos_ = state_.next (ch_);
|
||||
|
||||
if (eos_)
|
||||
{
|
||||
// Pointless returning index if at end of string
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"following '-'.");
|
||||
}
|
||||
|
||||
CharT curr_ = 0;
|
||||
|
||||
if (ch_ == '\\')
|
||||
{
|
||||
std::size_t str_len_ = 0;
|
||||
|
||||
if (escape_sequence (state_, curr_, str_len_))
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Charset cannot form end of range preceding index "
|
||||
<< state_.index () << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if (ch_ == '[' && !state_.eos () && *state_._curr == ':')
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "POSIX char class cannot form end of range at "
|
||||
"index " << state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
*/
|
||||
else
|
||||
{
|
||||
curr_ = ch_;
|
||||
}
|
||||
|
||||
eos_ = state_.next (ch_);
|
||||
|
||||
// Covers preceding if and else
|
||||
if (eos_)
|
||||
{
|
||||
// Pointless returning index if at end of string
|
||||
throw runtime_error ("Unexpected end of regex "
|
||||
"(missing ']').");
|
||||
}
|
||||
|
||||
std::size_t start_ = static_cast<typename Traits::index_type> (prev_);
|
||||
std::size_t end_ = static_cast<typename Traits::index_type> (curr_);
|
||||
|
||||
// Semanic check
|
||||
if (end_ < start_)
|
||||
{
|
||||
std::ostringstream ss_;
|
||||
|
||||
ss_ << "Invalid range in charset preceding index " <<
|
||||
state_.index () - 1 << '.';
|
||||
throw runtime_error (ss_.str ().c_str ());
|
||||
}
|
||||
|
||||
chars_.reserve (chars_.size () + (end_ + 1 - start_));
|
||||
|
||||
for (; start_ <= end_; ++start_)
|
||||
{
|
||||
CharT ch_ = static_cast<CharT> (start_);
|
||||
|
||||
if ((state_._flags & icase) &&
|
||||
(std::isupper (ch_, state_._locale) ||
|
||||
std::islower (ch_, state_._locale)))
|
||||
{
|
||||
CharT upper_ = std::toupper (ch_, state_._locale);
|
||||
CharT lower_ = std::tolower (ch_, state_._locale);
|
||||
|
||||
chars_ += (upper_);
|
||||
chars_ += (lower_);
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_ += (ch_);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
// tokeniser_state.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_RE_TOKENISER_STATE_HPP
|
||||
#define BOOST_LEXER_RE_TOKENISER_STATE_HPP
|
||||
|
||||
#include "../../consts.hpp"
|
||||
#include <locale>
|
||||
#include "../../size_t.hpp"
|
||||
#include <stack>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CharT>
|
||||
struct basic_re_tokeniser_state
|
||||
{
|
||||
const CharT * const _start;
|
||||
const CharT * const _end;
|
||||
const CharT *_curr;
|
||||
regex_flags _flags;
|
||||
std::stack<regex_flags> _flags_stack;
|
||||
std::locale _locale;
|
||||
long _paren_count;
|
||||
bool _in_string;
|
||||
bool _seen_BOL_assertion;
|
||||
bool _seen_EOL_assertion;
|
||||
|
||||
basic_re_tokeniser_state (const CharT *start_, const CharT * const end_,
|
||||
const regex_flags flags_, const std::locale locale_) :
|
||||
_start (start_),
|
||||
_end (end_),
|
||||
_curr (start_),
|
||||
_flags (flags_),
|
||||
_locale (locale_),
|
||||
_paren_count (0),
|
||||
_in_string (false),
|
||||
_seen_BOL_assertion (false),
|
||||
_seen_EOL_assertion (false)
|
||||
{
|
||||
}
|
||||
|
||||
// prevent VC++ 7.1 warning:
|
||||
const basic_re_tokeniser_state &operator =
|
||||
(const basic_re_tokeniser_state &rhs_)
|
||||
{
|
||||
_start = rhs_._start;
|
||||
_end = rhs_._end;
|
||||
_curr = rhs_._curr;
|
||||
_flags = rhs_._flags;
|
||||
_locale = rhs_._locale;
|
||||
_paren_count = rhs_._paren_count;
|
||||
_in_string = rhs_._in_string;
|
||||
_seen_BOL_assertion = rhs_._seen_BOL_assertion;
|
||||
_seen_EOL_assertion = rhs_._seen_EOL_assertion;
|
||||
return this;
|
||||
}
|
||||
|
||||
inline bool next (CharT &ch_)
|
||||
{
|
||||
if (_curr >= _end)
|
||||
{
|
||||
ch_ = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ch_ = *_curr;
|
||||
increment ();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline void increment ()
|
||||
{
|
||||
++_curr;
|
||||
}
|
||||
|
||||
inline std::size_t index ()
|
||||
{
|
||||
return _curr - _start;
|
||||
}
|
||||
|
||||
inline bool eos ()
|
||||
{
|
||||
return _curr >= _end;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
// end_node.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_END_NODE_HPP
|
||||
#define BOOST_LEXER_END_NODE_HPP
|
||||
|
||||
#include "node.hpp"
|
||||
#include "../../size_t.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class end_node : public node
|
||||
{
|
||||
public:
|
||||
end_node (const std::size_t id_, const std::size_t unique_id_,
|
||||
const std::size_t lexer_state_) :
|
||||
node (false),
|
||||
_id (id_),
|
||||
_unique_id (unique_id_),
|
||||
_lexer_state (lexer_state_)
|
||||
{
|
||||
node::_firstpos.push_back (this);
|
||||
node::_lastpos.push_back (this);
|
||||
}
|
||||
|
||||
virtual ~end_node ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual type what_type () const
|
||||
{
|
||||
return END;
|
||||
}
|
||||
|
||||
virtual bool traverse (const_node_stack &/*node_stack_*/,
|
||||
bool_stack &/*perform_op_stack_*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual const node_vector &followpos () const
|
||||
{
|
||||
// _followpos is always empty..!
|
||||
return _followpos;
|
||||
}
|
||||
|
||||
virtual bool end_state () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual std::size_t id () const
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
virtual std::size_t unique_id () const
|
||||
{
|
||||
return _unique_id;
|
||||
}
|
||||
|
||||
virtual std::size_t lexer_state () const
|
||||
{
|
||||
return _lexer_state;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _id;
|
||||
std::size_t _unique_id;
|
||||
std::size_t _lexer_state;
|
||||
node_vector _followpos;
|
||||
|
||||
virtual void copy_node (node_ptr_vector &/*node_ptr_vector_*/,
|
||||
node_stack &/*new_node_stack_*/, bool_stack &/*perform_op_stack_*/,
|
||||
bool &/*down_*/) const
|
||||
{
|
||||
// Nothing to do, as end_nodes are not copied.
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
// iteration_node.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_ITERATION_NODE_HPP
|
||||
#define BOOST_LEXER_ITERATION_NODE_HPP
|
||||
|
||||
#include "node.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class iteration_node : public node
|
||||
{
|
||||
public:
|
||||
iteration_node (node *next_, const bool greedy_) :
|
||||
node (true),
|
||||
_next (next_),
|
||||
_greedy (greedy_)
|
||||
{
|
||||
node_vector::iterator iter_;
|
||||
node_vector::iterator end_;
|
||||
|
||||
_next->append_firstpos (_firstpos);
|
||||
_next->append_lastpos (_lastpos);
|
||||
|
||||
for (iter_ = _lastpos.begin (), end_ = _lastpos.end ();
|
||||
iter_ != end_; ++iter_)
|
||||
{
|
||||
(*iter_)->append_followpos (_firstpos);
|
||||
}
|
||||
|
||||
for (iter_ = _firstpos.begin (), end_ = _firstpos.end ();
|
||||
iter_ != end_; ++iter_)
|
||||
{
|
||||
(*iter_)->greedy (greedy_);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~iteration_node ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual type what_type () const
|
||||
{
|
||||
return ITERATION;
|
||||
}
|
||||
|
||||
virtual bool traverse (const_node_stack &node_stack_,
|
||||
bool_stack &perform_op_stack_) const
|
||||
{
|
||||
perform_op_stack_.push (true);
|
||||
node_stack_.push (_next);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Not owner of this pointer...
|
||||
node *_next;
|
||||
bool _greedy;
|
||||
|
||||
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
|
||||
node_stack &new_node_stack_, bool_stack &perform_op_stack_,
|
||||
bool &down_) const
|
||||
{
|
||||
if (perform_op_stack_.top ())
|
||||
{
|
||||
node *ptr_ = new_node_stack_.top ();
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<iteration_node *>(0));
|
||||
node_ptr_vector_->back () = new iteration_node (ptr_, _greedy);
|
||||
new_node_stack_.top () = node_ptr_vector_->back ();
|
||||
}
|
||||
else
|
||||
{
|
||||
down_ = true;
|
||||
}
|
||||
|
||||
perform_op_stack_.pop ();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
// leaf_node.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_LEAF_NODE_HPP
|
||||
#define BOOST_LEXER_LEAF_NODE_HPP
|
||||
|
||||
#include "../../consts.hpp" // null_token
|
||||
#include "node.hpp"
|
||||
#include "../../size_t.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class leaf_node : public node
|
||||
{
|
||||
public:
|
||||
leaf_node (const std::size_t token_, const bool greedy_) :
|
||||
node (token_ == null_token),
|
||||
_token (token_),
|
||||
_set_greedy (!greedy_),
|
||||
_greedy (greedy_)
|
||||
{
|
||||
if (!_nullable)
|
||||
{
|
||||
_firstpos.push_back (this);
|
||||
_lastpos.push_back (this);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~leaf_node ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void append_followpos (const node_vector &followpos_)
|
||||
{
|
||||
for (node_vector::const_iterator iter_ = followpos_.begin (),
|
||||
end_ = followpos_.end (); iter_ != end_; ++iter_)
|
||||
{
|
||||
_followpos.push_back (*iter_);
|
||||
}
|
||||
}
|
||||
|
||||
virtual type what_type () const
|
||||
{
|
||||
return LEAF;
|
||||
}
|
||||
|
||||
virtual bool traverse (const_node_stack &/*node_stack_*/,
|
||||
bool_stack &/*perform_op_stack_*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::size_t token () const
|
||||
{
|
||||
return _token;
|
||||
}
|
||||
|
||||
virtual void greedy (const bool greedy_)
|
||||
{
|
||||
if (!_set_greedy)
|
||||
{
|
||||
_greedy = greedy_;
|
||||
_set_greedy = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool greedy () const
|
||||
{
|
||||
return _greedy;
|
||||
}
|
||||
|
||||
virtual const node_vector &followpos () const
|
||||
{
|
||||
return _followpos;
|
||||
}
|
||||
|
||||
virtual node_vector &followpos ()
|
||||
{
|
||||
return _followpos;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _token;
|
||||
bool _set_greedy;
|
||||
bool _greedy;
|
||||
node_vector _followpos;
|
||||
|
||||
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
|
||||
node_stack &new_node_stack_, bool_stack &/*perform_op_stack_*/,
|
||||
bool &/*down_*/) const
|
||||
{
|
||||
node_ptr_vector_->push_back (static_cast<leaf_node *>(0));
|
||||
node_ptr_vector_->back () = new leaf_node (_token, _greedy);
|
||||
new_node_stack_.push (node_ptr_vector_->back ());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
// node.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_NODE_HPP
|
||||
#define BOOST_LEXER_NODE_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include "../../containers/ptr_vector.hpp"
|
||||
#include "../../runtime_error.hpp"
|
||||
#include "../../size_t.hpp"
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class node
|
||||
{
|
||||
public:
|
||||
enum type {LEAF, SEQUENCE, SELECTION, ITERATION, END};
|
||||
|
||||
typedef std::stack<bool> bool_stack;
|
||||
typedef std::stack<node *> node_stack;
|
||||
// stack and vector not owner of node pointers
|
||||
typedef std::stack<const node *> const_node_stack;
|
||||
typedef std::vector<node *> node_vector;
|
||||
typedef ptr_vector<node> node_ptr_vector;
|
||||
|
||||
node () :
|
||||
_nullable (false)
|
||||
{
|
||||
}
|
||||
|
||||
node (const bool nullable_) :
|
||||
_nullable (nullable_)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~node ()
|
||||
{
|
||||
}
|
||||
|
||||
bool nullable () const
|
||||
{
|
||||
return _nullable;
|
||||
}
|
||||
|
||||
void append_firstpos (node_vector &firstpos_) const
|
||||
{
|
||||
firstpos_.insert (firstpos_.end (),
|
||||
_firstpos.begin (), _firstpos.end ());
|
||||
}
|
||||
|
||||
void append_lastpos (node_vector &lastpos_) const
|
||||
{
|
||||
lastpos_.insert (lastpos_.end (),
|
||||
_lastpos.begin (), _lastpos.end ());
|
||||
}
|
||||
|
||||
virtual void append_followpos (const node_vector &/*followpos_*/)
|
||||
{
|
||||
throw runtime_error ("Internal error node::append_followpos()");
|
||||
}
|
||||
|
||||
node *copy (node_ptr_vector &node_ptr_vector_) const
|
||||
{
|
||||
node *new_root_ = 0;
|
||||
const_node_stack node_stack_;
|
||||
bool_stack perform_op_stack_;
|
||||
bool down_ = true;
|
||||
node_stack new_node_stack_;
|
||||
|
||||
node_stack_.push (this);
|
||||
|
||||
while (!node_stack_.empty ())
|
||||
{
|
||||
while (down_)
|
||||
{
|
||||
down_ = node_stack_.top ()->traverse (node_stack_,
|
||||
perform_op_stack_);
|
||||
}
|
||||
|
||||
while (!down_ && !node_stack_.empty ())
|
||||
{
|
||||
const node *top_ = node_stack_.top ();
|
||||
|
||||
top_->copy_node (node_ptr_vector_, new_node_stack_,
|
||||
perform_op_stack_, down_);
|
||||
|
||||
if (!down_) node_stack_.pop ();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_ASSERT(new_node_stack_.size () == 1);
|
||||
new_root_ = new_node_stack_.top ();
|
||||
new_node_stack_.pop ();
|
||||
return new_root_;
|
||||
}
|
||||
|
||||
virtual type what_type () const = 0;
|
||||
|
||||
virtual bool traverse (const_node_stack &node_stack_,
|
||||
bool_stack &perform_op_stack_) const = 0;
|
||||
|
||||
node_vector &firstpos ()
|
||||
{
|
||||
return _firstpos;
|
||||
}
|
||||
|
||||
const node_vector &firstpos () const
|
||||
{
|
||||
return _firstpos;
|
||||
}
|
||||
|
||||
// _lastpos modified externally, so not const &
|
||||
node_vector &lastpos ()
|
||||
{
|
||||
return _lastpos;
|
||||
}
|
||||
|
||||
virtual bool end_state () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::size_t id () const
|
||||
{
|
||||
throw runtime_error ("Internal error node::id()");
|
||||
}
|
||||
|
||||
virtual std::size_t unique_id () const
|
||||
{
|
||||
throw runtime_error ("Internal error node::unique_id()");
|
||||
}
|
||||
|
||||
virtual std::size_t lexer_state () const
|
||||
{
|
||||
throw runtime_error ("Internal error node::state()");
|
||||
}
|
||||
|
||||
virtual std::size_t token () const
|
||||
{
|
||||
throw runtime_error ("Internal error node::token()");
|
||||
}
|
||||
|
||||
virtual void greedy (const bool /*greedy_*/)
|
||||
{
|
||||
throw runtime_error ("Internal error node::token(bool)");
|
||||
}
|
||||
|
||||
virtual bool greedy () const
|
||||
{
|
||||
throw runtime_error ("Internal error node::token()");
|
||||
}
|
||||
|
||||
virtual const node_vector &followpos () const
|
||||
{
|
||||
throw runtime_error ("Internal error node::followpos()");
|
||||
}
|
||||
|
||||
virtual node_vector &followpos ()
|
||||
{
|
||||
throw runtime_error ("Internal error node::followpos()");
|
||||
}
|
||||
|
||||
protected:
|
||||
const bool _nullable;
|
||||
node_vector _firstpos;
|
||||
node_vector _lastpos;
|
||||
|
||||
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
|
||||
node_stack &new_node_stack_, bool_stack &perform_op_stack_,
|
||||
bool &down_) const = 0;
|
||||
|
||||
private:
|
||||
node (node const &); // No copy construction.
|
||||
node &operator = (node const &); // No assignment.
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
// selection_node.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_SELECTION_NODE_HPP
|
||||
#define BOOST_LEXER_SELECTION_NODE_HPP
|
||||
|
||||
#include "node.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class selection_node : public node
|
||||
{
|
||||
public:
|
||||
selection_node (node *left_, node *right_) :
|
||||
node (left_->nullable () || right_->nullable ()),
|
||||
_left (left_),
|
||||
_right (right_)
|
||||
{
|
||||
_left->append_firstpos (_firstpos);
|
||||
_right->append_firstpos (_firstpos);
|
||||
_left->append_lastpos (_lastpos);
|
||||
_right->append_lastpos (_lastpos);
|
||||
}
|
||||
|
||||
virtual ~selection_node ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual type what_type () const
|
||||
{
|
||||
return SELECTION;
|
||||
}
|
||||
|
||||
virtual bool traverse (const_node_stack &node_stack_,
|
||||
bool_stack &perform_op_stack_) const
|
||||
{
|
||||
perform_op_stack_.push (true);
|
||||
|
||||
switch (_right->what_type ())
|
||||
{
|
||||
case SEQUENCE:
|
||||
case SELECTION:
|
||||
case ITERATION:
|
||||
perform_op_stack_.push (false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
node_stack_.push (_right);
|
||||
node_stack_.push (_left);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Not owner of these pointers...
|
||||
node *_left;
|
||||
node *_right;
|
||||
|
||||
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
|
||||
node_stack &new_node_stack_, bool_stack &perform_op_stack_,
|
||||
bool &down_) const
|
||||
{
|
||||
if (perform_op_stack_.top ())
|
||||
{
|
||||
node *rhs_ = new_node_stack_.top ();
|
||||
|
||||
new_node_stack_.pop ();
|
||||
|
||||
node *lhs_ = new_node_stack_.top ();
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<selection_node *>(0));
|
||||
node_ptr_vector_->back () = new selection_node (lhs_, rhs_);
|
||||
new_node_stack_.top () = node_ptr_vector_->back ();
|
||||
}
|
||||
else
|
||||
{
|
||||
down_ = true;
|
||||
}
|
||||
|
||||
perform_op_stack_.pop ();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
// sequence_node.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_SEQUENCE_NODE_HPP
|
||||
#define BOOST_LEXER_SEQUENCE_NODE_HPP
|
||||
|
||||
#include "node.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class sequence_node : public node
|
||||
{
|
||||
public:
|
||||
sequence_node (node *left_, node *right_) :
|
||||
node (left_->nullable () && right_->nullable ()),
|
||||
_left (left_),
|
||||
_right (right_)
|
||||
{
|
||||
_left->append_firstpos (_firstpos);
|
||||
|
||||
if (_left->nullable ())
|
||||
{
|
||||
_right->append_firstpos (_firstpos);
|
||||
}
|
||||
|
||||
if (_right->nullable ())
|
||||
{
|
||||
_left->append_lastpos (_lastpos);
|
||||
}
|
||||
|
||||
_right->append_lastpos (_lastpos);
|
||||
|
||||
node_vector &lastpos_ = _left->lastpos ();
|
||||
const node_vector &firstpos_ = _right->firstpos ();
|
||||
|
||||
for (node_vector::iterator iter_ = lastpos_.begin (),
|
||||
end_ = lastpos_.end (); iter_ != end_; ++iter_)
|
||||
{
|
||||
(*iter_)->append_followpos (firstpos_);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~sequence_node ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual type what_type () const
|
||||
{
|
||||
return SEQUENCE;
|
||||
}
|
||||
|
||||
virtual bool traverse (const_node_stack &node_stack_,
|
||||
bool_stack &perform_op_stack_) const
|
||||
{
|
||||
perform_op_stack_.push (true);
|
||||
|
||||
switch (_right->what_type ())
|
||||
{
|
||||
case SEQUENCE:
|
||||
case SELECTION:
|
||||
case ITERATION:
|
||||
perform_op_stack_.push (false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
node_stack_.push (_right);
|
||||
node_stack_.push (_left);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Not owner of these pointers...
|
||||
node *_left;
|
||||
node *_right;
|
||||
|
||||
virtual void copy_node (node_ptr_vector &node_ptr_vector_,
|
||||
node_stack &new_node_stack_, bool_stack &perform_op_stack_,
|
||||
bool &down_) const
|
||||
{
|
||||
if (perform_op_stack_.top ())
|
||||
{
|
||||
node *rhs_ = new_node_stack_.top ();
|
||||
|
||||
new_node_stack_.pop ();
|
||||
|
||||
node *lhs_ = new_node_stack_.top ();
|
||||
|
||||
node_ptr_vector_->push_back (static_cast<sequence_node *>(0));
|
||||
node_ptr_vector_->back () = new sequence_node (lhs_, rhs_);
|
||||
new_node_stack_.top () = node_ptr_vector_->back ();
|
||||
}
|
||||
else
|
||||
{
|
||||
down_ = true;
|
||||
}
|
||||
|
||||
perform_op_stack_.pop ();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
// charset.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_CHARSET_HPP
|
||||
#define BOOST_LEXER_CHARSET_HPP
|
||||
|
||||
#include <set>
|
||||
#include "../size_t.hpp"
|
||||
#include "../string_token.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename CharT>
|
||||
struct basic_charset
|
||||
{
|
||||
typedef basic_string_token<CharT> token;
|
||||
typedef std::set<std::size_t> index_set;
|
||||
|
||||
token _token;
|
||||
index_set _index_set;
|
||||
|
||||
basic_charset ()
|
||||
{
|
||||
}
|
||||
|
||||
basic_charset (const token &token_, const std::size_t index_) :
|
||||
_token (token_)
|
||||
{
|
||||
_index_set.insert (index_);
|
||||
}
|
||||
|
||||
bool empty () const
|
||||
{
|
||||
return _token.empty () && _index_set.empty ();
|
||||
}
|
||||
|
||||
void intersect (basic_charset &rhs_, basic_charset &overlap_)
|
||||
{
|
||||
_token.intersect (rhs_._token, overlap_._token);
|
||||
|
||||
if (!overlap_._token.empty ())
|
||||
{
|
||||
typename index_set::const_iterator iter_ = _index_set.begin ();
|
||||
typename index_set::const_iterator end_ = _index_set.end ();
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
overlap_._index_set.insert (*iter_);
|
||||
}
|
||||
|
||||
iter_ = rhs_._index_set.begin ();
|
||||
end_ = rhs_._index_set.end ();
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
overlap_._index_set.insert (*iter_);
|
||||
}
|
||||
|
||||
if (_token.empty ())
|
||||
{
|
||||
_index_set.clear ();
|
||||
}
|
||||
|
||||
if (rhs_._token.empty ())
|
||||
{
|
||||
rhs_._index_set.clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
// equivset.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_EQUIVSET_HPP
|
||||
#define BOOST_LEXER_EQUIVSET_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include "../parser/tree/node.hpp"
|
||||
#include <set>
|
||||
#include "../size_t.hpp"
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct equivset
|
||||
{
|
||||
typedef std::set<std::size_t> index_set;
|
||||
typedef std::vector<std::size_t> index_vector;
|
||||
// Not owner of nodes:
|
||||
typedef std::vector<node *> node_vector;
|
||||
|
||||
index_vector _index_vector;
|
||||
bool _greedy;
|
||||
std::size_t _id;
|
||||
node_vector _followpos;
|
||||
|
||||
equivset () :
|
||||
_greedy (true),
|
||||
_id (0)
|
||||
{
|
||||
}
|
||||
|
||||
equivset (const index_set &index_set_, const bool greedy_,
|
||||
const std::size_t id_, const node_vector &followpos_) :
|
||||
_greedy (greedy_),
|
||||
_id (id_),
|
||||
_followpos (followpos_)
|
||||
{
|
||||
index_set::const_iterator iter_ = index_set_.begin ();
|
||||
index_set::const_iterator end_ = index_set_.end ();
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
_index_vector.push_back (*iter_);
|
||||
}
|
||||
}
|
||||
|
||||
bool empty () const
|
||||
{
|
||||
return _index_vector.empty () && _followpos.empty ();
|
||||
}
|
||||
|
||||
void intersect (equivset &rhs_, equivset &overlap_)
|
||||
{
|
||||
intersect_indexes (rhs_._index_vector, overlap_._index_vector);
|
||||
|
||||
if (!overlap_._index_vector.empty ())
|
||||
{
|
||||
// Note that the LHS takes priority in order to
|
||||
// respect rule ordering priority in the lex spec.
|
||||
overlap_._id = _id;
|
||||
overlap_._greedy = _greedy;
|
||||
overlap_._followpos = _followpos;
|
||||
|
||||
node_vector::const_iterator overlap_begin_ =
|
||||
overlap_._followpos.begin ();
|
||||
node_vector::const_iterator overlap_end_ =
|
||||
overlap_._followpos.end ();
|
||||
node_vector::const_iterator rhs_iter_ =
|
||||
rhs_._followpos.begin ();
|
||||
node_vector::const_iterator rhs_end_ =
|
||||
rhs_._followpos.end ();
|
||||
|
||||
for (; rhs_iter_ != rhs_end_; ++rhs_iter_)
|
||||
{
|
||||
node *node_ = *rhs_iter_;
|
||||
|
||||
if (std::find (overlap_begin_, overlap_end_, node_) ==
|
||||
overlap_end_)
|
||||
{
|
||||
overlap_._followpos.push_back (node_);
|
||||
overlap_begin_ = overlap_._followpos.begin ();
|
||||
overlap_end_ = overlap_._followpos.end ();
|
||||
}
|
||||
}
|
||||
|
||||
if (_index_vector.empty ())
|
||||
{
|
||||
_followpos.clear ();
|
||||
}
|
||||
|
||||
if (rhs_._index_vector.empty ())
|
||||
{
|
||||
rhs_._followpos.clear ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void intersect_indexes (index_vector &rhs_, index_vector &overlap_)
|
||||
{
|
||||
index_vector::iterator iter_ = _index_vector.begin ();
|
||||
index_vector::iterator end_ = _index_vector.end ();
|
||||
index_vector::iterator rhs_iter_ = rhs_.begin ();
|
||||
index_vector::iterator rhs_end_ = rhs_.end ();
|
||||
|
||||
while (iter_ != end_ && rhs_iter_ != rhs_end_)
|
||||
{
|
||||
const std::size_t index_ = *iter_;
|
||||
const std::size_t rhs_index_ = *rhs_iter_;
|
||||
|
||||
if (index_ < rhs_index_)
|
||||
{
|
||||
++iter_;
|
||||
}
|
||||
else if (index_ > rhs_index_)
|
||||
{
|
||||
++rhs_iter_;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlap_.push_back (index_);
|
||||
iter_ = _index_vector.erase (iter_);
|
||||
end_ = _index_vector.end ();
|
||||
rhs_iter_ = rhs_.erase (rhs_iter_);
|
||||
rhs_end_ = rhs_.end ();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,806 @@
|
||||
// rules.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_RULES_HPP
|
||||
#define BOOST_LEXER_RULES_HPP
|
||||
|
||||
#include "consts.hpp"
|
||||
#include <deque>
|
||||
#include <locale>
|
||||
#include <map>
|
||||
#include "runtime_error.hpp"
|
||||
#include <set>
|
||||
#include "size_t.hpp"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// return name of initial state
|
||||
template <typename CharT>
|
||||
struct strings;
|
||||
|
||||
template <>
|
||||
struct strings<char>
|
||||
{
|
||||
static const char *initial ()
|
||||
{
|
||||
return "INITIAL";
|
||||
}
|
||||
|
||||
static const char *dot ()
|
||||
{
|
||||
return ".";
|
||||
}
|
||||
|
||||
static const char *all_states ()
|
||||
{
|
||||
return "*";
|
||||
}
|
||||
|
||||
static const char *char_name ()
|
||||
{
|
||||
return "char";
|
||||
}
|
||||
|
||||
static const char *char_prefix ()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct strings<wchar_t>
|
||||
{
|
||||
static const wchar_t *initial ()
|
||||
{
|
||||
return L"INITIAL";
|
||||
}
|
||||
|
||||
static const wchar_t *dot ()
|
||||
{
|
||||
return L".";
|
||||
}
|
||||
|
||||
static const wchar_t *all_states ()
|
||||
{
|
||||
return L"*";
|
||||
}
|
||||
|
||||
static const char *char_name ()
|
||||
{
|
||||
return "wchar_t";
|
||||
}
|
||||
|
||||
static const char *char_prefix ()
|
||||
{
|
||||
return "L";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename CharT>
|
||||
class basic_rules
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::size_t> id_vector;
|
||||
typedef std::deque<id_vector> id_vector_deque;
|
||||
typedef std::basic_string<CharT> string;
|
||||
typedef std::deque<string> string_deque;
|
||||
typedef std::deque<string_deque> string_deque_deque;
|
||||
typedef std::set<string> string_set;
|
||||
typedef std::pair<string, string> string_pair;
|
||||
typedef std::deque<string_pair> string_pair_deque;
|
||||
typedef std::map<string, std::size_t> string_size_t_map;
|
||||
typedef std::pair<string, std::size_t> string_size_t_pair;
|
||||
|
||||
basic_rules (const regex_flags flags_ = dot_not_newline,
|
||||
std::size_t (*counter_ptr_) () = 0) :
|
||||
_flags (flags_),
|
||||
_counter (0),
|
||||
_counter_ptr (counter_ptr_)
|
||||
{
|
||||
add_state (initial ());
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
_statemap.clear ();
|
||||
_macrodeque.clear ();
|
||||
_macroset.clear ();
|
||||
_regexes.clear ();
|
||||
_ids.clear ();
|
||||
_unique_ids.clear ();
|
||||
_states.clear ();
|
||||
_flags = dot_not_newline;
|
||||
_locale = std::locale ();
|
||||
add_state (initial ());
|
||||
}
|
||||
|
||||
void clear (const CharT *state_name_)
|
||||
{
|
||||
std::size_t state_ = state (state_name_);
|
||||
|
||||
if (state_ != npos)
|
||||
{
|
||||
_regexes[state_].clear ();
|
||||
_ids[state_].clear ();
|
||||
_unique_ids[state_].clear ();
|
||||
_states[state_].clear ();
|
||||
}
|
||||
}
|
||||
|
||||
void flags (const regex_flags flags_)
|
||||
{
|
||||
_flags = flags_;
|
||||
}
|
||||
|
||||
regex_flags flags () const
|
||||
{
|
||||
return _flags;
|
||||
}
|
||||
|
||||
std::size_t next_unique_id ()
|
||||
{
|
||||
return _counter_ptr ? _counter_ptr () : _counter++;
|
||||
}
|
||||
|
||||
std::locale imbue (std::locale &locale_)
|
||||
{
|
||||
std::locale loc_ = _locale;
|
||||
|
||||
_locale = locale_;
|
||||
return loc_;
|
||||
}
|
||||
|
||||
const std::locale &locale () const
|
||||
{
|
||||
return _locale;
|
||||
}
|
||||
|
||||
std::size_t state (const CharT *name_) const
|
||||
{
|
||||
std::size_t state_ = npos;
|
||||
typename string_size_t_map::const_iterator iter_ =
|
||||
_statemap.find (name_);
|
||||
|
||||
if (iter_ != _statemap.end ())
|
||||
{
|
||||
state_ = iter_->second;
|
||||
}
|
||||
|
||||
return state_;
|
||||
}
|
||||
|
||||
const CharT *state (const std::size_t index_) const
|
||||
{
|
||||
if (index_ == 0)
|
||||
{
|
||||
return initial ();
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::size_t vec_index_ = index_ - 1;
|
||||
|
||||
if (vec_index_ > _lexer_state_names.size () - 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _lexer_state_names[vec_index_].c_str ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t add_state (const CharT *name_)
|
||||
{
|
||||
validate (name_);
|
||||
|
||||
if (_statemap.insert (string_size_t_pair (name_,
|
||||
_statemap.size ())).second)
|
||||
{
|
||||
_regexes.push_back (string_deque ());
|
||||
_ids.push_back (id_vector ());
|
||||
_unique_ids.push_back (id_vector ());
|
||||
_states.push_back (id_vector ());
|
||||
|
||||
if (string (name_) != initial ())
|
||||
{
|
||||
_lexer_state_names.push_back (name_);
|
||||
}
|
||||
}
|
||||
|
||||
// Initial is not stored, so no need to - 1.
|
||||
return _lexer_state_names.size ();
|
||||
}
|
||||
|
||||
void add_macro (const CharT *name_, const CharT *regex_)
|
||||
{
|
||||
add_macro (name_, string (regex_));
|
||||
}
|
||||
|
||||
void add_macro (const CharT *name_, const CharT *regex_start_,
|
||||
const CharT *regex_end_)
|
||||
{
|
||||
add_macro (name_, string (regex_start_, regex_end_));
|
||||
}
|
||||
|
||||
void add_macro (const CharT *name_, const string ®ex_)
|
||||
{
|
||||
validate (name_);
|
||||
|
||||
typename string_set::const_iterator iter_ = _macroset.find (name_);
|
||||
|
||||
if (iter_ == _macroset.end ())
|
||||
{
|
||||
_macrodeque.push_back (string_pair (name_, regex_));
|
||||
_macroset.insert (name_);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "Attempt to redefine MACRO '";
|
||||
|
||||
while (*name_)
|
||||
{
|
||||
os_ << ss_.narrow (*name_++, static_cast<CharT> (' '));
|
||||
}
|
||||
|
||||
os_ << "'.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
}
|
||||
|
||||
void add_macros (const basic_rules<CharT> &rules_)
|
||||
{
|
||||
const string_pair_deque ¯os_ = rules_.macrodeque ();
|
||||
typename string_pair_deque::const_iterator macro_iter_ =
|
||||
macros_.begin ();
|
||||
typename string_pair_deque::const_iterator macro_end_ =
|
||||
macros_.end ();
|
||||
|
||||
for (; macro_iter_ != macro_end_; ++macro_iter_)
|
||||
{
|
||||
add_macro (macro_iter_->first.c_str (),
|
||||
macro_iter_->second.c_str ());
|
||||
}
|
||||
}
|
||||
|
||||
void merge_macros (const basic_rules<CharT> &rules_)
|
||||
{
|
||||
const string_pair_deque ¯os_ = rules_.macrodeque ();
|
||||
typename string_pair_deque::const_iterator macro_iter_ =
|
||||
macros_.begin ();
|
||||
typename string_pair_deque::const_iterator macro_end_ =
|
||||
macros_.end ();
|
||||
typename string_set::const_iterator macro_dest_iter_;
|
||||
typename string_set::const_iterator macro_dest_end_ = _macroset.end ();
|
||||
|
||||
for (; macro_iter_ != macro_end_; ++macro_iter_)
|
||||
{
|
||||
macro_dest_iter_ = _macroset.find (macro_iter_->first);
|
||||
|
||||
if (macro_dest_iter_ == macro_dest_end_)
|
||||
{
|
||||
add_macro (macro_iter_->first.c_str (),
|
||||
macro_iter_->second.c_str ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t add (const CharT *regex_, const std::size_t id_)
|
||||
{
|
||||
return add (string (regex_), id_);
|
||||
}
|
||||
|
||||
std::size_t add (const CharT *regex_start_, const CharT *regex_end_,
|
||||
const std::size_t id_)
|
||||
{
|
||||
return add (string (regex_start_, regex_end_), id_);
|
||||
}
|
||||
|
||||
std::size_t add (const string ®ex_, const std::size_t id_)
|
||||
{
|
||||
const std::size_t counter_ = next_unique_id ();
|
||||
|
||||
check_for_invalid_id (id_);
|
||||
_regexes.front ().push_back (regex_);
|
||||
_ids.front ().push_back (id_);
|
||||
_unique_ids.front ().push_back (counter_);
|
||||
_states.front ().push_back (0);
|
||||
return counter_;
|
||||
}
|
||||
|
||||
std::size_t add (const CharT *curr_state_, const CharT *regex_,
|
||||
const CharT *new_state_)
|
||||
{
|
||||
return add (curr_state_, string (regex_), new_state_);
|
||||
}
|
||||
|
||||
std::size_t add (const CharT *curr_state_, const CharT *regex_start_,
|
||||
const CharT *regex_end_, const CharT *new_state_)
|
||||
{
|
||||
return add (curr_state_, string (regex_start_, regex_end_),
|
||||
new_state_);
|
||||
}
|
||||
|
||||
std::size_t add (const CharT *curr_state_, const string ®ex_,
|
||||
const CharT *new_state_)
|
||||
{
|
||||
return add (curr_state_, regex_, 0, new_state_, false);
|
||||
}
|
||||
|
||||
std::size_t add (const CharT *curr_state_, const CharT *regex_,
|
||||
const std::size_t id_, const CharT *new_state_)
|
||||
{
|
||||
return add (curr_state_, string (regex_), id_, new_state_);
|
||||
}
|
||||
|
||||
std::size_t add (const CharT *curr_state_, const CharT *regex_start_,
|
||||
const CharT *regex_end_, const std::size_t id_,
|
||||
const CharT *new_state_)
|
||||
{
|
||||
return add (curr_state_, string (regex_start_, regex_end_), id_,
|
||||
new_state_);
|
||||
}
|
||||
|
||||
std::size_t add (const CharT *curr_state_, const string ®ex_,
|
||||
const std::size_t id_, const CharT *new_state_)
|
||||
{
|
||||
return add (curr_state_, regex_, id_, new_state_, true);
|
||||
}
|
||||
|
||||
void add (const CharT *source_, const basic_rules<CharT> &rules_,
|
||||
const CharT *dest_, const CharT *to_ = detail::strings<CharT>::dot ())
|
||||
{
|
||||
const bool star_ = *source_ == '*' && *(source_ + 1) == 0;
|
||||
const bool dest_dot_ = *dest_ == '.' && *(dest_ + 1) == 0;
|
||||
const bool to_dot_ = *to_ == '.' && *(to_ + 1) == 0;
|
||||
std::size_t state_ = 0;
|
||||
const string_deque_deque &all_regexes_ = rules_.regexes ();
|
||||
const id_vector_deque &all_ids_ = rules_.ids ();
|
||||
const id_vector_deque &all_unique_ids_ = rules_.unique_ids ();
|
||||
const id_vector_deque &all_states_ = rules_.states ();
|
||||
typename string_deque::const_iterator regex_iter_;
|
||||
typename string_deque::const_iterator regex_end_;
|
||||
typename id_vector::const_iterator id_iter_;
|
||||
typename id_vector::const_iterator uid_iter_;
|
||||
typename id_vector::const_iterator state_iter_;
|
||||
|
||||
if (star_)
|
||||
{
|
||||
typename string_deque_deque::const_iterator all_regexes_iter_ =
|
||||
all_regexes_.begin ();
|
||||
typename string_deque_deque::const_iterator all_regexes_end_ =
|
||||
all_regexes_.end ();
|
||||
typename id_vector_deque::const_iterator all_ids_iter_ =
|
||||
all_ids_.begin ();
|
||||
typename id_vector_deque::const_iterator all_uids_iter_ =
|
||||
all_unique_ids_.begin ();
|
||||
typename id_vector_deque::const_iterator all_states_iter_ =
|
||||
all_states_.begin ();
|
||||
|
||||
for (; all_regexes_iter_ != all_regexes_end_;
|
||||
++state_, ++all_regexes_iter_, ++all_ids_iter_,
|
||||
++all_uids_iter_, ++all_states_iter_)
|
||||
{
|
||||
regex_iter_ = all_regexes_iter_->begin ();
|
||||
regex_end_ = all_regexes_iter_->end ();
|
||||
id_iter_ = all_ids_iter_->begin ();
|
||||
uid_iter_ = all_uids_iter_->begin ();
|
||||
state_iter_ = all_states_iter_->begin ();
|
||||
|
||||
for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
|
||||
++uid_iter_, ++state_iter_)
|
||||
{
|
||||
// If ..._dot_ then lookup state name from rules_; otherwise
|
||||
// pass name through.
|
||||
add (dest_dot_ ? rules_.state (state_) : dest_, *regex_iter_,
|
||||
*id_iter_, to_dot_ ? rules_.state (*state_iter_) : to_, true,
|
||||
*uid_iter_);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const CharT *start_ = source_;
|
||||
string state_name_;
|
||||
|
||||
while (*source_)
|
||||
{
|
||||
while (*source_ && *source_ != ',')
|
||||
{
|
||||
++source_;
|
||||
}
|
||||
|
||||
state_name_.assign (start_, source_);
|
||||
|
||||
if (*source_)
|
||||
{
|
||||
++source_;
|
||||
start_ = source_;
|
||||
}
|
||||
|
||||
state_ = rules_.state (state_name_.c_str ());
|
||||
|
||||
if (state_ == npos)
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "Unknown state name '";
|
||||
source_ = state_name_.c_str ();
|
||||
|
||||
while (*source_)
|
||||
{
|
||||
os_ << ss_.narrow (*source_++, ' ');
|
||||
}
|
||||
|
||||
os_ << "'.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
|
||||
regex_iter_ = all_regexes_[state_].begin ();
|
||||
regex_end_ = all_regexes_[state_].end ();
|
||||
id_iter_ = all_ids_[state_].begin ();
|
||||
uid_iter_ = all_unique_ids_[state_].begin ();
|
||||
state_iter_ = all_states_[state_].begin ();
|
||||
|
||||
for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
|
||||
++uid_iter_, ++state_iter_)
|
||||
{
|
||||
// If ..._dot_ then lookup state name from rules_; otherwise
|
||||
// pass name through.
|
||||
add (dest_dot_ ? state_name_.c_str () : dest_, *regex_iter_,
|
||||
*id_iter_, to_dot_ ? rules_.state (*state_iter_) : to_, true,
|
||||
*uid_iter_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
void add (const CharT *curr_state_, const basic_rules<CharT> &rules_)
|
||||
{
|
||||
const string_deque_deque ®exes_ = rules_.regexes ();
|
||||
const id_vector_deque &ids_ = rules_.ids ();
|
||||
const id_vector_deque &unique_ids_ = rules_.unique_ids ();
|
||||
typename string_deque_deque::const_iterator state_regex_iter_ =
|
||||
regexes_.begin ();
|
||||
typename string_deque_deque::const_iterator state_regex_end_ =
|
||||
regexes_.end ();
|
||||
typename id_vector_deque::const_iterator state_id_iter_ =
|
||||
ids_.begin ();
|
||||
typename id_vector_deque::const_iterator state_uid_iter_ =
|
||||
unique_ids_.begin ();
|
||||
typename string_deque::const_iterator regex_iter_;
|
||||
typename string_deque::const_iterator regex_end_;
|
||||
typename id_vector::const_iterator id_iter_;
|
||||
typename id_vector::const_iterator uid_iter_;
|
||||
|
||||
for (; state_regex_iter_ != state_regex_end_; ++state_regex_iter_)
|
||||
{
|
||||
regex_iter_ = state_regex_iter_->begin ();
|
||||
regex_end_ = state_regex_iter_->end ();
|
||||
id_iter_ = state_id_iter_->begin ();
|
||||
uid_iter_ = state_uid_iter_->begin ();
|
||||
|
||||
for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
|
||||
++uid_iter_)
|
||||
{
|
||||
add (curr_state_, *regex_iter_, *id_iter_, curr_state_, true,
|
||||
*uid_iter_);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
const string_size_t_map &statemap () const
|
||||
{
|
||||
return _statemap;
|
||||
}
|
||||
|
||||
const string_pair_deque ¯odeque () const
|
||||
{
|
||||
return _macrodeque;
|
||||
}
|
||||
|
||||
const string_deque_deque ®exes () const
|
||||
{
|
||||
return _regexes;
|
||||
}
|
||||
|
||||
const id_vector_deque &ids () const
|
||||
{
|
||||
return _ids;
|
||||
}
|
||||
|
||||
const id_vector_deque &unique_ids () const
|
||||
{
|
||||
return _unique_ids;
|
||||
}
|
||||
|
||||
const id_vector_deque &states () const
|
||||
{
|
||||
return _states;
|
||||
}
|
||||
|
||||
bool empty () const
|
||||
{
|
||||
typename string_deque_deque::const_iterator iter_ = _regexes.begin ();
|
||||
typename string_deque_deque::const_iterator end_ = _regexes.end ();
|
||||
bool empty_ = true;
|
||||
|
||||
for (; iter_ != end_; ++iter_)
|
||||
{
|
||||
if (!iter_->empty ())
|
||||
{
|
||||
empty_ = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return empty_;
|
||||
}
|
||||
|
||||
static const CharT *initial ()
|
||||
{
|
||||
return detail::strings<CharT>::initial ();
|
||||
}
|
||||
|
||||
static const CharT *all_states ()
|
||||
{
|
||||
return detail::strings<CharT>::all_states ();
|
||||
}
|
||||
|
||||
static const CharT *dot ()
|
||||
{
|
||||
return detail::strings<CharT>::dot ();
|
||||
}
|
||||
|
||||
private:
|
||||
string_size_t_map _statemap;
|
||||
string_pair_deque _macrodeque;
|
||||
string_set _macroset;
|
||||
string_deque_deque _regexes;
|
||||
id_vector_deque _ids;
|
||||
id_vector_deque _unique_ids;
|
||||
id_vector_deque _states;
|
||||
regex_flags _flags;
|
||||
std::size_t _counter;
|
||||
std::size_t (*_counter_ptr) ();
|
||||
std::locale _locale;
|
||||
string_deque _lexer_state_names;
|
||||
|
||||
std::size_t add (const CharT *curr_state_, const string ®ex_,
|
||||
const std::size_t id_, const CharT *new_state_, const bool check_,
|
||||
const std::size_t uid_ = npos)
|
||||
{
|
||||
const bool star_ = *curr_state_ == '*' && *(curr_state_ + 1) == 0;
|
||||
const bool dot_ = *new_state_ == '.' && *(new_state_ + 1) == 0;
|
||||
|
||||
if (check_)
|
||||
{
|
||||
check_for_invalid_id (id_);
|
||||
}
|
||||
|
||||
if (!dot_)
|
||||
{
|
||||
validate (new_state_);
|
||||
}
|
||||
|
||||
std::size_t new_ = string::npos;
|
||||
typename string_size_t_map::const_iterator iter_;
|
||||
typename string_size_t_map::const_iterator end_ = _statemap.end ();
|
||||
id_vector states_;
|
||||
|
||||
if (!dot_)
|
||||
{
|
||||
iter_ = _statemap.find (new_state_);
|
||||
|
||||
if (iter_ == end_)
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "Unknown state name '";
|
||||
|
||||
while (*new_state_)
|
||||
{
|
||||
os_ << ss_.narrow (*new_state_++, ' ');
|
||||
}
|
||||
|
||||
os_ << "'.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
|
||||
new_ = iter_->second;
|
||||
}
|
||||
|
||||
if (star_)
|
||||
{
|
||||
const std::size_t size_ = _statemap.size ();
|
||||
|
||||
for (std::size_t i_ = 0; i_ < size_; ++i_)
|
||||
{
|
||||
states_.push_back (i_);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const CharT *start_ = curr_state_;
|
||||
string state_;
|
||||
|
||||
while (*curr_state_)
|
||||
{
|
||||
while (*curr_state_ && *curr_state_ != ',')
|
||||
{
|
||||
++curr_state_;
|
||||
}
|
||||
|
||||
state_.assign (start_, curr_state_);
|
||||
|
||||
if (*curr_state_)
|
||||
{
|
||||
++curr_state_;
|
||||
start_ = curr_state_;
|
||||
}
|
||||
|
||||
validate (state_.c_str ());
|
||||
iter_ = _statemap.find (state_.c_str ());
|
||||
|
||||
if (iter_ == end_)
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "Unknown state name '";
|
||||
curr_state_ = state_.c_str ();
|
||||
|
||||
while (*curr_state_)
|
||||
{
|
||||
os_ << ss_.narrow (*curr_state_++, ' ');
|
||||
}
|
||||
|
||||
os_ << "'.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
|
||||
states_.push_back (iter_->second);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t first_counter_ = npos;
|
||||
|
||||
for (std::size_t i_ = 0, size_ = states_.size (); i_ < size_; ++i_)
|
||||
{
|
||||
const std::size_t curr_ = states_[i_];
|
||||
|
||||
_regexes[curr_].push_back (regex_);
|
||||
_ids[curr_].push_back (id_);
|
||||
|
||||
if (uid_ == npos)
|
||||
{
|
||||
const std::size_t counter_ = next_unique_id ();
|
||||
|
||||
if (first_counter_ == npos)
|
||||
{
|
||||
first_counter_ = counter_;
|
||||
}
|
||||
|
||||
_unique_ids[curr_].push_back (counter_);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (first_counter_ == npos)
|
||||
{
|
||||
first_counter_ = uid_;
|
||||
}
|
||||
|
||||
_unique_ids[curr_].push_back (uid_);
|
||||
}
|
||||
|
||||
_states[curr_].push_back (dot_ ? curr_ : new_);
|
||||
}
|
||||
|
||||
return first_counter_;
|
||||
}
|
||||
|
||||
void validate (const CharT *name_) const
|
||||
{
|
||||
const CharT *start_ = name_;
|
||||
|
||||
if (*name_ != '_' && !(*name_ >= 'A' && *name_ <= 'Z') &&
|
||||
!(*name_ >= 'a' && *name_ <= 'z'))
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "Invalid name '";
|
||||
|
||||
while (*name_)
|
||||
{
|
||||
os_ << ss_.narrow (*name_++, ' ');
|
||||
}
|
||||
|
||||
os_ << "'.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
else if (*name_)
|
||||
{
|
||||
++name_;
|
||||
}
|
||||
|
||||
while (*name_)
|
||||
{
|
||||
if (*name_ != '_' && *name_ != '-' &&
|
||||
!(*name_ >= 'A' && *name_ <= 'Z') &&
|
||||
!(*name_ >= 'a' && *name_ <= 'z') &&
|
||||
!(*name_ >= '0' && *name_ <= '9'))
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "Invalid name '";
|
||||
name_ = start_;
|
||||
|
||||
while (*name_)
|
||||
{
|
||||
os_ << ss_.narrow (*name_++, ' ');
|
||||
}
|
||||
|
||||
os_ << "'.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
|
||||
++name_;
|
||||
}
|
||||
|
||||
if (name_ - start_ > static_cast<std::ptrdiff_t>(max_macro_len))
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
std::ostringstream os_;
|
||||
|
||||
os_ << "Name '";
|
||||
name_ = start_;
|
||||
|
||||
while (*name_)
|
||||
{
|
||||
os_ << ss_.narrow (*name_++, ' ');
|
||||
}
|
||||
|
||||
os_ << "' too long.";
|
||||
throw runtime_error (os_.str ());
|
||||
}
|
||||
}
|
||||
|
||||
void check_for_invalid_id (const std::size_t id_) const
|
||||
{
|
||||
switch (id_)
|
||||
{
|
||||
case 0:
|
||||
throw runtime_error ("id 0 is reserved for EOF.");
|
||||
case npos:
|
||||
throw runtime_error ("id npos is reserved for the "
|
||||
"UNKNOWN token.");
|
||||
default:
|
||||
// OK
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_rules<char> rules;
|
||||
typedef basic_rules<wchar_t> wrules;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// runtime_error.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_RUNTIME_ERROR_HPP
|
||||
#define BOOST_LEXER_RUNTIME_ERROR_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
class runtime_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
runtime_error (const std::string &what_arg_) :
|
||||
std::runtime_error (what_arg_)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// examples/serialise.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_SERIALISE_HPP
|
||||
#define BOOST_LEXER_SERIALISE_HPP
|
||||
|
||||
#include "internals.hpp"
|
||||
#include "state_machine.hpp"
|
||||
#include <boost/serialization/vector.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
// IMPORTANT! This won't work if you don't enable RTTI!
|
||||
template<typename CharT, class Archive>
|
||||
void serialise (basic_state_machine<CharT> &sm_, Archive &ar_,
|
||||
unsigned int version_ = 1)
|
||||
{
|
||||
detail::internals &internals_ = const_cast<detail::internals &>
|
||||
(sm_.data ());
|
||||
|
||||
ar_ & version_;
|
||||
ar_ & *internals_._lookup;
|
||||
ar_ & internals_._dfa_alphabet;
|
||||
ar_ & *internals_._dfa;
|
||||
ar_ & internals_._seen_BOL_assertion;
|
||||
ar_ & internals_._seen_EOL_assertion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
// size_t.h
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_SIZE_T_H
|
||||
#define BOOST_LEXER_SIZE_T_H
|
||||
|
||||
#include <stddef.h> // ptrdiff_t
|
||||
|
||||
#include <string>
|
||||
|
||||
#endif
|
||||
+431
@@ -0,0 +1,431 @@
|
||||
// state_machine.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_STATE_MACHINE_HPP
|
||||
#define BOOST_LEXER_STATE_MACHINE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include "conversion/char_state_machine.hpp"
|
||||
#include "consts.hpp"
|
||||
#include <deque>
|
||||
#include "internals.hpp"
|
||||
#include <map>
|
||||
#include "containers/ptr_vector.hpp"
|
||||
#include "size_t.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
template<typename CharT>
|
||||
class basic_state_machine
|
||||
{
|
||||
public:
|
||||
typedef CharT char_type;
|
||||
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
friend class basic_state_machine;
|
||||
|
||||
struct data
|
||||
{
|
||||
// Current iterator info
|
||||
std::size_t dfa;
|
||||
std::size_t states;
|
||||
std::size_t state;
|
||||
std::size_t transitions;
|
||||
std::size_t transition;
|
||||
|
||||
// Current state info
|
||||
bool end_state;
|
||||
std::size_t id;
|
||||
std::size_t unique_id;
|
||||
std::size_t goto_dfa;
|
||||
std::size_t bol_index;
|
||||
std::size_t eol_index;
|
||||
|
||||
// Current transition info
|
||||
basic_string_token<CharT> token;
|
||||
std::size_t goto_state;
|
||||
|
||||
data () :
|
||||
dfa (npos),
|
||||
states (0),
|
||||
state (npos),
|
||||
transitions (0),
|
||||
transition (npos),
|
||||
end_state (false),
|
||||
id (npos),
|
||||
unique_id (npos),
|
||||
goto_dfa (npos),
|
||||
bol_index (npos),
|
||||
eol_index (npos),
|
||||
goto_state (npos)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const data &rhs_) const
|
||||
{
|
||||
return dfa == rhs_.dfa &&
|
||||
states == rhs_.states &&
|
||||
state == rhs_.state &&
|
||||
transitions == rhs_.transitions &&
|
||||
transition == rhs_.transition &&
|
||||
end_state == rhs_.end_state &&
|
||||
id == rhs_.id &&
|
||||
unique_id == rhs_.unique_id &&
|
||||
goto_dfa == rhs_.goto_dfa &&
|
||||
bol_index == rhs_.bol_index &&
|
||||
eol_index == rhs_.eol_index &&
|
||||
token == rhs_.token &&
|
||||
goto_state == rhs_.goto_state;
|
||||
}
|
||||
};
|
||||
|
||||
iterator () :
|
||||
_sm (0),
|
||||
_dfas (0),
|
||||
_dfa (npos),
|
||||
_states (0),
|
||||
_state (npos),
|
||||
_transitions (0),
|
||||
_transition (npos)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const iterator &rhs_) const
|
||||
{
|
||||
return _dfas == rhs_._dfas && _dfa == rhs_._dfa &&
|
||||
_states == rhs_._states && _state == rhs_._state &&
|
||||
_transitions == rhs_._transitions &&
|
||||
_transition == rhs_._transition;
|
||||
}
|
||||
|
||||
bool operator != (const iterator &rhs_) const
|
||||
{
|
||||
return !(*this == rhs_);
|
||||
}
|
||||
|
||||
data &operator * ()
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
data *operator -> ()
|
||||
{
|
||||
return &_data;
|
||||
}
|
||||
|
||||
// Let compiler generate operator = ().
|
||||
|
||||
// prefix version
|
||||
iterator &operator ++ ()
|
||||
{
|
||||
next ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// postfix version
|
||||
iterator operator ++ (int)
|
||||
{
|
||||
iterator iter_ = *this;
|
||||
|
||||
next ();
|
||||
return iter_;
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
_dfas = _states = _transitions = 0;
|
||||
_dfa = _state = _transition = npos;
|
||||
}
|
||||
|
||||
private:
|
||||
basic_state_machine *_sm;
|
||||
data _data;
|
||||
std::size_t _dfas;
|
||||
std::size_t _dfa;
|
||||
std::size_t _states;
|
||||
std::size_t _state;
|
||||
std::size_t _transitions;
|
||||
std::size_t _transition;
|
||||
typename detail::basic_char_state_machine<CharT>::state::
|
||||
size_t_string_token_map::const_iterator _token_iter;
|
||||
typename detail::basic_char_state_machine<CharT>::state::
|
||||
size_t_string_token_map::const_iterator _token_end;
|
||||
|
||||
void next ()
|
||||
{
|
||||
bool reset_state_ = false;
|
||||
|
||||
if (_transition >= _transitions)
|
||||
{
|
||||
_transition = _data.transition = 0;
|
||||
_data.state = ++_state;
|
||||
reset_state_ = true;
|
||||
|
||||
if (_state >= _states)
|
||||
{
|
||||
++_dfa;
|
||||
|
||||
if (_dfa >= _dfas)
|
||||
{
|
||||
clear ();
|
||||
reset_state_ = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_states = _data.states =
|
||||
_sm->_csm._sm_vector[_dfa].size ();
|
||||
_state = _data.state = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_data.transition = _transition;
|
||||
}
|
||||
|
||||
if (reset_state_)
|
||||
{
|
||||
const typename detail::basic_char_state_machine<CharT>::
|
||||
state *ptr_ = &_sm->_csm._sm_vector[_dfa][_state];
|
||||
|
||||
_transitions = _data.transitions = ptr_->_transitions.size ();
|
||||
_data.end_state = ptr_->_end_state;
|
||||
_data.id = ptr_->_id;
|
||||
_data.unique_id = ptr_->_unique_id;
|
||||
_data.goto_dfa = ptr_->_state;
|
||||
_data.bol_index = ptr_->_bol_index;
|
||||
_data.eol_index = ptr_->_eol_index;
|
||||
_token_iter = ptr_->_transitions.begin ();
|
||||
_token_end = ptr_->_transitions.end ();
|
||||
}
|
||||
|
||||
if (_token_iter != _token_end)
|
||||
{
|
||||
_data.token = _token_iter->second;
|
||||
_data.goto_state = _token_iter->first;
|
||||
++_token_iter;
|
||||
++_transition;
|
||||
}
|
||||
else
|
||||
{
|
||||
_data.token.clear ();
|
||||
_data.goto_state = npos;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
friend class iterator;
|
||||
|
||||
basic_state_machine ()
|
||||
{
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
_internals.clear ();
|
||||
_csm.clear ();
|
||||
}
|
||||
|
||||
bool empty () const
|
||||
{
|
||||
// Don't include _csm in this test, as irrelevant to state.
|
||||
return _internals._lookup->empty () &&
|
||||
_internals._dfa_alphabet.empty () &&
|
||||
_internals._dfa->empty ();
|
||||
}
|
||||
|
||||
std::size_t size () const
|
||||
{
|
||||
return _internals._dfa->size ();
|
||||
}
|
||||
|
||||
bool operator == (const basic_state_machine &rhs_) const
|
||||
{
|
||||
// Don't include _csm in this test, as irrelevant to state.
|
||||
return _internals._lookup == rhs_._internals._lookup &&
|
||||
_internals._dfa_alphabet == rhs_._internals._dfa_alphabet &&
|
||||
_internals._dfa == rhs_._internals._dfa &&
|
||||
_internals._seen_BOL_assertion ==
|
||||
rhs_._internals._seen_BOL_assertion &&
|
||||
_internals._seen_EOL_assertion ==
|
||||
rhs_._internals._seen_EOL_assertion;
|
||||
}
|
||||
|
||||
iterator begin () const
|
||||
{
|
||||
iterator iter_;
|
||||
|
||||
iter_._sm = const_cast<basic_state_machine *>(this);
|
||||
check_for_csm ();
|
||||
|
||||
if (!_csm.empty ())
|
||||
{
|
||||
const typename detail::basic_char_state_machine<CharT>::
|
||||
state_vector *ptr_ = &_csm._sm_vector.front ();
|
||||
|
||||
iter_._dfas = _csm._sm_vector.size ();
|
||||
iter_._states = iter_._data.states = ptr_->size ();
|
||||
iter_._transitions = iter_._data.transitions =
|
||||
ptr_->front ()._transitions.size ();
|
||||
iter_._dfa = iter_._data.dfa = 0;
|
||||
iter_._state = iter_._data.state = 0;
|
||||
iter_._transition = 0;
|
||||
iter_._data.end_state = ptr_->front ()._end_state;
|
||||
iter_._data.id = ptr_->front ()._id;
|
||||
iter_._data.unique_id = ptr_->front ()._unique_id;
|
||||
iter_._data.goto_dfa = ptr_->front ()._state;
|
||||
iter_._data.bol_index = ptr_->front ()._bol_index;
|
||||
iter_._data.eol_index = ptr_->front ()._eol_index;
|
||||
iter_._token_iter = ptr_->front ()._transitions.begin ();
|
||||
iter_._token_end = ptr_->front ()._transitions.end ();
|
||||
|
||||
// Deal with case where there is only a bol or eol
|
||||
// but no other transitions.
|
||||
if (iter_._transitions)
|
||||
{
|
||||
++iter_;
|
||||
}
|
||||
}
|
||||
|
||||
return iter_;
|
||||
}
|
||||
|
||||
iterator end () const
|
||||
{
|
||||
iterator iter_;
|
||||
|
||||
iter_._sm = const_cast<basic_state_machine *>(this);
|
||||
return iter_;
|
||||
}
|
||||
|
||||
void swap (basic_state_machine &sm_)
|
||||
{
|
||||
_internals.swap (sm_._internals);
|
||||
_csm.swap (sm_._csm);
|
||||
}
|
||||
|
||||
const detail::internals &data () const
|
||||
{
|
||||
return _internals;
|
||||
}
|
||||
|
||||
private:
|
||||
detail::internals _internals;
|
||||
mutable detail::basic_char_state_machine<CharT> _csm;
|
||||
|
||||
void check_for_csm () const
|
||||
{
|
||||
if (_csm.empty ())
|
||||
{
|
||||
human_readable (_csm);
|
||||
}
|
||||
}
|
||||
|
||||
void human_readable (detail::basic_char_state_machine<CharT> &sm_) const
|
||||
{
|
||||
const std::size_t max_ = sizeof (CharT) == 1 ?
|
||||
num_chars : num_wchar_ts;
|
||||
const std::size_t start_states_ = _internals._dfa->size ();
|
||||
|
||||
sm_.clear ();
|
||||
sm_._sm_vector.resize (start_states_);
|
||||
|
||||
for (std::size_t start_state_index_ = 0;
|
||||
start_state_index_ < start_states_; ++start_state_index_)
|
||||
{
|
||||
const detail::internals::size_t_vector *lu_ =
|
||||
_internals._lookup[start_state_index_];
|
||||
const std::size_t alphabet_ =
|
||||
_internals._dfa_alphabet[start_state_index_] - dfa_offset;
|
||||
std::vector<std::basic_string<CharT> > chars_ (alphabet_);
|
||||
const std::size_t states_ = _internals._dfa[start_state_index_]->
|
||||
size () / (alphabet_ + dfa_offset);
|
||||
const std::size_t *read_ptr_ = &_internals.
|
||||
_dfa[start_state_index_]->front () + alphabet_ + dfa_offset;
|
||||
|
||||
sm_._sm_vector[start_state_index_].resize (states_ - 1);
|
||||
|
||||
for (std::size_t alpha_index_ = 0; alpha_index_ < max_;
|
||||
++alpha_index_)
|
||||
{
|
||||
const std::size_t col_ = lu_->at (alpha_index_);
|
||||
|
||||
if (col_ != static_cast<std::size_t>(dead_state_index))
|
||||
{
|
||||
chars_[col_ - dfa_offset] += static_cast<CharT>
|
||||
(alpha_index_);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t state_index_ = 1; state_index_ < states_;
|
||||
++state_index_)
|
||||
{
|
||||
typename detail::basic_char_state_machine<CharT>::state
|
||||
*state_ = &sm_._sm_vector[start_state_index_]
|
||||
[state_index_ - 1];
|
||||
|
||||
state_->_end_state = *read_ptr_ != 0;
|
||||
state_->_id = *(read_ptr_ + id_index);
|
||||
state_->_unique_id = *(read_ptr_ + unique_id_index);
|
||||
state_->_state = *(read_ptr_ + state_index);
|
||||
state_->_bol_index = *(read_ptr_ + bol_index) - 1;
|
||||
state_->_eol_index = *(read_ptr_ + eol_index) - 1;
|
||||
read_ptr_ += dfa_offset;
|
||||
|
||||
for (std::size_t col_index_ = 0; col_index_ < alphabet_;
|
||||
++col_index_, ++read_ptr_)
|
||||
{
|
||||
const std::size_t transition_ = *read_ptr_;
|
||||
|
||||
if (transition_ != 0)
|
||||
{
|
||||
const std::size_t i_ = transition_ - 1;
|
||||
typename detail::basic_char_state_machine<CharT>::
|
||||
state::size_t_string_token_map::iterator iter_ =
|
||||
state_->_transitions.find (i_);
|
||||
|
||||
if (iter_ == state_->_transitions.end ())
|
||||
{
|
||||
basic_string_token<CharT> token_
|
||||
(false, chars_[col_index_]);
|
||||
typename detail::basic_char_state_machine<CharT>::
|
||||
state::size_t_string_token_pair pair_
|
||||
(i_, token_);
|
||||
|
||||
state_->_transitions.insert (pair_);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter_->second._charset += chars_[col_index_];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (typename detail::basic_char_state_machine<CharT>::state::
|
||||
size_t_string_token_map::iterator iter_ =
|
||||
state_->_transitions.begin (),
|
||||
end_ = state_->_transitions.end ();
|
||||
iter_ != end_; ++iter_)
|
||||
{
|
||||
std::sort (iter_->second._charset.begin (),
|
||||
iter_->second._charset.end ());
|
||||
iter_->second.normalise ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_state_machine<char> state_machine;
|
||||
typedef basic_state_machine<wchar_t> wstate_machine;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+406
@@ -0,0 +1,406 @@
|
||||
// string_token.hpp
|
||||
// Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_LEXER_STRING_TOKEN_HPP
|
||||
#define BOOST_LEXER_STRING_TOKEN_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include "size_t.hpp"
|
||||
#include "consts.hpp" // num_chars, num_wchar_ts
|
||||
#include <string>
|
||||
#include <limits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace lexer
|
||||
{
|
||||
template<typename CharT>
|
||||
struct basic_string_token
|
||||
{
|
||||
typedef std::basic_string<CharT> string;
|
||||
|
||||
bool _negated;
|
||||
string _charset;
|
||||
|
||||
basic_string_token () :
|
||||
_negated (false)
|
||||
{
|
||||
}
|
||||
|
||||
basic_string_token (const bool negated_, const string &charset_) :
|
||||
_negated (negated_),
|
||||
_charset (charset_)
|
||||
{
|
||||
}
|
||||
|
||||
void remove_duplicates ()
|
||||
{
|
||||
const CharT *start_ = _charset.c_str ();
|
||||
const CharT *end_ = start_ + _charset.size ();
|
||||
|
||||
// Optimisation for very large charsets:
|
||||
// sorting via pointers is much quicker than
|
||||
// via iterators...
|
||||
std::sort (const_cast<CharT *> (start_), const_cast<CharT *> (end_));
|
||||
_charset.erase (std::unique (_charset.begin (), _charset.end ()),
|
||||
_charset.end ());
|
||||
}
|
||||
|
||||
void normalise ()
|
||||
{
|
||||
const std::size_t max_chars_ = sizeof (CharT) == 1 ?
|
||||
num_chars : num_wchar_ts;
|
||||
|
||||
if (_charset.length () == max_chars_)
|
||||
{
|
||||
_negated = !_negated;
|
||||
_charset.clear ();
|
||||
}
|
||||
else if (_charset.length () > max_chars_ / 2)
|
||||
{
|
||||
negate ();
|
||||
}
|
||||
}
|
||||
|
||||
void negate ()
|
||||
{
|
||||
const std::size_t max_chars_ = sizeof (CharT) == 1 ?
|
||||
num_chars : num_wchar_ts;
|
||||
CharT curr_char_ = (std::numeric_limits<CharT>::min)();
|
||||
string temp_;
|
||||
const CharT *curr_ = _charset.c_str ();
|
||||
const CharT *chars_end_ = curr_ + _charset.size ();
|
||||
|
||||
_negated = !_negated;
|
||||
temp_.resize (max_chars_ - _charset.size ());
|
||||
|
||||
CharT *ptr_ = const_cast<CharT *> (temp_.c_str ());
|
||||
std::size_t i_ = 0;
|
||||
|
||||
while (curr_ < chars_end_)
|
||||
{
|
||||
while (*curr_ > curr_char_)
|
||||
{
|
||||
*ptr_ = curr_char_;
|
||||
++ptr_;
|
||||
++curr_char_;
|
||||
++i_;
|
||||
}
|
||||
|
||||
++curr_char_;
|
||||
++curr_;
|
||||
++i_;
|
||||
}
|
||||
|
||||
for (; i_ < max_chars_; ++i_)
|
||||
{
|
||||
*ptr_ = curr_char_;
|
||||
++ptr_;
|
||||
++curr_char_;
|
||||
}
|
||||
|
||||
_charset = temp_;
|
||||
}
|
||||
|
||||
bool operator < (const basic_string_token &rhs_) const
|
||||
{
|
||||
return _negated < rhs_._negated ||
|
||||
(_negated == rhs_._negated && _charset < rhs_._charset);
|
||||
}
|
||||
|
||||
bool empty () const
|
||||
{
|
||||
return _charset.empty () && !_negated;
|
||||
}
|
||||
|
||||
bool any () const
|
||||
{
|
||||
return _charset.empty () && _negated;
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
_negated = false;
|
||||
_charset.clear ();
|
||||
}
|
||||
|
||||
void intersect (basic_string_token &rhs_, basic_string_token &overlap_)
|
||||
{
|
||||
if ((any () && rhs_.any ()) || (_negated == rhs_._negated &&
|
||||
!any () && !rhs_.any ()))
|
||||
{
|
||||
intersect_same_types (rhs_, overlap_);
|
||||
}
|
||||
else
|
||||
{
|
||||
intersect_diff_types (rhs_, overlap_);
|
||||
}
|
||||
}
|
||||
|
||||
static void escape_char (const CharT ch_, string &out_)
|
||||
{
|
||||
switch (ch_)
|
||||
{
|
||||
case '\0':
|
||||
out_ += '\\';
|
||||
out_ += '0';
|
||||
break;
|
||||
case '\a':
|
||||
out_ += '\\';
|
||||
out_ += 'a';
|
||||
break;
|
||||
case '\b':
|
||||
out_ += '\\';
|
||||
out_ += 'b';
|
||||
break;
|
||||
case 27:
|
||||
out_ += '\\';
|
||||
out_ += 'x';
|
||||
out_ += '1';
|
||||
out_ += 'b';
|
||||
break;
|
||||
case '\f':
|
||||
out_ += '\\';
|
||||
out_ += 'f';
|
||||
break;
|
||||
case '\n':
|
||||
out_ += '\\';
|
||||
out_ += 'n';
|
||||
break;
|
||||
case '\r':
|
||||
out_ += '\\';
|
||||
out_ += 'r';
|
||||
break;
|
||||
case '\t':
|
||||
out_ += '\\';
|
||||
out_ += 't';
|
||||
break;
|
||||
case '\v':
|
||||
out_ += '\\';
|
||||
out_ += 'v';
|
||||
break;
|
||||
case '\\':
|
||||
out_ += '\\';
|
||||
out_ += '\\';
|
||||
break;
|
||||
case '"':
|
||||
out_ += '\\';
|
||||
out_ += '"';
|
||||
break;
|
||||
case '\'':
|
||||
out_ += '\\';
|
||||
out_ += '\'';
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (ch_ < 32 && ch_ >= 0)
|
||||
{
|
||||
std::basic_stringstream<CharT> ss_;
|
||||
|
||||
out_ += '\\';
|
||||
out_ += 'x';
|
||||
ss_ << std::hex <<
|
||||
static_cast<std::size_t> (ch_);
|
||||
out_ += ss_.str ();
|
||||
}
|
||||
else
|
||||
{
|
||||
out_ += ch_;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void intersect_same_types (basic_string_token &rhs_,
|
||||
basic_string_token &overlap_)
|
||||
{
|
||||
if (any ())
|
||||
{
|
||||
clear ();
|
||||
overlap_._negated = true;
|
||||
rhs_.clear ();
|
||||
}
|
||||
else
|
||||
{
|
||||
typename string::iterator iter_ = _charset.begin ();
|
||||
typename string::iterator end_ = _charset.end ();
|
||||
typename string::iterator rhs_iter_ = rhs_._charset.begin ();
|
||||
typename string::iterator rhs_end_ = rhs_._charset.end ();
|
||||
|
||||
overlap_._negated = _negated;
|
||||
|
||||
while (iter_ != end_ && rhs_iter_ != rhs_end_)
|
||||
{
|
||||
if (*iter_ < *rhs_iter_)
|
||||
{
|
||||
++iter_;
|
||||
}
|
||||
else if (*iter_ > *rhs_iter_)
|
||||
{
|
||||
++rhs_iter_;
|
||||
}
|
||||
else
|
||||
{
|
||||
overlap_._charset += *iter_;
|
||||
iter_ = _charset.erase (iter_);
|
||||
end_ = _charset.end ();
|
||||
rhs_iter_ = rhs_._charset.erase (rhs_iter_);
|
||||
rhs_end_ = rhs_._charset.end ();
|
||||
}
|
||||
}
|
||||
|
||||
if (_negated)
|
||||
{
|
||||
// duplicates already merged, so safe to merge
|
||||
// using std lib.
|
||||
|
||||
// src, dest
|
||||
merge (_charset, overlap_._charset);
|
||||
// duplicates already merged, so safe to merge
|
||||
// using std lib.
|
||||
|
||||
// src, dest
|
||||
merge (rhs_._charset, overlap_._charset);
|
||||
_negated = false;
|
||||
rhs_._negated = false;
|
||||
std::swap (_charset, rhs_._charset);
|
||||
normalise ();
|
||||
overlap_.normalise ();
|
||||
rhs_.normalise ();
|
||||
}
|
||||
else if (!overlap_._charset.empty ())
|
||||
{
|
||||
normalise ();
|
||||
overlap_.normalise ();
|
||||
rhs_.normalise ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void intersect_diff_types (basic_string_token &rhs_,
|
||||
basic_string_token &overlap_)
|
||||
{
|
||||
if (any ())
|
||||
{
|
||||
intersect_any (rhs_, overlap_);
|
||||
}
|
||||
else if (_negated)
|
||||
{
|
||||
intersect_negated (rhs_, overlap_);
|
||||
}
|
||||
else // _negated == false
|
||||
{
|
||||
intersect_charset (rhs_, overlap_);
|
||||
}
|
||||
}
|
||||
|
||||
void intersect_any (basic_string_token &rhs_, basic_string_token &overlap_)
|
||||
{
|
||||
if (rhs_._negated)
|
||||
{
|
||||
rhs_.intersect_negated (*this, overlap_);
|
||||
}
|
||||
else // rhs._negated == false
|
||||
{
|
||||
rhs_.intersect_charset (*this, overlap_);
|
||||
}
|
||||
}
|
||||
|
||||
void intersect_negated (basic_string_token &rhs_,
|
||||
basic_string_token &overlap_)
|
||||
{
|
||||
if (rhs_.any ())
|
||||
{
|
||||
overlap_._negated = true;
|
||||
overlap_._charset = _charset;
|
||||
rhs_._negated = false;
|
||||
rhs_._charset = _charset;
|
||||
clear ();
|
||||
}
|
||||
else // rhs._negated == false
|
||||
{
|
||||
rhs_.intersect_charset (*this, overlap_);
|
||||
}
|
||||
}
|
||||
|
||||
void intersect_charset (basic_string_token &rhs_,
|
||||
basic_string_token &overlap_)
|
||||
{
|
||||
if (rhs_.any ())
|
||||
{
|
||||
overlap_._charset = _charset;
|
||||
rhs_._negated = true;
|
||||
rhs_._charset = _charset;
|
||||
clear ();
|
||||
}
|
||||
else // rhs_._negated == true
|
||||
{
|
||||
typename string::iterator iter_ = _charset.begin ();
|
||||
typename string::iterator end_ = _charset.end ();
|
||||
typename string::iterator rhs_iter_ = rhs_._charset.begin ();
|
||||
typename string::iterator rhs_end_ = rhs_._charset.end ();
|
||||
|
||||
while (iter_ != end_ && rhs_iter_ != rhs_end_)
|
||||
{
|
||||
if (*iter_ < *rhs_iter_)
|
||||
{
|
||||
overlap_._charset += *iter_;
|
||||
rhs_iter_ = rhs_._charset.insert (rhs_iter_, *iter_);
|
||||
++rhs_iter_;
|
||||
rhs_end_ = rhs_._charset.end ();
|
||||
iter_ = _charset.erase (iter_);
|
||||
end_ = _charset.end ();
|
||||
}
|
||||
else if (*iter_ > *rhs_iter_)
|
||||
{
|
||||
++rhs_iter_;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter_;
|
||||
++rhs_iter_;
|
||||
}
|
||||
}
|
||||
|
||||
if (iter_ != end_)
|
||||
{
|
||||
// nothing bigger in rhs_ than iter_,
|
||||
// so safe to merge using std lib.
|
||||
string temp_ (iter_, end_);
|
||||
|
||||
// src, dest
|
||||
merge (temp_, overlap_._charset);
|
||||
_charset.erase (iter_, end_);
|
||||
}
|
||||
|
||||
if (!overlap_._charset.empty ())
|
||||
{
|
||||
merge (overlap_._charset, rhs_._charset);
|
||||
// possible duplicates, so check for any and erase.
|
||||
rhs_._charset.erase (std::unique (rhs_._charset.begin (),
|
||||
rhs_._charset.end ()), rhs_._charset.end ());
|
||||
normalise ();
|
||||
overlap_.normalise ();
|
||||
rhs_.normalise ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void merge (string &src_, string &dest_)
|
||||
{
|
||||
string tmp_ (src_.size () + dest_.size (), 0);
|
||||
|
||||
std::merge (src_.begin (), src_.end (), dest_.begin (), dest_.end (),
|
||||
tmp_.begin ());
|
||||
dest_ = tmp_;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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_MAKE_CONS_OCTOBER_16_2008_1252PM
|
||||
#define BOOST_SPIRIT_MAKE_CONS_OCTOBER_16_2008_1252PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/include/phoenix_limits.hpp> // needs to be included before proto
|
||||
#include <boost/proto/proto.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/fusion/include/cons.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/is_abstract.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
struct as_meta_element
|
||||
: mpl::eval_if_c<is_abstract<T>::value || is_function<T>::value
|
||||
, add_reference<T>, remove_const<T> >
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct as_meta_element<T&> : as_meta_element<T> // always store by value
|
||||
{};
|
||||
|
||||
template <typename T, int N>
|
||||
struct as_meta_element<T[N]>
|
||||
{
|
||||
typedef const T(&type)[N];
|
||||
};
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
template <typename Car, typename Cdr = fusion::nil_>
|
||||
struct make_cons
|
||||
{
|
||||
typedef typename as_meta_element<Car>::type car_type; typedef typename fusion::cons<car_type, Cdr> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Car, typename Cdr>
|
||||
fusion::cons<typename as_meta_element<Car>::type, Cdr>
|
||||
make_cons(Car const& car, Cdr const& cdr)
|
||||
{
|
||||
typedef typename as_meta_element<Car>::type car_type;
|
||||
typedef typename fusion::cons<car_type, Cdr> result;
|
||||
return result(car, cdr);
|
||||
}
|
||||
|
||||
template <typename Car>
|
||||
fusion::cons<typename as_meta_element<Car>::type>
|
||||
make_cons(Car const& car)
|
||||
{
|
||||
typedef typename as_meta_element<Car>::type car_type;
|
||||
typedef typename fusion::cons<car_type> result;
|
||||
return result(car);
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 0)
|
||||
// workaround for gcc-4.0 bug where illegal function types
|
||||
// can be formed (const is added to function type)
|
||||
// description: http://lists.boost.org/Archives/boost/2009/04/150743.php
|
||||
template <typename Car>
|
||||
fusion::cons<typename as_meta_element<Car>::type>
|
||||
make_cons(Car& car, typename enable_if<is_function<Car> >::type* = 0)
|
||||
{
|
||||
typedef typename as_meta_element<Car>::type car_type;
|
||||
typedef typename fusion::cons<car_type> result;
|
||||
return result(car);
|
||||
}
|
||||
#endif
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,114 @@
|
||||
/*=============================================================================
|
||||
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)
|
||||
==============================================================================*/
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// This is the same as the one in fusion in Boost 1.41. This is provided
|
||||
// for compatibility with Boost 1.40 and below.
|
||||
|
||||
#if (BOOST_VERSION > 104000)
|
||||
|
||||
#include <boost/fusion/include/make_vector.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
namespace result_of
|
||||
{
|
||||
using fusion::result_of::make_vector;
|
||||
}
|
||||
using fusion::make_vector;
|
||||
}}}
|
||||
|
||||
#else
|
||||
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
#if !defined(SPIRIT_MAKE_VECTOR_07162005_0243)
|
||||
#define SPIRIT_MAKE_VECTOR_07162005_0243
|
||||
|
||||
#include <boost/preprocessor/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/fusion/container/vector/vector.hpp>
|
||||
#include <boost/fusion/support/detail/as_fusion_element.hpp>
|
||||
|
||||
namespace boost { namespace fusion
|
||||
{
|
||||
struct void_;
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
namespace result_of
|
||||
{
|
||||
template <
|
||||
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
|
||||
FUSION_MAX_VECTOR_SIZE, typename T, fusion::void_)
|
||||
, typename Extra = fusion::void_
|
||||
>
|
||||
struct make_vector;
|
||||
|
||||
template <>
|
||||
struct make_vector<>
|
||||
{
|
||||
typedef fusion::vector0 type;
|
||||
};
|
||||
}
|
||||
|
||||
inline fusion::vector0
|
||||
make_vector()
|
||||
{
|
||||
return fusion::vector0();
|
||||
}
|
||||
|
||||
#define BOOST_FUSION_AS_FUSION_ELEMENT(z, n, data) \
|
||||
typename fusion::detail::as_fusion_element<BOOST_PP_CAT(T, n)>::type
|
||||
|
||||
#define BOOST_PP_FILENAME_1 <boost/spirit/home/support/detail/make_vector.hpp>
|
||||
#define BOOST_PP_ITERATION_LIMITS (1, FUSION_MAX_VECTOR_SIZE)
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#undef BOOST_FUSION_AS_FUSION_ELEMENT
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
#else // defined(BOOST_PP_IS_ITERATING)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Preprocessor vertical repetition code
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
namespace result_of
|
||||
{
|
||||
template <BOOST_PP_ENUM_PARAMS(N, typename T)>
|
||||
#if defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS)
|
||||
#define TEXT(z, n, text) , text
|
||||
struct make_vector< BOOST_PP_ENUM_PARAMS(N, T) BOOST_PP_REPEAT_FROM_TO(BOOST_PP_DEC(N), FUSION_MAX_VECTOR_SIZE, TEXT, fusion::void_) >
|
||||
#undef TEXT
|
||||
#else
|
||||
struct make_vector<BOOST_PP_ENUM_PARAMS(N, T)>
|
||||
#endif
|
||||
{
|
||||
typedef BOOST_PP_CAT(fusion::vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <BOOST_PP_ENUM_PARAMS(N, typename T)>
|
||||
inline BOOST_PP_CAT(fusion::vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>
|
||||
make_vector(BOOST_PP_ENUM_BINARY_PARAMS(N, T, const& _))
|
||||
{
|
||||
return BOOST_PP_CAT(fusion::vector, N)<BOOST_PP_ENUM(N, BOOST_FUSION_AS_FUSION_ELEMENT, _)>(
|
||||
BOOST_PP_ENUM_PARAMS(N, _));
|
||||
}
|
||||
|
||||
#undef N
|
||||
#endif // defined(BOOST_PP_IS_ITERATING)
|
||||
#endif // (BOOST_VERSION > 103800)
|
||||
+583
@@ -0,0 +1,583 @@
|
||||
// fp_traits.hpp
|
||||
|
||||
#ifndef BOOST_SPIRIT_MATH_FP_TRAITS_HPP
|
||||
#define BOOST_SPIRIT_MATH_FP_TRAITS_HPP
|
||||
|
||||
// Copyright (c) 2006 Johan Rade
|
||||
|
||||
// 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(__vms) && defined(__DECCXX) && !__IEEE_FLOAT
|
||||
# error The VAX floating point mode on VMS is not supported.
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/detail/endian.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace boost {
|
||||
namespace spirit {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Most processors support three different floating point precisions:
|
||||
single precision (32 bits), double precision (64 bits)
|
||||
and extended double precision (>64 bits)
|
||||
|
||||
Note that the C++ type long double can be implemented
|
||||
both as double precision and extended double precision.
|
||||
*/
|
||||
|
||||
struct single_precision_tag {};
|
||||
struct double_precision_tag {};
|
||||
struct extended_double_precision_tag {};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
template<class T, class U> struct fp_traits_impl;
|
||||
|
||||
This is traits class that describes the binary structure of floating
|
||||
point numbers of C++ type T and precision U
|
||||
|
||||
Requirements:
|
||||
|
||||
T = float, double or long double
|
||||
U = single_precision_tag, double_precision_tag
|
||||
or extended_double_precision_tag
|
||||
|
||||
Typedef members:
|
||||
|
||||
bits -- the target type when copying the leading bytes of a floating
|
||||
point number. It is a typedef for uint32_t or uint64_t.
|
||||
|
||||
coverage -- tells us whether all bytes are copied or not.
|
||||
It is a typedef for all_bits or not_all_bits.
|
||||
|
||||
Static data members:
|
||||
|
||||
sign, exponent, flag, mantissa -- bit masks that give the meaning of the bits
|
||||
in the leading bytes.
|
||||
|
||||
Static function members:
|
||||
|
||||
init() -- initializes the static data members, if needed.
|
||||
(Is a no-op in the specialized versions of the template.)
|
||||
|
||||
get_bits(), set_bits() -- provide access to the leading bytes.
|
||||
*/
|
||||
|
||||
struct all_bits {};
|
||||
struct not_all_bits {};
|
||||
|
||||
// Generic version -------------------------------------------------------------
|
||||
|
||||
// The generic version uses run time initialization to determine the floating
|
||||
// point format. It is capable of handling most formats,
|
||||
// but not the Motorola 68K extended double precision format.
|
||||
|
||||
// Currently the generic version is used only for extended double precision
|
||||
// on Itanium. In all other cases there are specializations of the template
|
||||
// that use compile time initialization.
|
||||
|
||||
template<class T> struct uint32_t_coverage
|
||||
{
|
||||
typedef not_all_bits type;
|
||||
};
|
||||
|
||||
template<> struct uint32_t_coverage<single_precision_tag>
|
||||
{
|
||||
typedef all_bits type;
|
||||
};
|
||||
|
||||
template<class T, class U> struct fp_traits_impl
|
||||
{
|
||||
typedef uint32_t bits;
|
||||
typedef BOOST_DEDUCED_TYPENAME uint32_t_coverage<U>::type coverage;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
|
||||
static uint32_t exponent;
|
||||
static uint32_t flag;
|
||||
static uint32_t mantissa;
|
||||
|
||||
static void init()
|
||||
{
|
||||
if(is_init_) return;
|
||||
do_init_();
|
||||
is_init_ = true;
|
||||
}
|
||||
|
||||
static void get_bits(T x, uint32_t& a)
|
||||
{
|
||||
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(T& x, uint32_t a)
|
||||
{
|
||||
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
static size_t offset_;
|
||||
static bool is_init_;
|
||||
static void do_init_();
|
||||
};
|
||||
|
||||
//..............................................................................
|
||||
|
||||
template<class T, class U> uint32_t fp_traits_impl<T,U>::exponent;
|
||||
template<class T, class U> uint32_t fp_traits_impl<T,U>::flag;
|
||||
template<class T, class U> uint32_t fp_traits_impl<T,U>::mantissa;
|
||||
template<class T, class U> size_t fp_traits_impl<T,U>::offset_;
|
||||
template<class T, class U> bool fp_traits_impl<T,U>::is_init_;
|
||||
|
||||
// In a single-threaded program, do_init will be called exactly once.
|
||||
// In a multi-threaded program, do_init may be called simultaneously
|
||||
// by more then one thread. That should not be a problem.
|
||||
|
||||
//..............................................................................
|
||||
|
||||
template<class T, class U> void fp_traits_impl<T,U>::do_init_()
|
||||
{
|
||||
T x = static_cast<T>(3) / static_cast<T>(4);
|
||||
// sign bit = 0
|
||||
// exponent: first and last bit = 0, all other bits = 1
|
||||
// flag bit (if present) = 1
|
||||
// mantissa: first bit = 1, all other bits = 0
|
||||
|
||||
uint32_t a;
|
||||
|
||||
for(size_t k = 0; k <= sizeof(T) - 4; ++k) {
|
||||
|
||||
memcpy(&a, reinterpret_cast<unsigned char*>(&x) + k, 4);
|
||||
|
||||
switch(a) {
|
||||
|
||||
case 0x3f400000: // IEEE single precision format
|
||||
|
||||
offset_ = k;
|
||||
exponent = 0x7f800000;
|
||||
flag = 0x00000000;
|
||||
mantissa = 0x007fffff;
|
||||
return;
|
||||
|
||||
case 0x3fe80000: // IEEE double precision format
|
||||
// and PowerPC extended double precision format
|
||||
offset_ = k;
|
||||
exponent = 0x7ff00000;
|
||||
flag = 0x00000000;
|
||||
mantissa = 0x000fffff;
|
||||
return;
|
||||
|
||||
case 0x3ffe0000: // Motorola extended double precision format
|
||||
|
||||
// Must not get here. Must be handled by specialization.
|
||||
// To get accurate cutoff between normals and subnormals
|
||||
// we must use the flag bit that is in the 5th byte.
|
||||
// Otherwise this cutoff will be off by a factor 2.
|
||||
// If we do get here, then we have failed to detect the Motorola
|
||||
// processor at compile time.
|
||||
|
||||
BOOST_ASSERT(false &&
|
||||
"Failed to detect the Motorola processor at compile time");
|
||||
return;
|
||||
|
||||
case 0x3ffe8000: // IEEE extended double precision format
|
||||
// with 15 exponent bits
|
||||
offset_ = k;
|
||||
exponent = 0x7fff0000;
|
||||
flag = 0x00000000;
|
||||
mantissa = 0x0000ffff;
|
||||
return;
|
||||
|
||||
case 0x3ffec000: // Intel extended double precision format
|
||||
|
||||
offset_ = k;
|
||||
exponent = 0x7fff0000;
|
||||
flag = 0x00008000;
|
||||
mantissa = 0x00007fff;
|
||||
return;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_ASSERT(false);
|
||||
|
||||
// Unknown format.
|
||||
}
|
||||
|
||||
|
||||
// float (32 bits) -------------------------------------------------------------
|
||||
|
||||
template<> struct fp_traits_impl<float, single_precision_tag>
|
||||
{
|
||||
typedef uint32_t bits;
|
||||
typedef all_bits coverage;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7f800000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x007fffff);
|
||||
|
||||
static void init() {}
|
||||
static void get_bits(float x, uint32_t& a) { memcpy(&a, &x, 4); }
|
||||
static void set_bits(float& x, uint32_t a) { memcpy(&x, &a, 4); }
|
||||
};
|
||||
|
||||
|
||||
// double (64 bits) ------------------------------------------------------------
|
||||
|
||||
#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
|
||||
|
||||
template<> struct fp_traits_impl<double, double_precision_tag>
|
||||
{
|
||||
typedef uint32_t bits;
|
||||
typedef not_all_bits coverage;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
|
||||
|
||||
static void init() {}
|
||||
|
||||
static void get_bits(double x, uint32_t& a)
|
||||
{
|
||||
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(double& x, uint32_t a)
|
||||
{
|
||||
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(BOOST_BIG_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 0);
|
||||
#elif defined(BOOST_LITTLE_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 4);
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
//..............................................................................
|
||||
|
||||
#else
|
||||
|
||||
template<> struct fp_traits_impl<double, double_precision_tag>
|
||||
{
|
||||
typedef uint64_t bits;
|
||||
typedef all_bits coverage;
|
||||
|
||||
static const uint64_t sign = (uint64_t)0x80000000 << 32;
|
||||
static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
|
||||
static const uint64_t flag = 0;
|
||||
static const uint64_t mantissa
|
||||
= ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
|
||||
|
||||
static void init() {}
|
||||
static void get_bits(double x, uint64_t& a) { memcpy(&a, &x, 8); }
|
||||
static void set_bits(double& x, uint64_t a) { memcpy(&x, &a, 8); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// long double (64 bits) -------------------------------------------------------
|
||||
|
||||
#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
|
||||
|
||||
template<> struct fp_traits_impl<long double, double_precision_tag>
|
||||
{
|
||||
typedef uint32_t bits;
|
||||
typedef not_all_bits coverage;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
|
||||
|
||||
static void init() {}
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(BOOST_BIG_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 0);
|
||||
#elif defined(BOOST_LITTLE_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 4);
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
//..............................................................................
|
||||
|
||||
#else
|
||||
|
||||
template<> struct fp_traits_impl<long double, double_precision_tag>
|
||||
{
|
||||
typedef uint64_t bits;
|
||||
typedef all_bits coverage;
|
||||
|
||||
static const uint64_t sign = (uint64_t)0x80000000 << 32;
|
||||
static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
|
||||
static const uint64_t flag = 0;
|
||||
static const uint64_t mantissa
|
||||
= ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
|
||||
|
||||
static void init() {}
|
||||
static void get_bits(long double x, uint64_t& a) { memcpy(&a, &x, 8); }
|
||||
static void set_bits(long double& x, uint64_t a) { memcpy(&x, &a, 8); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// long double (>64 bits), x86 and x64 -----------------------------------------
|
||||
|
||||
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
|
||||
|| defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \
|
||||
|| defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
|
||||
|
||||
// Intel extended double precision format (80 bits)
|
||||
|
||||
template<> struct fp_traits_impl<long double, extended_double_precision_tag>
|
||||
{
|
||||
typedef uint32_t bits;
|
||||
typedef not_all_bits coverage;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
|
||||
|
||||
static void init() {}
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// long double (>64 bits), Itanium ---------------------------------------------
|
||||
|
||||
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||
|
||||
// The floating point format is unknown at compile time
|
||||
// No template specialization is provided.
|
||||
// The generic definition is used.
|
||||
|
||||
// The Itanium supports both
|
||||
// the Intel extended double precision format (80 bits) and
|
||||
// the IEEE extended double precision format with 15 exponent bits (128 bits).
|
||||
|
||||
|
||||
// long double (>64 bits), PowerPC ---------------------------------------------
|
||||
|
||||
#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
|
||||
|| defined(__ppc) || defined(__ppc__) || defined(__PPC__)
|
||||
|
||||
// PowerPC extended double precision format (128 bits)
|
||||
|
||||
template<> struct fp_traits_impl<long double, extended_double_precision_tag>
|
||||
{
|
||||
typedef uint32_t bits;
|
||||
typedef not_all_bits coverage;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
|
||||
|
||||
static void init() {}
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(BOOST_BIG_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 0);
|
||||
#elif defined(BOOST_LITTLE_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 12);
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// long double (>64 bits), Motorola 68K ----------------------------------------
|
||||
|
||||
#elif defined(__m68k) || defined(__m68k__) \
|
||||
|| defined(__mc68000) || defined(__mc68000__) \
|
||||
|
||||
// Motorola extended double precision format (96 bits)
|
||||
|
||||
// It is the same format as the Intel extended double precision format,
|
||||
// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and
|
||||
// 3) the flag bit is not set for infinity
|
||||
|
||||
template<> struct fp_traits_impl<long double, extended_double_precision_tag>
|
||||
{
|
||||
typedef uint32_t bits;
|
||||
typedef not_all_bits coverage;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
|
||||
|
||||
static void init() {}
|
||||
|
||||
// copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding.
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
memcpy(&a, &x, 2);
|
||||
memcpy(reinterpret_cast<unsigned char*>(&a) + 2,
|
||||
reinterpret_cast<const unsigned char*>(&x) + 4, 2);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
memcpy(&x, &a, 2);
|
||||
memcpy(reinterpret_cast<unsigned char*>(&x) + 4,
|
||||
reinterpret_cast<const unsigned char*>(&a) + 2, 2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// long double (>64 bits), All other processors --------------------------------
|
||||
|
||||
#else
|
||||
|
||||
// IEEE extended double precision format with 15 exponent bits (128 bits)
|
||||
|
||||
template<> struct fp_traits_impl<long double, extended_double_precision_tag>
|
||||
{
|
||||
typedef uint32_t bits;
|
||||
typedef not_all_bits coverage;
|
||||
|
||||
BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
|
||||
BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x0000ffff);
|
||||
|
||||
static void init() {}
|
||||
|
||||
static void get_bits(long double x, uint32_t& a)
|
||||
{
|
||||
memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
|
||||
}
|
||||
|
||||
static void set_bits(long double& x, uint32_t a)
|
||||
{
|
||||
memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#if defined(BOOST_BIG_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 0);
|
||||
#elif defined(BOOST_LITTLE_ENDIAN)
|
||||
BOOST_STATIC_CONSTANT(int, offset_ = 12);
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(false);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// size_to_precision is a type switch for converting a C++ floating point type
|
||||
// to the corresponding precision type.
|
||||
|
||||
template<int n> struct size_to_precision;
|
||||
|
||||
template<> struct size_to_precision<4>
|
||||
{
|
||||
typedef single_precision_tag type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<8>
|
||||
{
|
||||
typedef double_precision_tag type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<10>
|
||||
{
|
||||
typedef extended_double_precision_tag type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<12>
|
||||
{
|
||||
typedef extended_double_precision_tag type;
|
||||
};
|
||||
|
||||
template<> struct size_to_precision<16>
|
||||
{
|
||||
typedef extended_double_precision_tag type;
|
||||
};
|
||||
|
||||
// fp_traits is a type switch that selects the right fp_traits_impl
|
||||
|
||||
template<class T> struct fp_traits
|
||||
{
|
||||
BOOST_STATIC_ASSERT(boost::is_floating_point<T>::value);
|
||||
typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T)>::type precision;
|
||||
typedef fp_traits_impl<T, precision> type;
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // namespace detail
|
||||
} // namespace math
|
||||
} // namespace spirit
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
// fpclassify.hpp
|
||||
|
||||
#ifndef BOOST_SPIRIT_MATH_FPCLASSIFY_HPP
|
||||
#define BOOST_SPIRIT_MATH_FPCLASSIFY_HPP
|
||||
|
||||
// Copyright (c) 2006 Johan Rade
|
||||
|
||||
// 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)
|
||||
|
||||
/*
|
||||
The following algorithm is used:
|
||||
|
||||
If all exponent bits, the flag bit (if there is one),
|
||||
and all mantissa bits are 0, then the number is zero.
|
||||
|
||||
If all exponent bits and the flag bit (if there is one) are 0,
|
||||
and at least one mantissa bit is 1, then the number is subnormal.
|
||||
|
||||
If all exponent bits are 1 and all mantissa bits are 0,
|
||||
then the number is infinity.
|
||||
|
||||
If all exponent bits are 1 and at least one mantissa bit is 1,
|
||||
then the number is a not-a-number.
|
||||
|
||||
Otherwise the number is normal.
|
||||
|
||||
(Note that the binary representation of infinity
|
||||
has flag bit 0 for Motorola 68K extended double precision,
|
||||
and flag bit 1 for Intel extended double precision.)
|
||||
|
||||
To get the bits, the four or eight most significant bytes are copied
|
||||
into an uint32_t or uint64_t and bit masks are applied.
|
||||
This covers all the exponent bits and the flag bit (if there is one),
|
||||
but not always all the mantissa bits.
|
||||
Some of the functions below have two implementations,
|
||||
depending on whether all the mantissa bits are copied or not.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifndef FP_INFINITE
|
||||
# define FP_INFINITE 0
|
||||
# define FP_NAN 1
|
||||
# define FP_NORMAL 2
|
||||
# define FP_SUBNORMAL 3
|
||||
# define FP_ZERO 4
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/detail/math/detail/fp_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace spirit {
|
||||
namespace math {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class T> bool (isfinite)(T x)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent;
|
||||
return a != traits::exponent;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class T> bool (isnormal)(T x)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::flag;
|
||||
return (a != 0) && (a < traits::exponent);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T> bool isinf_impl(T x, all_bits)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::mantissa;
|
||||
return a == traits::exponent;
|
||||
}
|
||||
|
||||
template<class T> bool isinf_impl(T x, not_all_bits)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::mantissa;
|
||||
if(a != traits::exponent)
|
||||
return false;
|
||||
|
||||
traits::set_bits(x,0);
|
||||
return x == 0;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T> bool (isinf)(T x)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
return detail::isinf_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T> bool isnan_impl(T x, all_bits)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::mantissa;
|
||||
return a > traits::exponent;
|
||||
}
|
||||
|
||||
template<class T> bool isnan_impl(T x, not_all_bits)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
|
||||
a &= traits::exponent | traits::mantissa;
|
||||
if(a < traits::exponent)
|
||||
return false;
|
||||
|
||||
a &= traits::mantissa;
|
||||
traits::set_bits(x,a);
|
||||
return x != 0;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T> bool (isnan)(T x)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
return detail::isnan_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T> int fpclassify_impl(T x, all_bits)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::flag | traits::mantissa;
|
||||
|
||||
if(a <= traits::mantissa) {
|
||||
if(a == 0)
|
||||
return FP_ZERO;
|
||||
else
|
||||
return FP_SUBNORMAL;
|
||||
}
|
||||
|
||||
if(a < traits::exponent)
|
||||
return FP_NORMAL;
|
||||
|
||||
a &= traits::mantissa;
|
||||
if(a == 0)
|
||||
return FP_INFINITE;
|
||||
|
||||
return FP_NAN;
|
||||
}
|
||||
|
||||
template<class T> int fpclassify_impl(T x, not_all_bits)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::exponent | traits::flag | traits::mantissa;
|
||||
|
||||
if(a <= traits::mantissa) {
|
||||
if(x == 0)
|
||||
return FP_ZERO;
|
||||
else
|
||||
return FP_SUBNORMAL;
|
||||
}
|
||||
|
||||
if(a < traits::exponent)
|
||||
return FP_NORMAL;
|
||||
|
||||
a &= traits::mantissa;
|
||||
traits::set_bits(x,a);
|
||||
if(x == 0)
|
||||
return FP_INFINITE;
|
||||
|
||||
return FP_NAN;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T> int (fpclassify)(T x)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
return detail::fpclassify_impl(x, BOOST_DEDUCED_TYPENAME traits::coverage());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // namespace math
|
||||
} // namespace spirit
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
// signbit.hpp
|
||||
|
||||
#ifndef BOOST_SPIRIT_MATH_SIGNBIT_HPP
|
||||
#define BOOST_SPIRIT_MATH_SIGNBIT_HPP
|
||||
|
||||
// Copyright (c) 2006 Johan Rade
|
||||
|
||||
// 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(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/detail/math/detail/fp_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace spirit {
|
||||
namespace math {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class T> bool (signbit)(T x)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= traits::sign;
|
||||
return a != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class T> T copysign_impl(T x, T y)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a &= ~traits::sign;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits b;
|
||||
traits::get_bits(y,b);
|
||||
b &= traits::sign;
|
||||
|
||||
traits::set_bits(x,a|b);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
inline float (copysign)(float x, float y) // magnitude of x and sign of y
|
||||
{
|
||||
return detail::copysign_impl(x,y);
|
||||
}
|
||||
|
||||
inline double (copysign)(double x, double y)
|
||||
{
|
||||
return detail::copysign_impl(x,y);
|
||||
}
|
||||
|
||||
inline long double (copysign)(long double x, long double y)
|
||||
{
|
||||
return detail::copysign_impl(x,y);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class T> T (changesign)(T x)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::fp_traits<T>::type traits;
|
||||
traits::init();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME traits::bits a;
|
||||
traits::get_bits(x,a);
|
||||
a ^= traits::sign;
|
||||
traits::set_bits(x,a);
|
||||
return x;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // namespace math
|
||||
} // namespace spirit
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,113 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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_POW10_DECEMBER_26_2008_1118AM)
|
||||
#define SPIRIT_POW10_DECEMBER_26_2008_1118AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/numeric_traits.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <typename T, typename Enable/* = void*/>
|
||||
struct pow10_helper
|
||||
{
|
||||
static T call(unsigned dim)
|
||||
{
|
||||
using namespace std; // allow for ADL to find the correct overload
|
||||
return pow(T(10), T(dim));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pow10_helper<unused_type>
|
||||
{
|
||||
static unused_type call(unused_type)
|
||||
{
|
||||
return unused;
|
||||
}
|
||||
};
|
||||
|
||||
#if (DBL_MAX_10_EXP == 308) // for IEEE-754
|
||||
template <>
|
||||
struct pow10_helper<double>
|
||||
{
|
||||
static double call(unsigned dim)
|
||||
{
|
||||
static double const exponents[] =
|
||||
{
|
||||
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
|
||||
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
|
||||
1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
|
||||
1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
|
||||
1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
|
||||
1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
|
||||
1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
|
||||
1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
|
||||
1e80, 1e81, 1e82, 1e83, 1e84, 1e85, 1e86, 1e87, 1e88, 1e89,
|
||||
1e90, 1e91, 1e92, 1e93, 1e94, 1e95, 1e96, 1e97, 1e98, 1e99,
|
||||
1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109,
|
||||
1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119,
|
||||
1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129,
|
||||
1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139,
|
||||
1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149,
|
||||
1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159,
|
||||
1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169,
|
||||
1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179,
|
||||
1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189,
|
||||
1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199,
|
||||
1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209,
|
||||
1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219,
|
||||
1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229,
|
||||
1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239,
|
||||
1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249,
|
||||
1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259,
|
||||
1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269,
|
||||
1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279,
|
||||
1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289,
|
||||
1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
|
||||
1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
|
||||
};
|
||||
BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
|
||||
return exponents[dim];
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pow10_helper<float>
|
||||
{
|
||||
static float call(unsigned dim)
|
||||
{
|
||||
return pow10_helper<double>::call(dim);
|
||||
}
|
||||
};
|
||||
#endif // for IEEE-754
|
||||
|
||||
template <typename T>
|
||||
inline T pow10(unsigned dim)
|
||||
{
|
||||
return pow10_helper<T>::call(dim);
|
||||
}
|
||||
}}}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
// http://spirit.sourceforge.net/
|
||||
//
|
||||
// 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_SCOPED_ENUM_EMULATION_HPP
|
||||
#define BOOST_SPIRIT_SCOPED_ENUM_EMULATION_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 104000
|
||||
# include <boost/detail/scoped_enum_emulation.hpp>
|
||||
#else
|
||||
# if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
|
||||
# define BOOST_NO_CXX11_SCOPED_ENUMS
|
||||
# endif
|
||||
# define BOOST_SCOPED_ENUM_START(name) struct name { enum enum_type
|
||||
# define BOOST_SCOPED_ENUM_END };
|
||||
# define BOOST_SCOPED_ENUM(name) name::enum_type
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
http://spirit.sourceforge.net/
|
||||
|
||||
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_SIGN_MAR_11_2009_0734PM)
|
||||
#define SPIRIT_SIGN_MAR_11_2009_0734PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#if BOOST_VERSION < 104000
|
||||
#include <boost/spirit/home/support/detail/math/fpclassify.hpp>
|
||||
#include <boost/spirit/home/support/detail/math/signbit.hpp>
|
||||
#else
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/special_functions/sign.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
#if BOOST_VERSION < 104000
|
||||
// signbit(-NAN) is broken for versions of Boost earlier than 1.40.0
|
||||
// This routine has been taken and adapted from Johan Rade's fp_traits
|
||||
// library
|
||||
template<typename T>
|
||||
inline bool (signbit)(T x)
|
||||
{
|
||||
return (boost::spirit::math::signbit)(x);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T (changesign)(T x)
|
||||
{
|
||||
return (boost::spirit::math::changesign)(x);
|
||||
}
|
||||
#else
|
||||
template<typename T>
|
||||
inline bool (signbit)(T x)
|
||||
{
|
||||
return (boost::math::signbit)(x) ? true : false;
|
||||
}
|
||||
|
||||
// This routine has been taken and adapted from Johan Rade's fp_traits
|
||||
// library
|
||||
template<typename T>
|
||||
inline T (changesign)(T x)
|
||||
{
|
||||
#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)
|
||||
return -x;
|
||||
#else
|
||||
typedef typename math::detail::fp_traits<T>::type traits_type;
|
||||
|
||||
typename traits_type::bits a;
|
||||
traits_type::get_bits(x, a);
|
||||
a ^= traits_type::sign;
|
||||
traits_type::set_bits(x, a);
|
||||
return x;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*=============================================================================
|
||||
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_WHAT_FUNCTION_APRIL_22_2007_0236PM)
|
||||
#define SPIRIT_WHAT_FUNCTION_APRIL_22_2007_0236PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
template <typename Context>
|
||||
struct what_function
|
||||
{
|
||||
what_function(info& what_, Context& context_)
|
||||
: what(what_), context(context_)
|
||||
{
|
||||
what.value = std::list<info>();
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
void operator()(Component const& component) const
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
component; // suppresses warning: C4100: 'component' : unreferenced formal parameter
|
||||
#endif
|
||||
boost::get<std::list<info> >(what.value).
|
||||
push_back(component.what(context));
|
||||
}
|
||||
|
||||
info& what;
|
||||
Context& context;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
what_function& operator= (what_function const&);
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,185 @@
|
||||
/*=============================================================================
|
||||
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_EXTENDED_VARIANT_AUGUST_6_2011_0859AM)
|
||||
#define BOOST_SPIRIT_EXTENDED_VARIANT_AUGUST_6_2011_0859AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/mpl/limits/list.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
#define BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES BOOST_MPL_LIMIT_LIST_SIZE
|
||||
#else
|
||||
#define BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES BOOST_VARIANT_LIMIT_TYPES
|
||||
#endif
|
||||
|
||||
#define BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T) \
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES, T) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
template <
|
||||
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
|
||||
BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES,
|
||||
typename T, boost::detail::variant::void_)
|
||||
// We should not be depending on detail::variant::void_
|
||||
// but I'm not sure if this can fixed. Any other way is
|
||||
// clumsy at best.
|
||||
>
|
||||
#else
|
||||
template <typename... Types>
|
||||
#endif
|
||||
struct extended_variant
|
||||
{
|
||||
// tell spirit that this is an adapted variant
|
||||
struct adapted_variant_tag;
|
||||
|
||||
#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
typedef boost::variant<
|
||||
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>
|
||||
variant_type;
|
||||
typedef typename variant_type::types types;
|
||||
|
||||
typedef extended_variant<
|
||||
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)
|
||||
> base_type;
|
||||
#else
|
||||
typedef boost::variant<Types...> variant_type;
|
||||
typedef typename variant_type::types types;
|
||||
typedef extended_variant<Types...> base_type;
|
||||
#endif
|
||||
|
||||
extended_variant() : var() {}
|
||||
|
||||
template <typename T>
|
||||
extended_variant(T const& var)
|
||||
: var(var) {}
|
||||
|
||||
template <typename T>
|
||||
extended_variant(T& var)
|
||||
: var(var) {}
|
||||
|
||||
template <typename F>
|
||||
typename F::result_type apply_visitor(F const& v)
|
||||
{
|
||||
return var.apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
typename F::result_type apply_visitor(F const& v) const
|
||||
{
|
||||
return var.apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
typename F::result_type apply_visitor(F& v)
|
||||
{
|
||||
return var.apply_visitor(v);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
typename F::result_type apply_visitor(F& v) const
|
||||
{
|
||||
return var.apply_visitor(v);
|
||||
}
|
||||
|
||||
variant_type const& get() const
|
||||
{
|
||||
return var;
|
||||
}
|
||||
|
||||
variant_type& get()
|
||||
{
|
||||
return var;
|
||||
}
|
||||
|
||||
void swap(extended_variant& rhs) BOOST_NOEXCEPT
|
||||
{
|
||||
var.swap(rhs.var);
|
||||
}
|
||||
|
||||
variant_type var;
|
||||
};
|
||||
}}
|
||||
|
||||
namespace boost
|
||||
{
|
||||
#if defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
|
||||
inline T const&
|
||||
get(boost::spirit::extended_variant<
|
||||
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)> const& x)
|
||||
{
|
||||
return boost::get<T>(x.get());
|
||||
}
|
||||
|
||||
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
|
||||
inline T&
|
||||
get(boost::spirit::extended_variant<
|
||||
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>& x)
|
||||
{
|
||||
return boost::get<T>(x.get());
|
||||
}
|
||||
|
||||
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
|
||||
inline T const*
|
||||
get(boost::spirit::extended_variant<
|
||||
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)> const* x)
|
||||
{
|
||||
return boost::get<T>(&x->get());
|
||||
}
|
||||
|
||||
template <typename T, BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(typename T)>
|
||||
inline T*
|
||||
get(boost::spirit::extended_variant<
|
||||
BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS(T)>* x)
|
||||
{
|
||||
return boost::get<T>(&x->get());
|
||||
}
|
||||
#else
|
||||
template <typename T, typename... Types>
|
||||
inline T const&
|
||||
get(boost::spirit::extended_variant<Types...> const& x)
|
||||
{
|
||||
return boost::get<T>(x.get());
|
||||
}
|
||||
|
||||
template <typename T, typename... Types>
|
||||
inline T&
|
||||
get(boost::spirit::extended_variant<Types...>& x)
|
||||
{
|
||||
return boost::get<T>(x.get());
|
||||
}
|
||||
|
||||
template <typename T, typename... Types>
|
||||
inline T const*
|
||||
get(boost::spirit::extended_variant<Types...> const* x)
|
||||
{
|
||||
return boost::get<T>(&x->get());
|
||||
}
|
||||
|
||||
template <typename T, typename... Types>
|
||||
inline T*
|
||||
get(boost::spirit::extended_variant<Types...>* x)
|
||||
{
|
||||
return boost::get<T>(&x->get());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef BOOST_SPIRIT_EXTENDED_VARIANT_ENUM_PARAMS
|
||||
#undef BOOST_SPIRIT_EXTENDED_VARIANT_LIMIT_TYPES
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/*=============================================================================
|
||||
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_HANDLES_CONTAINER_DEC_18_2010_0920AM)
|
||||
#define BOOST_SPIRIT_HANDLES_CONTAINER_DEC_18_2010_0920AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/attributes_fwd.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/find_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
// Finds out whether a component handles container attributes intrinsically
|
||||
// (or whether container attributes need to be split up separately).
|
||||
template <typename T, typename Attribute, typename Context
|
||||
, typename Iterator, typename Enable>
|
||||
struct handles_container : mpl::false_ {};
|
||||
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct unary_handles_container
|
||||
: handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
|
||||
template <typename Left, typename Right, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct binary_handles_container
|
||||
: mpl::or_<
|
||||
handles_container<Left, Attribute, Context, Iterator>
|
||||
, handles_container<Right, Attribute, Context, Iterator> >
|
||||
{};
|
||||
|
||||
template <typename Elements, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct nary_handles_container
|
||||
: mpl::not_<
|
||||
is_same<
|
||||
typename mpl::find_if<
|
||||
Elements, handles_container<mpl::_, Attribute
|
||||
, Context, Iterator>
|
||||
>::type
|
||||
, typename mpl::end<Elements>::type> >
|
||||
{};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/*=============================================================================
|
||||
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_HAS_SEMANTIC_ACTION_SEP_20_2009_0626PM)
|
||||
#define BOOST_SPIRIT_HAS_SEMANTIC_ACTION_SEP_20_2009_0626PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/find_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
// finding out, whether a component contains a semantic action
|
||||
template <typename T, typename Enable = void>
|
||||
struct has_semantic_action
|
||||
: mpl::false_ {};
|
||||
|
||||
template <typename Subject>
|
||||
struct unary_has_semantic_action
|
||||
: has_semantic_action<Subject> {};
|
||||
|
||||
template <typename Left, typename Right>
|
||||
struct binary_has_semantic_action
|
||||
: mpl::or_<has_semantic_action<Left>, has_semantic_action<Right> > {};
|
||||
|
||||
template <typename Elements>
|
||||
struct nary_has_semantic_action
|
||||
: mpl::not_<
|
||||
is_same<
|
||||
typename mpl::find_if<
|
||||
Elements, has_semantic_action<mpl::_>
|
||||
>::type
|
||||
, typename mpl::end<Elements>::type
|
||||
>
|
||||
> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,159 @@
|
||||
/*=============================================================================
|
||||
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_INFO_NOVEMBER_22_2008_1132AM)
|
||||
#define BOOST_SPIRIT_INFO_NOVEMBER_22_2008_1132AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/variant/variant.hpp>
|
||||
#include <boost/variant/recursive_variant.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/spirit/home/support/utf8.hpp>
|
||||
#include <list>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
// info provides information about a component. Each component
|
||||
// has a what member function that returns an info object.
|
||||
// strings in the info object are assumed to be encoded as UTF8
|
||||
// for uniformity.
|
||||
struct info
|
||||
{
|
||||
struct nil_ {};
|
||||
|
||||
typedef
|
||||
boost::variant<
|
||||
nil_
|
||||
, utf8_string
|
||||
, recursive_wrapper<info>
|
||||
, recursive_wrapper<std::pair<info, info> >
|
||||
, recursive_wrapper<std::list<info> >
|
||||
>
|
||||
value_type;
|
||||
|
||||
explicit info(utf8_string const& tag_)
|
||||
: tag(tag_), value(nil_()) {}
|
||||
|
||||
template <typename T>
|
||||
info(utf8_string const& tag_, T const& value_)
|
||||
: tag(tag_), value(value_) {}
|
||||
|
||||
info(utf8_string const& tag_, char value_)
|
||||
: tag(tag_), value(utf8_string(1, value_)) {}
|
||||
|
||||
info(utf8_string const& tag_, wchar_t value_)
|
||||
: tag(tag_), value(to_utf8(value_)) {}
|
||||
|
||||
info(utf8_string const& tag_, ucs4_char value_)
|
||||
: tag(tag_), value(to_utf8(value_)) {}
|
||||
|
||||
template <typename Char>
|
||||
info(utf8_string const& tag_, Char const* str)
|
||||
: tag(tag_), value(to_utf8(str)) {}
|
||||
|
||||
template <typename Char, typename Traits, typename Allocator>
|
||||
info(utf8_string const& tag_
|
||||
, std::basic_string<Char, Traits, Allocator> const& str)
|
||||
: tag(tag_), value(to_utf8(str)) {}
|
||||
|
||||
utf8_string tag;
|
||||
value_type value;
|
||||
};
|
||||
|
||||
template <typename Callback>
|
||||
struct basic_info_walker
|
||||
{
|
||||
typedef void result_type;
|
||||
typedef basic_info_walker<Callback> this_type;
|
||||
|
||||
basic_info_walker(Callback& callback_, utf8_string const& tag_, int depth_)
|
||||
: callback(callback_), tag(tag_), depth(depth_) {}
|
||||
|
||||
void operator()(info::nil_) const
|
||||
{
|
||||
callback.element(tag, "", depth);
|
||||
}
|
||||
|
||||
void operator()(utf8_string const& str) const
|
||||
{
|
||||
callback.element(tag, str, depth);
|
||||
}
|
||||
|
||||
void operator()(info const& what) const
|
||||
{
|
||||
boost::apply_visitor(
|
||||
this_type(callback, what.tag, depth+1), what.value);
|
||||
}
|
||||
|
||||
void operator()(std::pair<info, info> const& pair) const
|
||||
{
|
||||
callback.element(tag, "", depth);
|
||||
boost::apply_visitor(
|
||||
this_type(callback, pair.first.tag, depth+1), pair.first.value);
|
||||
boost::apply_visitor(
|
||||
this_type(callback, pair.second.tag, depth+1), pair.second.value);
|
||||
}
|
||||
|
||||
void operator()(std::list<info> const& l) const
|
||||
{
|
||||
callback.element(tag, "", depth);
|
||||
BOOST_FOREACH(info const& what, l)
|
||||
{
|
||||
boost::apply_visitor(
|
||||
this_type(callback, what.tag, depth+1), what.value);
|
||||
}
|
||||
}
|
||||
|
||||
Callback& callback;
|
||||
utf8_string const& tag;
|
||||
int depth;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
basic_info_walker& operator= (basic_info_walker const&);
|
||||
};
|
||||
|
||||
// bare-bones print support
|
||||
template <typename Out>
|
||||
struct simple_printer
|
||||
{
|
||||
typedef utf8_string string;
|
||||
|
||||
simple_printer(Out& out_)
|
||||
: out(out_) {}
|
||||
|
||||
void element(string const& tag, string const& value, int /*depth*/) const
|
||||
{
|
||||
if (value == "")
|
||||
out << '<' << tag << '>';
|
||||
else
|
||||
out << '"' << value << '"';
|
||||
}
|
||||
|
||||
Out& out;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
simple_printer& operator= (simple_printer const&);
|
||||
};
|
||||
|
||||
template <typename Out>
|
||||
Out& operator<<(Out& out, info const& what)
|
||||
{
|
||||
simple_printer<Out> pr(out);
|
||||
basic_info_walker<simple_printer<Out> > walker(pr, what.tag, 0);
|
||||
boost::apply_visitor(walker, what.value);
|
||||
return out;
|
||||
}
|
||||
}}
|
||||
|
||||
#endif
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2001, Daniel C. Nuffer
|
||||
// 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_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM)
|
||||
#define BOOST_SPIRIT_ITERATOR_BUF_ID_CHECK_POLICY_MAR_16_2007_1108AM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <exception> // for std::exception
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class illegal_backtracking
|
||||
// thrown by buf_id_check CheckingPolicy if an instance of an iterator is
|
||||
// used after another one has invalidated the queue
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
class illegal_backtracking : public std::exception
|
||||
{
|
||||
public:
|
||||
illegal_backtracking() throw() {}
|
||||
~illegal_backtracking() throw() {}
|
||||
|
||||
char const* what() const throw()
|
||||
{
|
||||
return "boost::spirit::multi_pass::illegal_backtracking";
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class buf_id_check
|
||||
// Implementation of the CheckingPolicy used by multi_pass
|
||||
// This policy is most effective when used together with the std_deque
|
||||
// StoragePolicy.
|
||||
//
|
||||
// If used with the fixed_size_queue StoragePolicy, it will not detect
|
||||
// iterator dereferences that are out of the range of the queue.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
struct buf_id_check
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
struct unique //: detail::default_checking_policy
|
||||
{
|
||||
unique() : buf_id(0) {}
|
||||
unique(unique const& x) : buf_id(x.buf_id) {}
|
||||
|
||||
void swap(unique& x)
|
||||
{
|
||||
boost::swap(buf_id, x.buf_id);
|
||||
}
|
||||
|
||||
// called to verify that everything is ok.
|
||||
template <typename MultiPass>
|
||||
static void docheck(MultiPass const& mp)
|
||||
{
|
||||
if (mp.buf_id != mp.shared()->shared_buf_id)
|
||||
boost::throw_exception(illegal_backtracking());
|
||||
}
|
||||
|
||||
// called from multi_pass::clear_queue, so we can increment the count
|
||||
template <typename MultiPass>
|
||||
static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
++mp.shared()->shared_buf_id;
|
||||
++mp.buf_id;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
protected:
|
||||
unsigned long buf_id;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
struct shared
|
||||
{
|
||||
shared() : shared_buf_id(0) {}
|
||||
unsigned long shared_buf_id;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM)
|
||||
#define BOOST_SPIRIT_BUFFERING_ITERATOR_INPUT_ITERATOR_POLICY_MAR_04_2010_1224AM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp>
|
||||
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class input_iterator
|
||||
//
|
||||
// Implementation of the InputPolicy used by multi_pass, this is different
|
||||
// from the input_iterator policy only as it is buffering the last input
|
||||
// character to allow returning it by reference. This is needed for
|
||||
// wrapping iterators not buffering the last item (such as the
|
||||
// std::istreambuf_iterator). Unfortunately there is no way to
|
||||
// automatically figure this out at compile time.
|
||||
//
|
||||
// The buffering_input_iterator encapsulates an input iterator of type T
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct buffering_input_iterator
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
class unique // : public detail::default_input_policy
|
||||
{
|
||||
private:
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::value_type
|
||||
result_type;
|
||||
|
||||
public:
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::difference_type
|
||||
difference_type;
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::difference_type
|
||||
distance_type;
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::pointer
|
||||
pointer;
|
||||
typedef result_type& reference;
|
||||
typedef result_type value_type;
|
||||
|
||||
protected:
|
||||
unique() {}
|
||||
explicit unique(T x) {}
|
||||
|
||||
void swap(unique&) {}
|
||||
|
||||
public:
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{
|
||||
return mp.shared()->get_input();
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void advance_input(MultiPass& mp)
|
||||
{
|
||||
BOOST_ASSERT(0 != mp.shared());
|
||||
mp.shared()->advance_input();
|
||||
}
|
||||
|
||||
// test, whether we reached the end of the underlying stream
|
||||
template <typename MultiPass>
|
||||
static bool input_at_eof(MultiPass const& mp)
|
||||
{
|
||||
static T const end_iter;
|
||||
return mp.shared()->input_ == end_iter;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool input_is_valid(MultiPass const& mp, value_type const& t)
|
||||
{
|
||||
return mp.shared()->input_is_valid_;
|
||||
}
|
||||
|
||||
// no unique data elements
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct shared
|
||||
{
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::value_type
|
||||
result_type;
|
||||
|
||||
explicit shared(T const& input)
|
||||
: input_(input), curtok_(0), input_is_valid_(false) {}
|
||||
|
||||
void advance_input()
|
||||
{
|
||||
++input_;
|
||||
input_is_valid_ = false;
|
||||
}
|
||||
|
||||
result_type& get_input()
|
||||
{
|
||||
if (!input_is_valid_) {
|
||||
curtok_ = *input_;
|
||||
input_is_valid_ = true;
|
||||
}
|
||||
return curtok_;
|
||||
}
|
||||
|
||||
T input_;
|
||||
result_type curtok_;
|
||||
bool input_is_valid_;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+520
@@ -0,0 +1,520 @@
|
||||
// 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_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM)
|
||||
#define BOOST_SPIRIT_ITERATOR_COMBINE_POLICIES_APR_06_2008_0136PM
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/is_empty.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// The purpose of the multi_pass_unique template is to eliminate
|
||||
// empty policy classes (policies not containing any data items) from the
|
||||
// multiple inheritance chain. This is necessary since some compilers
|
||||
// fail to apply the empty base optimization if multiple inheritance is
|
||||
// involved.
|
||||
// Additionally this can be used to combine separate policies into one
|
||||
// single multi_pass_policy as required by the multi_pass template
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// select the correct derived classes based on if a policy is empty
|
||||
template <typename T
|
||||
, typename Ownership, typename Checking, typename Input, typename Storage
|
||||
, bool OwnershipIsEmpty = boost::is_empty<Ownership>::value
|
||||
, bool CheckingIsEmpty = boost::is_empty<Checking>::value
|
||||
, bool InputIsEmpty = boost::is_empty<Input>::value>
|
||||
struct multi_pass_unique;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Ownership, typename Checking
|
||||
, typename Input, typename Storage>
|
||||
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
|
||||
, false, false, false>
|
||||
: Ownership, Checking, Input, Storage
|
||||
{
|
||||
multi_pass_unique() {}
|
||||
multi_pass_unique(T& x) : Input(x) {}
|
||||
multi_pass_unique(T const& x) : Input(x) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
Ownership::destroy(mp);
|
||||
Checking::destroy(mp);
|
||||
Input::destroy(mp);
|
||||
Storage::destroy(mp);
|
||||
}
|
||||
|
||||
void swap(multi_pass_unique& x)
|
||||
{
|
||||
this->Ownership::swap(x);
|
||||
this->Checking::swap(x);
|
||||
this->Input::swap(x);
|
||||
this->Storage::swap(x);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
Checking::clear_queue(mp);
|
||||
Storage::clear_queue(mp);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Ownership, typename Checking
|
||||
, typename Input, typename Storage>
|
||||
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
|
||||
, false, false, true>
|
||||
: Ownership, Checking, Storage
|
||||
{
|
||||
multi_pass_unique() {}
|
||||
multi_pass_unique(T const&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
Ownership::destroy(mp);
|
||||
Checking::destroy(mp);
|
||||
Input::destroy(mp);
|
||||
Storage::destroy(mp);
|
||||
}
|
||||
|
||||
void swap(multi_pass_unique& x)
|
||||
{
|
||||
this->Ownership::swap(x);
|
||||
this->Checking::swap(x);
|
||||
this->Storage::swap(x);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
Checking::clear_queue(mp);
|
||||
Storage::clear_queue(mp);
|
||||
}
|
||||
|
||||
// implement input policy functions by forwarding to the Input type
|
||||
template <typename MultiPass>
|
||||
inline static void advance_input(MultiPass& mp)
|
||||
{ Input::advance_input(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{ return Input::get_input(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool input_at_eof(MultiPass const& mp)
|
||||
{ return Input::input_at_eof(mp); }
|
||||
|
||||
template <typename MultiPass, typename TokenType>
|
||||
inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
|
||||
{ return Input::input_is_valid(mp, curtok); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Ownership, typename Checking
|
||||
, typename Input, typename Storage>
|
||||
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
|
||||
, false, true, false>
|
||||
: Ownership, Input, Storage
|
||||
{
|
||||
multi_pass_unique() {}
|
||||
multi_pass_unique(T& x) : Input(x) {}
|
||||
multi_pass_unique(T const& x) : Input(x) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
Ownership::destroy(mp);
|
||||
Input::destroy(mp);
|
||||
Storage::destroy(mp);
|
||||
}
|
||||
|
||||
void swap(multi_pass_unique& x)
|
||||
{
|
||||
this->Ownership::swap(x);
|
||||
this->Input::swap(x);
|
||||
this->Storage::swap(x);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
Checking::clear_queue(mp);
|
||||
Storage::clear_queue(mp);
|
||||
}
|
||||
|
||||
// checking policy functions are forwarded to the Checking type
|
||||
template <typename MultiPass>
|
||||
inline static void docheck(MultiPass const& mp)
|
||||
{ Checking::docheck(mp); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Ownership, typename Checking
|
||||
, typename Input, typename Storage>
|
||||
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
|
||||
, false, true, true>
|
||||
: Ownership, Storage
|
||||
{
|
||||
multi_pass_unique() {}
|
||||
multi_pass_unique(T const&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
Ownership::destroy(mp);
|
||||
Input::destroy(mp);
|
||||
Storage::destroy(mp);
|
||||
}
|
||||
|
||||
void swap(multi_pass_unique& x)
|
||||
{
|
||||
this->Ownership::swap(x);
|
||||
this->Storage::swap(x);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
Checking::clear_queue(mp);
|
||||
Storage::clear_queue(mp);
|
||||
}
|
||||
|
||||
// implement input policy functions by forwarding to the Input type
|
||||
template <typename MultiPass>
|
||||
inline static void advance_input(MultiPass& mp)
|
||||
{ Input::advance_input(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{ return Input::get_input(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool input_at_eof(MultiPass const& mp)
|
||||
{ return Input::input_at_eof(mp); }
|
||||
|
||||
template <typename MultiPass, typename TokenType>
|
||||
inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
|
||||
{ return Input::input_is_valid(mp, curtok); }
|
||||
|
||||
// checking policy functions are forwarded to the Checking type
|
||||
template <typename MultiPass>
|
||||
inline static void docheck(MultiPass const& mp)
|
||||
{ Checking::docheck(mp); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Ownership, typename Checking
|
||||
, typename Input, typename Storage>
|
||||
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
|
||||
, true, false, false>
|
||||
: Checking, Input, Storage
|
||||
{
|
||||
multi_pass_unique() {}
|
||||
multi_pass_unique(T& x) : Input(x) {}
|
||||
multi_pass_unique(T const& x) : Input(x) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
Checking::destroy(mp);
|
||||
Input::destroy(mp);
|
||||
Storage::destroy(mp);
|
||||
}
|
||||
|
||||
void swap(multi_pass_unique& x)
|
||||
{
|
||||
this->Checking::swap(x);
|
||||
this->Input::swap(x);
|
||||
this->Storage::swap(x);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
Checking::clear_queue(mp);
|
||||
Storage::clear_queue(mp);
|
||||
}
|
||||
|
||||
// ownership policy functions are forwarded to the Ownership type
|
||||
template <typename MultiPass>
|
||||
inline static void clone(MultiPass& mp)
|
||||
{ Ownership::clone(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool release(MultiPass& mp)
|
||||
{ return Ownership::release(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool is_unique(MultiPass const& mp)
|
||||
{ return Ownership::is_unique(mp); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Ownership, typename Checking
|
||||
, typename Input, typename Storage>
|
||||
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
|
||||
, true, false, true>
|
||||
: Checking, Storage
|
||||
{
|
||||
multi_pass_unique() {}
|
||||
multi_pass_unique(T const&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
Checking::destroy(mp);
|
||||
Input::destroy(mp);
|
||||
Storage::destroy(mp);
|
||||
}
|
||||
|
||||
void swap(multi_pass_unique& x)
|
||||
{
|
||||
this->Checking::swap(x);
|
||||
this->Storage::swap(x);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
Checking::clear_queue(mp);
|
||||
Storage::clear_queue(mp);
|
||||
}
|
||||
|
||||
// implement input policy functions by forwarding to the Input type
|
||||
template <typename MultiPass>
|
||||
inline static void advance_input(MultiPass& mp)
|
||||
{ Input::advance_input(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{ return Input::get_input(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool input_at_eof(MultiPass const& mp)
|
||||
{ return Input::input_at_eof(mp); }
|
||||
|
||||
template <typename MultiPass, typename TokenType>
|
||||
inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
|
||||
{ return Input::input_is_valid(mp, curtok); }
|
||||
|
||||
// ownership policy functions are forwarded to the Ownership type
|
||||
template <typename MultiPass>
|
||||
inline static void clone(MultiPass& mp)
|
||||
{ Ownership::clone(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool release(MultiPass& mp)
|
||||
{ return Ownership::release(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool is_unique(MultiPass const& mp)
|
||||
{ return Ownership::is_unique(mp); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Ownership, typename Checking
|
||||
, typename Input, typename Storage>
|
||||
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
|
||||
, true, true, false>
|
||||
: Input, Storage
|
||||
{
|
||||
multi_pass_unique() {}
|
||||
multi_pass_unique(T& x) : Input(x) {}
|
||||
multi_pass_unique(T const& x) : Input(x) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
Input::destroy(mp);
|
||||
Storage::destroy(mp);
|
||||
}
|
||||
|
||||
void swap(multi_pass_unique& x)
|
||||
{
|
||||
this->Input::swap(x);
|
||||
this->Storage::swap(x);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
Checking::clear_queue(mp);
|
||||
Storage::clear_queue(mp);
|
||||
}
|
||||
|
||||
// checking policy functions are forwarded to the Checking type
|
||||
template <typename MultiPass>
|
||||
inline static void docheck(MultiPass const& mp)
|
||||
{ Checking::docheck(mp); }
|
||||
|
||||
// ownership policy functions are forwarded to the Ownership type
|
||||
template <typename MultiPass>
|
||||
inline static void clone(MultiPass& mp)
|
||||
{ Ownership::clone(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool release(MultiPass& mp)
|
||||
{ return Ownership::release(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool is_unique(MultiPass const& mp)
|
||||
{ return Ownership::is_unique(mp); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Ownership, typename Checking
|
||||
, typename Input, typename Storage>
|
||||
struct multi_pass_unique<T, Ownership, Checking, Input, Storage
|
||||
, true, true, true>
|
||||
: Storage
|
||||
{
|
||||
multi_pass_unique() {}
|
||||
multi_pass_unique(T const&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
Input::destroy(mp);
|
||||
Storage::destroy(mp);
|
||||
}
|
||||
|
||||
void swap(multi_pass_unique& x)
|
||||
{
|
||||
this->Storage::swap(x);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
Checking::clear_queue(mp);
|
||||
Storage::clear_queue(mp);
|
||||
}
|
||||
|
||||
// implement input policy functions by forwarding to the Input type
|
||||
template <typename MultiPass>
|
||||
inline static void advance_input(MultiPass& mp)
|
||||
{ Input::advance_input(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{ return Input::get_input(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool input_at_eof(MultiPass const& mp)
|
||||
{ return Input::input_at_eof(mp); }
|
||||
|
||||
template <typename MultiPass, typename TokenType>
|
||||
inline static bool input_is_valid(MultiPass& mp, TokenType& curtok)
|
||||
{ return Input::input_is_valid(mp, curtok); }
|
||||
|
||||
// checking policy functions are forwarded to the Checking type
|
||||
template <typename MultiPass>
|
||||
inline static void docheck(MultiPass const& mp)
|
||||
{ Checking::docheck(mp); }
|
||||
|
||||
// ownership policy functions are forwarded to the Ownership type
|
||||
template <typename MultiPass>
|
||||
inline static void clone(MultiPass& mp)
|
||||
{ Ownership::clone(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool release(MultiPass& mp)
|
||||
{ return Ownership::release(mp); }
|
||||
|
||||
template <typename MultiPass>
|
||||
inline static bool is_unique(MultiPass const& mp)
|
||||
{ return Ownership::is_unique(mp); }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// the multi_pass_shared structure is used to combine the shared data items
|
||||
// of all policies into one single structure
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename T, typename Ownership, typename Checking, typename Input
|
||||
, typename Storage>
|
||||
struct multi_pass_shared : Ownership, Checking, Input, Storage
|
||||
{
|
||||
explicit multi_pass_shared(T& input) : Input(input) {}
|
||||
explicit multi_pass_shared(T const& input) : Input(input) {}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is a default implementation of a policy class as required by the
|
||||
// multi_pass template, combining 4 separate policies into one. Any other
|
||||
// multi_pass policy class needs to follow the scheme as shown below.
|
||||
template<typename Ownership, typename Checking, typename Input
|
||||
, typename Storage>
|
||||
struct default_policy
|
||||
{
|
||||
typedef Ownership ownership_policy;
|
||||
typedef Checking checking_policy;
|
||||
typedef Input input_policy;
|
||||
typedef Storage storage_policy;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct unique : multi_pass_unique<T
|
||||
, typename Ownership::unique, typename Checking::unique
|
||||
, typename Input::BOOST_NESTED_TEMPLATE unique<T>
|
||||
, typename Storage::BOOST_NESTED_TEMPLATE unique<
|
||||
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
|
||||
{
|
||||
typedef typename Ownership::unique ownership_policy;
|
||||
typedef typename Checking::unique checking_policy;
|
||||
typedef typename Input::BOOST_NESTED_TEMPLATE unique<T>
|
||||
input_policy;
|
||||
typedef typename Storage::BOOST_NESTED_TEMPLATE unique<
|
||||
typename input_policy::value_type> storage_policy;
|
||||
|
||||
typedef multi_pass_unique<T, ownership_policy, checking_policy
|
||||
, input_policy, storage_policy> unique_base_type;
|
||||
|
||||
unique() {}
|
||||
explicit unique(T& input) : unique_base_type(input) {}
|
||||
explicit unique(T const& input) : unique_base_type(input) {}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct shared : multi_pass_shared<T
|
||||
, typename Ownership::shared, typename Checking::shared
|
||||
, typename Input::BOOST_NESTED_TEMPLATE shared<T>
|
||||
, typename Storage::BOOST_NESTED_TEMPLATE shared<
|
||||
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type> >
|
||||
{
|
||||
typedef typename Ownership::shared ownership_policy;
|
||||
typedef typename Checking::shared checking_policy;
|
||||
typedef typename Input::BOOST_NESTED_TEMPLATE shared<T>
|
||||
input_policy;
|
||||
typedef typename Storage::BOOST_NESTED_TEMPLATE shared<
|
||||
typename Input::BOOST_NESTED_TEMPLATE unique<T>::value_type>
|
||||
storage_policy;
|
||||
|
||||
typedef multi_pass_shared<T, ownership_policy, checking_policy
|
||||
, input_policy, storage_policy> shared_base_type;
|
||||
|
||||
explicit shared(T& input)
|
||||
: shared_base_type(input), inhibit_clear_queue_(false) {}
|
||||
explicit shared(T const& input)
|
||||
: shared_base_type(input), inhibit_clear_queue_(false) {}
|
||||
|
||||
// This is needed for the correct implementation of expectation
|
||||
// points. Normally expectation points flush any multi_pass
|
||||
// iterator they may act on, but if the corresponding error handler
|
||||
// is of type 'retry' no flushing of the internal buffers should be
|
||||
// executed (even if explicitly requested).
|
||||
bool inhibit_clear_queue_;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) 2001, Daniel C. Nuffer
|
||||
// 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_ITERATOR_FIRST_OWNER_POLICY_MAR_16_2007_1108AM)
|
||||
#define BOOST_SPIRIT_ITERATOR_FIRST_OWNER_POLICY_MAR_16_2007_1108AM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class first_owner
|
||||
// Implementation of an OwnershipPolicy used by multi_pass
|
||||
// This ownership policy dictates that the first iterator created will
|
||||
// determine the lifespan of the shared components. This works well for
|
||||
// spirit, since no dynamic allocation of iterators is done, and all
|
||||
// copies are make on the stack.
|
||||
//
|
||||
// There is a caveat about using this policy together with the std_deque
|
||||
// StoragePolicy. Since first_owner always returns false from unique(),
|
||||
// std_deque will only release the queued data if clear_queue() is called.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct first_owner
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
struct unique : detail::default_ownership_policy
|
||||
{
|
||||
unique() : first(true) {}
|
||||
unique(unique const&) : first(false) {}
|
||||
|
||||
// return true to indicate deletion of resources
|
||||
template <typename MultiPass>
|
||||
static bool release(MultiPass& mp)
|
||||
{
|
||||
return mp.first;
|
||||
}
|
||||
|
||||
// use swap from default policy
|
||||
// if we're the first, we still remain the first, even if assigned
|
||||
// to, so don't swap first. swap is only called from operator=
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool is_unique(MultiPass const&)
|
||||
{
|
||||
return false; // no way to know, so always return false
|
||||
}
|
||||
|
||||
protected:
|
||||
bool first;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
struct shared {}; // no shared data
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+392
@@ -0,0 +1,392 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ITERATOR_FIXED_SIZE_QUEUE_MAR_16_2007_1137AM)
|
||||
#define BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_MAR_16_2007_1137AM
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iterator>
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp> // for BOOST_ASSERT
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Make sure we're using a decent version of the Boost.IteratorAdaptors lib
|
||||
#if !defined(BOOST_ITERATOR_ADAPTORS_VERSION) || \
|
||||
BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
#error "Please use at least Boost V1.31.0 while compiling the fixed_size_queue class!"
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_SPIRIT_ASSERT_FSQ_SIZE \
|
||||
BOOST_ASSERT(((m_tail + N + 1) - m_head) % (N+1) == m_size % (N+1)) \
|
||||
/**/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Queue, typename T, typename Pointer>
|
||||
class fsq_iterator
|
||||
: public boost::iterator_facade<
|
||||
fsq_iterator<Queue, T, Pointer>, T,
|
||||
std::random_access_iterator_tag
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef typename Queue::position_type position_type;
|
||||
typedef boost::iterator_facade<
|
||||
fsq_iterator<Queue, T, Pointer>, T,
|
||||
std::random_access_iterator_tag
|
||||
> base_type;
|
||||
|
||||
fsq_iterator() {}
|
||||
fsq_iterator(position_type const &p_) : p(p_) {}
|
||||
|
||||
position_type &get_position() { return p; }
|
||||
position_type const &get_position() const { return p; }
|
||||
|
||||
private:
|
||||
friend class boost::iterator_core_access;
|
||||
|
||||
typename base_type::reference dereference() const
|
||||
{
|
||||
return p.self->m_queue[p.pos];
|
||||
}
|
||||
|
||||
void increment()
|
||||
{
|
||||
++p.pos;
|
||||
if (p.pos == Queue::MAX_SIZE+1)
|
||||
p.pos = 0;
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
if (p.pos == 0)
|
||||
p.pos = Queue::MAX_SIZE;
|
||||
else
|
||||
--p.pos;
|
||||
}
|
||||
|
||||
bool is_eof() const
|
||||
{
|
||||
return p.self == 0 || p.pos == p.self->size();
|
||||
}
|
||||
|
||||
template <typename Q, typename T_, typename P>
|
||||
bool equal(fsq_iterator<Q, T_, P> const &x) const
|
||||
{
|
||||
if (is_eof())
|
||||
return x.is_eof();
|
||||
if (x.is_eof())
|
||||
return false;
|
||||
|
||||
position_type const &rhs_pos = x.get_position();
|
||||
return (p.self == rhs_pos.self) && (p.pos == rhs_pos.pos);
|
||||
}
|
||||
|
||||
template <typename Q, typename T_, typename P>
|
||||
typename base_type::difference_type distance_to(
|
||||
fsq_iterator<Q, T_, P> const &x) const
|
||||
{
|
||||
typedef typename base_type::difference_type difference_type;
|
||||
|
||||
position_type const &p2 = x.get_position();
|
||||
std::size_t pos1 = p.pos;
|
||||
std::size_t pos2 = p2.pos;
|
||||
|
||||
// Undefined behavior if the iterators come from different
|
||||
// containers
|
||||
BOOST_ASSERT(p.self == p2.self);
|
||||
|
||||
if (pos1 < p.self->m_head)
|
||||
pos1 += Queue::MAX_SIZE;
|
||||
if (pos2 < p2.self->m_head)
|
||||
pos2 += Queue::MAX_SIZE;
|
||||
|
||||
if (pos2 > pos1)
|
||||
return difference_type(pos2 - pos1);
|
||||
else
|
||||
return -difference_type(pos1 - pos2);
|
||||
}
|
||||
|
||||
void advance(typename base_type::difference_type n)
|
||||
{
|
||||
// Notice that we don't care values of n that can
|
||||
// wrap around more than one time, since it would
|
||||
// be undefined behavior anyway (going outside
|
||||
// the begin/end range). Negative wrapping is a bit
|
||||
// cumbersome because we don't want to case p.pos
|
||||
// to signed.
|
||||
if (n < 0)
|
||||
{
|
||||
n = -n;
|
||||
if (p.pos < (std::size_t)n)
|
||||
p.pos = Queue::MAX_SIZE+1 - (n - p.pos);
|
||||
else
|
||||
p.pos -= n;
|
||||
}
|
||||
else
|
||||
{
|
||||
p.pos += n;
|
||||
if (p.pos >= Queue::MAX_SIZE+1)
|
||||
p.pos -= Queue::MAX_SIZE+1;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
position_type p;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, std::size_t N>
|
||||
class fixed_size_queue
|
||||
{
|
||||
private:
|
||||
struct position
|
||||
{
|
||||
fixed_size_queue* self;
|
||||
std::size_t pos;
|
||||
|
||||
position() : self(0), pos(0) {}
|
||||
|
||||
// The const_cast here is just to avoid to have two different
|
||||
// position structures for the const and non-const case.
|
||||
// The const semantic is guaranteed by the iterator itself
|
||||
position(const fixed_size_queue* s, std::size_t p)
|
||||
: self(const_cast<fixed_size_queue*>(s)), pos(p)
|
||||
{}
|
||||
|
||||
bool is_initialized() const { return self != 0; }
|
||||
void set_queue(fixed_size_queue* q) { self = q; }
|
||||
};
|
||||
|
||||
public:
|
||||
// Declare the iterators
|
||||
typedef fsq_iterator<fixed_size_queue<T, N>, T, T*> iterator;
|
||||
typedef
|
||||
fsq_iterator<fixed_size_queue<T, N>, T const, T const*>
|
||||
const_iterator;
|
||||
typedef position position_type;
|
||||
|
||||
friend class fsq_iterator<fixed_size_queue<T, N>, T, T*>;
|
||||
friend class fsq_iterator<fixed_size_queue<T, N>, T const, T const*>;
|
||||
|
||||
fixed_size_queue();
|
||||
fixed_size_queue(const fixed_size_queue& x);
|
||||
fixed_size_queue& operator=(const fixed_size_queue& x);
|
||||
~fixed_size_queue();
|
||||
|
||||
void push_back(const T& e);
|
||||
void push_front(const T& e);
|
||||
void serve(T& e);
|
||||
void pop_front();
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
bool full() const
|
||||
{
|
||||
return m_size == N;
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(position(this, m_head));
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(position(this, m_head));
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return iterator(position(0, m_tail));
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(position(0, m_tail));
|
||||
}
|
||||
|
||||
std::size_t size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
T& front()
|
||||
{
|
||||
return m_queue[m_head];
|
||||
}
|
||||
|
||||
const T& front() const
|
||||
{
|
||||
return m_queue[m_head];
|
||||
}
|
||||
|
||||
private:
|
||||
// Redefine the template parameters to avoid using partial template
|
||||
// specialization on the iterator policy to extract N.
|
||||
BOOST_STATIC_CONSTANT(std::size_t, MAX_SIZE = N);
|
||||
|
||||
std::size_t m_head;
|
||||
std::size_t m_tail;
|
||||
std::size_t m_size;
|
||||
T m_queue[N+1];
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline
|
||||
fixed_size_queue<T, N>::fixed_size_queue()
|
||||
: m_head(0)
|
||||
, m_tail(0)
|
||||
, m_size(0)
|
||||
{
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline
|
||||
fixed_size_queue<T, N>::fixed_size_queue(const fixed_size_queue& x)
|
||||
: m_head(x.m_head)
|
||||
, m_tail(x.m_tail)
|
||||
, m_size(x.m_size)
|
||||
{
|
||||
copy(x.begin(), x.end(), begin());
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline fixed_size_queue<T, N>&
|
||||
fixed_size_queue<T, N>::operator=(const fixed_size_queue& x)
|
||||
{
|
||||
if (this != &x)
|
||||
{
|
||||
m_head = x.m_head;
|
||||
m_tail = x.m_tail;
|
||||
m_size = x.m_size;
|
||||
copy(x.begin(), x.end(), begin());
|
||||
}
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline
|
||||
fixed_size_queue<T, N>::~fixed_size_queue()
|
||||
{
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline void
|
||||
fixed_size_queue<T, N>::push_back(const T& e)
|
||||
{
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
|
||||
BOOST_ASSERT(!full());
|
||||
|
||||
m_queue[m_tail] = e;
|
||||
++m_size;
|
||||
++m_tail;
|
||||
if (m_tail == N+1)
|
||||
m_tail = 0;
|
||||
|
||||
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline void
|
||||
fixed_size_queue<T, N>::push_front(const T& e)
|
||||
{
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
|
||||
BOOST_ASSERT(!full());
|
||||
|
||||
if (m_head == 0)
|
||||
m_head = N;
|
||||
else
|
||||
--m_head;
|
||||
|
||||
m_queue[m_head] = e;
|
||||
++m_size;
|
||||
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline void
|
||||
fixed_size_queue<T, N>::serve(T& e)
|
||||
{
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
|
||||
e = m_queue[m_head];
|
||||
pop_front();
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
inline void
|
||||
fixed_size_queue<T, N>::pop_front()
|
||||
{
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
|
||||
++m_head;
|
||||
if (m_head == N+1)
|
||||
m_head = 0;
|
||||
--m_size;
|
||||
|
||||
BOOST_ASSERT(m_size <= N+1);
|
||||
BOOST_SPIRIT_ASSERT_FSQ_SIZE;
|
||||
BOOST_ASSERT(m_head <= N+1);
|
||||
BOOST_ASSERT(m_tail <= N+1);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#undef BOOST_SPIRIT_ASSERT_FSQ_SIZE
|
||||
|
||||
#endif
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ITERATOR_FIXED_SIZE_QUEUE_POLICY_MAR_16_2007_1134AM)
|
||||
#define BOOST_SPIRIT_ITERATOR_FIXED_SIZE_QUEUE_POLICY_MAR_16_2007_1134AM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/fixed_size_queue.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class fixed_size_queue
|
||||
// Implementation of the StoragePolicy used by multi_pass
|
||||
// fixed_size_queue keeps a circular buffer (implemented by
|
||||
// boost::spirit::fixed_size_queue class) that is size N+1 and stores N
|
||||
// elements.
|
||||
//
|
||||
// It is up to the user to ensure that there is enough look ahead for
|
||||
// their grammar. Currently there is no way to tell if an iterator is
|
||||
// pointing to forgotten data. The leading iterator will put an item in
|
||||
// the queue and remove one when it is incremented. No dynamic allocation
|
||||
// is done, except on creation of the queue (fixed_size_queue constructor).
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <std::size_t N>
|
||||
struct fixed_size_queue
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Value>
|
||||
class unique : public detail::default_storage_policy
|
||||
{
|
||||
private:
|
||||
typedef detail::fixed_size_queue<Value, N> queue_type;
|
||||
|
||||
protected:
|
||||
unique() {}
|
||||
|
||||
unique(unique const& x)
|
||||
: queued_position(x.queued_position) {}
|
||||
|
||||
void swap(unique& x)
|
||||
{
|
||||
boost::swap(queued_position, x.queued_position);
|
||||
}
|
||||
|
||||
// This is called when the iterator is dereferenced. It's a
|
||||
// template method so we can recover the type of the multi_pass
|
||||
// iterator and access the m_input data member.
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference
|
||||
dereference(MultiPass const& mp)
|
||||
{
|
||||
if (!mp.queued_position.get_position().is_initialized())
|
||||
mp.queued_position.get_position().set_queue(&mp.shared()->queued_elements);
|
||||
|
||||
if (mp.queued_position == mp.shared()->queued_elements.end())
|
||||
return MultiPass::get_input(mp);
|
||||
|
||||
return *mp.queued_position;
|
||||
}
|
||||
|
||||
// This is called when the iterator is incremented. It's a
|
||||
// template method so we can recover the type of the multi_pass
|
||||
// iterator and access the m_input data member.
|
||||
template <typename MultiPass>
|
||||
static void increment(MultiPass& mp)
|
||||
{
|
||||
if (!mp.queued_position.get_position().is_initialized())
|
||||
mp.queued_position.get_position().set_queue(&mp.shared()->queued_elements);
|
||||
|
||||
if (mp.queued_position == mp.shared()->queued_elements.end())
|
||||
{
|
||||
// don't let the queue get larger than N
|
||||
if (mp.shared()->queued_elements.size() >= N)
|
||||
mp.shared()->queued_elements.pop_front();
|
||||
|
||||
mp.shared()->queued_elements.push_back(
|
||||
MultiPass::get_input(mp));
|
||||
MultiPass::advance_input(mp);
|
||||
}
|
||||
++mp.queued_position;
|
||||
}
|
||||
|
||||
// clear_queue is a no-op
|
||||
|
||||
// called to determine whether the iterator is an eof iterator
|
||||
template <typename MultiPass>
|
||||
static bool is_eof(MultiPass const& mp)
|
||||
{
|
||||
return mp.queued_position == mp.shared()->queued_elements.end() &&
|
||||
MultiPass::input_at_eof(mp);
|
||||
}
|
||||
|
||||
// called by operator==
|
||||
template <typename MultiPass>
|
||||
static bool equal_to(MultiPass const& mp, MultiPass const& x)
|
||||
{
|
||||
return mp.queued_position == x.queued_position;
|
||||
}
|
||||
|
||||
// called by operator<
|
||||
template <typename MultiPass>
|
||||
static bool less_than(MultiPass const& mp, MultiPass const& x)
|
||||
{
|
||||
return mp.queued_position < x.queued_position;
|
||||
}
|
||||
|
||||
protected:
|
||||
mutable typename queue_type::iterator queued_position;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Value>
|
||||
struct shared
|
||||
{
|
||||
typedef detail::fixed_size_queue<Value, N> queue_type;
|
||||
queue_type queued_elements;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
// 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_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M)
|
||||
#define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_16_2008_0448M
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
namespace is_valid_test_
|
||||
{
|
||||
template <typename Token>
|
||||
inline bool token_is_valid(Token const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class functor_input
|
||||
// Implementation of the InputPolicy used by multi_pass
|
||||
// functor_input gets tokens from a functor
|
||||
//
|
||||
// Note: the functor must have a typedef for result_type
|
||||
// It also must have a static variable of type result_type defined
|
||||
// to represent EOF that is called eof.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct functor_input
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Functor>
|
||||
class unique : public detail::default_input_policy
|
||||
{
|
||||
private:
|
||||
typedef typename Functor::result_type result_type;
|
||||
|
||||
protected:
|
||||
unique() {}
|
||||
explicit unique(Functor const& x) : ftor(x) {}
|
||||
|
||||
void swap(unique& x)
|
||||
{
|
||||
boost::swap(ftor, x.ftor);
|
||||
}
|
||||
|
||||
public:
|
||||
typedef result_type value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::ptrdiff_t distance_type;
|
||||
typedef result_type* pointer;
|
||||
typedef result_type& reference;
|
||||
|
||||
public:
|
||||
// get the next token
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{
|
||||
value_type& curtok = mp.shared()->curtok;
|
||||
if (!input_is_valid(mp, curtok))
|
||||
curtok = mp.ftor();
|
||||
return curtok;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void advance_input(MultiPass& mp)
|
||||
{
|
||||
// if mp.shared is NULL then this instance of the multi_pass
|
||||
// represents a end iterator
|
||||
BOOST_ASSERT(0 != mp.shared());
|
||||
mp.shared()->curtok = mp.ftor();
|
||||
}
|
||||
|
||||
// test, whether we reached the end of the underlying stream
|
||||
template <typename MultiPass>
|
||||
static bool input_at_eof(MultiPass const& mp)
|
||||
{
|
||||
return mp.shared()->curtok == mp.ftor.eof;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool input_is_valid(MultiPass const&, value_type const& t)
|
||||
{
|
||||
using namespace is_valid_test_;
|
||||
return token_is_valid(t);
|
||||
}
|
||||
|
||||
Functor& get_functor() const
|
||||
{
|
||||
return ftor;
|
||||
}
|
||||
|
||||
protected:
|
||||
mutable Functor ftor;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Functor>
|
||||
struct shared
|
||||
{
|
||||
explicit shared(Functor const&) : curtok(0) {}
|
||||
|
||||
typename Functor::result_type curtok;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ITERATOR_INPUT_ITERATOR_POLICY_MAR_16_2007_1156AM)
|
||||
#define BOOST_SPIRIT_ITERATOR_INPUT_ITERATOR_POLICY_MAR_16_2007_1156AM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
namespace input_iterator_is_valid_test_
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Token>
|
||||
inline bool token_is_valid(Token const& c)
|
||||
{
|
||||
return c ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class input_iterator
|
||||
// Implementation of the InputPolicy used by multi_pass
|
||||
//
|
||||
// The input_iterator encapsulates an input iterator of type T
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct input_iterator
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
class unique // : public detail::default_input_policy
|
||||
{
|
||||
private:
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::value_type
|
||||
result_type;
|
||||
|
||||
public:
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::difference_type
|
||||
difference_type;
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::difference_type
|
||||
distance_type;
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::pointer
|
||||
pointer;
|
||||
typedef
|
||||
typename boost::detail::iterator_traits<T>::reference
|
||||
reference;
|
||||
typedef result_type value_type;
|
||||
|
||||
protected:
|
||||
unique() {}
|
||||
explicit unique(T x) {}
|
||||
|
||||
void swap(unique&) {}
|
||||
|
||||
public:
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{
|
||||
return *mp.shared()->input_;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void advance_input(MultiPass& mp)
|
||||
{
|
||||
++mp.shared()->input_;
|
||||
}
|
||||
|
||||
// test, whether we reached the end of the underlying stream
|
||||
template <typename MultiPass>
|
||||
static bool input_at_eof(MultiPass const& mp)
|
||||
{
|
||||
static T const end_iter;
|
||||
return mp.shared()->input_ == end_iter;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool input_is_valid(MultiPass const& mp, value_type const& t)
|
||||
{
|
||||
using namespace input_iterator_is_valid_test_;
|
||||
return token_is_valid(t);
|
||||
}
|
||||
|
||||
// no unique data elements
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct shared
|
||||
{
|
||||
explicit shared(T const& input) : input_(input) {}
|
||||
|
||||
T input_;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ISTREAM_POLICY_JAN_04_2010_0130PM)
|
||||
#define BOOST_SPIRIT_ISTREAM_POLICY_JAN_04_2010_0130PM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class istream
|
||||
// Implementation of the InputPolicy used by multi_pass
|
||||
//
|
||||
// The istream encapsulates an std::basic_istream
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct istream
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
class unique // : public detail::default_input_policy
|
||||
{
|
||||
private:
|
||||
typedef typename T::char_type result_type;
|
||||
|
||||
public:
|
||||
typedef typename T::off_type difference_type;
|
||||
typedef typename T::off_type distance_type;
|
||||
typedef result_type const* pointer;
|
||||
typedef result_type const& reference;
|
||||
typedef result_type value_type;
|
||||
|
||||
protected:
|
||||
unique() {}
|
||||
explicit unique(T&) {}
|
||||
|
||||
void swap(unique&) {}
|
||||
|
||||
public:
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{
|
||||
if (!mp.shared()->initialized_)
|
||||
mp.shared()->read_one();
|
||||
return mp.shared()->curtok_;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void advance_input(MultiPass& mp)
|
||||
{
|
||||
// We invalidate the currently cached input character to avoid
|
||||
// reading more input from the underlying iterator than
|
||||
// required. Without this we would always read ahead one
|
||||
// character, even if this character never gets consumed by the
|
||||
// client.
|
||||
mp.shared()->peek_one();
|
||||
}
|
||||
|
||||
// test, whether we reached the end of the underlying stream
|
||||
template <typename MultiPass>
|
||||
static bool input_at_eof(MultiPass const& mp)
|
||||
{
|
||||
return mp.shared()->eof_reached_;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool input_is_valid(MultiPass const& mp, value_type const&)
|
||||
{
|
||||
return mp.shared()->initialized_;
|
||||
}
|
||||
|
||||
// no unique data elements
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct shared
|
||||
{
|
||||
private:
|
||||
typedef typename T::char_type result_type;
|
||||
|
||||
public:
|
||||
explicit shared(T& input)
|
||||
: input_(input), curtok_(-1)
|
||||
, initialized_(false), eof_reached_(false)
|
||||
{
|
||||
peek_one(); // istreams may be at eof right in the beginning
|
||||
}
|
||||
|
||||
void read_one()
|
||||
{
|
||||
if (!(input_ >> curtok_)) {
|
||||
initialized_ = false;
|
||||
eof_reached_ = true;
|
||||
}
|
||||
else {
|
||||
initialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void peek_one()
|
||||
{
|
||||
input_.peek(); // try for eof
|
||||
initialized_ = false;
|
||||
eof_reached_ = input_.eof();
|
||||
}
|
||||
|
||||
T& input_;
|
||||
result_type curtok_;
|
||||
bool initialized_;
|
||||
bool eof_reached_;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ITERATOR_LEX_INPUT_POLICY_MAR_16_2007_1205PM)
|
||||
#define BOOST_SPIRIT_ITERATOR_LEX_INPUT_POLICY_MAR_16_2007_1205PM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// class lex_input
|
||||
// Implementation of the InputPolicy used by multi_pass
|
||||
//
|
||||
// The lex_input class gets tokens (integers) from yylex()
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct lex_input
|
||||
{
|
||||
typedef int value_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
class unique : public detail::default_input_policy
|
||||
{
|
||||
public:
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::ptrdiff_t distance_type;
|
||||
typedef int* pointer;
|
||||
typedef int& reference;
|
||||
|
||||
protected:
|
||||
unique() {}
|
||||
explicit unique(T) {}
|
||||
|
||||
public:
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{
|
||||
value_type& curtok = mp.shared()->curtok;
|
||||
if (-1 == curtok)
|
||||
{
|
||||
extern int yylex();
|
||||
curtok = yylex();
|
||||
}
|
||||
return curtok;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void advance_input(MultiPass& mp)
|
||||
{
|
||||
extern int yylex();
|
||||
mp.shared()->curtok = yylex();
|
||||
}
|
||||
|
||||
// test, whether we reached the end of the underlying stream
|
||||
template <typename MultiPass>
|
||||
static bool input_at_eof(MultiPass const& mp)
|
||||
{
|
||||
return mp.shared()->curtok == 0;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool input_is_valid(MultiPass const&, value_type const& t)
|
||||
{
|
||||
return -1 != t;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct shared
|
||||
{
|
||||
explicit shared(T) : curtok(-1) {}
|
||||
|
||||
value_type curtok;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ITERATOR_MULTI_PASS_MAR_16_2007_1122AM)
|
||||
#define BOOST_SPIRIT_ITERATOR_MULTI_PASS_MAR_16_2007_1122AM
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Default implementations of the different policies to be used with a
|
||||
// multi_pass iterator
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct default_input_policy
|
||||
{
|
||||
default_input_policy() {}
|
||||
|
||||
template <typename Functor>
|
||||
default_input_policy(Functor const&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
void swap(default_input_policy&) {}
|
||||
|
||||
template <typename MultiPass, typename TokenType>
|
||||
static void advance_input(MultiPass& mp);
|
||||
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference get_input(MultiPass& mp);
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool input_at_eof(MultiPass const& mp);
|
||||
|
||||
template <typename MultiPass, typename TokenType>
|
||||
static bool input_is_valid(MultiPass& mp, TokenType& curtok);
|
||||
};
|
||||
|
||||
struct default_ownership_policy
|
||||
{
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
void swap(default_ownership_policy&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void clone(MultiPass&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool release(MultiPass& mp);
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool is_unique(MultiPass const& mp);
|
||||
};
|
||||
|
||||
struct default_storage_policy
|
||||
{
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
void swap(default_storage_policy&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference dereference(MultiPass const& mp);
|
||||
|
||||
template <typename MultiPass>
|
||||
static void increment(MultiPass&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void clear_queue(MultiPass&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool is_eof(MultiPass const& mp);
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool equal_to(MultiPass const& mp, MultiPass const& x);
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool less_than(MultiPass const& mp, MultiPass const& x);
|
||||
};
|
||||
|
||||
struct default_checking_policy
|
||||
{
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
void swap(default_checking_policy&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void docheck(MultiPass const&) {}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void clear_queue(MultiPass&) {}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ITERATOR_NO_CHECK_POLICY_MAR_16_2007_1121AM)
|
||||
#define BOOST_SPIRIT_ITERATOR_NO_CHECK_POLICY_MAR_16_2007_1121AM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class no_check
|
||||
// Implementation of the CheckingPolicy used by multi_pass
|
||||
// It does not do anything :-)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct no_check
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
struct unique : public detail::default_checking_policy {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
struct shared {};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM)
|
||||
#define BOOST_SPIRIT_ITERATOR_REF_COUNTED_POLICY_MAR_16_2007_1108AM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
#endif
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class ref_counted
|
||||
// Implementation of an OwnershipPolicy used by multi_pass.
|
||||
//
|
||||
// Implementation modified from RefCounted class from the Loki library by
|
||||
// Andrei Alexandrescu.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct ref_counted
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
struct unique // : detail::default_ownership_policy
|
||||
{
|
||||
void swap(unique&) {}
|
||||
|
||||
// clone is called when a copy of the iterator is made, so
|
||||
// increment the ref-count.
|
||||
template <typename MultiPass>
|
||||
static void clone(MultiPass& mp)
|
||||
{
|
||||
if (0 != mp.shared())
|
||||
++mp.shared()->count;
|
||||
}
|
||||
|
||||
// called when a copy is deleted. Decrement the ref-count. Return
|
||||
// value of true indicates that the last copy has been released.
|
||||
template <typename MultiPass>
|
||||
static bool release(MultiPass& mp)
|
||||
{
|
||||
return 0 != mp.shared() && 0 == --mp.shared()->count;
|
||||
}
|
||||
|
||||
// returns true if there is only one iterator in existence.
|
||||
// std_deque StoragePolicy will free it's buffered data if this
|
||||
// returns true.
|
||||
template <typename MultiPass>
|
||||
static bool is_unique(MultiPass const& mp)
|
||||
{
|
||||
return 0 == mp.shared() || 1 == mp.shared()->count;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
struct shared
|
||||
{
|
||||
shared() : count(1) {}
|
||||
|
||||
#if defined(BOOST_HAS_THREADS)
|
||||
boost::detail::atomic_count count;
|
||||
#else
|
||||
std::size_t count;
|
||||
#endif
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
// 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_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM)
|
||||
#define BOOST_SPIRIT_ITERATOR_SPLIT_FUNCTOR_INPUT_POLICY_JAN_17_2008_0103PM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/type_traits/is_empty.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
namespace split_functor_input_is_valid_test_
|
||||
{
|
||||
template <typename Token>
|
||||
inline bool token_is_valid(Token const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class split_functor_input
|
||||
// Implementation of the InputPolicy used by multi_pass
|
||||
// split_functor_input gets tokens from a functor
|
||||
//
|
||||
// This policy should be used when the functor holds two parts of data: a
|
||||
// unique part (unique for each instance of the iterator) and a shared
|
||||
// part (to be shared between the different copies of the same iterator).
|
||||
// Using this policy allows to merge the shared part of the functor with
|
||||
// the shared part of the iterator data, saving one pointer and one
|
||||
// allocation per iterator instance.
|
||||
//
|
||||
// The Functor template parameter of this policy is expected to be a
|
||||
// std::pair<unique, shared>, where 'unique' and 'shared' represent the
|
||||
// respective parts of the functor itself.
|
||||
//
|
||||
// Note: the unique part of the functor must have a typedef for result_type
|
||||
// It also must have a static variable of type result_type defined
|
||||
// to represent EOF that is called eof.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct split_functor_input
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Functor
|
||||
, bool FunctorIsEmpty = is_empty<typename Functor::first_type>::value>
|
||||
class unique;
|
||||
|
||||
// the unique part of the functor is empty, do not include the functor
|
||||
// as a member at all to avoid unnecessary padding bytes to be included
|
||||
// into the generated structure
|
||||
template <typename Functor>
|
||||
class unique<Functor, true> // : public detail::default_input_policy
|
||||
{
|
||||
protected:
|
||||
typedef typename Functor::first_type functor_type;
|
||||
typedef typename functor_type::result_type result_type;
|
||||
|
||||
public:
|
||||
typedef result_type value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::ptrdiff_t distance_type;
|
||||
typedef result_type const* pointer;
|
||||
typedef result_type const& reference;
|
||||
|
||||
protected:
|
||||
unique() {}
|
||||
explicit unique(Functor const&) {}
|
||||
|
||||
public:
|
||||
void swap(unique&) {}
|
||||
|
||||
// get the next token
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{
|
||||
value_type& curtok = mp.shared()->curtok;
|
||||
using namespace split_functor_input_is_valid_test_;
|
||||
if (!token_is_valid(curtok))
|
||||
functor_type::get_next(mp, curtok);
|
||||
return curtok;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void advance_input(MultiPass& mp)
|
||||
{
|
||||
functor_type::get_next(mp, mp.shared()->curtok);
|
||||
}
|
||||
|
||||
// test, whether we reached the end of the underlying stream
|
||||
template <typename MultiPass>
|
||||
static bool input_at_eof(MultiPass const& mp)
|
||||
{
|
||||
return mp.shared()->curtok == functor_type::eof;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool input_is_valid(MultiPass const&, value_type const& t)
|
||||
{
|
||||
using namespace split_functor_input_is_valid_test_;
|
||||
return token_is_valid(t);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass& mp)
|
||||
{
|
||||
functor_type::destroy(mp);
|
||||
}
|
||||
};
|
||||
|
||||
// the unique part of the functor is non-empty
|
||||
template <typename Functor>
|
||||
class unique<Functor, false> : public unique<Functor, true>
|
||||
{
|
||||
protected:
|
||||
typedef typename Functor::first_type functor_type;
|
||||
typedef typename functor_type::result_type result_type;
|
||||
|
||||
protected:
|
||||
unique() {}
|
||||
explicit unique(Functor const& x) : ftor(x.first) {}
|
||||
|
||||
void swap(unique& x)
|
||||
{
|
||||
boost::swap(ftor, x.ftor);
|
||||
}
|
||||
|
||||
public:
|
||||
typedef result_type value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::ptrdiff_t distance_type;
|
||||
typedef result_type const* pointer;
|
||||
typedef result_type const& reference;
|
||||
|
||||
public:
|
||||
// get the next token
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference get_input(MultiPass& mp)
|
||||
{
|
||||
value_type& curtok = mp.shared()->curtok;
|
||||
using namespace split_functor_input_is_valid_test_;
|
||||
if (!token_is_valid(curtok))
|
||||
functor_type::get_next(mp, curtok);
|
||||
return curtok;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void advance_input(MultiPass& mp)
|
||||
{
|
||||
mp.ftor.get_next(mp, mp.shared()->curtok);
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static bool input_is_valid(MultiPass const&, value_type const& t)
|
||||
{
|
||||
using namespace split_functor_input_is_valid_test_;
|
||||
return token_is_valid(t);
|
||||
}
|
||||
|
||||
// test, whether we reached the end of the underlying stream
|
||||
template <typename MultiPass>
|
||||
static bool input_at_eof(MultiPass const& mp)
|
||||
{
|
||||
return mp.shared()->curtok == mp.ftor.eof;
|
||||
}
|
||||
|
||||
typename Functor::first_type& get_functor() const
|
||||
{
|
||||
return ftor;
|
||||
}
|
||||
|
||||
mutable functor_type ftor;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Functor>
|
||||
struct shared
|
||||
{
|
||||
protected:
|
||||
typedef typename Functor::first_type functor_type;
|
||||
typedef typename functor_type::result_type result_type;
|
||||
|
||||
public:
|
||||
explicit shared(Functor const& x) : ftor(x.second), curtok(0) {}
|
||||
|
||||
mutable typename Functor::second_type ftor;
|
||||
result_type curtok;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
shared& operator= (shared const&);
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
// Copyright (c) 2001 Daniel C. Nuffer
|
||||
// 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_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM)
|
||||
#define BOOST_SPIRIT_ITERATOR_SPLIT_DEQUE_POLICY_APR_06_2008_0138PM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/multi_pass_fwd.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/multi_pass.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace spirit { namespace iterator_policies
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// class split_std_deque
|
||||
//
|
||||
// Implementation of the StoragePolicy used by multi_pass
|
||||
// This stores all data in a std::vector (despite its name), and keeps an
|
||||
// offset to the current position. It stores all the data unless there is
|
||||
// only one iterator using the queue.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
struct split_std_deque
|
||||
{
|
||||
enum { threshold = 16 };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Value>
|
||||
class unique //: public detail::default_storage_policy
|
||||
{
|
||||
private:
|
||||
typedef std::vector<Value> queue_type;
|
||||
|
||||
protected:
|
||||
unique() : queued_position(0) {}
|
||||
|
||||
unique(unique const& x)
|
||||
: queued_position(x.queued_position) {}
|
||||
|
||||
void swap(unique& x)
|
||||
{
|
||||
boost::swap(queued_position, x.queued_position);
|
||||
}
|
||||
|
||||
// This is called when the iterator is dereferenced. It's a
|
||||
// template method so we can recover the type of the multi_pass
|
||||
// iterator and call advance_input and input_is_valid.
|
||||
template <typename MultiPass>
|
||||
static typename MultiPass::reference
|
||||
dereference(MultiPass const& mp)
|
||||
{
|
||||
queue_type& queue = mp.shared()->queued_elements;
|
||||
typename queue_type::size_type size = queue.size();
|
||||
|
||||
BOOST_ASSERT(mp.queued_position <= size);
|
||||
|
||||
if (mp.queued_position == size)
|
||||
{
|
||||
// check if this is the only iterator
|
||||
if (size >= threshold && MultiPass::is_unique(mp))
|
||||
{
|
||||
// free up the memory used by the queue.
|
||||
queue.clear();
|
||||
mp.queued_position = 0;
|
||||
}
|
||||
return MultiPass::get_input(mp);
|
||||
}
|
||||
|
||||
return queue[mp.queued_position];
|
||||
}
|
||||
|
||||
// This is called when the iterator is incremented. It's a template
|
||||
// method so we can recover the type of the multi_pass iterator
|
||||
// and call is_unique and advance_input.
|
||||
template <typename MultiPass>
|
||||
static void increment(MultiPass& mp)
|
||||
{
|
||||
queue_type& queue = mp.shared()->queued_elements;
|
||||
typename queue_type::size_type size = queue.size();
|
||||
|
||||
BOOST_ASSERT(mp.queued_position <= size);
|
||||
|
||||
// // do not increment iterator as long as the current token is
|
||||
// // invalid
|
||||
// if (size > 0 && !MultiPass::input_is_valid(mp, queue[mp.queued_position-1]))
|
||||
// return;
|
||||
|
||||
if (mp.queued_position == size)
|
||||
{
|
||||
// check if this is the only iterator
|
||||
if (size >= threshold && MultiPass::is_unique(mp))
|
||||
{
|
||||
// free up the memory used by the queue. we avoid
|
||||
// clearing the queue on every increment, though,
|
||||
// because this would be too time consuming
|
||||
queue.clear();
|
||||
mp.queued_position = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
queue.push_back(MultiPass::get_input(mp));
|
||||
++mp.queued_position;
|
||||
}
|
||||
MultiPass::advance_input(mp);
|
||||
}
|
||||
else
|
||||
{
|
||||
++mp.queued_position;
|
||||
}
|
||||
}
|
||||
|
||||
// called to forcibly clear the queue
|
||||
template <typename MultiPass>
|
||||
static void clear_queue(MultiPass& mp)
|
||||
{
|
||||
mp.shared()->queued_elements.clear();
|
||||
mp.queued_position = 0;
|
||||
}
|
||||
|
||||
// called to determine whether the iterator is an eof iterator
|
||||
template <typename MultiPass>
|
||||
static bool is_eof(MultiPass const& mp)
|
||||
{
|
||||
return mp.queued_position == mp.shared()->queued_elements.size()
|
||||
&& MultiPass::input_at_eof(mp);
|
||||
}
|
||||
|
||||
// called by operator==
|
||||
template <typename MultiPass>
|
||||
static bool equal_to(MultiPass const& mp, MultiPass const& x)
|
||||
{
|
||||
return mp.queued_position == x.queued_position;
|
||||
}
|
||||
|
||||
// called by operator<
|
||||
template <typename MultiPass>
|
||||
static bool less_than(MultiPass const& mp, MultiPass const& x)
|
||||
{
|
||||
return mp.queued_position < x.queued_position;
|
||||
}
|
||||
|
||||
template <typename MultiPass>
|
||||
static void destroy(MultiPass&) {}
|
||||
|
||||
protected:
|
||||
mutable typename queue_type::size_type queued_position;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Value>
|
||||
struct shared
|
||||
{
|
||||
shared()
|
||||
{
|
||||
queued_elements.reserve(threshold);
|
||||
}
|
||||
|
||||
typedef std::vector<Value> queue_type;
|
||||
queue_type queued_elements;
|
||||
};
|
||||
|
||||
}; // split_std_deque
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
// 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_ISTREAM_ITERATOR_JAN_03_2010_0522PM)
|
||||
#define BOOST_SPIRIT_ISTREAM_ITERATOR_JAN_03_2010_0522PM
|
||||
|
||||
#include <boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp>
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
#include <boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp>
|
||||
#else
|
||||
#include <boost/spirit/home/support/iterators/detail/no_check_policy.hpp>
|
||||
#endif
|
||||
#include <boost/spirit/home/support/iterators/detail/istream_policy.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp>
|
||||
#include <boost/spirit/home/support/iterators/detail/combine_policies.hpp>
|
||||
#include <boost/spirit/home/support/iterators/multi_pass.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elem, typename Traits = std::char_traits<Elem> >
|
||||
class basic_istream_iterator :
|
||||
public multi_pass<
|
||||
std::basic_istream<Elem, Traits>
|
||||
, iterator_policies::default_policy<
|
||||
iterator_policies::ref_counted
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
, iterator_policies::buf_id_check
|
||||
#else
|
||||
, iterator_policies::no_check
|
||||
#endif
|
||||
, iterator_policies::istream
|
||||
, iterator_policies::split_std_deque>
|
||||
>
|
||||
{
|
||||
private:
|
||||
typedef multi_pass<
|
||||
std::basic_istream<Elem, Traits>
|
||||
, iterator_policies::default_policy<
|
||||
iterator_policies::ref_counted
|
||||
#if defined(BOOST_SPIRIT_DEBUG)
|
||||
, iterator_policies::buf_id_check
|
||||
#else
|
||||
, iterator_policies::no_check
|
||||
#endif
|
||||
, iterator_policies::istream
|
||||
, iterator_policies::split_std_deque>
|
||||
> base_type;
|
||||
|
||||
public:
|
||||
basic_istream_iterator()
|
||||
: base_type() {}
|
||||
|
||||
explicit basic_istream_iterator(std::basic_istream<Elem, Traits>& x)
|
||||
: base_type(x) {}
|
||||
|
||||
basic_istream_iterator(basic_istream_iterator const& x)
|
||||
: base_type(x) {}
|
||||
|
||||
#if BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
|
||||
basic_istream_iterator(int) // workaround for a bug in the library
|
||||
: base_type() {} // shipped with gcc 3.1
|
||||
#endif // BOOST_WORKAROUND(__GLIBCPP__, == 20020514)
|
||||
|
||||
basic_istream_iterator operator= (base_type const& rhs)
|
||||
{
|
||||
this->base_type::operator=(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// default generated operators, destructor and assignment operator are ok.
|
||||
};
|
||||
|
||||
typedef basic_istream_iterator<char> istream_iterator;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user