stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
/*=============================================================================
|
||||
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_ACTION_JANUARY_07_2007_1233PM)
|
||||
#define SPIRIT_ACTION_JANUARY_07_2007_1233PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/action/action.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,202 @@
|
||||
/*=============================================================================
|
||||
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_ACTION_JANUARY_07_2007_1128AM)
|
||||
#define SPIRIT_ACTION_JANUARY_07_2007_1128AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/argument.hpp>
|
||||
#include <boost/spirit/home/support/context.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/action_dispatch.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _)
|
||||
|
||||
template <typename Subject, typename Action>
|
||||
struct action : unary_parser<action<Subject, Action> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
typedef Action action_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: traits::attribute_of<Subject, Context, Iterator>
|
||||
{};
|
||||
|
||||
action(Subject const& subject_, Action f_)
|
||||
: subject(subject_), f(f_) {}
|
||||
|
||||
#ifndef BOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef typename attribute<Context, Iterator>::type attr_type;
|
||||
typedef traits::make_attribute<attr_type, Attribute> make_attribute;
|
||||
|
||||
// create an attribute if one is not supplied
|
||||
typedef traits::transform_attribute<
|
||||
typename make_attribute::type, attr_type, domain> transform;
|
||||
|
||||
typename make_attribute::type made_attr = make_attribute::call(attr_);
|
||||
typename transform::type attr = transform::pre(made_attr);
|
||||
|
||||
Iterator save = first;
|
||||
if (subject.parse(first, last, context, skipper, attr))
|
||||
{
|
||||
// call the function, passing the attribute, the context.
|
||||
// The client can return false to fail parsing.
|
||||
if (traits::action_dispatch<Subject>()(f, attr, context))
|
||||
{
|
||||
// Do up-stream transformation, this integrates the results
|
||||
// back into the original attribute value, if appropriate.
|
||||
traits::post_transform(attr_, attr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// reset iterators if semantic action failed the match
|
||||
// retrospectively
|
||||
first = save;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr) const
|
||||
{
|
||||
Iterator save = first;
|
||||
if (subject.parse(first, last, context, skipper, attr)) // Use the attribute as-is
|
||||
{
|
||||
// call the function, passing the attribute, the context.
|
||||
// The client can return false to fail parsing.
|
||||
if (traits::action_dispatch<Subject>()(f, attr, context))
|
||||
return true;
|
||||
|
||||
// reset iterators if semantic action failed the match
|
||||
// retrospectively
|
||||
first = save;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, unused_type) const
|
||||
{
|
||||
typedef typename attribute<Context, Iterator>::type attr_type;
|
||||
typedef traits::make_attribute<attr_type, unused_type> make_attribute;
|
||||
|
||||
// synthesize the attribute since one is not supplied
|
||||
typedef traits::transform_attribute<
|
||||
typename make_attribute::type, attr_type, domain> transform;
|
||||
|
||||
typename make_attribute::type made_attr = make_attribute::call(unused_type());
|
||||
typename transform::type attr = transform::pre(made_attr);
|
||||
|
||||
Iterator save = first;
|
||||
if (subject.parse(first, last, context, skipper, attr))
|
||||
{
|
||||
// call the function, passing the attribute, the context.
|
||||
// The client can return false to fail parsing.
|
||||
if (traits::action_dispatch<Subject>()(f, attr, context))
|
||||
return true;
|
||||
|
||||
// reset iterators if semantic action failed the match
|
||||
// retrospectively
|
||||
first = save;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
// the action is transparent (does not add any info)
|
||||
return subject.what(context);
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
Action f;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
action& operator= (action const&);
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
// Qi action meta-compiler
|
||||
template <>
|
||||
struct make_component<qi::domain, tag::action>
|
||||
{
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <typename This, typename Elements, typename Modifiers>
|
||||
struct result<This(Elements, Modifiers)>
|
||||
{
|
||||
typedef typename
|
||||
remove_const<typename Elements::car_type>::type
|
||||
subject_type;
|
||||
|
||||
typedef typename
|
||||
remove_const<typename Elements::cdr_type::car_type>::type
|
||||
action_type;
|
||||
|
||||
typedef qi::action<subject_type, action_type> type;
|
||||
};
|
||||
|
||||
template <typename Elements>
|
||||
typename result<make_component(Elements, unused_type)>::type
|
||||
operator()(Elements const& elements, unused_type) const
|
||||
{
|
||||
typename result<make_component(Elements, unused_type)>::type
|
||||
result(elements.car, elements.cdr.car);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Action>
|
||||
struct has_semantic_action<qi::action<Subject, Action> >
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Action, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct handles_container<qi::action<Subject, Action>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
/*=============================================================================
|
||||
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_AUTO_NOV_29_2009_0335PM)
|
||||
#define BOOST_SPIRIT_AUTO_NOV_29_2009_0335PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/auto/auto.hpp>
|
||||
#include <boost/spirit/home/qi/detail/parse_auto.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_QI_AUTO_NOV_29_2009_0336PM)
|
||||
#define BOOST_SPIRIT_QI_AUTO_NOV_29_2009_0336PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/support/detail/hold_any.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/auto/create_parser.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_terminal<qi::domain, tag::auto_> // enables auto_
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::auto_;
|
||||
#endif
|
||||
using spirit::auto_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct auto_parser
|
||||
: parser<auto_parser<Modifiers> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef spirit::hold_any type;
|
||||
};
|
||||
|
||||
auto_parser(Modifiers const& modifiers)
|
||||
: modifiers_(modifiers) {}
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper
|
||||
, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, Attribute& attr) const
|
||||
{
|
||||
return compile<qi::domain>(create_parser<Attribute>(), modifiers_)
|
||||
.parse(first, last, context, skipper, attr);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("auto_");
|
||||
}
|
||||
|
||||
Modifiers modifiers_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Generator generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::auto_, Modifiers>
|
||||
{
|
||||
typedef auto_parser<Modifiers> result_type;
|
||||
|
||||
result_type operator()(unused_type, Modifiers const& modifiers) const
|
||||
{
|
||||
return result_type(modifiers);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_QI_CREATE_NOV_21_2009_0444PM)
|
||||
#define BOOST_SPIRIT_QI_CREATE_NOV_21_2009_0444PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/auto/meta_create.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace result_of
|
||||
{
|
||||
template <typename T>
|
||||
struct create_parser
|
||||
: spirit::traits::meta_create<qi::domain, T> {};
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
// Main API function for parser creation from data type
|
||||
template <typename T>
|
||||
typename result_of::create_parser<T>::type
|
||||
create_parser()
|
||||
{
|
||||
return spirit::traits::meta_create<qi::domain, T>::call();
|
||||
}
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
// Meta function returning true if create_parser does return a valid
|
||||
// parser for the given type T.
|
||||
template <typename T>
|
||||
struct create_parser_exists
|
||||
: meta_create_exists<qi::domain, T> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,274 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM)
|
||||
#define BOOST_SPIRIT_QI_META_CREATE_NOV_21_2009_0432PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/auto/meta_create.hpp>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/fusion/include/as_vector.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// compatible STL containers
|
||||
template <typename Container>
|
||||
struct meta_create_container
|
||||
{
|
||||
typedef make_unary_proto_expr<
|
||||
typename Container::value_type
|
||||
, proto::tag::dereference, qi::domain
|
||||
> make_proto_expr;
|
||||
|
||||
typedef typename make_proto_expr::type type;
|
||||
|
||||
static type call()
|
||||
{
|
||||
return make_proto_expr::call();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Fusion sequences
|
||||
template <typename Sequence>
|
||||
struct meta_create_sequence
|
||||
{
|
||||
// create a mpl sequence from the given fusion sequence
|
||||
typedef typename mpl::fold<
|
||||
typename fusion::result_of::as_vector<Sequence>::type
|
||||
, mpl::vector<>, mpl::push_back<mpl::_, mpl::_>
|
||||
>::type sequence_type;
|
||||
|
||||
typedef make_nary_proto_expr<
|
||||
sequence_type, proto::tag::shift_right, qi::domain
|
||||
> make_proto_expr;
|
||||
|
||||
typedef typename make_proto_expr::type type;
|
||||
|
||||
static type call()
|
||||
{
|
||||
return make_proto_expr::call();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// the default is to use the standard streaming operator unless it's a
|
||||
// STL container or a fusion sequence
|
||||
|
||||
// The default implementation will be chosen if no predefined mapping of
|
||||
// the data type T to a Qi component is defined.
|
||||
struct no_auto_mapping_exists {};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct meta_create_impl : mpl::identity<no_auto_mapping_exists> {};
|
||||
|
||||
template <typename T>
|
||||
struct meta_create_impl<T
|
||||
, typename enable_if<mpl::and_<
|
||||
traits::is_container<T>, mpl::not_<traits::is_string<T> > >
|
||||
>::type>
|
||||
: meta_create_container<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct meta_create_impl<T, typename enable_if<
|
||||
spirit::detail::is_fusion_sequence_but_not_proto_expr<T>
|
||||
>::type>
|
||||
: meta_create_sequence<T> {};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct meta_create : meta_create_impl<T> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// optional
|
||||
template <typename T>
|
||||
struct meta_create<boost::optional<T> >
|
||||
{
|
||||
typedef make_unary_proto_expr<
|
||||
T, proto::tag::negate, qi::domain
|
||||
> make_proto_expr;
|
||||
|
||||
typedef typename make_proto_expr::type type;
|
||||
|
||||
static type call()
|
||||
{
|
||||
return make_proto_expr::call();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// alternatives
|
||||
template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct meta_create<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
|
||||
{
|
||||
typedef make_nary_proto_expr<
|
||||
typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types
|
||||
, proto::tag::bitwise_or, qi::domain
|
||||
> make_proto_expr;
|
||||
|
||||
typedef typename make_proto_expr::type type;
|
||||
|
||||
static type call()
|
||||
{
|
||||
return make_proto_expr::call();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// predefined specializations for primitive components
|
||||
|
||||
// character generator
|
||||
template <>
|
||||
struct meta_create<char>
|
||||
{
|
||||
typedef spirit::standard::char_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
template <>
|
||||
struct meta_create<signed char>
|
||||
{
|
||||
typedef spirit::standard::char_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
template <>
|
||||
struct meta_create<wchar_t>
|
||||
{
|
||||
typedef spirit::standard_wide::char_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct meta_create<unsigned char>
|
||||
{
|
||||
typedef spirit::standard::char_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
|
||||
// boolean generator
|
||||
template <>
|
||||
struct meta_create<bool>
|
||||
{
|
||||
typedef spirit::bool_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
|
||||
// integral generators
|
||||
template <>
|
||||
struct meta_create<int>
|
||||
{
|
||||
typedef spirit::int_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
template <>
|
||||
struct meta_create<short>
|
||||
{
|
||||
typedef spirit::short_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
template <>
|
||||
struct meta_create<long>
|
||||
{
|
||||
typedef spirit::long_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
template <>
|
||||
struct meta_create<unsigned int>
|
||||
{
|
||||
typedef spirit::uint_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
template <>
|
||||
struct meta_create<unsigned short>
|
||||
{
|
||||
typedef spirit::ushort_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
#endif
|
||||
template <>
|
||||
struct meta_create<unsigned long>
|
||||
{
|
||||
typedef spirit::ulong_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <>
|
||||
struct meta_create<boost::long_long_type>
|
||||
{
|
||||
typedef spirit::long_long_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
template <>
|
||||
struct meta_create<boost::ulong_long_type>
|
||||
{
|
||||
typedef spirit::ulong_long_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
// floating point generators
|
||||
template <>
|
||||
struct meta_create<float>
|
||||
{
|
||||
typedef spirit::float_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
template <>
|
||||
struct meta_create<double>
|
||||
{
|
||||
typedef spirit::double_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
template <>
|
||||
struct meta_create<long double>
|
||||
{
|
||||
typedef spirit::long_double_type type;
|
||||
static type call() { return type(); }
|
||||
};
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// main customization point for create_parser
|
||||
template <typename T, typename Enable = void>
|
||||
struct create_parser : qi::meta_create<T> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// dispatch this to the Qi related specializations
|
||||
template <typename T>
|
||||
struct meta_create<qi::domain, T>
|
||||
: create_parser<typename spirit::detail::remove_const_ref<T>::type> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Check whether a valid mapping exits for the given data type to a Qi
|
||||
// component
|
||||
template <typename T>
|
||||
struct meta_create_exists<qi::domain, T>
|
||||
: mpl::not_<is_same<
|
||||
qi::no_auto_mapping_exists
|
||||
, typename meta_create<qi::domain, T>::type
|
||||
> > {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
/*=============================================================================
|
||||
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_AUXILIARY_FEBRUARY_03_2007_0355PM)
|
||||
#define BOOST_SPIRIT_AUXILIARY_FEBRUARY_03_2007_0355PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/auxiliary/eps.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/eol.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/eoi.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/attr.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/attr_cast.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,110 @@
|
||||
/*=============================================================================
|
||||
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_ATTR_JUL_23_2008_0956AM)
|
||||
#define BOOST_SPIRIT_ATTR_JUL_23_2008_0956AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables attr()
|
||||
struct use_terminal<
|
||||
qi::domain, terminal_ex<tag::attr, fusion::vector1<A0> > >
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* attr()
|
||||
struct use_lazy_terminal<qi::domain, tag::attr, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::attr;
|
||||
#endif
|
||||
using spirit::attr_type;
|
||||
|
||||
template <typename Value>
|
||||
struct attr_parser : primitive_parser<attr_parser<Value> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute : remove_const<Value> {};
|
||||
|
||||
attr_parser(typename add_reference<Value>::type value)
|
||||
: value_(value) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& /*first*/, Iterator const& /*last*/
|
||||
, Context& /*context*/, Skipper const& /*skipper*/
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
spirit::traits::assign_to(value_, attr_);
|
||||
return true; // never consume any input, succeed always
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("attr");
|
||||
}
|
||||
|
||||
Value value_;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
attr_parser& operator= (attr_parser const&);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::attr, fusion::vector1<A0> >
|
||||
, Modifiers>
|
||||
{
|
||||
typedef typename add_const<A0>::type const_value;
|
||||
typedef attr_parser<const_value> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Attr, typename Context, typename Iterator>
|
||||
struct handles_container<qi::attr_parser<T>, Attr, Context, Iterator>
|
||||
: traits::is_container<Attr> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
// 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_QI_ATTR_CAST_SEP_26_2009_0735PM)
|
||||
#define SPIRIT_QI_ATTR_CAST_SEP_26_2009_0735PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/auxiliary/attr_cast.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// enables attr_cast<>() pseudo parser
|
||||
template <typename Expr, typename Exposed, typename Transformed>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed> >
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
using spirit::attr_cast;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// attr_cast_parser consumes the attribute of subject generator without
|
||||
// generating anything
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Exposed, typename Transformed, typename Subject>
|
||||
struct attr_cast_parser
|
||||
: unary_parser<attr_cast_parser<Exposed, Transformed, Subject> >
|
||||
{
|
||||
typedef typename result_of::compile<qi::domain, Subject>::type
|
||||
subject_type;
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
traits::not_is_unused<Transformed>
|
||||
, mpl::identity<Transformed>
|
||||
, traits::attribute_of<subject_type> >::type
|
||||
transformed_attribute_type;
|
||||
|
||||
attr_cast_parser(Subject const& subject_)
|
||||
: subject(subject_)
|
||||
{
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (Subject) is not a valid spirit qi
|
||||
// expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Subject);
|
||||
}
|
||||
|
||||
// If Exposed is given, we use the given type, otherwise all we can do
|
||||
// is to guess, so we expose our inner type as an attribute and
|
||||
// deal with the passed attribute inside the parse function.
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_<traits::not_is_unused<Exposed>, Exposed
|
||||
, transformed_attribute_type>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper
|
||||
, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
// Find the real exposed attribute. If exposed is given, we use it
|
||||
// otherwise we assume the exposed attribute type to be the actual
|
||||
// attribute type as passed by the user.
|
||||
typedef typename mpl::if_<
|
||||
traits::not_is_unused<Exposed>, Exposed, Attribute>::type
|
||||
exposed_attribute_type;
|
||||
|
||||
// do down-stream transformation, provides attribute for embedded
|
||||
// parser
|
||||
typedef traits::transform_attribute<
|
||||
exposed_attribute_type, transformed_attribute_type, domain>
|
||||
transform;
|
||||
|
||||
typename transform::type attr_ = transform::pre(attr_param);
|
||||
|
||||
if (!compile<qi::domain>(subject).
|
||||
parse(first, last, context, skipper, attr_))
|
||||
{
|
||||
transform::fail(attr_param);
|
||||
return false;
|
||||
}
|
||||
|
||||
// do up-stream transformation, this mainly integrates the results
|
||||
// back into the original attribute value, if appropriate
|
||||
traits::post_transform(attr_param, attr_);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("attr_cast"
|
||||
, compile<qi::domain>(subject).what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
attr_cast_parser& operator= (attr_cast_parser const&);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generator: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Exposed, typename Transformed
|
||||
, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed>, Modifiers>
|
||||
{
|
||||
typedef attr_cast_parser<Exposed, Transformed, Expr> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
typedef tag::stateful_tag<
|
||||
Expr, tag::attr_cast, Exposed, Transformed> tag_type;
|
||||
using spirit::detail::get_stateful_data;
|
||||
return result_type(get_stateful_data<tag_type>::call(term));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,80 @@
|
||||
/*=============================================================================
|
||||
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_EOI_APRIL_18_2008_0751PM)
|
||||
#define BOOST_SPIRIT_EOI_APRIL_18_2008_0751PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_terminal<qi::domain, tag::eoi> // enables eoi
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::eoi;
|
||||
#endif
|
||||
using spirit::eoi_type;
|
||||
|
||||
struct eoi_parser : primitive_parser<eoi_parser>
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& /*attr*/) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
return first == last;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("eoi");
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::eoi, Modifiers>
|
||||
{
|
||||
typedef eoi_parser result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*=============================================================================
|
||||
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_EOL_APRIL_18_2008_0751PM)
|
||||
#define BOOST_SPIRIT_EOL_APRIL_18_2008_0751PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_terminal<qi::domain, tag::eol> // enables eol
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::eol;
|
||||
#endif
|
||||
using spirit::eol_type;
|
||||
|
||||
struct eol_parser : primitive_parser<eol_parser>
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& /*attr*/) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
Iterator it = first;
|
||||
bool matched = false;
|
||||
if (it != last && *it == '\r') // CR
|
||||
{
|
||||
matched = true;
|
||||
++it;
|
||||
}
|
||||
if (it != last && *it == '\n') // LF
|
||||
{
|
||||
matched = true;
|
||||
++it;
|
||||
}
|
||||
|
||||
if (!matched)
|
||||
return false;
|
||||
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("eol");
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::eol, Modifiers>
|
||||
{
|
||||
typedef eol_parser result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_EPS_MARCH_23_2007_0454PM)
|
||||
#define BOOST_SPIRIT_EPS_MARCH_23_2007_0454PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_terminal<qi::domain, tag::eps> // enables eps
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::eps, fusion::vector1<A0> > // enables eps(bool-condition)
|
||||
> : is_convertible<A0, bool> {};
|
||||
|
||||
template <> // enables eps(f)
|
||||
struct use_lazy_terminal<
|
||||
qi::domain, tag::eps, 1 /*arity*/
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::eps;
|
||||
#endif
|
||||
using spirit::eps_type;
|
||||
|
||||
struct eps_parser : primitive_parser<eps_parser>
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& /*attr*/) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("eps");
|
||||
}
|
||||
};
|
||||
|
||||
struct semantic_predicate : primitive_parser<semantic_predicate>
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
semantic_predicate(bool predicate_)
|
||||
: predicate(predicate_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& /*attr*/) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
return predicate;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("semantic-predicate");
|
||||
}
|
||||
|
||||
bool predicate;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::eps, Modifiers>
|
||||
{
|
||||
typedef eps_parser result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::eps, fusion::vector1<A0> >
|
||||
, Modifiers>
|
||||
{
|
||||
typedef semantic_predicate result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args) ? true : false);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,287 @@
|
||||
/*=============================================================================
|
||||
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_LAZY_MARCH_27_2007_1002AM)
|
||||
#define BOOST_SPIRIT_LAZY_MARCH_27_2007_1002AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/lazy.hpp>
|
||||
#include <boost/spirit/include/phoenix_core.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Eval>
|
||||
struct use_terminal<qi::domain, phoenix::actor<Eval> > // enables phoenix actors
|
||||
: mpl::true_ {};
|
||||
|
||||
// forward declaration
|
||||
template <typename Terminal, typename Actor, int Arity>
|
||||
struct lazy_terminal;
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
using spirit::lazy;
|
||||
typedef modify<qi::domain> qi_modify;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename Parser, typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool lazy_parse_impl(Parser const& p
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr, mpl::false_)
|
||||
{
|
||||
return p.parse(first, last, context, skipper, attr);
|
||||
}
|
||||
|
||||
template <typename Parser, typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool lazy_parse_impl(Parser const& p
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& /*attr*/, mpl::true_)
|
||||
{
|
||||
// If DeducedAuto is false (semantic actions is present), the
|
||||
// component's attribute is unused.
|
||||
return p.parse(first, last, context, skipper, unused);
|
||||
}
|
||||
|
||||
template <typename Parser, typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool lazy_parse_impl_main(Parser const& p
|
||||
, Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr)
|
||||
{
|
||||
// If DeducedAuto is true (no semantic action), we pass the parser's
|
||||
// attribute on to the component.
|
||||
typedef typename traits::has_semantic_action<Parser>::type auto_rule;
|
||||
return lazy_parse_impl(p, first, last, context, skipper, attr, auto_rule());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Function, typename Modifiers>
|
||||
struct lazy_parser : parser<lazy_parser<Function, Modifiers> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
boost::result_of<qi_modify(tag::lazy_eval, Modifiers)>::type
|
||||
modifier;
|
||||
|
||||
typedef typename
|
||||
remove_reference<
|
||||
typename boost::result_of<Function(unused_type, Context)>::type
|
||||
>::type
|
||||
expr_type;
|
||||
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr_type) is not a valid spirit qi
|
||||
// expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, expr_type);
|
||||
|
||||
typedef typename
|
||||
result_of::compile<qi::domain, expr_type, modifier>::type
|
||||
parser_type;
|
||||
|
||||
typedef typename
|
||||
traits::attribute_of<parser_type, Context, Iterator>::type
|
||||
type;
|
||||
};
|
||||
|
||||
lazy_parser(Function const& function_, Modifiers const& modifiers_)
|
||||
: function(function_), modifiers(modifiers_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr) const
|
||||
{
|
||||
return detail::lazy_parse_impl_main(
|
||||
compile<qi::domain>(function(unused, context)
|
||||
, qi_modify()(tag::lazy_eval(), modifiers))
|
||||
, first, last, context, skipper, attr);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("lazy"
|
||||
, compile<qi::domain>(function(unused, context)
|
||||
, qi_modify()(tag::lazy_eval(), modifiers))
|
||||
.what(context)
|
||||
);
|
||||
}
|
||||
|
||||
Function function;
|
||||
Modifiers modifiers;
|
||||
};
|
||||
|
||||
|
||||
template <typename Function, typename Subject, typename Modifiers>
|
||||
struct lazy_directive
|
||||
: unary_parser<lazy_directive<Function, Subject, Modifiers> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
boost::result_of<qi_modify(tag::lazy_eval, Modifiers)>::type
|
||||
modifier;
|
||||
|
||||
typedef typename
|
||||
remove_reference<
|
||||
typename boost::result_of<Function(unused_type, Context)>::type
|
||||
>::type
|
||||
directive_expr_type;
|
||||
|
||||
typedef typename
|
||||
proto::result_of::make_expr<
|
||||
proto::tag::subscript
|
||||
, directive_expr_type
|
||||
, Subject
|
||||
>::type
|
||||
expr_type;
|
||||
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr_type) is not a valid spirit qi
|
||||
// expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, expr_type);
|
||||
|
||||
typedef typename
|
||||
result_of::compile<qi::domain, expr_type, modifier>::type
|
||||
parser_type;
|
||||
|
||||
typedef typename
|
||||
traits::attribute_of<parser_type, Context, Iterator>::type
|
||||
type;
|
||||
};
|
||||
|
||||
lazy_directive(
|
||||
Function const& function_
|
||||
, Subject const& subject_
|
||||
, Modifiers const& modifiers_)
|
||||
: function(function_), subject(subject_), modifiers(modifiers_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr) const
|
||||
{
|
||||
return detail::lazy_parse_impl_main(compile<qi::domain>(
|
||||
proto::make_expr<proto::tag::subscript>(
|
||||
function(unused, context)
|
||||
, subject)
|
||||
, qi_modify()(tag::lazy_eval(), modifiers))
|
||||
, first, last, context, skipper, attr);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("lazy-directive"
|
||||
, compile<qi::domain>(
|
||||
proto::make_expr<proto::tag::subscript>(
|
||||
function(unused, context)
|
||||
, subject
|
||||
), qi_modify()(tag::lazy_eval(), modifiers))
|
||||
.what(context)
|
||||
);
|
||||
}
|
||||
|
||||
Function function;
|
||||
Subject subject;
|
||||
Modifiers modifiers;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Eval, typename Modifiers>
|
||||
struct make_primitive<phoenix::actor<Eval>, Modifiers>
|
||||
{
|
||||
typedef lazy_parser<phoenix::actor<Eval>, Modifiers> result_type;
|
||||
result_type operator()(phoenix::actor<Eval> const& f
|
||||
, Modifiers const& modifiers) const
|
||||
{
|
||||
return result_type(f, modifiers);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Terminal, typename Actor, int Arity, typename Modifiers>
|
||||
struct make_primitive<lazy_terminal<Terminal, Actor, Arity>, Modifiers>
|
||||
{
|
||||
typedef lazy_parser<Actor, Modifiers> result_type;
|
||||
result_type operator()(
|
||||
lazy_terminal<Terminal, Actor, Arity> const& lt
|
||||
, Modifiers const& modifiers) const
|
||||
{
|
||||
return result_type(lt.actor, modifiers);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Terminal, typename Actor, int Arity, typename Subject, typename Modifiers>
|
||||
struct make_directive<lazy_terminal<Terminal, Actor, Arity>, Subject, Modifiers>
|
||||
{
|
||||
typedef lazy_directive<Actor, Subject, Modifiers> result_type;
|
||||
result_type operator()(
|
||||
lazy_terminal<Terminal, Actor, Arity> const& lt
|
||||
, Subject const& subject, Modifiers const& modifiers) const
|
||||
{
|
||||
return result_type(lt.actor, subject, modifiers);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Actor, typename Modifiers, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct handles_container<
|
||||
qi::lazy_parser<Actor, Modifiers>, Attribute, Context, Iterator>
|
||||
: handles_container<
|
||||
typename qi::lazy_parser<Actor, Modifiers>::template
|
||||
attribute<Context, Iterator>::parser_type
|
||||
, Attribute, Context, Iterator>
|
||||
{};
|
||||
|
||||
template <typename Subject, typename Actor, typename Modifiers
|
||||
, typename Attribute, typename Context, typename Iterator>
|
||||
struct handles_container<
|
||||
qi::lazy_directive<Actor, Subject, Modifiers>, Attribute
|
||||
, Context, Iterator>
|
||||
: handles_container<
|
||||
typename qi::lazy_directive<Actor, Subject, Modifiers>::template
|
||||
attribute<Context, Iterator>::parser_type
|
||||
, Attribute, Context, Iterator>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -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_BINARY_MAY_08_2007_0906AM)
|
||||
#define BOOST_SPIRIT_BINARY_MAY_08_2007_0906AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/binary/binary.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,413 @@
|
||||
/*=============================================================================
|
||||
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_BINARY_MAY_08_2007_0808AM)
|
||||
#define BOOST_SPIRIT_BINARY_MAY_08_2007_0808AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/detail/endian.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_floating_point.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#define BOOST_SPIRIT_ENABLE_BINARY(name) \
|
||||
template <> \
|
||||
struct use_terminal<qi::domain, tag::name> \
|
||||
: mpl::true_ {}; \
|
||||
\
|
||||
template <typename A0> \
|
||||
struct use_terminal<qi::domain \
|
||||
, terminal_ex<tag::name, fusion::vector1<A0> > > \
|
||||
: mpl::or_<is_integral<A0>, is_enum<A0> > {}; \
|
||||
\
|
||||
template <> \
|
||||
struct use_lazy_terminal<qi::domain, tag::name, 1> : mpl::true_ {}; \
|
||||
\
|
||||
/***/
|
||||
|
||||
#define BOOST_SPIRIT_ENABLE_BINARY_IEEE754(name) \
|
||||
template<> \
|
||||
struct use_terminal<qi::domain, tag::name>: mpl::true_ {}; \
|
||||
\
|
||||
template<typename A0> \
|
||||
struct use_terminal<qi::domain, terminal_ex<tag::name, \
|
||||
fusion::vector1<A0> > >: is_floating_point<A0> {}; \
|
||||
\
|
||||
template<> \
|
||||
struct use_lazy_terminal<qi::domain, tag::name, 1>: mpl::true_ {}; \
|
||||
\
|
||||
/***/
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SPIRIT_ENABLE_BINARY(byte_) // enables byte_
|
||||
BOOST_SPIRIT_ENABLE_BINARY(word) // enables word
|
||||
BOOST_SPIRIT_ENABLE_BINARY(big_word) // enables big_word
|
||||
BOOST_SPIRIT_ENABLE_BINARY(little_word) // enables little_word
|
||||
BOOST_SPIRIT_ENABLE_BINARY(dword) // enables dword
|
||||
BOOST_SPIRIT_ENABLE_BINARY(big_dword) // enables big_dword
|
||||
BOOST_SPIRIT_ENABLE_BINARY(little_dword) // enables little_dword
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
BOOST_SPIRIT_ENABLE_BINARY(qword) // enables qword
|
||||
BOOST_SPIRIT_ENABLE_BINARY(big_qword) // enables big_qword
|
||||
BOOST_SPIRIT_ENABLE_BINARY(little_qword) // enables little_qword
|
||||
#endif
|
||||
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_float)
|
||||
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_float)
|
||||
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_float)
|
||||
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(bin_double)
|
||||
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(big_bin_double)
|
||||
BOOST_SPIRIT_ENABLE_BINARY_IEEE754(little_bin_double)
|
||||
}}
|
||||
|
||||
#undef BOOST_SPIRIT_ENABLE_BINARY
|
||||
#undef BOOST_SPIRIT_ENABLE_BINARY_IEEE754
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using boost::spirit::byte_;
|
||||
using boost::spirit::word;
|
||||
using boost::spirit::big_word;
|
||||
using boost::spirit::little_word;
|
||||
using boost::spirit::dword;
|
||||
using boost::spirit::big_dword;
|
||||
using boost::spirit::little_dword;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using boost::spirit::qword;
|
||||
using boost::spirit::big_qword;
|
||||
using boost::spirit::little_qword;
|
||||
#endif
|
||||
using boost::spirit::bin_float;
|
||||
using boost::spirit::big_bin_float;
|
||||
using boost::spirit::little_bin_float;
|
||||
using boost::spirit::bin_double;
|
||||
using boost::spirit::big_bin_double;
|
||||
using boost::spirit::little_bin_double;
|
||||
#endif
|
||||
|
||||
using boost::spirit::byte_type;
|
||||
using boost::spirit::word_type;
|
||||
using boost::spirit::big_word_type;
|
||||
using boost::spirit::little_word_type;
|
||||
using boost::spirit::dword_type;
|
||||
using boost::spirit::big_dword_type;
|
||||
using boost::spirit::little_dword_type;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using boost::spirit::qword_type;
|
||||
using boost::spirit::big_qword_type;
|
||||
using boost::spirit::little_qword_type;
|
||||
#endif
|
||||
using boost::spirit::bin_float_type;
|
||||
using boost::spirit::big_bin_float_type;
|
||||
using boost::spirit::little_bin_float_type;
|
||||
using boost::spirit::bin_double_type;
|
||||
using boost::spirit::big_bin_double_type;
|
||||
using boost::spirit::little_bin_double_type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <int bits>
|
||||
struct integer
|
||||
{
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
bits == 8 || bits == 16 || bits == 32 || bits == 64,
|
||||
not_supported_binary_size, ());
|
||||
#else
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
bits == 8 || bits == 16 || bits == 32,
|
||||
not_supported_binary_size, ());
|
||||
#endif
|
||||
};
|
||||
|
||||
template <>
|
||||
struct integer<8>
|
||||
{
|
||||
enum { size = 1 };
|
||||
typedef uint_least8_t type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct integer<16>
|
||||
{
|
||||
enum { size = 2 };
|
||||
typedef uint_least16_t type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct integer<32>
|
||||
{
|
||||
enum { size = 4 };
|
||||
typedef uint_least32_t type;
|
||||
};
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <>
|
||||
struct integer<64>
|
||||
{
|
||||
enum { size = 8 };
|
||||
typedef uint_least64_t type;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <int bits>
|
||||
struct floating_point
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
bits == 32 || bits == 64,
|
||||
not_supported_binary_size, ());
|
||||
};
|
||||
|
||||
template <>
|
||||
struct floating_point<32>
|
||||
{
|
||||
enum { size = 4 };
|
||||
typedef float type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct floating_point<64>
|
||||
{
|
||||
enum { size = 8 };
|
||||
typedef double type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <BOOST_SCOPED_ENUM(boost::endian::endianness) bits>
|
||||
struct what;
|
||||
|
||||
template <>
|
||||
struct what<boost::endian::endianness::native>
|
||||
{
|
||||
static std::string is()
|
||||
{
|
||||
return "native-endian binary";
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct what<boost::endian::endianness::little>
|
||||
{
|
||||
static char const* is()
|
||||
{
|
||||
return "little-endian binary";
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct what<boost::endian::endianness::big>
|
||||
{
|
||||
static char const* is()
|
||||
{
|
||||
return "big-endian binary";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
|
||||
struct any_binary_parser : primitive_parser<any_binary_parser<T, endian, bits> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef boost::endian::endian<endian, typename T::type,
|
||||
bits> type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
typename attribute<Context, Iterator>::type attr_;
|
||||
unsigned char* bytes = reinterpret_cast<unsigned char*>(&attr_);
|
||||
|
||||
Iterator it = first;
|
||||
for (unsigned int i = 0; i < sizeof(attr_); ++i)
|
||||
{
|
||||
if (it == last)
|
||||
return false;
|
||||
*bytes++ = *it++;
|
||||
}
|
||||
|
||||
first = it;
|
||||
spirit::traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info(qi::detail::what<endian>::is());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename V, typename T
|
||||
, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
|
||||
struct binary_lit_parser
|
||||
: primitive_parser<binary_lit_parser<V, T, endian, bits> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
binary_lit_parser(V n_)
|
||||
: n(n_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
// Even if the endian types are not pod's (at least not in the
|
||||
// definition of C++03) it seems to be safe to assume they are
|
||||
// (but in C++0x the endian types _are_ PODs).
|
||||
// This allows us to treat them as a sequence of consecutive bytes.
|
||||
boost::endian::endian<endian, typename T::type, bits> attr_;
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
// warning C4244: 'argument' : conversion from 'const int' to 'foo', possible loss of data
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4244)
|
||||
#endif
|
||||
attr_ = n;
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
unsigned char* bytes = reinterpret_cast<unsigned char*>(&attr_);
|
||||
|
||||
Iterator it = first;
|
||||
for (unsigned int i = 0; i < sizeof(attr_); ++i)
|
||||
{
|
||||
if (it == last || *bytes++ != static_cast<unsigned char>(*it++))
|
||||
return false;
|
||||
}
|
||||
|
||||
first = it;
|
||||
spirit::traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info(qi::detail::what<endian>::is());
|
||||
}
|
||||
|
||||
V n;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
|
||||
struct make_binary_parser
|
||||
{
|
||||
typedef any_binary_parser<T, endian, bits> result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename V, typename T
|
||||
, BOOST_SCOPED_ENUM(boost::endian::endianness) endian, int bits>
|
||||
struct make_binary_lit_parser
|
||||
{
|
||||
typedef binary_lit_parser<V, T, endian, bits> result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
#define BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(name, endiantype, bits) \
|
||||
template <typename Modifiers> \
|
||||
struct make_primitive<tag::name, Modifiers> \
|
||||
: make_binary_parser<detail::integer<bits>, \
|
||||
boost::endian::endianness::endiantype, bits> {}; \
|
||||
\
|
||||
template <typename Modifiers, typename A0> \
|
||||
struct make_primitive< \
|
||||
terminal_ex<tag::name, fusion::vector1<A0> > , Modifiers> \
|
||||
: make_binary_lit_parser<A0, detail::integer<bits>, \
|
||||
boost::endian::endianness::endiantype, bits> {}; \
|
||||
\
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(byte_, native, 8)
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(word, native, 16)
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_word, big, 16)
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_word, little, 16)
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(dword, native, 32)
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_dword, big, 32)
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_dword, little, 32)
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(qword, native, 64)
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(big_qword, big, 64)
|
||||
BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE(little_qword, little, 64)
|
||||
#endif
|
||||
|
||||
#undef BOOST_SPIRIT_MAKE_BINARY_PRIMITIVE
|
||||
|
||||
#define BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(name, endiantype, bits) \
|
||||
template<typename Modifiers> \
|
||||
struct make_primitive<tag::name, Modifiers> \
|
||||
: make_binary_parser<detail::floating_point<bits>, \
|
||||
boost::endian::endianness::endiantype, bits> {}; \
|
||||
\
|
||||
template<typename Modifiers, typename A0> \
|
||||
struct make_primitive< \
|
||||
terminal_ex<tag::name, fusion::vector1<A0> >, Modifiers> \
|
||||
: make_binary_lit_parser<A0, detail::floating_point<bits>, \
|
||||
boost::endian::endianness::endiantype, \
|
||||
bits> {}; \
|
||||
\
|
||||
/***/
|
||||
|
||||
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_float, native, 32)
|
||||
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_float, big, 32)
|
||||
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_float, little, 32)
|
||||
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(bin_double, native, 64)
|
||||
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(big_bin_double, big, 64)
|
||||
BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE(little_bin_double, little, 64)
|
||||
|
||||
#undef BOOST_SPIRIT_MAKE_BINARY_IEEE754_PRIMITIVE
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
/*=============================================================================
|
||||
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_CHAR_FEBRUARY_02_2007_0921AM)
|
||||
#define BOOST_SPIRIT_CHAR_FEBRUARY_02_2007_0921AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/char/char_parser.hpp>
|
||||
#include <boost/spirit/home/qi/char/char.hpp>
|
||||
#include <boost/spirit/home/qi/char/char_class.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,615 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
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_CHAR_APRIL_16_2006_1051AM)
|
||||
#define BOOST_SPIRIT_CHAR_APRIL_16_2006_1051AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/string_traits.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/detail/get_encoding.hpp>
|
||||
#include <boost/spirit/home/support/char_set/basic_chset.hpp>
|
||||
#include <boost/spirit/home/qi/char/char_parser.hpp>
|
||||
#include <boost/spirit/home/qi/char/char_class.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <string>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharEncoding>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal<
|
||||
tag::char_code<tag::char_, CharEncoding> // enables char_
|
||||
>
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename CharEncoding, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<
|
||||
tag::char_code<tag::char_, CharEncoding> // enables char_('x'), char_("x")
|
||||
, fusion::vector1<A0> // and char_("a-z0-9")
|
||||
>
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename CharEncoding, typename A0, typename A1>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<
|
||||
tag::char_code<tag::char_, CharEncoding> // enables char_('a','z')
|
||||
, fusion::vector2<A0, A1>
|
||||
>
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename CharEncoding> // enables *lazy* char_('x'), char_("x")
|
||||
struct use_lazy_terminal< // and char_("a-z0-9")
|
||||
qi::domain
|
||||
, tag::char_code<tag::char_, CharEncoding>
|
||||
, 1 // arity
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename CharEncoding> // enables *lazy* char_('a','z')
|
||||
struct use_lazy_terminal<
|
||||
qi::domain
|
||||
, tag::char_code<tag::char_, CharEncoding>
|
||||
, 2 // arity
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct use_terminal<qi::domain, char> // enables 'x'
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct use_terminal<qi::domain, char[2]> // enables "x"
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct use_terminal<qi::domain, wchar_t> // enables wchar_t
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct use_terminal<qi::domain, wchar_t[2]> // enables L"x"
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables lit(...)
|
||||
template <typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<traits::is_char<A0> >::type>
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::lit; // lit('x') is equivalent to 'x'
|
||||
#endif
|
||||
using spirit::lit_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser for a single character
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharEncoding, bool no_attribute, bool no_case = false>
|
||||
struct literal_char
|
||||
: char_parser<
|
||||
literal_char<CharEncoding, no_attribute, false>
|
||||
, typename CharEncoding::char_type
|
||||
, typename mpl::if_c<no_attribute, unused_type
|
||||
, typename CharEncoding::char_type>::type>
|
||||
{
|
||||
typedef typename CharEncoding::char_type char_type;
|
||||
typedef CharEncoding char_encoding;
|
||||
|
||||
template <typename Char>
|
||||
literal_char(Char ch_)
|
||||
: ch(static_cast<char_type>(ch_)) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename mpl::if_c<
|
||||
no_attribute, unused_type, char_type>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename CharParam, typename Context>
|
||||
bool test(CharParam ch_, Context&) const
|
||||
{
|
||||
return traits::ischar<CharParam, char_encoding>::call(ch_) &&
|
||||
ch == char_type(ch_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("literal-char", char_encoding::toucs4(ch));
|
||||
}
|
||||
|
||||
char_type ch;
|
||||
};
|
||||
|
||||
template <typename CharEncoding, bool no_attribute>
|
||||
struct literal_char<CharEncoding, no_attribute, true> // case insensitive
|
||||
: char_parser<
|
||||
literal_char<CharEncoding, no_attribute, true>
|
||||
, typename mpl::if_c<no_attribute, unused_type
|
||||
, typename CharEncoding::char_type>::type>
|
||||
{
|
||||
typedef typename CharEncoding::char_type char_type;
|
||||
typedef CharEncoding char_encoding;
|
||||
|
||||
literal_char(char_type ch)
|
||||
: lo(static_cast<char_type>(char_encoding::tolower(ch)))
|
||||
, hi(static_cast<char_type>(char_encoding::toupper(ch))) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename mpl::if_c<
|
||||
no_attribute, unused_type, char_type>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename CharParam, typename Context>
|
||||
bool test(CharParam ch_, Context&) const
|
||||
{
|
||||
if (!traits::ischar<CharParam, char_encoding>::call(ch_))
|
||||
return false;
|
||||
|
||||
char_type ch = char_type(ch_); // optimize for token based parsing
|
||||
return this->lo == ch || this->hi == ch;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("no-case-literal-char", char_encoding::toucs4(lo));
|
||||
}
|
||||
|
||||
char_type lo, hi;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser for a character range
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharEncoding, bool no_case = false>
|
||||
struct char_range
|
||||
: char_parser<char_range<CharEncoding, false>, typename CharEncoding::char_type>
|
||||
{
|
||||
typedef typename CharEncoding::char_type char_type;
|
||||
typedef CharEncoding char_encoding;
|
||||
|
||||
char_range(char_type from_, char_type to_)
|
||||
: from(from_), to(to_) {}
|
||||
|
||||
template <typename CharParam, typename Context>
|
||||
bool test(CharParam ch_, Context&) const
|
||||
{
|
||||
if (!traits::ischar<CharParam, char_encoding>::call(ch_))
|
||||
return false;
|
||||
|
||||
char_type ch = char_type(ch_); // optimize for token based parsing
|
||||
return !(ch < from) && !(to < ch);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
info result("char-range", char_encoding::toucs4(from));
|
||||
boost::get<std::string>(result.value) += '-';
|
||||
boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to));
|
||||
return result;
|
||||
}
|
||||
|
||||
char_type from, to;
|
||||
};
|
||||
|
||||
template <typename CharEncoding>
|
||||
struct char_range<CharEncoding, true> // case insensitive
|
||||
: char_parser<char_range<CharEncoding, true>, typename CharEncoding::char_type>
|
||||
{
|
||||
typedef typename CharEncoding::char_type char_type;
|
||||
typedef CharEncoding char_encoding;
|
||||
|
||||
char_range(char_type from, char_type to)
|
||||
: from_lo(static_cast<char_type>(char_encoding::tolower(from)))
|
||||
, to_lo(static_cast<char_type>(char_encoding::tolower(to)))
|
||||
, from_hi(static_cast<char_type>(char_encoding::toupper(from)))
|
||||
, to_hi(static_cast<char_type>(char_encoding::toupper(to)))
|
||||
{}
|
||||
|
||||
template <typename CharParam, typename Context>
|
||||
bool test(CharParam ch_, Context&) const
|
||||
{
|
||||
if (!traits::ischar<CharParam, char_encoding>::call(ch_))
|
||||
return false;
|
||||
|
||||
char_type ch = char_type(ch_); // optimize for token based parsing
|
||||
return (!(ch < from_lo) && !(to_lo < ch))
|
||||
|| (!(ch < from_hi) && !(to_hi < ch))
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
info result("no-case-char-range", char_encoding::toucs4(from_lo));
|
||||
boost::get<std::string>(result.value) += '-';
|
||||
boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to_lo));
|
||||
return result;
|
||||
}
|
||||
|
||||
char_type from_lo, to_lo, from_hi, to_hi;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser for a character set
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharEncoding, bool no_attribute, bool no_case = false>
|
||||
struct char_set
|
||||
: char_parser<char_set<CharEncoding, no_attribute, false>
|
||||
, typename mpl::if_c<no_attribute, unused_type
|
||||
, typename CharEncoding::char_type>::type>
|
||||
{
|
||||
typedef typename CharEncoding::char_type char_type;
|
||||
typedef CharEncoding char_encoding;
|
||||
|
||||
template <typename String>
|
||||
char_set(String const& str)
|
||||
{
|
||||
using spirit::detail::cast_char;
|
||||
|
||||
typedef typename
|
||||
remove_const<
|
||||
typename traits::char_type_of<String>::type
|
||||
>::type
|
||||
in_type;
|
||||
|
||||
BOOST_SPIRIT_ASSERT_MSG((
|
||||
(sizeof(char_type) >= sizeof(in_type))
|
||||
), cannot_convert_string, (String));
|
||||
|
||||
in_type const* definition =
|
||||
(in_type const*)traits::get_c_string(str);
|
||||
in_type ch = *definition++;
|
||||
while (ch)
|
||||
{
|
||||
in_type next = *definition++;
|
||||
if (next == '-')
|
||||
{
|
||||
next = *definition++;
|
||||
if (next == 0)
|
||||
{
|
||||
chset.set(cast_char<char_type>(ch));
|
||||
chset.set('-');
|
||||
break;
|
||||
}
|
||||
chset.set(
|
||||
cast_char<char_type>(ch),
|
||||
cast_char<char_type>(next)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
chset.set(cast_char<char_type>(ch));
|
||||
}
|
||||
ch = next;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharParam, typename Context>
|
||||
bool test(CharParam ch, Context&) const
|
||||
{
|
||||
return traits::ischar<CharParam, char_encoding>::call(ch) &&
|
||||
chset.test(char_type(ch));
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("char-set");
|
||||
}
|
||||
|
||||
support::detail::basic_chset<char_type> chset;
|
||||
};
|
||||
|
||||
template <typename CharEncoding, bool no_attribute>
|
||||
struct char_set<CharEncoding, no_attribute, true> // case insensitive
|
||||
: char_parser<char_set<CharEncoding, no_attribute, true>
|
||||
, typename mpl::if_c<no_attribute, unused_type
|
||||
, typename CharEncoding::char_type>::type>
|
||||
{
|
||||
typedef typename CharEncoding::char_type char_type;
|
||||
typedef CharEncoding char_encoding;
|
||||
|
||||
template <typename String>
|
||||
char_set(String const& str)
|
||||
{
|
||||
typedef typename traits::char_type_of<String>::type in_type;
|
||||
|
||||
BOOST_SPIRIT_ASSERT_MSG((
|
||||
(sizeof(char_type) == sizeof(in_type))
|
||||
), cannot_convert_string, (String));
|
||||
|
||||
char_type const* definition =
|
||||
(char_type const*)traits::get_c_string(str);
|
||||
char_type ch = *definition++;
|
||||
while (ch)
|
||||
{
|
||||
char_type next = *definition++;
|
||||
if (next == '-')
|
||||
{
|
||||
next = *definition++;
|
||||
if (next == 0)
|
||||
{
|
||||
chset.set(static_cast<char_type>(CharEncoding::tolower(ch)));
|
||||
chset.set(static_cast<char_type>(CharEncoding::toupper(ch)));
|
||||
chset.set('-');
|
||||
break;
|
||||
}
|
||||
chset.set(static_cast<char_type>(CharEncoding::tolower(ch))
|
||||
, static_cast<char_type>(CharEncoding::tolower(next)));
|
||||
chset.set(static_cast<char_type>(CharEncoding::toupper(ch))
|
||||
, static_cast<char_type>(CharEncoding::toupper(next)));
|
||||
}
|
||||
else
|
||||
{
|
||||
chset.set(static_cast<char_type>(CharEncoding::tolower(ch)));
|
||||
chset.set(static_cast<char_type>(CharEncoding::toupper(ch)));
|
||||
}
|
||||
ch = next;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharParam, typename Context>
|
||||
bool test(CharParam ch, Context&) const
|
||||
{
|
||||
return traits::ischar<CharParam, char_encoding>::call(ch) &&
|
||||
chset.test(char_type(ch));
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("no-case-char-set");
|
||||
}
|
||||
|
||||
support::detail::basic_chset<char_type> chset;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
template <typename Modifiers, typename Encoding>
|
||||
struct basic_literal
|
||||
{
|
||||
static bool const no_case =
|
||||
has_modifier<
|
||||
Modifiers
|
||||
, tag::char_code_base<tag::no_case>
|
||||
>::value;
|
||||
|
||||
static bool const no_attr =
|
||||
!has_modifier<
|
||||
Modifiers
|
||||
, tag::lazy_eval
|
||||
>::value;
|
||||
|
||||
typedef literal_char<
|
||||
typename spirit::detail::get_encoding_with_case<
|
||||
Modifiers, Encoding, no_case>::type
|
||||
, no_attr
|
||||
, no_case>
|
||||
result_type;
|
||||
|
||||
template <typename Char>
|
||||
result_type operator()(Char ch, unused_type) const
|
||||
{
|
||||
return result_type(ch);
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
result_type operator()(Char const* str, unused_type) const
|
||||
{
|
||||
return result_type(str[0]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<char, Modifiers>
|
||||
: detail::basic_literal<Modifiers, char_encoding::standard> {};
|
||||
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<char const(&)[2], Modifiers>
|
||||
: detail::basic_literal<Modifiers, char_encoding::standard> {};
|
||||
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<wchar_t, Modifiers>
|
||||
: detail::basic_literal<Modifiers, char_encoding::standard_wide> {};
|
||||
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<wchar_t const(&)[2], Modifiers>
|
||||
: detail::basic_literal<Modifiers, char_encoding::standard_wide> {};
|
||||
|
||||
template <typename CharEncoding, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal<tag::char_code<tag::char_, CharEncoding> >, Modifiers>
|
||||
{
|
||||
typedef typename
|
||||
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
||||
char_encoding;
|
||||
|
||||
typedef tag::char_code<tag::char_, char_encoding> tag;
|
||||
typedef char_class<tag> result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// char_('x')
|
||||
template <typename CharEncoding, typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<
|
||||
tag::char_code<tag::char_, CharEncoding>
|
||||
, fusion::vector1<A0> >
|
||||
, Modifiers>
|
||||
{
|
||||
static bool const no_case =
|
||||
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
||||
|
||||
typedef typename
|
||||
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
||||
char_encoding;
|
||||
|
||||
typedef typename
|
||||
mpl::if_<
|
||||
traits::is_string<A0>
|
||||
, char_set<char_encoding, false, no_case>
|
||||
, literal_char<char_encoding, false, no_case>
|
||||
>::type
|
||||
result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
// lit('x')
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers
|
||||
, typename enable_if<traits::is_char<A0> >::type>
|
||||
{
|
||||
static bool const no_case =
|
||||
has_modifier<
|
||||
Modifiers
|
||||
, tag::char_code_base<tag::no_case>
|
||||
>::value;
|
||||
|
||||
typedef typename traits::char_encoding_from_char<
|
||||
typename traits::char_type_of<A0>::type>::type encoding;
|
||||
|
||||
typedef literal_char<
|
||||
typename spirit::detail::get_encoding_with_case<
|
||||
Modifiers, encoding, no_case>::type
|
||||
, true, no_case>
|
||||
result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharEncoding, typename Modifiers, typename Char>
|
||||
struct make_primitive<
|
||||
terminal_ex<
|
||||
tag::char_code<tag::char_, CharEncoding>
|
||||
, fusion::vector1<Char(&)[2]> // For single char strings
|
||||
>
|
||||
, Modifiers>
|
||||
{
|
||||
static bool const no_case =
|
||||
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
||||
|
||||
typedef typename
|
||||
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
||||
char_encoding;
|
||||
|
||||
typedef literal_char<char_encoding, false, no_case> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args)[0]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CharEncoding, typename Modifiers, typename A0, typename A1>
|
||||
struct make_primitive<
|
||||
terminal_ex<
|
||||
tag::char_code<tag::char_, CharEncoding>
|
||||
, fusion::vector2<A0, A1>
|
||||
>
|
||||
, Modifiers>
|
||||
{
|
||||
static bool const no_case =
|
||||
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
||||
|
||||
typedef typename
|
||||
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
||||
char_encoding;
|
||||
|
||||
typedef char_range<char_encoding, no_case> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(
|
||||
fusion::at_c<0>(term.args)
|
||||
, fusion::at_c<1>(term.args)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CharEncoding, typename Modifiers, typename Char>
|
||||
struct make_primitive<
|
||||
terminal_ex<
|
||||
tag::char_code<tag::char_, CharEncoding>
|
||||
, fusion::vector2<Char(&)[2], Char(&)[2]> // For single char strings
|
||||
>
|
||||
, Modifiers>
|
||||
{
|
||||
static bool const no_case =
|
||||
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
||||
|
||||
typedef typename
|
||||
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
||||
char_encoding;
|
||||
|
||||
typedef char_range<char_encoding, no_case> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(
|
||||
fusion::at_c<0>(term.args)[0]
|
||||
, fusion::at_c<1>(term.args)[0]
|
||||
);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/*=============================================================================
|
||||
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_CHAR_CLASS_APRIL_16_2006_1051AM)
|
||||
#define BOOST_SPIRIT_CHAR_CLASS_APRIL_16_2006_1051AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/char/char_parser.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/support/char_class.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/modify.hpp>
|
||||
#include <boost/spirit/home/support/detail/get_encoding.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables alnum, alpha, graph, etc.
|
||||
template <typename CharClass, typename CharEncoding>
|
||||
struct use_terminal<qi::domain, tag::char_code<CharClass, CharEncoding> >
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
// hoist the char classification namespaces into qi sub-namespaces of the
|
||||
// same name
|
||||
namespace ascii { using namespace boost::spirit::ascii; }
|
||||
namespace iso8859_1 { using namespace boost::spirit::iso8859_1; }
|
||||
namespace standard { using namespace boost::spirit::standard; }
|
||||
namespace standard_wide { using namespace boost::spirit::standard_wide; }
|
||||
#if defined(BOOST_SPIRIT_UNICODE)
|
||||
namespace unicode { using namespace boost::spirit::unicode; }
|
||||
#endif
|
||||
|
||||
// Import the standard namespace into the qi namespace. This allows
|
||||
// for default handling of all character/string related operations if not
|
||||
// prefixed with a character set namespace.
|
||||
using namespace boost::spirit::standard;
|
||||
|
||||
// Import encoding
|
||||
using spirit::encoding;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Generic char classification parser (for alnum, alpha, graph, etc.)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Tag>
|
||||
struct char_class
|
||||
: char_parser<char_class<Tag>, typename Tag::char_encoding::char_type>
|
||||
{
|
||||
typedef typename Tag::char_encoding char_encoding;
|
||||
typedef typename Tag::char_class classification;
|
||||
|
||||
template <typename CharParam, typename Context>
|
||||
bool test(CharParam ch, Context&) const
|
||||
{
|
||||
using spirit::char_class::classify;
|
||||
return traits::ischar<CharParam, char_encoding>::call(ch) &&
|
||||
classify<char_encoding>::is(classification(), ch);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
typedef spirit::char_class::what<char_encoding> what_;
|
||||
return info(what_::is(classification()));
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename Tag, bool no_case = false>
|
||||
struct make_char_class : mpl::identity<Tag> {};
|
||||
|
||||
template <>
|
||||
struct make_char_class<tag::lower, true> : mpl::identity<tag::alpha> {};
|
||||
|
||||
template <>
|
||||
struct make_char_class<tag::upper, true> : mpl::identity<tag::alpha> {};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharClass, typename CharEncoding, typename Modifiers>
|
||||
struct make_primitive<tag::char_code<CharClass, CharEncoding>, Modifiers>
|
||||
{
|
||||
static bool const no_case =
|
||||
has_modifier<Modifiers, tag::char_code_base<tag::no_case> >::value;
|
||||
|
||||
typedef typename
|
||||
spirit::detail::get_encoding<Modifiers, CharEncoding>::type
|
||||
char_encoding;
|
||||
|
||||
typedef tag::char_code<
|
||||
typename detail::make_char_class<CharClass, no_case>::type
|
||||
, char_encoding>
|
||||
tag;
|
||||
|
||||
typedef char_class<tag> result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,157 @@
|
||||
/*=============================================================================
|
||||
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_CHAR_PARSER_APR_16_2006_0906AM)
|
||||
#define BOOST_SPIRIT_CHAR_PARSER_APR_16_2006_0906AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::complement> // enables ~
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits // classification
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(char_parser_id)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct is_char_parser : detail::has_char_parser_id<T> {};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// The base char_parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Derived, typename Char, typename Attr = Char>
|
||||
struct char_parser : primitive_parser<Derived>
|
||||
{
|
||||
typedef Char char_type;
|
||||
struct char_parser_id;
|
||||
|
||||
// if Attr is unused_type, Derived must supply its own attribute
|
||||
// metafunction
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef Attr type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, Attribute& attr_) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
if (first != last && this->derived().test(*first, context))
|
||||
{
|
||||
spirit::traits::assign_to(*first, attr_);
|
||||
++first;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Requirement: p.test(ch, context) -> bool
|
||||
//
|
||||
// ch: character being parsed
|
||||
// context: enclosing rule context
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// negated_char_parser handles ~cp expressions (cp is a char_parser)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Positive>
|
||||
struct negated_char_parser :
|
||||
char_parser<negated_char_parser<Positive>, typename Positive::char_type>
|
||||
{
|
||||
negated_char_parser(Positive const& positive_)
|
||||
: positive(positive_) {}
|
||||
|
||||
template <typename CharParam, typename Context>
|
||||
bool test(CharParam ch, Context& context) const
|
||||
{
|
||||
return !positive.test(ch, context);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("not", positive.what(context));
|
||||
}
|
||||
|
||||
Positive positive;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
template <typename Positive>
|
||||
struct make_negated_char_parser
|
||||
{
|
||||
typedef negated_char_parser<Positive> result_type;
|
||||
result_type operator()(Positive const& positive) const
|
||||
{
|
||||
return result_type(positive);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Positive>
|
||||
struct make_negated_char_parser<negated_char_parser<Positive> >
|
||||
{
|
||||
typedef Positive result_type;
|
||||
result_type operator()(negated_char_parser<Positive> const& ncp) const
|
||||
{
|
||||
return ncp.positive;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::complement, Elements, Modifiers>
|
||||
{
|
||||
typedef typename
|
||||
fusion::result_of::value_at_c<Elements, 0>::type
|
||||
subject;
|
||||
|
||||
BOOST_SPIRIT_ASSERT_MSG((
|
||||
traits::is_char_parser<subject>::value
|
||||
), subject_is_not_negatable, (subject));
|
||||
|
||||
typedef typename
|
||||
detail::make_negated_char_parser<subject>::result_type
|
||||
result_type;
|
||||
|
||||
result_type operator()(Elements const& elements, unused_type) const
|
||||
{
|
||||
return detail::make_negated_char_parser<subject>()(
|
||||
fusion::at_c<0>(elements));
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
/*=============================================================================
|
||||
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_COPY_FEBRUARY_7_2012_0159PM)
|
||||
#define BOOST_SPIRIT_COPY_FEBRUARY_7_2012_0159PM
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/proto/proto.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Expr>
|
||||
typename boost::proto::result_of::deep_copy<Expr>::type
|
||||
copy(Expr const& expr)
|
||||
{
|
||||
BOOST_SPIRIT_ASSERT_MATCH(boost::spirit::qi::domain, Expr);
|
||||
return boost::proto::deep_copy(expr);
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
/*=============================================================================
|
||||
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_ALTERNATIVE_FUNCTION_APRIL_23_2007_1046AM)
|
||||
#define SPIRIT_ALTERNATIVE_FUNCTION_APRIL_23_2007_1046AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename Variant, typename Expected>
|
||||
struct find_substitute
|
||||
{
|
||||
// Get the typr from the variant that can be a substitute for Expected.
|
||||
// If none is found, just return Expected
|
||||
|
||||
typedef Variant variant_type;
|
||||
typedef typename variant_type::types types;
|
||||
typedef typename mpl::end<types>::type end;
|
||||
|
||||
typedef typename
|
||||
mpl::find_if<types, is_same<mpl::_1, Expected> >::type
|
||||
iter_1;
|
||||
|
||||
typedef typename
|
||||
mpl::eval_if<
|
||||
is_same<iter_1, end>,
|
||||
mpl::find_if<types, traits::is_substitute<mpl::_1, Expected> >,
|
||||
mpl::identity<iter_1>
|
||||
>::type
|
||||
iter;
|
||||
|
||||
typedef typename
|
||||
mpl::eval_if<
|
||||
is_same<iter, end>,
|
||||
mpl::identity<Expected>,
|
||||
mpl::deref<iter>
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper,
|
||||
typename Attribute>
|
||||
struct alternative_function
|
||||
{
|
||||
alternative_function(
|
||||
Iterator& first_, Iterator const& last_, Context& context_,
|
||||
Skipper const& skipper_, Attribute& attr_)
|
||||
: first(first_), last(last_), context(context_), skipper(skipper_),
|
||||
attr(attr_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool call(Component const& component, mpl::true_) const
|
||||
{
|
||||
// if Attribute is not a variant, then pass it as-is
|
||||
return component.parse(first, last, context, skipper, attr);
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool call_optional_or_variant(Component const& component, mpl::true_) const
|
||||
{
|
||||
// If Attribute is an optional, then create an attribute for the Component
|
||||
// with the type optional::value_type. If the expected attribute is unused type,
|
||||
// use it instead.
|
||||
typedef typename
|
||||
traits::attribute_of<Component, Context, Iterator>::type
|
||||
expected_type;
|
||||
|
||||
typename mpl::if_<
|
||||
is_same<expected_type, unused_type>,
|
||||
unused_type,
|
||||
typename Attribute::value_type>::type
|
||||
val;
|
||||
|
||||
if (component.parse(first, last, context, skipper, val))
|
||||
{
|
||||
traits::assign_to(val, attr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool call_variant(Component const& component, mpl::false_) const
|
||||
{
|
||||
// If Attribute is a variant, then search the variant types for a
|
||||
// suitable substitute type.
|
||||
|
||||
typename
|
||||
find_substitute<Attribute,
|
||||
typename traits::attribute_of<Component, Context, Iterator>::type
|
||||
>::type
|
||||
val;
|
||||
|
||||
if (component.parse(first, last, context, skipper, val))
|
||||
{
|
||||
traits::assign_to(val, attr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool call_variant(Component const& component, mpl::true_) const
|
||||
{
|
||||
// If Attribute is a variant and the expected attribute is
|
||||
// the same type (pass the variant as-is).
|
||||
|
||||
return component.parse(first, last, context, skipper, attr);
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool call_optional_or_variant(Component const& component, mpl::false_) const
|
||||
{
|
||||
// Attribute is a variant...
|
||||
|
||||
typedef typename
|
||||
traits::attribute_of<Component, Context, Iterator>::type
|
||||
expected;
|
||||
return call_variant(component,
|
||||
is_same<Attribute, expected>());
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool call(Component const& component, mpl::false_) const
|
||||
{
|
||||
return call_optional_or_variant(
|
||||
component, spirit::traits::not_is_variant<Attribute, qi::domain>());
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool call_unused(Component const& component, mpl::true_) const
|
||||
{
|
||||
// return true if the parser succeeds
|
||||
return call(component,
|
||||
mpl::and_<
|
||||
spirit::traits::not_is_variant<Attribute, qi::domain>,
|
||||
spirit::traits::not_is_optional<Attribute, qi::domain>
|
||||
>());
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool call_unused(Component const& component, mpl::false_) const
|
||||
{
|
||||
return component.parse(first, last, context, skipper, unused);
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component) const
|
||||
{
|
||||
// return true if the parser succeeds
|
||||
typedef typename traits::not_is_unused<
|
||||
typename traits::attribute_of<Component, Context, Iterator>::type
|
||||
>::type predicate;
|
||||
|
||||
return call_unused(component, predicate());
|
||||
}
|
||||
|
||||
Iterator& first;
|
||||
Iterator const& last;
|
||||
Context& context;
|
||||
Skipper const& skipper;
|
||||
Attribute& attr;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
alternative_function& operator= (alternative_function const&);
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
struct alternative_function<Iterator, Context, Skipper, unused_type const>
|
||||
{
|
||||
alternative_function(
|
||||
Iterator& first_, Iterator const& last_, Context& context_,
|
||||
Skipper const& skipper_, unused_type)
|
||||
: first(first_), last(last_), context(context_), skipper(skipper_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component) const
|
||||
{
|
||||
// return true if the parser succeeds
|
||||
return component.parse(first, last, context, skipper,
|
||||
unused);
|
||||
}
|
||||
|
||||
Iterator& first;
|
||||
Iterator const& last;
|
||||
Context& context;
|
||||
Skipper const& skipper;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
alternative_function& operator= (alternative_function const&);
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,403 @@
|
||||
/*=============================================================================
|
||||
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_ASSIGN_TO_APR_16_2006_0812PM)
|
||||
#define BOOST_SPIRIT_ASSIGN_TO_APR_16_2006_0812PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/detail/construct.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/fusion/include/copy.hpp>
|
||||
#include <boost/fusion/adapted/struct/detail/extension.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This file contains assignment utilities. The utilities provided also
|
||||
// accept spirit's unused_type; all no-ops. Compiler optimization will
|
||||
// easily strip these away.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
struct is_iter_range : mpl::false_ {};
|
||||
|
||||
template <typename I>
|
||||
struct is_iter_range<boost::iterator_range<I> > : mpl::true_ {};
|
||||
|
||||
template <typename C>
|
||||
struct is_container_of_ranges
|
||||
: is_iter_range<typename C::value_type> {};
|
||||
}
|
||||
|
||||
template <typename Attribute, typename Iterator, typename Enable>
|
||||
struct assign_to_attribute_from_iterators
|
||||
{
|
||||
// Common case
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::false_)
|
||||
{
|
||||
if (traits::is_empty(attr))
|
||||
attr = Attribute(first, last);
|
||||
else {
|
||||
for (Iterator i = first; i != last; ++i)
|
||||
push_back(attr, *i);
|
||||
}
|
||||
}
|
||||
|
||||
// If Attribute is a container with value_type==iterator_range<T> just push the
|
||||
// iterator_range into it
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, Attribute& attr, mpl::true_)
|
||||
{
|
||||
typename Attribute::value_type rng(first, last);
|
||||
push_back(attr, rng);
|
||||
}
|
||||
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
call(first, last, attr, detail::is_container_of_ranges<Attribute>());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute, typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<
|
||||
reference_wrapper<Attribute>, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last
|
||||
, reference_wrapper<Attribute> attr)
|
||||
{
|
||||
if (traits::is_empty(attr))
|
||||
attr = Attribute(first, last);
|
||||
else {
|
||||
for (Iterator i = first; i != last; ++i)
|
||||
push_back(attr, *i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute, typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<
|
||||
boost::optional<Attribute>, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last
|
||||
, boost::optional<Attribute>& attr)
|
||||
{
|
||||
Attribute val;
|
||||
assign_to(first, last, val);
|
||||
attr = val;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<
|
||||
iterator_range<Iterator>, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last
|
||||
, iterator_range<Iterator>& attr)
|
||||
{
|
||||
attr = iterator_range<Iterator>(first, last);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline void
|
||||
assign_to(Iterator const& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
assign_to_attribute_from_iterators<Attribute, Iterator>::
|
||||
call(first, last, attr);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
inline void
|
||||
assign_to(Iterator const&, Iterator const&, unused_type)
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Attribute>
|
||||
void assign_to(T const& val, Attribute& attr);
|
||||
|
||||
template <typename Attribute, typename T, typename Enable>
|
||||
struct assign_to_attribute_from_value
|
||||
{
|
||||
typedef typename traits::one_element_sequence<Attribute>::type
|
||||
is_one_element_sequence;
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
is_one_element_sequence
|
||||
, fusion::result_of::at_c<Attribute, 0>
|
||||
, mpl::identity<Attribute&>
|
||||
>::type type;
|
||||
|
||||
template <typename T_>
|
||||
static void
|
||||
call(T_ const& val, Attribute& attr, mpl::false_)
|
||||
{
|
||||
attr = static_cast<Attribute>(val);
|
||||
}
|
||||
|
||||
// This handles the case where the attribute is a single element fusion
|
||||
// sequence. We silently assign to the only element and treat it as the
|
||||
// attribute to parse the results into.
|
||||
template <typename T_>
|
||||
static void
|
||||
call(T_ const& val, Attribute& attr, mpl::true_)
|
||||
{
|
||||
typedef typename fusion::result_of::value_at_c<Attribute, 0>::type
|
||||
element_type;
|
||||
fusion::at_c<0>(attr) = static_cast<element_type>(val);
|
||||
}
|
||||
|
||||
static void
|
||||
call(T const& val, Attribute& attr)
|
||||
{
|
||||
call(val, attr, is_one_element_sequence());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute>
|
||||
struct assign_to_attribute_from_value<Attribute, Attribute>
|
||||
{
|
||||
static void
|
||||
call(Attribute const& val, Attribute& attr)
|
||||
{
|
||||
attr = val;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute, typename T>
|
||||
struct assign_to_attribute_from_value<Attribute, reference_wrapper<T>
|
||||
, typename disable_if<is_same<Attribute, reference_wrapper<T> > >::type>
|
||||
{
|
||||
static void
|
||||
call(reference_wrapper<T> const& val, Attribute& attr)
|
||||
{
|
||||
assign_to(val.get(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute, typename T>
|
||||
struct assign_to_attribute_from_value<Attribute, boost::optional<T>
|
||||
, typename disable_if<is_same<Attribute, boost::optional<T> > >::type>
|
||||
{
|
||||
static void
|
||||
call(boost::optional<T> const& val, Attribute& attr)
|
||||
{
|
||||
assign_to(val.get(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute, int N, bool Const, typename T>
|
||||
struct assign_to_attribute_from_value<fusion::extension::adt_attribute_proxy<Attribute, N, Const>, T>
|
||||
{
|
||||
static void
|
||||
call(T const& val, typename fusion::extension::adt_attribute_proxy<Attribute, N, Const>& attr)
|
||||
{
|
||||
attr = val;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename A, typename B>
|
||||
struct is_same_size_sequence
|
||||
: mpl::bool_<fusion::result_of::size<A>::value
|
||||
== fusion::result_of::size<B>::value>
|
||||
{};
|
||||
}
|
||||
|
||||
template <typename Attribute, typename T>
|
||||
struct assign_to_attribute_from_value<Attribute, T,
|
||||
mpl::and_<
|
||||
fusion::traits::is_sequence<Attribute>,
|
||||
fusion::traits::is_sequence<T>,
|
||||
detail::is_same_size_sequence<Attribute, T>
|
||||
>
|
||||
>
|
||||
{
|
||||
static void
|
||||
call(T const& val, Attribute& attr)
|
||||
{
|
||||
fusion::copy(val, attr);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Attribute, typename T, typename Enable>
|
||||
struct assign_to_container_from_value
|
||||
{
|
||||
// T is not a container and not a string
|
||||
template <typename T_>
|
||||
static void call(T_ const& val, Attribute& attr, mpl::false_, mpl::false_)
|
||||
{
|
||||
traits::push_back(attr, val);
|
||||
}
|
||||
|
||||
// T is a container (but not a string), and T is convertible to the
|
||||
// value_type of the Attribute container
|
||||
template <typename T_>
|
||||
static void
|
||||
append_to_container_not_string(T_ const& val, Attribute& attr, mpl::true_)
|
||||
{
|
||||
traits::push_back(attr, val);
|
||||
}
|
||||
|
||||
// T is a container (but not a string), generic overload
|
||||
template <typename T_>
|
||||
static void
|
||||
append_to_container_not_string(T_ const& val, Attribute& attr, mpl::false_)
|
||||
{
|
||||
typedef typename traits::container_iterator<T_ const>::type
|
||||
iterator_type;
|
||||
|
||||
iterator_type end = traits::end(val);
|
||||
for (iterator_type i = traits::begin(val); i != end; traits::next(i))
|
||||
traits::push_back(attr, traits::deref(i));
|
||||
}
|
||||
|
||||
// T is a container (but not a string)
|
||||
template <typename T_>
|
||||
static void call(T_ const& val, Attribute& attr, mpl::true_, mpl::false_)
|
||||
{
|
||||
typedef typename container_value<Attribute>::type value_type;
|
||||
typedef typename is_convertible<T, value_type>::type is_value_type;
|
||||
|
||||
append_to_container_not_string(val, attr, is_value_type());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// T is a string
|
||||
template <typename Iterator>
|
||||
static void append_to_string(Attribute& attr, Iterator begin, Iterator end)
|
||||
{
|
||||
for (Iterator i = begin; i != end; ++i)
|
||||
traits::push_back(attr, *i);
|
||||
}
|
||||
|
||||
// T is string, but not convertible to value_type of container
|
||||
template <typename T_>
|
||||
static void append_to_container(T_ const& val, Attribute& attr, mpl::false_)
|
||||
{
|
||||
typedef typename char_type_of<T_>::type char_type;
|
||||
|
||||
append_to_string(attr, traits::get_begin<char_type>(val)
|
||||
, traits::get_end<char_type>(val));
|
||||
}
|
||||
|
||||
// T is string, and convertible to value_type of container
|
||||
template <typename T_>
|
||||
static void append_to_container(T_ const& val, Attribute& attr, mpl::true_)
|
||||
{
|
||||
traits::push_back(attr, val);
|
||||
}
|
||||
|
||||
template <typename T_, typename Pred>
|
||||
static void call(T_ const& val, Attribute& attr, Pred, mpl::true_)
|
||||
{
|
||||
typedef typename container_value<Attribute>::type value_type;
|
||||
typedef typename is_convertible<T, value_type>::type is_value_type;
|
||||
|
||||
append_to_container(val, attr, is_value_type());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
static void call(T const& val, Attribute& attr)
|
||||
{
|
||||
typedef typename traits::is_container<T>::type is_container;
|
||||
typedef typename traits::is_string<T>::type is_string;
|
||||
|
||||
call(val, attr, is_container(), is_string());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute>
|
||||
struct assign_to_container_from_value<Attribute, Attribute>
|
||||
{
|
||||
static void
|
||||
call(Attribute const& val, Attribute& attr)
|
||||
{
|
||||
attr = val;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute, typename T>
|
||||
struct assign_to_container_from_value<Attribute, boost::optional<T>
|
||||
, typename disable_if<is_same<Attribute, boost::optional<T> > >::type>
|
||||
{
|
||||
static void
|
||||
call(boost::optional<T> const& val, Attribute& attr)
|
||||
{
|
||||
assign_to(val.get(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Attribute, typename T>
|
||||
struct assign_to_container_from_value<Attribute, reference_wrapper<T>
|
||||
, typename disable_if<is_same<Attribute, reference_wrapper<T> > >::type>
|
||||
{
|
||||
static void
|
||||
call(reference_wrapper<T> const& val, Attribute& attr)
|
||||
{
|
||||
assign_to(val.get(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
// overload for non-container attributes
|
||||
template <typename T, typename Attribute>
|
||||
inline void
|
||||
assign_to(T const& val, Attribute& attr, mpl::false_)
|
||||
{
|
||||
assign_to_attribute_from_value<Attribute, T>::call(val, attr);
|
||||
}
|
||||
|
||||
// overload for containers (but not for variants or optionals
|
||||
// holding containers)
|
||||
template <typename T, typename Attribute>
|
||||
inline void
|
||||
assign_to(T const& val, Attribute& attr, mpl::true_)
|
||||
{
|
||||
assign_to_container_from_value<Attribute, T>::call(val, attr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Attribute>
|
||||
inline void
|
||||
assign_to(T const& val, Attribute& attr)
|
||||
{
|
||||
typedef typename mpl::and_<
|
||||
traits::is_container<Attribute>
|
||||
, traits::not_is_variant<Attribute>
|
||||
, traits::not_is_optional<Attribute>
|
||||
>::type is_not_wrapped_container;
|
||||
|
||||
detail::assign_to(val, attr, is_not_wrapped_container());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
assign_to(T const&, unused_type)
|
||||
{
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,176 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
// Copyright (c) 2001-2011 Joel de Guzman
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM)
|
||||
#define SPIRIT_QI_DETAIL_ATTRIBUTES_APR_18_2010_0458PM
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/support/attributes_fwd.hpp>
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
#include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct default_transform_attribute
|
||||
{
|
||||
typedef Transformed type;
|
||||
|
||||
static Transformed pre(Exposed&) { return Transformed(); }
|
||||
|
||||
static void post(Exposed& val, Transformed const& attr)
|
||||
{
|
||||
traits::assign_to(attr, val);
|
||||
}
|
||||
|
||||
// fail() will be called by Qi rule's if the rhs failed parsing
|
||||
static void fail(Exposed&) {}
|
||||
};
|
||||
|
||||
// handle case where no transformation is required as the types are the same
|
||||
template <typename Attribute>
|
||||
struct default_transform_attribute<Attribute, Attribute>
|
||||
{
|
||||
typedef Attribute& type;
|
||||
static Attribute& pre(Attribute& val) { return val; }
|
||||
static void post(Attribute&, Attribute const&) {}
|
||||
static void fail(Attribute&) {}
|
||||
};
|
||||
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct proxy_transform_attribute
|
||||
{
|
||||
typedef Transformed type;
|
||||
|
||||
static Transformed pre(Exposed& val) { return Transformed(val); }
|
||||
static void post(Exposed&, Transformed const&) { /* no-op */ }
|
||||
|
||||
// fail() will be called by Qi rule's if the rhs failed parsing
|
||||
static void fail(Exposed&) {}
|
||||
};
|
||||
|
||||
// handle case where no transformation is required as the types are the same
|
||||
template <typename Attribute>
|
||||
struct proxy_transform_attribute<Attribute, Attribute>
|
||||
{
|
||||
typedef Attribute& type;
|
||||
static Attribute& pre(Attribute& val) { return val; }
|
||||
static void post(Attribute&, Attribute const&) {}
|
||||
static void fail(Attribute&) {}
|
||||
};
|
||||
|
||||
// main specialization for Qi
|
||||
template <typename Exposed, typename Transformed, typename Enable = void>
|
||||
struct transform_attribute
|
||||
: mpl::if_<
|
||||
mpl::and_<
|
||||
mpl::not_<is_const<Exposed> >
|
||||
, mpl::not_<is_reference<Exposed> >
|
||||
, traits::is_proxy<Transformed> >
|
||||
, proxy_transform_attribute<Exposed, Transformed>
|
||||
, default_transform_attribute<Exposed, Transformed>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct transform_attribute<boost::optional<Exposed>, Transformed
|
||||
, typename disable_if<is_same<boost::optional<Exposed>, Transformed> >::type>
|
||||
{
|
||||
typedef Transformed& type;
|
||||
static Transformed& pre(boost::optional<Exposed>& val)
|
||||
{
|
||||
if (!val)
|
||||
val = Transformed();
|
||||
return boost::get<Transformed>(val);
|
||||
}
|
||||
static void post(boost::optional<Exposed>&, Transformed const&) {}
|
||||
static void fail(boost::optional<Exposed>& val)
|
||||
{
|
||||
val = none; // leave optional uninitialized if rhs failed
|
||||
}
|
||||
};
|
||||
|
||||
// reference types need special handling
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute&, Attribute>
|
||||
{
|
||||
typedef Attribute& type;
|
||||
static Attribute& pre(Attribute& val) { return val; }
|
||||
static void post(Attribute&, Attribute const&) {}
|
||||
static void fail(Attribute&) {}
|
||||
};
|
||||
|
||||
// unused_type needs some special handling as well
|
||||
template <>
|
||||
struct transform_attribute<unused_type, unused_type>
|
||||
{
|
||||
typedef unused_type type;
|
||||
static unused_type pre(unused_type) { return unused; }
|
||||
static void post(unused_type, unused_type) {}
|
||||
static void fail(unused_type) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct transform_attribute<unused_type const, unused_type>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<unused_type, Attribute>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<unused_type const, Attribute>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute, unused_type>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute const, unused_type>
|
||||
: transform_attribute<unused_type, unused_type>
|
||||
{};
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct transform_attribute<Exposed, Transformed, qi::domain>
|
||||
: qi::transform_attribute<Exposed, Transformed>
|
||||
{};
|
||||
|
||||
template <typename Exposed, typename Transformed>
|
||||
struct transform_attribute<Exposed&, Transformed, qi::domain>
|
||||
: transform_attribute<Exposed, Transformed, qi::domain>
|
||||
{};
|
||||
|
||||
template <typename Attribute>
|
||||
struct transform_attribute<Attribute&, Attribute, qi::domain>
|
||||
: qi::transform_attribute<Attribute&, Attribute>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Exposed, typename Transformed>
|
||||
void post_transform(Exposed& dest, Transformed const& attr)
|
||||
{
|
||||
return transform_attribute<Exposed, Transformed, qi::domain>::post(dest, attr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Exposed, typename Transformed>
|
||||
void fail_transform(Exposed& dest, Transformed const&)
|
||||
{
|
||||
return transform_attribute<Exposed, Transformed, qi::domain>::fail(dest);
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,202 @@
|
||||
/*=============================================================================
|
||||
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_CONSTRUCT_MAR_24_2007_0629PM)
|
||||
#define BOOST_SPIRIT_CONSTRUCT_MAR_24_2007_0629PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/spirit/home/qi/parse.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/attributes_fwd.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// We provide overloads for the assign_to_attribute_from_iterators
|
||||
// customization point for all built in types
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<char, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const&, char& attr)
|
||||
{
|
||||
attr = *first;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<signed char, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const&, signed char& attr)
|
||||
{
|
||||
attr = *first;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<unsigned char, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const&, unsigned char& attr)
|
||||
{
|
||||
attr = *first;
|
||||
}
|
||||
};
|
||||
|
||||
// wchar_t is intrinsic
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<wchar_t, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const&, wchar_t& attr)
|
||||
{
|
||||
attr = *first;
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
||||
// wchar_t is intrinsic, have separate overload for unsigned short
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<unsigned short, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const&, unsigned short& attr)
|
||||
{
|
||||
attr = *first;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<bool, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, bool& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, bool_type(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<short, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, short& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, short_type(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<int, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, int& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, int_type(), attr);
|
||||
}
|
||||
};
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<unsigned int, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, unsigned int& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, uint_type(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<long, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, long& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, long_type(), attr);
|
||||
}
|
||||
};
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<unsigned long, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, unsigned long& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, ulong_type(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<long_long_type, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, long_long_type& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, long_long_type(), attr);
|
||||
}
|
||||
};
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<ulong_long_type, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, ulong_long_type& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, ulong_long_type(), attr);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<float, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, float& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, float_type(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<double, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, double& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, double_type(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator>
|
||||
struct assign_to_attribute_from_iterators<long double, Iterator>
|
||||
{
|
||||
static void
|
||||
call(Iterator const& first, Iterator const& last, long double& attr)
|
||||
{
|
||||
Iterator first_ = first;
|
||||
qi::parse(first_, last, long_double_type(), attr);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_QI_DETAIL_ENABLE_LIT_JAN_06_2011_0945PM)
|
||||
#define BOOST_SPIRIT_QI_DETAIL_ENABLE_LIT_JAN_06_2011_0945PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/spirit/home/support/string_traits.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
// enables lazy lit(...) for qi
|
||||
template <>
|
||||
struct use_lazy_terminal<qi::domain, tag::lit, 1>
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*=============================================================================
|
||||
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_EXPECT_FUNCTION_APR_29_2007_0558PM)
|
||||
#define SPIRIT_EXPECT_FUNCTION_APR_29_2007_0558PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/multi_pass_wrapper.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <
|
||||
typename Iterator, typename Context
|
||||
, typename Skipper, typename Exception>
|
||||
struct expect_function
|
||||
{
|
||||
typedef Iterator iterator_type;
|
||||
typedef Context context_type;
|
||||
|
||||
expect_function(
|
||||
Iterator& first_, Iterator const& last_
|
||||
, Context& context_, Skipper const& skipper_)
|
||||
: first(first_)
|
||||
, last(last_)
|
||||
, context(context_)
|
||||
, skipper(skipper_)
|
||||
, is_first(true)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Component, typename Attribute>
|
||||
bool operator()(Component const& component, Attribute& attr) const
|
||||
{
|
||||
// if this is not the first component in the expect chain we
|
||||
// need to flush any multi_pass iterator we might be acting on
|
||||
if (!is_first)
|
||||
spirit::traits::clear_queue(first);
|
||||
|
||||
// if we are testing the first component in the sequence,
|
||||
// return true if the parser fails, if this is not the first
|
||||
// component, throw exception if the parser fails
|
||||
if (!component.parse(first, last, context, skipper, attr))
|
||||
{
|
||||
if (is_first)
|
||||
{
|
||||
is_first = false;
|
||||
return true; // true means the match failed
|
||||
}
|
||||
boost::throw_exception(Exception(first, last, component.what(context)));
|
||||
#if defined(BOOST_NO_EXCEPTIONS)
|
||||
return true; // for systems not supporting exceptions
|
||||
#endif
|
||||
}
|
||||
is_first = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component) const
|
||||
{
|
||||
// if this is not the first component in the expect chain we
|
||||
// need to flush any multi_pass iterator we might be acting on
|
||||
if (!is_first)
|
||||
spirit::traits::clear_queue(first);
|
||||
|
||||
// if we are testing the first component in the sequence,
|
||||
// return true if the parser fails, if this not the first
|
||||
// component, throw exception if the parser fails
|
||||
if (!component.parse(first, last, context, skipper, unused))
|
||||
{
|
||||
if (is_first)
|
||||
{
|
||||
is_first = false;
|
||||
return true;
|
||||
}
|
||||
boost::throw_exception(Exception(first, last, component.what(context)));
|
||||
#if defined(BOOST_NO_EXCEPTIONS)
|
||||
return false; // for systems not supporting exceptions
|
||||
#endif
|
||||
}
|
||||
is_first = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator& first;
|
||||
Iterator const& last;
|
||||
Context& context;
|
||||
Skipper const& skipper;
|
||||
mutable bool is_first;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
expect_function& operator= (expect_function const&);
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/*=============================================================================
|
||||
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_FAIL_FUNCTION_APRIL_22_2006_0159PM)
|
||||
#define SPIRIT_FAIL_FUNCTION_APRIL_22_2006_0159PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
struct fail_function
|
||||
{
|
||||
typedef Iterator iterator_type;
|
||||
typedef Context context_type;
|
||||
|
||||
fail_function(
|
||||
Iterator& first_, Iterator const& last_
|
||||
, Context& context_, Skipper const& skipper_)
|
||||
: first(first_)
|
||||
, last(last_)
|
||||
, context(context_)
|
||||
, skipper(skipper_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Component, typename Attribute>
|
||||
bool operator()(Component const& component, Attribute& attr) const
|
||||
{
|
||||
// return true if the parser fails
|
||||
return !component.parse(first, last, context, skipper, attr);
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component) const
|
||||
{
|
||||
// return true if the parser fails
|
||||
return !component.parse(first, last, context, skipper, unused);
|
||||
}
|
||||
|
||||
Iterator& first;
|
||||
Iterator const& last;
|
||||
Context& context;
|
||||
Skipper const& skipper;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
fail_function& operator= (fail_function const&);
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,97 @@
|
||||
/*=============================================================================
|
||||
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_DETAIL_PARSE_DEC_02_2009_0411PM)
|
||||
#define BOOST_SPIRIT_DETAIL_PARSE_DEC_02_2009_0411PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_flag.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Enable = void>
|
||||
struct parse_impl
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
// Did you intend to use the auto_ facilities while forgetting to
|
||||
// #include <boost/spirit/include/qi_auto.hpp>?
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct parse_impl<Expr
|
||||
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
|
||||
{
|
||||
template <typename Iterator>
|
||||
static bool call(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr)
|
||||
{
|
||||
return compile<qi::domain>(expr).parse(
|
||||
first, last, unused, unused, unused);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Enable = void>
|
||||
struct phrase_parse_impl
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
// Did you intend to use the auto_ facilities while forgetting to
|
||||
// #include <boost/spirit/include/qi_auto.hpp>?
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct phrase_parse_impl<Expr
|
||||
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
|
||||
{
|
||||
template <typename Iterator, typename Skipper>
|
||||
static bool call(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the skipper is not a valid spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
|
||||
typedef
|
||||
typename result_of::compile<qi::domain, Skipper>::type
|
||||
skipper_type;
|
||||
skipper_type const skipper_ = compile<qi::domain>(skipper);
|
||||
|
||||
if (!compile<qi::domain>(expr).parse(
|
||||
first, last, unused, skipper_, unused))
|
||||
return false;
|
||||
|
||||
if (post_skip == skip_flag::postskip)
|
||||
qi::skip_over(first, last, skipper_);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/*=============================================================================
|
||||
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_DETAIL_PARSE_AUTO_DEC_02_2009_0426PM)
|
||||
#define BOOST_SPIRIT_DETAIL_PARSE_AUTO_DEC_02_2009_0426PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/parse.hpp>
|
||||
#include <boost/spirit/home/qi/auto/create_parser.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
struct parse_impl<Expr
|
||||
, typename enable_if<
|
||||
mpl::and_<
|
||||
traits::meta_create_exists<qi::domain, Expr>
|
||||
, mpl::not_<traits::matches<qi::domain, Expr> > >
|
||||
>::type>
|
||||
{
|
||||
template <typename Iterator>
|
||||
static bool call(Iterator& first, Iterator last, Expr& expr)
|
||||
{
|
||||
return qi::parse(first, last, create_parser<Expr>(), expr);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool call(Iterator& first, Iterator last, Expr const& expr)
|
||||
{
|
||||
return qi::parse(first, last, create_parser<Expr>()
|
||||
, const_cast<Expr&>(expr));
|
||||
}
|
||||
};
|
||||
|
||||
// the following specializations are needed to explicitly disambiguate
|
||||
// the two possible specializations for parse_impl<char> and
|
||||
// parse_impl<wchar_t>
|
||||
template <>
|
||||
struct parse_impl<char>
|
||||
{
|
||||
template <typename Iterator>
|
||||
static bool call(Iterator& first, Iterator last, char& expr)
|
||||
{
|
||||
return qi::parse(first, last, create_parser<char>(), expr);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool call(Iterator& first, Iterator last, char const&)
|
||||
{
|
||||
return qi::parse(first, last, create_parser<char>());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct parse_impl<wchar_t>
|
||||
{
|
||||
template <typename Iterator>
|
||||
static bool call(Iterator& first, Iterator last, wchar_t& expr)
|
||||
{
|
||||
return qi::parse(first, last, create_parser<wchar_t>(), expr);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool call(Iterator& first, Iterator last, wchar_t const&)
|
||||
{
|
||||
return qi::parse(first, last, create_parser<wchar_t>());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
struct phrase_parse_impl<Expr
|
||||
, typename enable_if<
|
||||
mpl::and_<
|
||||
traits::meta_create_exists<qi::domain, Expr>
|
||||
, mpl::not_<traits::matches<qi::domain, Expr> > >
|
||||
>::type>
|
||||
{
|
||||
template <typename Iterator, typename Skipper>
|
||||
static bool call(Iterator& first, Iterator last, Expr& expr
|
||||
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
return qi::phrase_parse(first, last, create_parser<Expr>()
|
||||
, skipper, post_skip, expr);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Skipper>
|
||||
static bool call(Iterator& first, Iterator last, Expr const& expr
|
||||
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
return qi::phrase_parse(first, last, create_parser<Expr>()
|
||||
, skipper, post_skip, const_cast<Expr&>(expr));
|
||||
}
|
||||
};
|
||||
|
||||
// the following specializations are needed to explicitly disambiguate
|
||||
// the two possible specializations for phrase_parse_impl<char> and
|
||||
// phrase_parse_impl<wchar_t>
|
||||
template <>
|
||||
struct phrase_parse_impl<char>
|
||||
{
|
||||
template <typename Iterator, typename Skipper>
|
||||
static bool call(Iterator& first, Iterator last, char& expr
|
||||
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
return qi::phrase_parse(first, last, create_parser<char>()
|
||||
, skipper, post_skip, expr);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Skipper>
|
||||
static bool call(Iterator& first, Iterator last, char const&
|
||||
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
return qi::phrase_parse(first, last, create_parser<char>()
|
||||
, skipper, post_skip);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct phrase_parse_impl<wchar_t>
|
||||
{
|
||||
template <typename Iterator, typename Skipper>
|
||||
static bool call(Iterator& first, Iterator last, wchar_t& expr
|
||||
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
return qi::phrase_parse(first, last, create_parser<wchar_t>()
|
||||
, skipper, post_skip, expr);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Skipper>
|
||||
static bool call(Iterator& first, Iterator last, wchar_t const&
|
||||
, Skipper const& skipper, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
return qi::phrase_parse(first, last, create_parser<wchar_t>()
|
||||
, skipper, post_skip);
|
||||
}
|
||||
};
|
||||
}}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr>
|
||||
inline bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr& expr)
|
||||
{
|
||||
// Make sure the iterator is at least a forward_iterator. If you got a
|
||||
// compilation error here, then you are using an input_iterator while
|
||||
// calling this function, you need to supply at least a
|
||||
// forward_iterator instead.
|
||||
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
|
||||
|
||||
return detail::parse_impl<Expr>::call(first, last, expr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr, typename Skipper>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
|
||||
{
|
||||
// Make sure the iterator is at least a forward_iterator. If you got a
|
||||
// compilation error here, then you are using an input_iterator while
|
||||
// calling this function, you need to supply at least a
|
||||
// forward_iterator instead.
|
||||
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
|
||||
|
||||
return detail::phrase_parse_impl<Expr>::call(
|
||||
first, last, expr, skipper, post_skip);
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_PASS_CONTAINER_JANUARY_06_2009_0802PM)
|
||||
#define SPIRIT_PASS_CONTAINER_JANUARY_06_2009_0802PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
// Helper meta-function allowing to evaluate weak substitutability and
|
||||
// negate the result if the predicate (Sequence) is not true
|
||||
template <typename Sequence, typename Attribute, typename ValueType>
|
||||
struct negate_weak_substitute_if_not
|
||||
: mpl::if_<
|
||||
Sequence
|
||||
, typename traits::is_weak_substitute<Attribute, ValueType>::type
|
||||
, typename mpl::not_<
|
||||
traits::is_weak_substitute<Attribute, ValueType>
|
||||
>::type>
|
||||
{};
|
||||
|
||||
// pass_through_container: utility to check decide whether a provided
|
||||
// container attribute needs to be passed through to the current component
|
||||
// or of we need to split the container by passing along instances of its
|
||||
// value type
|
||||
|
||||
// if the expected attribute of the current component is neither a Fusion
|
||||
// sequence nor a container, we will pass through the provided container
|
||||
// only if its value type is not compatible with the component
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence, typename Enable = void>
|
||||
struct pass_through_container_base
|
||||
: negate_weak_substitute_if_not<Sequence, Attribute, ValueType>
|
||||
{};
|
||||
|
||||
// Specialization for fusion sequences, in this case we check whether all
|
||||
// the types in the sequence are convertible to the lhs attribute.
|
||||
//
|
||||
// We return false if the rhs attribute itself is a fusion sequence, which
|
||||
// is compatible with the LHS sequence (we want to pass through this
|
||||
// attribute without it being split apart).
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence = mpl::true_>
|
||||
struct not_compatible_element
|
||||
: mpl::and_<
|
||||
negate_weak_substitute_if_not<Sequence, Attribute, Container>
|
||||
, negate_weak_substitute_if_not<Sequence, Attribute, ValueType> >
|
||||
{};
|
||||
|
||||
// If the value type of the container is not a Fusion sequence, we pass
|
||||
// through the container if each of the elements of the Attribute
|
||||
// sequence is compatible with either the container or its value type.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence
|
||||
, bool IsSequence = fusion::traits::is_sequence<ValueType>::value>
|
||||
struct pass_through_container_fusion_sequence
|
||||
{
|
||||
typedef typename mpl::find_if<
|
||||
Attribute, not_compatible_element<Container, ValueType, mpl::_1>
|
||||
>::type iter;
|
||||
typedef typename mpl::end<Attribute>::type end;
|
||||
|
||||
typedef typename is_same<iter, end>::type type;
|
||||
};
|
||||
|
||||
// If both, the Attribute and the value type of the provided container
|
||||
// are Fusion sequences, we pass the container only if the two
|
||||
// sequences are not compatible.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container_fusion_sequence<
|
||||
Container, ValueType, Attribute, Sequence, true>
|
||||
{
|
||||
typedef typename mpl::find_if<
|
||||
Attribute
|
||||
, not_compatible_element<Container, ValueType, mpl::_1, Sequence>
|
||||
>::type iter;
|
||||
typedef typename mpl::end<Attribute>::type end;
|
||||
|
||||
typedef typename is_same<iter, end>::type type;
|
||||
};
|
||||
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container_base<Container, ValueType, Attribute
|
||||
, Sequence
|
||||
, typename enable_if<fusion::traits::is_sequence<Attribute> >::type>
|
||||
: pass_through_container_fusion_sequence<
|
||||
Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
|
||||
// Specialization for containers
|
||||
//
|
||||
// If the value type of the attribute of the current component is not
|
||||
// a Fusion sequence, we have to pass through the provided container if
|
||||
// both are compatible.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence, typename AttributeValueType
|
||||
, bool IsSequence = fusion::traits::is_sequence<AttributeValueType>::value>
|
||||
struct pass_through_container_container
|
||||
: mpl::or_<
|
||||
traits::is_weak_substitute<Attribute, Container>
|
||||
, traits::is_weak_substitute<AttributeValueType, Container> >
|
||||
{};
|
||||
|
||||
// If the value type of the exposed container attribute is a Fusion
|
||||
// sequence, we use the already existing logic for those.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence, typename AttributeValueType>
|
||||
struct pass_through_container_container<
|
||||
Container, ValueType, Attribute, Sequence, AttributeValueType, true>
|
||||
: pass_through_container_fusion_sequence<
|
||||
Container, ValueType, AttributeValueType, Sequence>
|
||||
{};
|
||||
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container_base<
|
||||
Container, ValueType, Attribute, Sequence
|
||||
, typename enable_if<traits::is_container<Attribute> >::type>
|
||||
: detail::pass_through_container_container<
|
||||
Container, ValueType, Attribute, Sequence
|
||||
, typename traits::container_value<Attribute>::type>
|
||||
{};
|
||||
|
||||
// Specialization for exposed optional attributes
|
||||
//
|
||||
// If the type embedded in the exposed optional is not a Fusion
|
||||
// sequence we pass through the container attribute if it is compatible
|
||||
// either to the optionals embedded type or to the containers value
|
||||
// type.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence
|
||||
, bool IsSequence = fusion::traits::is_sequence<Attribute>::value>
|
||||
struct pass_through_container_optional
|
||||
: mpl::or_<
|
||||
traits::is_weak_substitute<Attribute, Container>
|
||||
, traits::is_weak_substitute<Attribute, ValueType> >
|
||||
{};
|
||||
|
||||
// If the embedded type of the exposed optional attribute is a Fusion
|
||||
// sequence, we use the already existing logic for those.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container_optional<
|
||||
Container, ValueType, Attribute, Sequence, true>
|
||||
: pass_through_container_fusion_sequence<
|
||||
Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container
|
||||
: pass_through_container_base<Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
|
||||
// Handle optional attributes
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container<
|
||||
Container, ValueType, boost::optional<Attribute>, Sequence>
|
||||
: pass_through_container_optional<
|
||||
Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
|
||||
// If both, the containers value type and the exposed attribute type are
|
||||
// optionals we are allowed to pass through the container only if the
|
||||
// embedded types of those optionals are not compatible.
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container<
|
||||
Container, boost::optional<ValueType>, boost::optional<Attribute>
|
||||
, Sequence>
|
||||
: mpl::not_<traits::is_weak_substitute<Attribute, ValueType> >
|
||||
{};
|
||||
|
||||
// Specialization for exposed variant attributes
|
||||
//
|
||||
// We pass through the container attribute if at least one of the embedded
|
||||
// types in the variant requires to pass through the attribute
|
||||
|
||||
#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
|
||||
template <typename Container, typename ValueType, typename Sequence
|
||||
, typename T>
|
||||
struct pass_through_container<Container, ValueType, boost::variant<T>
|
||||
, Sequence>
|
||||
: pass_through_container<Container, ValueType, T, Sequence>
|
||||
{};
|
||||
|
||||
template <typename Container, typename ValueType, typename Sequence
|
||||
, typename T0, typename ...TN>
|
||||
struct pass_through_container<Container, ValueType
|
||||
, boost::variant<T0, TN...>, Sequence>
|
||||
: mpl::bool_<pass_through_container<
|
||||
Container, ValueType, T0, Sequence
|
||||
>::type::value || pass_through_container<
|
||||
Container, ValueType, boost::variant<TN...>, Sequence
|
||||
>::type::value>
|
||||
{};
|
||||
#else
|
||||
#define BOOST_SPIRIT_PASS_THROUGH_CONTAINER(z, N, _) \
|
||||
pass_through_container<Container, ValueType, \
|
||||
BOOST_PP_CAT(T, N), Sequence>::type::value || \
|
||||
/***/
|
||||
|
||||
// make sure unused variant parameters do not affect the outcome
|
||||
template <typename Container, typename ValueType, typename Sequence>
|
||||
struct pass_through_container<Container, ValueType
|
||||
, boost::detail::variant::void_, Sequence>
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template <typename Container, typename ValueType, typename Sequence
|
||||
, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct pass_through_container<Container, ValueType
|
||||
, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Sequence>
|
||||
: mpl::bool_<BOOST_PP_REPEAT(BOOST_VARIANT_LIMIT_TYPES
|
||||
, BOOST_SPIRIT_PASS_THROUGH_CONTAINER, _) false>
|
||||
{};
|
||||
|
||||
#undef BOOST_SPIRIT_PASS_THROUGH_CONTAINER
|
||||
#endif
|
||||
}}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// forwarding customization point for domain qi::domain
|
||||
template <typename Container, typename ValueType, typename Attribute
|
||||
, typename Sequence>
|
||||
struct pass_through_container<
|
||||
Container, ValueType, Attribute, Sequence, qi::domain>
|
||||
: qi::detail::pass_through_container<
|
||||
Container, ValueType, Attribute, Sequence>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This function handles the case where the attribute (Attr) given
|
||||
// the sequence is an STL container. This is a wrapper around F.
|
||||
// The function F does the actual parsing.
|
||||
template <typename F, typename Attr, typename Sequence>
|
||||
struct pass_container
|
||||
{
|
||||
typedef typename F::context_type context_type;
|
||||
typedef typename F::iterator_type iterator_type;
|
||||
|
||||
pass_container(F const& f_, Attr& attr_)
|
||||
: f(f_), attr(attr_) {}
|
||||
|
||||
// this is for the case when the current element exposes an attribute
|
||||
// which is pushed back onto the container
|
||||
template <typename Component>
|
||||
bool dispatch_container(Component const& component, mpl::false_) const
|
||||
{
|
||||
// synthesized attribute needs to be default constructed
|
||||
typename traits::container_value<Attr>::type val =
|
||||
typename traits::container_value<Attr>::type();
|
||||
|
||||
iterator_type save = f.first;
|
||||
bool r = f(component, val);
|
||||
if (!r)
|
||||
{
|
||||
// push the parsed value into our attribute
|
||||
r = !traits::push_back(attr, val);
|
||||
if (r)
|
||||
f.first = save;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// this is for the case when the current element is able to handle an
|
||||
// attribute which is a container itself, this element will push its
|
||||
// data directly into the attribute container
|
||||
template <typename Component>
|
||||
bool dispatch_container(Component const& component, mpl::true_) const
|
||||
{
|
||||
return f(component, attr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// this is for the case when the current element doesn't expect an
|
||||
// attribute
|
||||
template <typename Component>
|
||||
bool dispatch_attribute(Component const& component, mpl::false_) const
|
||||
{
|
||||
return f(component, unused);
|
||||
}
|
||||
|
||||
// the current element expects an attribute
|
||||
template <typename Component>
|
||||
bool dispatch_attribute(Component const& component, mpl::true_) const
|
||||
{
|
||||
typedef typename traits::container_value<Attr>::type value_type;
|
||||
typedef typename traits::attribute_of<
|
||||
Component, context_type, iterator_type>::type
|
||||
rhs_attribute;
|
||||
|
||||
// this predicate detects, whether the attribute of the current
|
||||
// element is a substitute for the value type of the container
|
||||
// attribute
|
||||
typedef mpl::and_<
|
||||
traits::handles_container<
|
||||
Component, Attr, context_type, iterator_type>
|
||||
, traits::pass_through_container<
|
||||
Attr, value_type, rhs_attribute, Sequence, qi::domain>
|
||||
> predicate;
|
||||
|
||||
return dispatch_container(component, predicate());
|
||||
}
|
||||
|
||||
// Dispatches to dispatch_main depending on the attribute type
|
||||
// of the Component
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component) const
|
||||
{
|
||||
// we need to dispatch depending on the type of the attribute
|
||||
// of the current element (component). If this is has no attribute
|
||||
// we shouldn't pass an attribute at all.
|
||||
typedef typename traits::not_is_unused<
|
||||
typename traits::attribute_of<
|
||||
Component, context_type, iterator_type
|
||||
>::type
|
||||
>::type predicate;
|
||||
|
||||
// ensure the attribute is actually a container type
|
||||
traits::make_container(attr);
|
||||
|
||||
return dispatch_attribute(component, predicate());
|
||||
}
|
||||
|
||||
F f;
|
||||
Attr& attr;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
pass_container& operator= (pass_container const&);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Utility function to make a pass_container for container components
|
||||
// (kleene, list, plus, repeat)
|
||||
template <typename F, typename Attr>
|
||||
inline pass_container<F, Attr, mpl::false_>
|
||||
make_pass_container(F const& f, Attr& attr)
|
||||
{
|
||||
return pass_container<F, Attr, mpl::false_>(f, attr);
|
||||
}
|
||||
|
||||
// Utility function to make a pass_container for sequences
|
||||
template <typename F, typename Attr>
|
||||
inline pass_container<F, Attr, mpl::true_>
|
||||
make_sequence_pass_container(F const& f, Attr& attr)
|
||||
{
|
||||
return pass_container<F, Attr, mpl::true_>(f, attr);
|
||||
}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*=============================================================================
|
||||
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_PASS_FUNCTION_FEBRUARY_05_2007_1138AM)
|
||||
#define SPIRIT_PASS_FUNCTION_FEBRUARY_05_2007_1138AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
struct pass_function
|
||||
{
|
||||
pass_function(
|
||||
Iterator& first_, Iterator const& last_
|
||||
, Context& context_, Skipper const& skipper_)
|
||||
: first(first_)
|
||||
, last(last_)
|
||||
, context(context_)
|
||||
, skipper(skipper_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Component, typename Attribute>
|
||||
bool operator()(Component const& component, Attribute& attr)
|
||||
{
|
||||
// return true if the parser succeeds
|
||||
return component.parse(first, last, context, skipper, attr);
|
||||
}
|
||||
|
||||
template <typename Component, typename Attribute>
|
||||
bool operator()(Component const& component, boost::optional<Attribute>& attr)
|
||||
{
|
||||
// return true if the parser succeeds
|
||||
Attribute val;
|
||||
if (component.parse(first, last, context, skipper, val))
|
||||
{
|
||||
attr = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component)
|
||||
{
|
||||
// return true if the parser succeeds
|
||||
return component.parse(first, last, context, skipper, unused);
|
||||
}
|
||||
|
||||
Iterator& first;
|
||||
Iterator const& last;
|
||||
Context& context;
|
||||
Skipper const& skipper;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
pass_function& operator= (pass_function const&);
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
/*=============================================================================
|
||||
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_PERMUTE_FUNCTION_MARCH_13_2007_1129AM)
|
||||
#define SPIRIT_PERMUTE_FUNCTION_MARCH_13_2007_1129AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
struct permute_function
|
||||
{
|
||||
permute_function(
|
||||
Iterator& first_, Iterator const& last_
|
||||
, Context& context_, Skipper const& skipper_)
|
||||
: first(first_)
|
||||
, last(last_)
|
||||
, context(context_)
|
||||
, skipper(skipper_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Component, typename Attribute>
|
||||
bool operator()(Component const& component, Attribute& attr)
|
||||
{
|
||||
// return true if the parser succeeds and the slot is not yet taken
|
||||
if (!*taken && component.parse(first, last, context, skipper, attr))
|
||||
{
|
||||
*taken = true;
|
||||
++taken;
|
||||
return true;
|
||||
}
|
||||
++taken;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Component, typename Attribute>
|
||||
bool operator()(Component const& component, boost::optional<Attribute>& attr)
|
||||
{
|
||||
// return true if the parser succeeds and the slot is not yet taken
|
||||
Attribute val;
|
||||
if (!*taken && component.parse(first, last, context, skipper, val))
|
||||
{
|
||||
attr = val;
|
||||
*taken = true;
|
||||
++taken;
|
||||
return true;
|
||||
}
|
||||
++taken;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Component>
|
||||
bool operator()(Component const& component)
|
||||
{
|
||||
// return true if the parser succeeds and the slot is not yet taken
|
||||
if (!*taken && component.parse(first, last, context, skipper, unused))
|
||||
{
|
||||
*taken = true;
|
||||
++taken;
|
||||
return true;
|
||||
}
|
||||
++taken;
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator& first;
|
||||
Iterator const& last;
|
||||
Context& context;
|
||||
Skipper const& skipper;
|
||||
bool* taken;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
permute_function& operator= (permute_function const&);
|
||||
};
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
/*=============================================================================
|
||||
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_STRING_PARSE_APR_18_2006_1125PM)
|
||||
#define BOOST_SPIRIT_STRING_PARSE_APR_18_2006_1125PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename Char, typename Iterator, typename Attribute>
|
||||
inline bool string_parse(
|
||||
Char const* str
|
||||
, Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
Iterator i = first;
|
||||
Char ch = *str;
|
||||
|
||||
for (; !!ch; ++i)
|
||||
{
|
||||
if (i == last || (ch != *i))
|
||||
return false;
|
||||
ch = *++str;
|
||||
}
|
||||
|
||||
spirit::traits::assign_to(first, i, attr);
|
||||
first = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename String, typename Iterator, typename Attribute>
|
||||
inline bool string_parse(
|
||||
String const& str
|
||||
, Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
Iterator i = first;
|
||||
typename String::const_iterator stri = str.begin();
|
||||
typename String::const_iterator str_last = str.end();
|
||||
|
||||
for (; stri != str_last; ++stri, ++i)
|
||||
if (i == last || (*stri != *i))
|
||||
return false;
|
||||
spirit::traits::assign_to(first, i, attr);
|
||||
first = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char, typename Iterator, typename Attribute>
|
||||
inline bool string_parse(
|
||||
Char const* uc_i, Char const* lc_i
|
||||
, Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
Iterator i = first;
|
||||
|
||||
for (; *uc_i && *lc_i; ++uc_i, ++lc_i, ++i)
|
||||
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
|
||||
return false;
|
||||
spirit::traits::assign_to(first, i, attr);
|
||||
first = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename String, typename Iterator, typename Attribute>
|
||||
inline bool string_parse(
|
||||
String const& ucstr, String const& lcstr
|
||||
, Iterator& first, Iterator const& last, Attribute& attr)
|
||||
{
|
||||
typename String::const_iterator uc_i = ucstr.begin();
|
||||
typename String::const_iterator uc_last = ucstr.end();
|
||||
typename String::const_iterator lc_i = lcstr.begin();
|
||||
Iterator i = first;
|
||||
|
||||
for (; uc_i != uc_last; ++uc_i, ++lc_i, ++i)
|
||||
if (i == last || ((*uc_i != *i) && (*lc_i != *i)))
|
||||
return false;
|
||||
spirit::traits::assign_to(first, i, attr);
|
||||
first = i;
|
||||
return true;
|
||||
}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_QI_UNUSED_SKIPPER_JUL_25_2009_0921AM)
|
||||
#define BOOST_SPIRIT_QI_UNUSED_SKIPPER_JUL_25_2009_0921AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename Skipper>
|
||||
struct unused_skipper : unused_type
|
||||
{
|
||||
unused_skipper(Skipper const& skipper_)
|
||||
: skipper(skipper_) {}
|
||||
Skipper const& skipper;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
unused_skipper& operator= (unused_skipper const&);
|
||||
};
|
||||
|
||||
template <typename Skipper>
|
||||
struct is_unused_skipper
|
||||
: mpl::false_ {};
|
||||
|
||||
template <typename Skipper>
|
||||
struct is_unused_skipper<unused_skipper<Skipper> >
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct is_unused_skipper<unused_type>
|
||||
: mpl::true_ {};
|
||||
|
||||
// If a surrounding lexeme[] directive was specified, the current
|
||||
// skipper is of the type unused_skipper. In this case we
|
||||
// re-activate the skipper which was active before the skip[]
|
||||
// directive.
|
||||
template <typename Skipper>
|
||||
inline Skipper const&
|
||||
get_skipper(unused_skipper<Skipper> const& u)
|
||||
{
|
||||
return u.skipper;
|
||||
}
|
||||
|
||||
// If no surrounding lexeme[] directive was specified we keep what we got.
|
||||
template <typename Skipper>
|
||||
inline Skipper const&
|
||||
get_skipper(Skipper const& u)
|
||||
{
|
||||
return u;
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
/*=============================================================================
|
||||
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_DIRECTIVE_FEBRUARY_05_2007_0313PM)
|
||||
#define BOOST_SPIRIT_DIRECTIVE_FEBRUARY_05_2007_0313PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/directive/as.hpp>
|
||||
#include <boost/spirit/home/qi/directive/encoding.hpp>
|
||||
#include <boost/spirit/home/qi/directive/hold.hpp>
|
||||
#include <boost/spirit/home/qi/directive/lexeme.hpp>
|
||||
#include <boost/spirit/home/qi/directive/no_skip.hpp>
|
||||
#include <boost/spirit/home/qi/directive/matches.hpp>
|
||||
#include <boost/spirit/home/qi/directive/no_case.hpp>
|
||||
#include <boost/spirit/home/qi/directive/omit.hpp>
|
||||
#include <boost/spirit/home/qi/directive/raw.hpp>
|
||||
#include <boost/spirit/home/qi/directive/repeat.hpp>
|
||||
#include <boost/spirit/home/qi/directive/skip.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,178 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
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(SPIRIT_AS_DECEMBER_6_2010_1013AM)
|
||||
#define SPIRIT_AS_DECEMBER_6_2010_1013AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/assert_msg.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename T>
|
||||
struct as
|
||||
: stateful_tag_type<T, tag::as>
|
||||
{
|
||||
//~ BOOST_SPIRIT_ASSERT_MSG(
|
||||
//~ (traits::is_container<T>::type::value),
|
||||
//~ error_type_must_be_a_container,
|
||||
//~ (T));
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables as_string[...]
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::as_string>
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables as_wstring[...]
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::as_wstring>
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables as<T>[...]
|
||||
template <typename T>
|
||||
struct use_directive<qi::domain, tag::stateful_tag<T, tag::as> >
|
||||
: mpl::true_
|
||||
{};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::as_string;
|
||||
using spirit::as_wstring;
|
||||
#endif
|
||||
using spirit::as_string_type;
|
||||
using spirit::as_wstring_type;
|
||||
|
||||
template <typename Subject, typename T>
|
||||
struct as_directive : unary_parser<as_directive<Subject, T> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
as_directive(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, Attribute& attr_) const
|
||||
{
|
||||
Iterator i = first;
|
||||
T as_attr;
|
||||
if (subject.parse(i, last, context, skipper, as_attr))
|
||||
{
|
||||
spirit::traits::assign_to(as_attr, attr_);
|
||||
first = i;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, T& attr_) const
|
||||
{
|
||||
Iterator i = first;
|
||||
if (subject.parse(i, last, context, skipper, attr_))
|
||||
{
|
||||
first = i;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("as", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::as_string, Subject, Modifiers>
|
||||
{
|
||||
typedef as_directive<Subject, std::string> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject
|
||||
, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::as_wstring, Subject, Modifiers>
|
||||
{
|
||||
typedef as_directive<Subject, std::basic_string<wchar_t> > result_type;
|
||||
result_type operator()(unused_type, Subject const& subject
|
||||
, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::stateful_tag<T, tag::as>, Subject, Modifiers>
|
||||
{
|
||||
typedef as_directive<Subject, T> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject
|
||||
, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename T>
|
||||
struct has_semantic_action<qi::as_directive<Subject, T> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename T, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct handles_container<qi::as_directive<Subject, T>, Attribute
|
||||
, Context, Iterator>
|
||||
: mpl::false_ {};
|
||||
}}}
|
||||
|
||||
#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(SPIRIT_ENCODING_MARCH_05_2010_0528PM)
|
||||
#define SPIRIT_ENCODING_MARCH_05_2010_0528PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharEncoding>
|
||||
struct use_directive<
|
||||
qi::domain, tag::char_code<tag::encoding, CharEncoding> > // enables encoding
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename CharEncoding>
|
||||
struct is_modifier_directive<qi::domain, tag::char_code<tag::encoding, CharEncoding> >
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,109 @@
|
||||
/*=============================================================================
|
||||
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_HOLD_FEBRUARY_6_2010_0917AM)
|
||||
#define SPIRIT_HOLD_FEBRUARY_6_2010_0917AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::hold> // enables hold
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::hold;
|
||||
#endif
|
||||
using spirit::hold_type;
|
||||
|
||||
template <typename Subject>
|
||||
struct hold_directive : unary_parser<hold_directive<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
hold_directive(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
traits::attribute_of<subject_type, Context, Iterator>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, Attribute& attr_) const
|
||||
{
|
||||
Attribute copy(attr_);
|
||||
if (subject.parse(first, last, context, skipper, copy))
|
||||
{
|
||||
traits::swap_impl(copy, attr_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("hold", subject.what(context));
|
||||
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::hold, Subject, Modifiers>
|
||||
{
|
||||
typedef hold_directive<Subject> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::hold_directive<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::hold_directive<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
/*=============================================================================
|
||||
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_LEXEME_MARCH_24_2007_0802AM)
|
||||
#define SPIRIT_LEXEME_MARCH_24_2007_0802AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::lexeme> // enables lexeme
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::lexeme;
|
||||
#endif
|
||||
using spirit::lexeme_type;
|
||||
|
||||
template <typename Subject>
|
||||
struct lexeme_directive : unary_parser<lexeme_directive<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
lexeme_directive(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
traits::attribute_of<subject_type, Context, Iterator>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
typename disable_if<detail::is_unused_skipper<Skipper>, bool>::type
|
||||
parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
return subject.parse(first, last, context
|
||||
, detail::unused_skipper<Skipper>(skipper), attr_);
|
||||
}
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
typename enable_if<detail::is_unused_skipper<Skipper>, bool>::type
|
||||
parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
// no need to pre-skip if skipper is unused
|
||||
//- qi::skip_over(first, last, skipper);
|
||||
return subject.parse(first, last, context
|
||||
, skipper, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("lexeme", subject.what(context));
|
||||
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::lexeme, Subject, Modifiers>
|
||||
{
|
||||
typedef lexeme_directive<Subject> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::lexeme_directive<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::lexeme_directive<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,108 @@
|
||||
/*=============================================================================
|
||||
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_MATCHES_JAN_07_2010_0745PM)
|
||||
#define SPIRIT_MATCHES_JAN_07_2010_0745PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::matches> // enables matches
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::matches;
|
||||
#endif
|
||||
using spirit::matches_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// matches_directive returns whether the embedded parser matched
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct matches_directive : unary_parser<matches_directive<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
matches_directive(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef bool type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, Attribute& attr_) const
|
||||
{
|
||||
bool result = subject.parse(first, last, context, skipper, unused);
|
||||
spirit::traits::assign_to(result, attr_);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("matches", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
matches_directive& operator= (matches_directive const&);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::matches, Subject, Modifiers>
|
||||
{
|
||||
typedef matches_directive<Subject> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::matches_directive<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::matches_directive<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#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(SPIRIT_NO_CASE_OCTOBER_25_2008_0424PM)
|
||||
#define SPIRIT_NO_CASE_OCTOBER_25_2008_0424PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename CharEncoding>
|
||||
struct use_directive<
|
||||
qi::domain, tag::char_code<tag::no_case, CharEncoding> > // enables no_case
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename CharEncoding>
|
||||
struct is_modifier_directive<qi::domain, tag::char_code<tag::no_case, CharEncoding> >
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_NO_SKIP_JAN_16_2010_0802PM)
|
||||
#define SPIRIT_NO_SKIP_JAN_16_2010_0802PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::no_skip> // enables no_skip
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::no_skip;
|
||||
#endif
|
||||
using spirit::no_skip_type;
|
||||
|
||||
// same as lexeme[], but does not pre-skip
|
||||
template <typename Subject>
|
||||
struct no_skip_directive : unary_parser<no_skip_directive<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
no_skip_directive(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
traits::attribute_of<subject_type, Context, Iterator>::type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
typename disable_if<detail::is_unused_skipper<Skipper>, bool>::type
|
||||
parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
return subject.parse(first, last, context
|
||||
, detail::unused_skipper<Skipper>(skipper), attr_);
|
||||
}
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
typename enable_if<detail::is_unused_skipper<Skipper>, bool>::type
|
||||
parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
return subject.parse(first, last, context
|
||||
, skipper, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("no_skip", subject.what(context));
|
||||
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::no_skip, Subject, Modifiers>
|
||||
{
|
||||
typedef no_skip_directive<Subject> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::no_skip_directive<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::no_skip_directive<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,107 @@
|
||||
/*=============================================================================
|
||||
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_OMIT_MARCH_24_2007_0802AM)
|
||||
#define SPIRIT_OMIT_MARCH_24_2007_0802AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::omit> // enables omit
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::omit;
|
||||
#endif
|
||||
using spirit::omit_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// omit_directive forces the attribute of subject parser
|
||||
// to be unused_type
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct omit_directive : unary_parser<omit_directive<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
omit_directive(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, Attribute& attr_) const
|
||||
{
|
||||
return subject.parse(first, last, context, skipper, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("omit", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
omit_directive& operator= (omit_directive const&);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::omit, Subject, Modifiers>
|
||||
{
|
||||
typedef omit_directive<Subject> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::omit_directive<Subject> >
|
||||
: mpl::false_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::omit_directive<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,111 @@
|
||||
/*=============================================================================
|
||||
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_RAW_APRIL_9_2007_0912AM)
|
||||
#define SPIRIT_RAW_APRIL_9_2007_0912AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::raw> // enables raw
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::raw;
|
||||
#endif
|
||||
using spirit::raw_type;
|
||||
|
||||
template <typename Subject>
|
||||
struct raw_directive : unary_parser<raw_directive<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
raw_directive(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef iterator_range<Iterator> type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, Attribute& attr_) const
|
||||
{
|
||||
qi::skip_over(first, last, skipper);
|
||||
Iterator i = first;
|
||||
if (subject.parse(i, last, context, skipper, unused))
|
||||
{
|
||||
spirit::traits::assign_to(first, i, attr_);
|
||||
first = i;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("raw", subject.what(context));
|
||||
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::raw, Subject, Modifiers>
|
||||
{
|
||||
typedef raw_directive<Subject> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::raw_directive<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::raw_directive<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,297 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_REPEAT_NOVEMBER_14_2008_1148AM)
|
||||
#define SPIRIT_REPEAT_NOVEMBER_14_2008_1148AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
|
||||
#include <boost/spirit/home/qi/operator/kleene.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/qi/detail/fail_function.hpp>
|
||||
#include <boost/spirit/home/qi/detail/pass_container.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::repeat> // enables repeat[p]
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename T>
|
||||
struct use_directive<qi::domain
|
||||
, terminal_ex<tag::repeat // enables repeat(exact)[p]
|
||||
, fusion::vector1<T> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename T>
|
||||
struct use_directive<qi::domain
|
||||
, terminal_ex<tag::repeat // enables repeat(min, max)[p]
|
||||
, fusion::vector2<T, T> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename T>
|
||||
struct use_directive<qi::domain
|
||||
, terminal_ex<tag::repeat // enables repeat(min, inf)[p]
|
||||
, fusion::vector2<T, inf_type> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* repeat(exact)[p]
|
||||
struct use_lazy_directive<
|
||||
qi::domain
|
||||
, tag::repeat
|
||||
, 1 // arity
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* repeat(min, max)[p]
|
||||
struct use_lazy_directive< // and repeat(min, inf)[p]
|
||||
qi::domain
|
||||
, tag::repeat
|
||||
, 2 // arity
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::repeat;
|
||||
using spirit::inf;
|
||||
#endif
|
||||
using spirit::repeat_type;
|
||||
using spirit::inf_type;
|
||||
|
||||
template <typename T>
|
||||
struct exact_iterator // handles repeat(exact)[p]
|
||||
{
|
||||
exact_iterator(T const exact_)
|
||||
: exact(exact_) {}
|
||||
|
||||
typedef T type;
|
||||
T start() const { return 0; }
|
||||
bool got_max(T i) const { return i >= exact; }
|
||||
bool got_min(T i) const { return i >= exact; }
|
||||
|
||||
T const exact;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
exact_iterator& operator= (exact_iterator const&);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct finite_iterator // handles repeat(min, max)[p]
|
||||
{
|
||||
finite_iterator(T const min_, T const max_)
|
||||
: min BOOST_PREVENT_MACRO_SUBSTITUTION (min_)
|
||||
, max BOOST_PREVENT_MACRO_SUBSTITUTION (max_) {}
|
||||
|
||||
typedef T type;
|
||||
T start() const { return 0; }
|
||||
bool got_max(T i) const { return i >= max; }
|
||||
bool got_min(T i) const { return i >= min; }
|
||||
|
||||
T const min;
|
||||
T const max;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
finite_iterator& operator= (finite_iterator const&);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct infinite_iterator // handles repeat(min, inf)[p]
|
||||
{
|
||||
infinite_iterator(T const min_)
|
||||
: min BOOST_PREVENT_MACRO_SUBSTITUTION (min_) {}
|
||||
|
||||
typedef T type;
|
||||
T start() const { return 0; }
|
||||
bool got_max(T /*i*/) const { return false; }
|
||||
bool got_min(T i) const { return i >= min; }
|
||||
|
||||
T const min;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
infinite_iterator& operator= (infinite_iterator const&);
|
||||
};
|
||||
|
||||
template <typename Subject, typename LoopIter>
|
||||
struct repeat_parser : unary_parser<repeat_parser<Subject, LoopIter> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Build a std::vector from the subject's attribute. Note
|
||||
// that build_std_vector may return unused_type if the
|
||||
// subject's attribute is an unused_type.
|
||||
typedef typename
|
||||
traits::build_std_vector<
|
||||
typename traits::attribute_of<
|
||||
Subject, Context, Iterator>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
repeat_parser(Subject const& subject_, LoopIter const& iter_)
|
||||
: subject(subject_), iter(iter_) {}
|
||||
|
||||
template <typename F>
|
||||
bool parse_container(F f) const
|
||||
{
|
||||
typename LoopIter::type i = iter.start();
|
||||
for (/**/; !iter.got_min(i); ++i)
|
||||
{
|
||||
if (f (subject))
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse some more up to the maximum specified
|
||||
typename F::iterator_type save = f.f.first;
|
||||
for (/**/; !iter.got_max(i); ++i)
|
||||
{
|
||||
if (f (subject))
|
||||
break;
|
||||
save = f.f.first;
|
||||
}
|
||||
|
||||
f.f.first = save;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef detail::fail_function<Iterator, Context, Skipper>
|
||||
fail_function;
|
||||
|
||||
// ensure the attribute is actually a container type
|
||||
traits::make_container(attr_);
|
||||
|
||||
Iterator iter_local = first;
|
||||
fail_function f(iter_local, last, context, skipper);
|
||||
if (!parse_container(detail::make_pass_container(f, attr_)))
|
||||
return false;
|
||||
|
||||
first = f.first;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("repeat", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
LoopIter iter;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
repeat_parser& operator= (repeat_parser const&);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::repeat, Subject, Modifiers>
|
||||
{
|
||||
typedef kleene<Subject> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Subject, typename Modifiers>
|
||||
struct make_directive<
|
||||
terminal_ex<tag::repeat, fusion::vector1<T> >, Subject, Modifiers>
|
||||
{
|
||||
typedef exact_iterator<T> iterator_type;
|
||||
typedef repeat_parser<Subject, iterator_type> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(
|
||||
Terminal const& term, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject, fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Subject, typename Modifiers>
|
||||
struct make_directive<
|
||||
terminal_ex<tag::repeat, fusion::vector2<T, T> >, Subject, Modifiers>
|
||||
{
|
||||
typedef finite_iterator<T> iterator_type;
|
||||
typedef repeat_parser<Subject, iterator_type> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(
|
||||
Terminal const& term, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject,
|
||||
iterator_type(
|
||||
fusion::at_c<0>(term.args)
|
||||
, fusion::at_c<1>(term.args)
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Subject, typename Modifiers>
|
||||
struct make_directive<
|
||||
terminal_ex<tag::repeat
|
||||
, fusion::vector2<T, inf_type> >, Subject, Modifiers>
|
||||
{
|
||||
typedef infinite_iterator<T> iterator_type;
|
||||
typedef repeat_parser<Subject, iterator_type> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(
|
||||
Terminal const& term, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject, fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename LoopIter>
|
||||
struct has_semantic_action<qi::repeat_parser<Subject, LoopIter> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename LoopIter, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct handles_container<qi::repeat_parser<Subject, LoopIter>
|
||||
, Attribute, Context, Iterator>
|
||||
: mpl::true_ {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,202 @@
|
||||
/*=============================================================================
|
||||
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_SKIP_JANUARY_26_2008_0422PM)
|
||||
#define SPIRIT_SKIP_JANUARY_26_2008_0422PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
|
||||
#include <boost/spirit/home/qi/operator/kleene.hpp>
|
||||
#include <boost/spirit/home/qi/directive/lexeme.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_directive<qi::domain, tag::skip> // enables skip[p]
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename T>
|
||||
struct use_directive<qi::domain
|
||||
, terminal_ex<tag::skip // enables skip(s)[p]
|
||||
, fusion::vector1<T> >
|
||||
> : boost::spirit::traits::matches<qi::domain, T> {};
|
||||
|
||||
template <> // enables *lazy* skip(s)[p]
|
||||
struct use_lazy_directive<
|
||||
qi::domain
|
||||
, tag::skip
|
||||
, 1 // arity
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::skip;
|
||||
#endif
|
||||
using spirit::skip_type;
|
||||
|
||||
template <typename Subject>
|
||||
struct reskip_parser : unary_parser<reskip_parser<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
traits::attribute_of<Subject, Context, Iterator>::type
|
||||
type;
|
||||
};
|
||||
|
||||
reskip_parser(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
typename enable_if<detail::is_unused_skipper<Skipper>, bool>::type
|
||||
parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& u // --> The skipper is reintroduced
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
return subject.parse(first, last, context
|
||||
, detail::get_skipper(u), attr_);
|
||||
}
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
typename disable_if<detail::is_unused_skipper<Skipper>, bool>::type
|
||||
parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
return subject.parse(first, last, context
|
||||
, skipper, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("skip", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
template <typename Subject, typename Skipper>
|
||||
struct skip_parser : unary_parser<skip_parser<Subject, Skipper> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
typedef Skipper skipper_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
traits::attribute_of<Subject, Context, Iterator>::type
|
||||
type;
|
||||
};
|
||||
|
||||
skip_parser(Subject const& subject_, Skipper const& skipper_)
|
||||
: subject(subject_), skipper(skipper_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper_, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper_ const& //skipper --> bypass the supplied skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
return subject.parse(first, last, context, skipper, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("skip", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
Skipper skipper;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Modifiers>
|
||||
struct make_directive<tag::skip, Subject, Modifiers>
|
||||
{
|
||||
typedef reskip_parser<Subject> result_type;
|
||||
result_type operator()(unused_type, Subject const& subject, unused_type) const
|
||||
{
|
||||
return result_type(subject);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Skipper, typename Subject, typename Modifiers>
|
||||
struct make_directive<
|
||||
terminal_ex<tag::skip, fusion::vector1<Skipper> >, Subject, Modifiers>
|
||||
{
|
||||
typedef typename
|
||||
result_of::compile<qi::domain, Skipper, Modifiers>::type
|
||||
skipper_type;
|
||||
|
||||
typedef skip_parser<Subject, skipper_type> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, Subject const& subject
|
||||
, Modifiers const& modifiers) const
|
||||
{
|
||||
return result_type(subject
|
||||
, compile<qi::domain>(fusion::at_c<0>(term.args), modifiers));
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::reskip_parser<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
template <typename Subject, typename Skipper>
|
||||
struct has_semantic_action<qi::skip_parser<Subject, Skipper> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::reskip_parser<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
|
||||
template <typename Subject, typename Skipper, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct handles_container<qi::skip_parser<Subject, Skipper>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
/*=============================================================================
|
||||
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_DOMAIN_JANUARY_29_2007_0954AM)
|
||||
#define BOOST_SPIRIT_DOMAIN_JANUARY_29_2007_0954AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/argument.hpp>
|
||||
#include <boost/spirit/home/support/context.hpp>
|
||||
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
// qi's domain
|
||||
struct domain {};
|
||||
|
||||
// bring in some of spirit parts into spirit::qi
|
||||
using spirit::unused;
|
||||
using spirit::unused_type;
|
||||
using spirit::compile;
|
||||
using spirit::info;
|
||||
|
||||
// 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, _)
|
||||
|
||||
using spirit::_pass_type;
|
||||
using spirit::_val_type;
|
||||
using spirit::_a_type;
|
||||
using spirit::_b_type;
|
||||
using spirit::_c_type;
|
||||
using spirit::_d_type;
|
||||
using spirit::_e_type;
|
||||
using spirit::_f_type;
|
||||
using spirit::_g_type;
|
||||
using spirit::_h_type;
|
||||
using spirit::_i_type;
|
||||
using spirit::_j_type;
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
|
||||
using spirit::_pass;
|
||||
using spirit::_val;
|
||||
using spirit::_a;
|
||||
using spirit::_b;
|
||||
using spirit::_c;
|
||||
using spirit::_d;
|
||||
using spirit::_e;
|
||||
using spirit::_f;
|
||||
using spirit::_g;
|
||||
using spirit::_h;
|
||||
using spirit::_i;
|
||||
using spirit::_j;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -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_QI_MATCH_DEC_02_2009_0749PM)
|
||||
#define BOOST_SPIRIT_QI_MATCH_DEC_02_2009_0749PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/stream/match_manip.hpp>
|
||||
#include <boost/spirit/home/qi/stream/match_manip_attr.hpp>
|
||||
|
||||
#endif
|
||||
@@ -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_QI_MATCH_AUTO_DEC_02_2009_0750PM)
|
||||
#define BOOST_SPIRIT_QI_MATCH_AUTO_DEC_02_2009_0750PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/stream/match_manip.hpp>
|
||||
#include <boost/spirit/home/qi/stream/detail/match_manip_auto.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,177 @@
|
||||
/*=============================================================================
|
||||
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_META_COMPILER_OCTOBER_16_2008_0347PM)
|
||||
#define BOOST_SPIRIT_META_COMPILER_OCTOBER_16_2008_0347PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/string_traits.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
template <typename T>
|
||||
struct use_terminal<qi::domain, T
|
||||
, typename enable_if<traits::is_parser<T> >::type> // enables parsers
|
||||
: mpl::true_ {};
|
||||
|
||||
namespace qi
|
||||
{
|
||||
template <typename T, typename Modifiers, typename Enable = void>
|
||||
struct make_primitive // by default, return it as-is
|
||||
{
|
||||
typedef T result_type;
|
||||
|
||||
template <typename T_>
|
||||
T_& operator()(T_& val, unused_type) const
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
template <typename T_>
|
||||
T_ const& operator()(T_ const& val, unused_type) const
|
||||
{
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tag, typename Elements
|
||||
, typename Modifiers, typename Enable = void>
|
||||
struct make_composite;
|
||||
|
||||
template <typename Directive, typename Body
|
||||
, typename Modifiers, typename Enable = void>
|
||||
struct make_directive
|
||||
{
|
||||
typedef Body result_type;
|
||||
result_type operator()(unused_type, Body const& body, unused_type) const
|
||||
{
|
||||
return body; // By default, a directive simply returns its subject
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Qi primitive meta-compiler
|
||||
template <>
|
||||
struct make_component<qi::domain, proto::tag::terminal>
|
||||
{
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <typename This, typename Elements, typename Modifiers>
|
||||
struct result<This(Elements, Modifiers)>
|
||||
{
|
||||
typedef typename qi::make_primitive<
|
||||
typename remove_const<typename Elements::car_type>::type,
|
||||
typename remove_reference<Modifiers>::type>::result_type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Elements, typename Modifiers>
|
||||
typename result<make_component(Elements, Modifiers)>::type
|
||||
operator()(Elements const& elements, Modifiers const& modifiers) const
|
||||
{
|
||||
typedef typename remove_const<typename Elements::car_type>::type term;
|
||||
return qi::make_primitive<term, Modifiers>()(elements.car, modifiers);
|
||||
}
|
||||
};
|
||||
|
||||
// Qi composite meta-compiler
|
||||
template <typename Tag>
|
||||
struct make_component<qi::domain, Tag>
|
||||
{
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <typename This, typename Elements, typename Modifiers>
|
||||
struct result<This(Elements, Modifiers)>
|
||||
{
|
||||
typedef typename
|
||||
qi::make_composite<Tag, Elements,
|
||||
typename remove_reference<Modifiers>::type>::result_type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Elements, typename Modifiers>
|
||||
typename result<make_component(Elements, Modifiers)>::type
|
||||
operator()(Elements const& elements, Modifiers const& modifiers) const
|
||||
{
|
||||
return qi::make_composite<Tag, Elements, Modifiers>()(
|
||||
elements, modifiers);
|
||||
}
|
||||
};
|
||||
|
||||
// Qi function meta-compiler
|
||||
template <>
|
||||
struct make_component<qi::domain, proto::tag::function>
|
||||
{
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <typename This, typename Elements, typename Modifiers>
|
||||
struct result<This(Elements, Modifiers)>
|
||||
{
|
||||
typedef typename
|
||||
qi::make_composite<
|
||||
typename remove_const<typename Elements::car_type>::type,
|
||||
typename Elements::cdr_type,
|
||||
typename remove_reference<Modifiers>::type
|
||||
>::result_type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Elements, typename Modifiers>
|
||||
typename result<make_component(Elements, Modifiers)>::type
|
||||
operator()(Elements const& elements, Modifiers const& modifiers) const
|
||||
{
|
||||
return qi::make_composite<
|
||||
typename remove_const<typename Elements::car_type>::type,
|
||||
typename Elements::cdr_type,
|
||||
Modifiers>()(elements.cdr, modifiers);
|
||||
}
|
||||
};
|
||||
|
||||
// Qi directive meta-compiler
|
||||
template <>
|
||||
struct make_component<qi::domain, tag::directive>
|
||||
{
|
||||
template <typename Sig>
|
||||
struct result;
|
||||
|
||||
template <typename This, typename Elements, typename Modifiers>
|
||||
struct result<This(Elements, Modifiers)>
|
||||
{
|
||||
typedef typename
|
||||
qi::make_directive<
|
||||
typename remove_const<typename Elements::car_type>::type,
|
||||
typename remove_const<typename Elements::cdr_type::car_type>::type,
|
||||
typename remove_reference<Modifiers>::type
|
||||
>::result_type
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename Elements, typename Modifiers>
|
||||
typename result<make_component(Elements, Modifiers)>::type
|
||||
operator()(Elements const& elements, Modifiers const& modifiers) const
|
||||
{
|
||||
return qi::make_directive<
|
||||
typename remove_const<typename Elements::car_type>::type,
|
||||
typename remove_const<typename Elements::cdr_type::car_type>::type,
|
||||
Modifiers>()(elements.car, elements.cdr.car, modifiers);
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
/*=============================================================================
|
||||
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_NONTERMINAL_FEBRUARY_12_2007_1018AM)
|
||||
#define BOOST_SPIRIT_NONTERMINAL_FEBRUARY_12_2007_1018AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/grammar.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/error_handler.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/debug_handler.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/simple_trace.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/success_handler.hpp>
|
||||
|
||||
#endif
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM)
|
||||
#define BOOST_SPIRIT_DEBUG_HANDLER_DECEMBER_05_2008_0734PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
|
||||
#include <boost/spirit/home/qi/operator/expect.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/fusion/include/out.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <
|
||||
typename Iterator, typename Context
|
||||
, typename Skipper, typename F>
|
||||
struct debug_handler
|
||||
{
|
||||
typedef function<
|
||||
bool(Iterator& first, Iterator const& last
|
||||
, Context& context
|
||||
, Skipper const& skipper
|
||||
)>
|
||||
function_type;
|
||||
|
||||
debug_handler(
|
||||
function_type subject_
|
||||
, F f_
|
||||
, std::string const& rule_name_)
|
||||
: subject(subject_)
|
||||
, f(f_)
|
||||
, rule_name(rule_name_)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper) const
|
||||
{
|
||||
f(first, last, context, pre_parse, rule_name);
|
||||
try // subject might throw an exception
|
||||
{
|
||||
if (subject(first, last, context, skipper))
|
||||
{
|
||||
f(first, last, context, successful_parse, rule_name);
|
||||
return true;
|
||||
}
|
||||
f(first, last, context, failed_parse, rule_name);
|
||||
}
|
||||
catch (expectation_failure<Iterator> const& e)
|
||||
{
|
||||
f(first, last, context, failed_parse, rule_name);
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function_type subject;
|
||||
F f;
|
||||
std::string rule_name;
|
||||
};
|
||||
|
||||
template <typename Iterator
|
||||
, typename T1, typename T2, typename T3, typename T4, typename F>
|
||||
void debug(rule<Iterator, T1, T2, T3, T4>& r, F f)
|
||||
{
|
||||
typedef rule<Iterator, T1, T2, T3, T4> rule_type;
|
||||
|
||||
typedef
|
||||
debug_handler<
|
||||
Iterator
|
||||
, typename rule_type::context_type
|
||||
, typename rule_type::skipper_type
|
||||
, F>
|
||||
debug_handler;
|
||||
r.f = debug_handler(r.f, f, r.name());
|
||||
}
|
||||
|
||||
struct simple_trace;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// This class provides an extra level of indirection through a
|
||||
// template to produce the simple_trace type. This way, the use
|
||||
// of simple_trace below is hidden behind a dependent type, so
|
||||
// that compilers eagerly type-checking template definitions
|
||||
// won't complain that simple_trace is incomplete.
|
||||
template<typename T>
|
||||
struct get_simple_trace
|
||||
{
|
||||
typedef simple_trace type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Iterator
|
||||
, typename T1, typename T2, typename T3, typename T4>
|
||||
void debug(rule<Iterator, T1, T2, T3, T4>& r)
|
||||
{
|
||||
typedef rule<Iterator, T1, T2, T3, T4> rule_type;
|
||||
|
||||
typedef
|
||||
debug_handler<
|
||||
Iterator
|
||||
, typename rule_type::context_type
|
||||
, typename rule_type::skipper_type
|
||||
, simple_trace>
|
||||
debug_handler;
|
||||
|
||||
typedef typename qi::detail::get_simple_trace<Iterator>::type trace;
|
||||
r.f = debug_handler(r.f, trace(), r.name());
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Utility macro for easy enabling of rule and grammar debugging
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
|
||||
#if defined(BOOST_SPIRIT_DEBUG) || defined(BOOST_SPIRIT_QI_DEBUG)
|
||||
#define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r); debug(r)
|
||||
#else
|
||||
#define BOOST_SPIRIT_DEBUG_NODE(r) r.name(#r)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BOOST_SPIRIT_DEBUG_NODE_A(r, _, name) \
|
||||
BOOST_SPIRIT_DEBUG_NODE(name); \
|
||||
/***/
|
||||
|
||||
#define BOOST_SPIRIT_DEBUG_NODES(seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_SPIRIT_DEBUG_NODE_A, _, seq) \
|
||||
/***/
|
||||
|
||||
#endif
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_HANDLER_STATE_APR_21_2010_0733PM)
|
||||
#define BOOST_SPIRIT_DEBUG_HANDLER_STATE_APR_21_2010_0733PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
enum debug_handler_state
|
||||
{
|
||||
pre_parse
|
||||
, successful_parse
|
||||
, failed_parse
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#ifndef BOOST_PP_IS_ITERATING
|
||||
|
||||
#include <boost/preprocessor/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
|
||||
#define BOOST_PP_FILENAME_1 \
|
||||
<boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
|
||||
#define BOOST_PP_ITERATION_LIMITS (1, SPIRIT_ARGUMENTS_LIMIT)
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Preprocessor vertical repetition code
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#else // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
|
||||
template <BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
typename lazy_enable_if_c<
|
||||
(params_size == N)
|
||||
, proto::terminal<
|
||||
spirit::qi::parameterized_nonterminal<
|
||||
parameterized_subject_type
|
||||
, fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> >
|
||||
>
|
||||
>::type
|
||||
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& f)) const
|
||||
{
|
||||
typedef fusion::vector<BOOST_PP_ENUM_PARAMS(N, A)> vector_type;
|
||||
typedef spirit::qi::parameterized_nonterminal<
|
||||
parameterized_subject_type, vector_type> parameterized_type;
|
||||
typedef typename proto::terminal<parameterized_type>::type result_type;
|
||||
|
||||
return result_type::make(
|
||||
parameterized_type(
|
||||
this->get_parameterized_subject()
|
||||
, fusion::make_vector(BOOST_PP_ENUM_PARAMS(N, f)))
|
||||
);
|
||||
}
|
||||
|
||||
#undef N
|
||||
#endif // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2009 Francois Barel
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PARAMETERIZED_AUGUST_09_2009_0539AM)
|
||||
#define BOOST_SPIRIT_PARAMETERIZED_AUGUST_09_2009_0539AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// parameterized_nonterminal: parser representing the invocation of a
|
||||
// nonterminal, passing inherited attributes
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Params>
|
||||
struct parameterized_nonterminal
|
||||
: parser<parameterized_nonterminal<Subject, Params> >
|
||||
{
|
||||
parameterized_nonterminal(Subject const& subject, Params const& params_)
|
||||
: ref(subject), params(params_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
// Forward to subject.
|
||||
: Subject::template attribute<Context, Iterator> {};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
// Forward to subject, passing the additional
|
||||
// params argument to parse.
|
||||
return ref.get().parse(first, last, context, skipper, attr_, params);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
// Forward to subject.
|
||||
return ref.get().what(context);
|
||||
}
|
||||
|
||||
boost::reference_wrapper<Subject const> ref;
|
||||
Params params;
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Params, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct handles_container<qi::parameterized_nonterminal<Subject, Params>
|
||||
, Attribute, Context, Iterator>
|
||||
: handles_container<typename remove_const<Subject>::type
|
||||
, Attribute, Context, Iterator>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PARSER_BINDER_DECEMBER_05_2008_0516_PM)
|
||||
#define BOOST_SPIRIT_PARSER_BINDER_DECEMBER_05_2008_0516_PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
// parser_binder for plain rules
|
||||
template <typename Parser, typename Auto>
|
||||
struct parser_binder
|
||||
{
|
||||
parser_binder(Parser const& p_)
|
||||
: p(p_) {}
|
||||
|
||||
template <typename Iterator, typename Skipper, typename Context>
|
||||
bool call(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, mpl::true_) const
|
||||
{
|
||||
// If DeducedAuto is false (semantic actions is present), the
|
||||
// component's attribute is unused.
|
||||
return p.parse(first, last, context, skipper, unused);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Skipper, typename Context>
|
||||
bool call(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper, mpl::false_) const
|
||||
{
|
||||
// If DeducedAuto is true (no semantic action), we pass the rule's
|
||||
// attribute on to the component.
|
||||
return p.parse(first, last, context, skipper
|
||||
, fusion::at_c<0>(context.attributes));
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Skipper, typename Context>
|
||||
bool operator()(
|
||||
Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper) const
|
||||
{
|
||||
// If Auto is false, we need to deduce whether to apply auto rule
|
||||
typedef typename traits::has_semantic_action<Parser>::type auto_rule;
|
||||
return call(first, last, context, skipper, auto_rule());
|
||||
}
|
||||
|
||||
Parser p;
|
||||
};
|
||||
|
||||
// parser_binder for auto rules
|
||||
template <typename Parser>
|
||||
struct parser_binder<Parser, mpl::true_>
|
||||
{
|
||||
parser_binder(Parser const& p_)
|
||||
: p(p_) {}
|
||||
|
||||
template <typename Iterator, typename Skipper, typename Context>
|
||||
bool operator()(
|
||||
Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper) const
|
||||
{
|
||||
// If Auto is true, we pass the rule's attribute on to the component.
|
||||
return p.parse(first, last, context, skipper
|
||||
, fusion::at_c<0>(context.attributes));
|
||||
}
|
||||
|
||||
Parser p;
|
||||
};
|
||||
|
||||
template <typename Auto, typename Parser>
|
||||
inline parser_binder<Parser, Auto>
|
||||
bind_parser(Parser const& p)
|
||||
{
|
||||
return parser_binder<Parser, Auto>(p);
|
||||
}
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_ERROR_HANDLER_APRIL_29_2007_1042PM)
|
||||
#define BOOST_SPIRIT_ERROR_HANDLER_APRIL_29_2007_1042PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/operator/expect.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
|
||||
#include <boost/spirit/home/support/multi_pass_wrapper.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
enum error_handler_result
|
||||
{
|
||||
fail
|
||||
, retry
|
||||
, accept
|
||||
, rethrow
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Helper template allowing to manage the inhibit clear queue flag in
|
||||
// a multi_pass iterator. This is the usual specialization used for
|
||||
// anything but a multi_pass iterator.
|
||||
template <typename Iterator, bool active>
|
||||
struct reset_on_exit
|
||||
{
|
||||
reset_on_exit(Iterator&) {}
|
||||
};
|
||||
|
||||
// For 'retry' or 'fail' error handlers we need to inhibit the flushing
|
||||
// of the internal multi_pass buffers which otherwise might happen at
|
||||
// deterministic expectation points inside the encapsulated right hand
|
||||
// side of rule.
|
||||
template <typename Iterator>
|
||||
struct reset_on_exit<Iterator, true>
|
||||
{
|
||||
reset_on_exit(Iterator& it)
|
||||
: it_(it)
|
||||
, inhibit_clear_queue_(spirit::traits::inhibit_clear_queue(it))
|
||||
{
|
||||
spirit::traits::inhibit_clear_queue(it_, true);
|
||||
}
|
||||
|
||||
~reset_on_exit()
|
||||
{
|
||||
// reset inhibit flag in multi_pass on exit
|
||||
spirit::traits::inhibit_clear_queue(it_, inhibit_clear_queue_);
|
||||
}
|
||||
|
||||
Iterator& it_;
|
||||
bool inhibit_clear_queue_;
|
||||
};
|
||||
}
|
||||
|
||||
template <
|
||||
typename Iterator, typename Context
|
||||
, typename Skipper, typename F, error_handler_result action
|
||||
>
|
||||
struct error_handler
|
||||
{
|
||||
typedef function<
|
||||
bool(Iterator& first, Iterator const& last
|
||||
, Context& context
|
||||
, Skipper const& skipper
|
||||
)>
|
||||
function_type;
|
||||
|
||||
error_handler(function_type subject_, F f_)
|
||||
: subject(subject_)
|
||||
, f(f_)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper) const
|
||||
{
|
||||
typedef qi::detail::reset_on_exit<Iterator
|
||||
, traits::is_multi_pass<Iterator>::value &&
|
||||
(action == retry || action == fail)> on_exit_type;
|
||||
|
||||
on_exit_type on_exit(first);
|
||||
for(;;)
|
||||
{
|
||||
try
|
||||
{
|
||||
Iterator i = first;
|
||||
bool r = subject(i, last, context, skipper);
|
||||
if (r)
|
||||
first = i;
|
||||
return r;
|
||||
}
|
||||
catch (expectation_failure<Iterator> const& x)
|
||||
{
|
||||
typedef
|
||||
fusion::vector<
|
||||
Iterator&
|
||||
, Iterator const&
|
||||
, Iterator const&
|
||||
, info const&>
|
||||
params;
|
||||
error_handler_result r = action;
|
||||
params args(first, last, x.first, x.what_);
|
||||
f(args, context, r);
|
||||
|
||||
// The assertions below will fire if you are using a
|
||||
// multi_pass as the underlying iterator, one of your error
|
||||
// handlers forced its guarded rule to 'fail' or 'retry',
|
||||
// and the error handler has not been instantiated using
|
||||
// either 'fail' or 'retry' in the first place. Please see
|
||||
// the multi_pass docs for more information.
|
||||
switch (r)
|
||||
{
|
||||
case fail:
|
||||
BOOST_ASSERT(
|
||||
!traits::is_multi_pass<Iterator>::value ||
|
||||
action == retry || action == fail);
|
||||
return false;
|
||||
case retry:
|
||||
BOOST_ASSERT(
|
||||
!traits::is_multi_pass<Iterator>::value ||
|
||||
action == retry || action == fail);
|
||||
continue;
|
||||
case accept: return true;
|
||||
case rethrow: boost::throw_exception(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function_type subject;
|
||||
F f;
|
||||
};
|
||||
|
||||
template <
|
||||
error_handler_result action
|
||||
, typename Iterator, typename T0, typename T1, typename T2
|
||||
, typename F>
|
||||
void on_error(rule<Iterator, T0, T1, T2>& r, F f)
|
||||
{
|
||||
typedef rule<Iterator, T0, T1, T2> rule_type;
|
||||
|
||||
typedef
|
||||
error_handler<
|
||||
Iterator
|
||||
, typename rule_type::context_type
|
||||
, typename rule_type::skipper_type
|
||||
, F
|
||||
, action>
|
||||
error_handler;
|
||||
r.f = error_handler(r.f, f);
|
||||
}
|
||||
|
||||
// Error handling support when <action> is not
|
||||
// specified. We will default to <fail>.
|
||||
template <typename Iterator, typename T0, typename T1
|
||||
, typename T2, typename F>
|
||||
void on_error(rule<Iterator, T0, T1, T2>& r, F f)
|
||||
{
|
||||
on_error<fail>(r, f);
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,132 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_GRAMMAR_FEBRUARY_19_2007_0236PM)
|
||||
#define BOOST_SPIRIT_GRAMMAR_FEBRUARY_19_2007_0236PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/assert_msg.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
|
||||
#include <boost/spirit/home/qi/reference.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <
|
||||
typename Iterator, typename T1, typename T2, typename T3
|
||||
, typename T4>
|
||||
struct grammar
|
||||
: proto::extends<
|
||||
typename proto::terminal<
|
||||
reference<rule<Iterator, T1, T2, T3, T4> const>
|
||||
>::type
|
||||
, grammar<Iterator, T1, T2, T3, T4>
|
||||
>
|
||||
, parser<grammar<Iterator, T1, T2, T3, T4> >
|
||||
, noncopyable
|
||||
{
|
||||
typedef Iterator iterator_type;
|
||||
typedef rule<Iterator, T1, T2, T3, T4> start_type;
|
||||
typedef typename start_type::sig_type sig_type;
|
||||
typedef typename start_type::locals_type locals_type;
|
||||
typedef typename start_type::skipper_type skipper_type;
|
||||
typedef typename start_type::encoding_type encoding_type;
|
||||
typedef grammar<Iterator, T1, T2, T3, T4> base_type;
|
||||
typedef reference<start_type const> reference_;
|
||||
typedef typename proto::terminal<reference_>::type terminal;
|
||||
|
||||
static size_t const params_size = start_type::params_size;
|
||||
|
||||
template <typename Context, typename Iterator_>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename start_type::attr_type type;
|
||||
};
|
||||
|
||||
grammar(
|
||||
start_type const& start
|
||||
, std::string const& name = "unnamed-grammar")
|
||||
: proto::extends<terminal, base_type>(terminal::make(reference_(start)))
|
||||
, name_(name)
|
||||
{}
|
||||
|
||||
// This constructor is used to catch if the start rule is not
|
||||
// compatible with the grammar.
|
||||
template <typename Iterator_,
|
||||
typename T1_, typename T2_, typename T3_, typename T4_>
|
||||
grammar(
|
||||
rule<Iterator_, T1_, T2_, T3_, T4_> const&
|
||||
, std::string const& = "unnamed-grammar")
|
||||
{
|
||||
// If you see the assertion below failing then the start rule
|
||||
// passed to the constructor of the grammar is not compatible with
|
||||
// the grammar (i.e. it uses different template parameters).
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
(is_same<start_type, rule<Iterator_, T1_, T2_, T3_, T4_> >::value)
|
||||
, incompatible_start_rule, (rule<Iterator_, T1_, T2_, T3_, T4_>));
|
||||
}
|
||||
|
||||
std::string name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
void name(std::string const& str)
|
||||
{
|
||||
name_ = str;
|
||||
}
|
||||
|
||||
template <typename Context, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
return this->proto_base().child0.parse(
|
||||
first, last, context, skipper, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context&) const
|
||||
{
|
||||
return info(name_);
|
||||
}
|
||||
|
||||
// bring in the operator() overloads
|
||||
start_type const& get_parameterized_subject() const
|
||||
{ return this->proto_base().child0.ref.get(); }
|
||||
typedef start_type parameterized_subject_type;
|
||||
#include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
|
||||
|
||||
std::string name_;
|
||||
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename IteratorA, typename IteratorB, typename Attribute
|
||||
, typename Context, typename T1, typename T2, typename T3, typename T4>
|
||||
struct handles_container<
|
||||
qi::grammar<IteratorA, T1, T2, T3, T4>, Attribute, Context, IteratorB>
|
||||
: traits::is_container<
|
||||
typename attribute_of<
|
||||
qi::grammar<IteratorA, T1, T2, T3, T4>, Context, IteratorB
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_QI_NONTERMINAL_FWD_DEC_24_2010_1105PM)
|
||||
#define BOOST_SPIRIT_QI_NONTERMINAL_FWD_DEC_24_2010_1105PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
// forward declaration only
|
||||
template <
|
||||
typename Iterator, typename T1 = unused_type
|
||||
, typename T2 = unused_type, typename T3 = unused_type
|
||||
, typename T4 = unused_type>
|
||||
struct rule;
|
||||
|
||||
template <
|
||||
typename Iterator, typename T1 = unused_type
|
||||
, typename T2 = unused_type, typename T3 = unused_type
|
||||
, typename T4 = unused_type>
|
||||
struct grammar;
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,440 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_RULE_FEBRUARY_12_2007_1020AM)
|
||||
#define BOOST_SPIRIT_RULE_FEBRUARY_12_2007_1020AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/fusion/include/size.hpp>
|
||||
#include <boost/fusion/include/make_vector.hpp>
|
||||
#include <boost/fusion/include/cons.hpp>
|
||||
#include <boost/fusion/include/as_list.hpp>
|
||||
#include <boost/fusion/include/as_vector.hpp>
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/argument.hpp>
|
||||
#include <boost/spirit/home/support/context.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/nonterminal/extract_param.hpp>
|
||||
#include <boost/spirit/home/support/nonterminal/locals.hpp>
|
||||
#include <boost/spirit/home/qi/reference.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/detail/parameterized.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/detail/parser_binder.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/nonterminal_fwd.hpp>
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
BOOST_PP_REPEAT(SPIRIT_ATTRIBUTES_LIMIT, SPIRIT_USING_ATTRIBUTE, _)
|
||||
|
||||
using spirit::_pass_type;
|
||||
using spirit::_val_type;
|
||||
using spirit::_a_type;
|
||||
using spirit::_b_type;
|
||||
using spirit::_c_type;
|
||||
using spirit::_d_type;
|
||||
using spirit::_e_type;
|
||||
using spirit::_f_type;
|
||||
using spirit::_g_type;
|
||||
using spirit::_h_type;
|
||||
using spirit::_i_type;
|
||||
using spirit::_j_type;
|
||||
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
|
||||
using spirit::_pass;
|
||||
using spirit::_val;
|
||||
using spirit::_a;
|
||||
using spirit::_b;
|
||||
using spirit::_c;
|
||||
using spirit::_d;
|
||||
using spirit::_e;
|
||||
using spirit::_f;
|
||||
using spirit::_g;
|
||||
using spirit::_h;
|
||||
using spirit::_i;
|
||||
using spirit::_j;
|
||||
|
||||
#endif
|
||||
|
||||
using spirit::info;
|
||||
using spirit::locals;
|
||||
|
||||
template <
|
||||
typename Iterator, typename T1, typename T2, typename T3
|
||||
, typename T4>
|
||||
struct rule
|
||||
: proto::extends<
|
||||
typename proto::terminal<
|
||||
reference<rule<Iterator, T1, T2, T3, T4> const>
|
||||
>::type
|
||||
, rule<Iterator, T1, T2, T3, T4>
|
||||
>
|
||||
, parser<rule<Iterator, T1, T2, T3, T4> >
|
||||
{
|
||||
typedef Iterator iterator_type;
|
||||
typedef rule<Iterator, T1, T2, T3, T4> this_type;
|
||||
typedef reference<this_type const> reference_;
|
||||
typedef typename proto::terminal<reference_>::type terminal;
|
||||
typedef proto::extends<terminal, this_type> base_type;
|
||||
typedef mpl::vector<T1, T2, T3, T4> template_params;
|
||||
|
||||
// The rule's locals_type: a sequence of types to be used as local variables
|
||||
typedef typename
|
||||
spirit::detail::extract_locals<template_params>::type
|
||||
locals_type;
|
||||
|
||||
// The rule's skip-parser type
|
||||
typedef typename
|
||||
spirit::detail::extract_component<
|
||||
qi::domain, template_params>::type
|
||||
skipper_type;
|
||||
|
||||
// The rule's encoding type
|
||||
typedef typename
|
||||
spirit::detail::extract_encoding<template_params>::type
|
||||
encoding_type;
|
||||
|
||||
// The rule's signature
|
||||
typedef typename
|
||||
spirit::detail::extract_sig<template_params, encoding_type, qi::domain>::type
|
||||
sig_type;
|
||||
|
||||
// This is the rule's attribute type
|
||||
typedef typename
|
||||
spirit::detail::attr_from_sig<sig_type>::type
|
||||
attr_type;
|
||||
typedef typename add_reference<attr_type>::type attr_reference_type;
|
||||
|
||||
// parameter_types is a sequence of types passed as parameters to the rule
|
||||
typedef typename
|
||||
spirit::detail::params_from_sig<sig_type>::type
|
||||
parameter_types;
|
||||
|
||||
static size_t const params_size =
|
||||
fusion::result_of::size<parameter_types>::type::value;
|
||||
|
||||
typedef context<
|
||||
fusion::cons<attr_reference_type, parameter_types>
|
||||
, locals_type>
|
||||
context_type;
|
||||
|
||||
typedef function<
|
||||
bool(Iterator& first, Iterator const& last
|
||||
, context_type& context
|
||||
, skipper_type const& skipper
|
||||
)>
|
||||
function_type;
|
||||
|
||||
typedef typename
|
||||
mpl::if_<
|
||||
is_same<encoding_type, unused_type>
|
||||
, unused_type
|
||||
, tag::char_code<tag::encoding, encoding_type>
|
||||
>::type
|
||||
encoding_modifier_type;
|
||||
|
||||
explicit rule(std::string const& name = "unnamed-rule")
|
||||
: base_type(terminal::make(reference_(*this)))
|
||||
, name_(name)
|
||||
{
|
||||
}
|
||||
|
||||
rule(rule const& rhs)
|
||||
: base_type(terminal::make(reference_(*this)))
|
||||
, name_(rhs.name_)
|
||||
, f(rhs.f)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Auto, typename Expr>
|
||||
static void define(rule& /*lhs*/, Expr const& /*expr*/, mpl::false_)
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
}
|
||||
|
||||
template <typename Auto, typename Expr>
|
||||
static void define(rule& lhs, Expr const& expr, mpl::true_)
|
||||
{
|
||||
lhs.f = detail::bind_parser<Auto>(
|
||||
compile<qi::domain>(expr, encoding_modifier_type()));
|
||||
}
|
||||
|
||||
template <typename Expr>
|
||||
rule(Expr const& expr, std::string const& name = "unnamed-rule")
|
||||
: base_type(terminal::make(reference_(*this)))
|
||||
, name_(name)
|
||||
{
|
||||
define<mpl::false_>(*this, expr, traits::matches<qi::domain, Expr>());
|
||||
}
|
||||
|
||||
rule& operator=(rule const& rhs)
|
||||
{
|
||||
// The following assertion fires when you try to initialize a rule
|
||||
// from an uninitialized one. Did you mean to refer to the right
|
||||
// hand side rule instead of assigning from it? In this case you
|
||||
// should write lhs = rhs.alias();
|
||||
BOOST_ASSERT(rhs.f && "Did you mean rhs.alias() instead of rhs?");
|
||||
|
||||
f = rhs.f;
|
||||
name_ = rhs.name_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string const& name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
void name(std::string const& str)
|
||||
{
|
||||
name_ = str;
|
||||
}
|
||||
|
||||
template <typename Expr>
|
||||
rule& operator=(Expr const& expr)
|
||||
{
|
||||
define<mpl::false_>(*this, expr, traits::matches<qi::domain, Expr>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// VC7.1 has problems to resolve 'rule' without explicit template parameters
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
// g++ 3.3 barfs if this is a member function :(
|
||||
template <typename Expr>
|
||||
friend rule& operator%=(rule& r, Expr const& expr)
|
||||
{
|
||||
define<mpl::true_>(r, expr, traits::matches<qi::domain, Expr>());
|
||||
return r;
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
// non-const version needed to suppress proto's %= kicking in
|
||||
template <typename Expr>
|
||||
friend rule& operator%=(rule& r, Expr& expr)
|
||||
{
|
||||
return r %= static_cast<Expr const&>(expr);
|
||||
}
|
||||
#else
|
||||
// for rvalue references
|
||||
template <typename Expr>
|
||||
friend rule& operator%=(rule& r, Expr&& expr)
|
||||
{
|
||||
define<mpl::true_>(r, expr, traits::matches<qi::domain, Expr>());
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
// both friend functions have to be defined out of class as VC7.1
|
||||
// will complain otherwise
|
||||
template <typename OutputIterator_, typename T1_, typename T2_
|
||||
, typename T3_, typename T4_, typename Expr>
|
||||
friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
|
||||
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr const& expr);
|
||||
|
||||
// non-const version needed to suppress proto's %= kicking in
|
||||
template <typename OutputIterator_, typename T1_, typename T2_
|
||||
, typename T3_, typename T4_, typename Expr>
|
||||
friend rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
|
||||
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr& expr);
|
||||
#endif
|
||||
|
||||
template <typename Context, typename Iterator_>
|
||||
struct attribute
|
||||
{
|
||||
typedef attr_type type;
|
||||
};
|
||||
|
||||
template <typename Context, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
if (f)
|
||||
{
|
||||
// do a preskip if this is an implied lexeme
|
||||
if (is_same<skipper_type, unused_type>::value)
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
typedef traits::make_attribute<attr_type, Attribute> make_attribute;
|
||||
|
||||
// do down-stream transformation, provides attribute for
|
||||
// rhs parser
|
||||
typedef traits::transform_attribute<
|
||||
typename make_attribute::type, attr_type, domain>
|
||||
transform;
|
||||
|
||||
typename make_attribute::type made_attr = make_attribute::call(attr_param);
|
||||
typename transform::type attr_ = transform::pre(made_attr);
|
||||
|
||||
// If you are seeing a compilation error here, you are probably
|
||||
// trying to use a rule or a grammar which has inherited
|
||||
// attributes, without passing values for them.
|
||||
context_type context(attr_);
|
||||
|
||||
// If you are seeing a compilation error here stating that the
|
||||
// fourth parameter can't be converted to a required target type
|
||||
// then you are probably trying to use a rule or a grammar with
|
||||
// an incompatible skipper type.
|
||||
if (f(first, last, context, skipper))
|
||||
{
|
||||
// do up-stream transformation, this integrates the results
|
||||
// back into the original attribute value, if appropriate
|
||||
traits::post_transform(attr_param, attr_);
|
||||
return true;
|
||||
}
|
||||
|
||||
// inform attribute transformation of failed rhs
|
||||
traits::fail_transform(attr_param, attr_);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context, typename Skipper
|
||||
, typename Attribute, typename Params>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& caller_context, Skipper const& skipper
|
||||
, Attribute& attr_param, Params const& params) const
|
||||
{
|
||||
if (f)
|
||||
{
|
||||
// do a preskip if this is an implied lexeme
|
||||
if (is_same<skipper_type, unused_type>::value)
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
typedef traits::make_attribute<attr_type, Attribute> make_attribute;
|
||||
|
||||
// do down-stream transformation, provides attribute for
|
||||
// rhs parser
|
||||
typedef traits::transform_attribute<
|
||||
typename make_attribute::type, attr_type, domain>
|
||||
transform;
|
||||
|
||||
typename make_attribute::type made_attr = make_attribute::call(attr_param);
|
||||
typename transform::type attr_ = transform::pre(made_attr);
|
||||
|
||||
// If you are seeing a compilation error here, you are probably
|
||||
// trying to use a rule or a grammar which has inherited
|
||||
// attributes, passing values of incompatible types for them.
|
||||
context_type context(attr_, params, caller_context);
|
||||
|
||||
// If you are seeing a compilation error here stating that the
|
||||
// fourth parameter can't be converted to a required target type
|
||||
// then you are probably trying to use a rule or a grammar with
|
||||
// an incompatible skipper type.
|
||||
if (f(first, last, context, skipper))
|
||||
{
|
||||
// do up-stream transformation, this integrates the results
|
||||
// back into the original attribute value, if appropriate
|
||||
traits::post_transform(attr_param, attr_);
|
||||
return true;
|
||||
}
|
||||
|
||||
// inform attribute transformation of failed rhs
|
||||
traits::fail_transform(attr_param, attr_);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info(name_);
|
||||
}
|
||||
|
||||
reference_ alias() const
|
||||
{
|
||||
return reference_(*this);
|
||||
}
|
||||
|
||||
typename proto::terminal<this_type>::type copy() const
|
||||
{
|
||||
typename proto::terminal<this_type>::type result = {*this};
|
||||
return result;
|
||||
}
|
||||
|
||||
// bring in the operator() overloads
|
||||
rule const& get_parameterized_subject() const { return *this; }
|
||||
typedef rule parameterized_subject_type;
|
||||
#include <boost/spirit/home/qi/nonterminal/detail/fcall.hpp>
|
||||
|
||||
std::string name_;
|
||||
function_type f;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
template <typename OutputIterator_, typename T1_, typename T2_
|
||||
, typename T3_, typename T4_, typename Expr>
|
||||
rule<OutputIterator_, T1_, T2_, T3_, T4_>& operator%=(
|
||||
rule<OutputIterator_, T1_, T2_, T3_, T4_>& r, Expr const& expr)
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
|
||||
typedef typename
|
||||
rule<OutputIterator_, T1_, T2_, T3_, T4_>::encoding_modifier_type
|
||||
encoding_modifier_type;
|
||||
|
||||
r.f = detail::bind_parser<mpl::true_>(
|
||||
compile<qi::domain>(expr, encoding_modifier_type()));
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename Iterator_, typename T1_, typename T2_
|
||||
, typename T3_, typename T4_, typename Expr>
|
||||
rule<Iterator_, T1_, T2_, T3_, T4_>& operator%=(
|
||||
rule<Iterator_, T1_, T2_, T3_, T4_>& r, Expr& expr)
|
||||
{
|
||||
return r %= static_cast<Expr const&>(expr);
|
||||
}
|
||||
#endif
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <
|
||||
typename IteratorA, typename IteratorB, typename Attribute
|
||||
, typename Context, typename T1, typename T2, typename T3, typename T4>
|
||||
struct handles_container<
|
||||
qi::rule<IteratorA, T1, T2, T3, T4>, Attribute, Context, IteratorB>
|
||||
: traits::is_container<
|
||||
typename attribute_of<
|
||||
qi::rule<IteratorA, T1, T2, T3, T4>, Context, IteratorB
|
||||
>::type
|
||||
>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SIMPLE_TRACE_DECEMBER_06_2008_1102AM)
|
||||
#define BOOST_SPIRIT_SIMPLE_TRACE_DECEMBER_06_2008_1102AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/nonterminal/debug_handler_state.hpp>
|
||||
#include <boost/fusion/include/out.hpp>
|
||||
#include <iostream>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/spirit/home/support/attributes.hpp>
|
||||
|
||||
// The stream to use for debug output
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
|
||||
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
|
||||
#endif
|
||||
|
||||
// number of tokens to print while debugging
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
|
||||
#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
|
||||
#endif
|
||||
|
||||
// number of spaces to indent
|
||||
#if !defined(BOOST_SPIRIT_DEBUG_INDENT)
|
||||
#define BOOST_SPIRIT_DEBUG_INDENT 2
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Char>
|
||||
inline void token_printer(std::ostream& o, Char c)
|
||||
{
|
||||
// allow to customize the token printer routine
|
||||
spirit::traits::print_token(o, c);
|
||||
}
|
||||
}
|
||||
|
||||
struct simple_trace
|
||||
{
|
||||
int& get_indent() const
|
||||
{
|
||||
static int indent = 0;
|
||||
return indent;
|
||||
}
|
||||
|
||||
void print_indent(int n) const
|
||||
{
|
||||
n *= BOOST_SPIRIT_DEBUG_INDENT;
|
||||
for (int i = 0; i != n; ++i)
|
||||
BOOST_SPIRIT_DEBUG_OUT << ' ';
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void print_some(
|
||||
char const* tag
|
||||
, int /*indent*/
|
||||
, Iterator first, Iterator const& last) const
|
||||
{
|
||||
print_indent(get_indent());
|
||||
BOOST_SPIRIT_DEBUG_OUT << '<' << tag << '>';
|
||||
int const n = BOOST_SPIRIT_DEBUG_PRINT_SOME;
|
||||
for (int i = 0; first != last && i != n && *first; ++i, ++first)
|
||||
detail::token_printer(BOOST_SPIRIT_DEBUG_OUT, *first);
|
||||
BOOST_SPIRIT_DEBUG_OUT << "</" << tag << '>' << std::endl;
|
||||
|
||||
// $$$ FIXME convert invalid xml characters (e.g. '<') to valid
|
||||
// character entities. $$$
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context, typename State>
|
||||
void operator()(
|
||||
Iterator const& first
|
||||
, Iterator const& last
|
||||
, Context const& context
|
||||
, State state
|
||||
, std::string const& rule_name) const
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case pre_parse:
|
||||
print_indent(get_indent()++);
|
||||
BOOST_SPIRIT_DEBUG_OUT
|
||||
<< '<' << rule_name << '>'
|
||||
<< std::endl;
|
||||
print_some("try", get_indent(), first, last);
|
||||
break;
|
||||
case successful_parse:
|
||||
print_some("success", get_indent(), first, last);
|
||||
print_indent(get_indent());
|
||||
BOOST_SPIRIT_DEBUG_OUT
|
||||
<< "<attributes>";
|
||||
traits::print_attribute(
|
||||
BOOST_SPIRIT_DEBUG_OUT,
|
||||
context.attributes
|
||||
);
|
||||
BOOST_SPIRIT_DEBUG_OUT
|
||||
<< "</attributes>";
|
||||
if (!fusion::empty(context.locals))
|
||||
BOOST_SPIRIT_DEBUG_OUT
|
||||
<< "<locals>"
|
||||
<< context.locals
|
||||
<< "</locals>";
|
||||
BOOST_SPIRIT_DEBUG_OUT << std::endl;
|
||||
print_indent(--get_indent());
|
||||
BOOST_SPIRIT_DEBUG_OUT
|
||||
<< "</" << rule_name << '>'
|
||||
<< std::endl;
|
||||
break;
|
||||
case failed_parse:
|
||||
print_indent(get_indent());
|
||||
BOOST_SPIRIT_DEBUG_OUT << "<fail/>" << std::endl;
|
||||
print_indent(--get_indent());
|
||||
BOOST_SPIRIT_DEBUG_OUT
|
||||
<< "</" << rule_name << '>'
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_SUCCESS_HANDLER_FEBRUARY_25_2011_1051AM)
|
||||
#define BOOST_SPIRIT_SUCCESS_HANDLER_FEBRUARY_25_2011_1051AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <
|
||||
typename Iterator, typename Context
|
||||
, typename Skipper, typename F
|
||||
>
|
||||
struct success_handler
|
||||
{
|
||||
typedef function<
|
||||
bool(Iterator& first, Iterator const& last
|
||||
, Context& context
|
||||
, Skipper const& skipper
|
||||
)>
|
||||
function_type;
|
||||
|
||||
success_handler(function_type subject_, F f_)
|
||||
: subject(subject_)
|
||||
, f(f_)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator()(
|
||||
Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper) const
|
||||
{
|
||||
Iterator i = first;
|
||||
bool r = subject(i, last, context, skipper);
|
||||
if (r)
|
||||
{
|
||||
typedef
|
||||
fusion::vector<
|
||||
Iterator&
|
||||
, Iterator const&
|
||||
, Iterator const&>
|
||||
params;
|
||||
skip_over(first, last, skipper);
|
||||
params args(first, last, i);
|
||||
f(args, context);
|
||||
|
||||
first = i;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
function_type subject;
|
||||
F f;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Iterator, typename T0, typename T1, typename T2
|
||||
, typename F>
|
||||
void on_success(rule<Iterator, T0, T1, T2>& r, F f)
|
||||
{
|
||||
typedef rule<Iterator, T0, T1, T2> rule_type;
|
||||
|
||||
typedef
|
||||
success_handler<
|
||||
Iterator
|
||||
, typename rule_type::context_type
|
||||
, typename rule_type::skipper_type
|
||||
, F>
|
||||
success_handler;
|
||||
r.f = success_handler(r.f, f);
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
/*=============================================================================
|
||||
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_NUMERIC_FEBRUARY_05_2007_1231PM)
|
||||
#define BOOST_SPIRIT_NUMERIC_FEBRUARY_05_2007_1231PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/numeric/bool.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/int.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/uint.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/real.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,338 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
Copyright (c) 2011 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(SPIRIT_QI_BOOL_SEP_29_2009_0709AM)
|
||||
#define SPIRIT_QI_BOOL_SEP_29_2009_0709AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/bool_policies.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// forward declaration only
|
||||
template <typename T>
|
||||
struct bool_policies;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This is the class that the user can instantiate directly in
|
||||
// order to create a customized bool parser
|
||||
template <typename T, typename BoolPolicies = bool_policies<T> >
|
||||
struct bool_parser
|
||||
: spirit::terminal<tag::stateful_tag<BoolPolicies, tag::bool_, T> >
|
||||
{
|
||||
typedef tag::stateful_tag<BoolPolicies, tag::bool_, T> tag_type;
|
||||
|
||||
bool_parser() {}
|
||||
bool_parser(BoolPolicies const& data)
|
||||
: spirit::terminal<tag_type>(data) {}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables bool_
|
||||
struct use_terminal<qi::domain, tag::bool_>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables true_
|
||||
struct use_terminal<qi::domain, tag::true_>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables false_
|
||||
struct use_terminal<qi::domain, tag::false_>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables lit(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, bool> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables bool_(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::bool_, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* bool_(...)
|
||||
struct use_lazy_terminal<qi::domain, tag::bool_, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables any custom bool_parser
|
||||
template <typename T, typename BoolPolicies>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::stateful_tag<BoolPolicies, tag::bool_, T> >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables any custom bool_parser(...)
|
||||
template <typename T, typename BoolPolicies, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::stateful_tag<BoolPolicies, tag::bool_, T>
|
||||
, fusion::vector1<A0> > >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables *lazy* custom bool_parser(...)
|
||||
template <typename T, typename BoolPolicies>
|
||||
struct use_lazy_terminal<
|
||||
qi::domain
|
||||
, tag::stateful_tag<BoolPolicies, tag::bool_, T>
|
||||
, 1 // arity
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::bool_;
|
||||
using spirit::true_;
|
||||
using spirit::false_;
|
||||
using spirit::lit; // lit(true) is equivalent to true
|
||||
#endif
|
||||
using spirit::bool_type;
|
||||
using spirit::true_type;
|
||||
using spirit::false_type;
|
||||
using spirit::lit_type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename T, typename BoolPolicies>
|
||||
struct bool_impl
|
||||
{
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool parse(Iterator& first, Iterator const& last
|
||||
, Attribute& attr, BoolPolicies const& p, bool allow_true = true
|
||||
, bool disallow_false = false)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
|
||||
p; // suppresses warning: C4100: 'p' : unreferenced formal parameter
|
||||
#endif
|
||||
return (allow_true && p.parse_true(first, last, attr)) ||
|
||||
(!disallow_false && p.parse_false(first, last, attr));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This actual boolean parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename BoolPolicies = bool_policies<T> >
|
||||
struct any_bool_parser
|
||||
: primitive_parser<any_bool_parser<T, BoolPolicies> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef detail::bool_impl<T, BoolPolicies> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::parse(first, last, attr_, BoolPolicies());
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("boolean");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename BoolPolicies = bool_policies<T>
|
||||
, bool no_attribute = true>
|
||||
struct literal_bool_parser
|
||||
: primitive_parser<literal_bool_parser<T, BoolPolicies, no_attribute> >
|
||||
{
|
||||
template <typename Value>
|
||||
literal_bool_parser(Value const& n) : n_(n) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_c<no_attribute, unused_type, T>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef detail::bool_impl<T, BoolPolicies> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::parse(first, last, attr_, BoolPolicies(), n_, n_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("boolean");
|
||||
}
|
||||
|
||||
T n_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Modifiers
|
||||
, typename Policies = bool_policies<T> >
|
||||
struct make_bool
|
||||
{
|
||||
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
|
||||
no_case;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
no_case
|
||||
, is_same<bool_policies<T>, Policies>
|
||||
>
|
||||
, any_bool_parser<T, no_case_bool_policies<T> >
|
||||
, any_bool_parser<T, Policies> >::type
|
||||
result_type;
|
||||
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Modifiers
|
||||
, typename Policies = bool_policies<T> >
|
||||
struct make_direct_bool
|
||||
{
|
||||
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
|
||||
no_case;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
no_case
|
||||
, is_same<bool_policies<T>, Policies>
|
||||
>
|
||||
, literal_bool_parser<T, no_case_bool_policies<T>, false>
|
||||
, literal_bool_parser<T, Policies, false> >::type
|
||||
result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Modifiers, bool b
|
||||
, typename Policies = bool_policies<T> >
|
||||
struct make_predefined_direct_bool
|
||||
{
|
||||
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
|
||||
no_case;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
no_case
|
||||
, is_same<bool_policies<T>, Policies>
|
||||
>
|
||||
, literal_bool_parser<T, no_case_bool_policies<T>, false>
|
||||
, literal_bool_parser<T, Policies, false> >::type
|
||||
result_type;
|
||||
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type(b);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Modifiers
|
||||
, typename Policies = bool_policies<T> >
|
||||
struct make_literal_bool
|
||||
{
|
||||
typedef has_modifier<Modifiers, tag::char_code_base<tag::no_case> >
|
||||
no_case;
|
||||
|
||||
typedef typename mpl::if_<
|
||||
mpl::and_<
|
||||
no_case
|
||||
, is_same<bool_policies<T>, Policies>
|
||||
>
|
||||
, literal_bool_parser<T, no_case_bool_policies<T> >
|
||||
, literal_bool_parser<T, Policies> >::type
|
||||
result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, bool> >::type>
|
||||
: make_literal_bool<bool, Modifiers> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::false_, Modifiers>
|
||||
: make_predefined_direct_bool<bool, Modifiers, false>
|
||||
{};
|
||||
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::true_, Modifiers>
|
||||
: make_predefined_direct_bool<bool, Modifiers, true>
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Policies, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::stateful_tag<Policies, tag::bool_, T>, Modifiers>
|
||||
: make_bool<T, Modifiers, Policies> {};
|
||||
|
||||
template <typename T, typename Policies, typename A0, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::stateful_tag<Policies, tag::bool_, T>
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_bool<T, Modifiers, Policies> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::bool_, Modifiers>
|
||||
: make_bool<bool, Modifiers> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::bool_
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_bool<bool, Modifiers> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/*=============================================================================
|
||||
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_QI_BOOL_POLICIES_SEP_29_2009_0710AM)
|
||||
#define SPIRIT_QI_BOOL_POLICIES_SEP_29_2009_0710AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/detail/string_parse.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Default boolean policies
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T = bool>
|
||||
struct bool_policies
|
||||
{
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_true(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (detail::string_parse("true", first, last, unused))
|
||||
{
|
||||
spirit::traits::assign_to(T(true), attr_); // result is true
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_false(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (detail::string_parse("false", first, last, unused))
|
||||
{
|
||||
spirit::traits::assign_to(T(false), attr_); // result is false
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T = bool>
|
||||
struct no_case_bool_policies
|
||||
{
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_true(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (detail::string_parse("true", "TRUE", first, last, unused))
|
||||
{
|
||||
spirit::traits::assign_to(T(true), attr_); // result is true
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_false(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (detail::string_parse("false", "FALSE", first, last, unused))
|
||||
{
|
||||
spirit::traits::assign_to(T(false), attr_); // result is false
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
+534
@@ -0,0 +1,534 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
Copyright (c) 2011 Jan Frederick Eick
|
||||
Copyright (c) 2011 Christopher Jefferson
|
||||
Copyright (c) 2006 Stephen Nutt
|
||||
|
||||
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_NUMERIC_UTILS_APRIL_17_2006_0816AM)
|
||||
#define SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0816AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/char_encoding/ascii.hpp>
|
||||
#include <boost/spirit/home/support/numeric_traits.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/comparison/less.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/seq/elem.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/is_signed.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/integer_traits.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
|
||||
# define SPIRIT_NUMERICS_LOOP_UNROLL 3
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The maximum radix digits that can be represented without
|
||||
// overflow:
|
||||
//
|
||||
// template<typename T, unsigned Radix>
|
||||
// struct digits_traits::value;
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix>
|
||||
struct digits_traits;
|
||||
|
||||
// lookup table for log2(x) : 2 <= x <= 36
|
||||
#define BOOST_SPIRIT_LOG2 (#error)(#error) \
|
||||
(1000000)(1584960)(2000000)(2321920)(2584960)(2807350) \
|
||||
(3000000)(3169920)(3321920)(3459430)(3584960)(3700430) \
|
||||
(3807350)(3906890)(4000000)(4087460)(4169920)(4247920) \
|
||||
(4321920)(4392310)(4459430)(4523560)(4584960)(4643850) \
|
||||
(4700430)(4754880)(4807350)(4857980)(4906890)(4954190) \
|
||||
(5000000)(5044390)(5087460)(5129280)(5169925) \
|
||||
/***/
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(Radix) \
|
||||
template <typename T> struct digits_traits<T, Radix> \
|
||||
{ \
|
||||
typedef std::numeric_limits<T> numeric_limits_type; \
|
||||
BOOST_STATIC_CONSTANT(int, value = static_cast<int>( \
|
||||
(numeric_limits_type::digits * 1000000) / \
|
||||
BOOST_PP_SEQ_ELEM(Radix, BOOST_SPIRIT_LOG2))); \
|
||||
}; \
|
||||
/***/
|
||||
|
||||
#define BOOST_PP_LOCAL_LIMITS (2, 36)
|
||||
#include BOOST_PP_LOCAL_ITERATE()
|
||||
|
||||
#undef BOOST_SPIRIT_LOG2
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Traits class for radix specific number conversion
|
||||
//
|
||||
// Test the validity of a single character:
|
||||
//
|
||||
// template<typename Char> static bool is_valid(Char ch);
|
||||
//
|
||||
// Convert a digit from character representation to binary
|
||||
// representation:
|
||||
//
|
||||
// template<typename Char> static int digit(Char ch);
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <unsigned Radix>
|
||||
struct radix_traits
|
||||
{
|
||||
template <typename Char>
|
||||
inline static bool is_valid(Char ch)
|
||||
{
|
||||
if (Radix <= 10)
|
||||
return (ch >= '0' && ch <= static_cast<Char>('0' + Radix -1));
|
||||
return (ch >= '0' && ch <= '9')
|
||||
|| (ch >= 'a' && ch <= static_cast<Char>('a' + Radix -10 -1))
|
||||
|| (ch >= 'A' && ch <= static_cast<Char>('A' + Radix -10 -1));
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline static unsigned digit(Char ch)
|
||||
{
|
||||
if (Radix <= 10 || (ch >= '0' && ch <= '9'))
|
||||
return ch - '0';
|
||||
return spirit::char_encoding::ascii::tolower(ch) - 'a' + 10;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, T Val>
|
||||
struct constexpr_int
|
||||
{
|
||||
BOOST_STATIC_CONSTEXPR T value = Val;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// positive_accumulator/negative_accumulator: Accumulator policies for
|
||||
// extracting integers. Use positive_accumulator if number is positive.
|
||||
// Use negative_accumulator if number is negative.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <unsigned Radix>
|
||||
struct positive_accumulator
|
||||
{
|
||||
template <typename T, typename Char>
|
||||
inline static void add(T& n, Char ch, mpl::false_) // unchecked add
|
||||
{
|
||||
const int digit = radix_traits<Radix>::digit(ch);
|
||||
n = n * T(Radix) + T(digit);
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline static bool add(T& n, Char ch, mpl::true_) // checked add
|
||||
{
|
||||
// Ensure n *= Radix will not overflow
|
||||
typedef constexpr_int<T, boost::integer_traits<T>::const_max> max;
|
||||
typedef constexpr_int<T, max::value / Radix> val;
|
||||
|
||||
if (n > val::value)
|
||||
return false;
|
||||
|
||||
n *= Radix;
|
||||
|
||||
// Ensure n += digit will not overflow
|
||||
const int digit = radix_traits<Radix>::digit(ch);
|
||||
if (n > max::value - digit)
|
||||
return false;
|
||||
|
||||
n += static_cast<T>(digit);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned Radix>
|
||||
struct negative_accumulator
|
||||
{
|
||||
template <typename T, typename Char>
|
||||
inline static void add(T& n, Char ch, mpl::false_) // unchecked subtract
|
||||
{
|
||||
const int digit = radix_traits<Radix>::digit(ch);
|
||||
n = n * T(Radix) - T(digit);
|
||||
}
|
||||
|
||||
template <typename T, typename Char>
|
||||
inline static bool add(T& n, Char ch, mpl::true_) // checked subtract
|
||||
{
|
||||
// Ensure n *= Radix will not underflow
|
||||
typedef constexpr_int<T, boost::integer_traits<T>::const_min> min;
|
||||
typedef constexpr_int<T, (min::value + 1) / T(Radix)> val;
|
||||
|
||||
if (n < val::value)
|
||||
return false;
|
||||
|
||||
n *= Radix;
|
||||
|
||||
// Ensure n -= digit will not underflow
|
||||
int const digit = radix_traits<Radix>::digit(ch);
|
||||
if (n < min::value + digit)
|
||||
return false;
|
||||
|
||||
n -= static_cast<T>(digit);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Common code for extract_int::parse specializations
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <unsigned Radix, typename Accumulator, int MaxDigits, bool AlwaysCheckOverflow>
|
||||
struct int_extractor
|
||||
{
|
||||
template <typename Char, typename T>
|
||||
inline static bool
|
||||
call(Char ch, std::size_t count, T& n, mpl::true_)
|
||||
{
|
||||
typedef constexpr_int<std::size_t, digits_traits<T, Radix>::value - 1> overflow_free;
|
||||
|
||||
if (!AlwaysCheckOverflow && (count < overflow_free::value))
|
||||
{
|
||||
Accumulator::add(n, ch, mpl::false_());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Accumulator::add(n, ch, mpl::true_()))
|
||||
return false; // over/underflow!
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
inline static bool
|
||||
call(Char ch, std::size_t /*count*/, T& n, mpl::false_)
|
||||
{
|
||||
// no need to check for overflow
|
||||
Accumulator::add(n, ch, mpl::false_());
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
inline static bool
|
||||
call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
inline static bool
|
||||
call(Char ch, std::size_t count, T& n)
|
||||
{
|
||||
return call(ch, count, n
|
||||
, mpl::bool_<
|
||||
( (MaxDigits < 0)
|
||||
|| (MaxDigits > digits_traits<T, Radix>::value)
|
||||
)
|
||||
&& traits::check_overflow<T>::value
|
||||
>()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// End of loop checking: check if the number of digits
|
||||
// being parsed exceeds MaxDigits. Note: if MaxDigits == -1
|
||||
// we don't do any checking.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <int MaxDigits>
|
||||
struct check_max_digits
|
||||
{
|
||||
inline static bool
|
||||
call(std::size_t count)
|
||||
{
|
||||
return count < MaxDigits; // bounded
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct check_max_digits<-1>
|
||||
{
|
||||
inline static bool
|
||||
call(std::size_t /*count*/)
|
||||
{
|
||||
return true; // unbounded
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// extract_int: main code for extracting integers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
|
||||
if (!check_max_digits<MaxDigits>::call(count + leading_zeros) \
|
||||
|| it == last) \
|
||||
break; \
|
||||
ch = *it; \
|
||||
if (!radix_check::is_valid(ch)) \
|
||||
break; \
|
||||
if (!extractor::call(ch, count, val)) \
|
||||
{ \
|
||||
if (IgnoreOverflowDigits) \
|
||||
first = it; \
|
||||
traits::assign_to(val, attr); \
|
||||
return IgnoreOverflowDigits; \
|
||||
} \
|
||||
++it; \
|
||||
++count; \
|
||||
/**/
|
||||
|
||||
template <
|
||||
typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename Accumulator = positive_accumulator<Radix>
|
||||
, bool Accumulate = false
|
||||
, bool IgnoreOverflowDigits = false
|
||||
>
|
||||
struct extract_int
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool
|
||||
parse_main(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
typedef radix_traits<Radix> radix_check;
|
||||
typedef int_extractor<Radix, Accumulator, MaxDigits, Accumulate> extractor;
|
||||
typedef typename
|
||||
boost::detail::iterator_traits<Iterator>::value_type
|
||||
char_type;
|
||||
|
||||
Iterator it = first;
|
||||
std::size_t leading_zeros = 0;
|
||||
if (!Accumulate)
|
||||
{
|
||||
// skip leading zeros
|
||||
while (it != last && *it == '0' && (MaxDigits < 0 || leading_zeros < static_cast< std::size_t >(MaxDigits)))
|
||||
{
|
||||
++it;
|
||||
++leading_zeros;
|
||||
}
|
||||
}
|
||||
|
||||
typedef typename
|
||||
traits::attribute_type<Attribute>::type
|
||||
attribute_type;
|
||||
|
||||
attribute_type val = Accumulate ? attr : attribute_type(0);
|
||||
std::size_t count = 0;
|
||||
char_type ch;
|
||||
|
||||
while (true)
|
||||
{
|
||||
BOOST_PP_REPEAT(
|
||||
SPIRIT_NUMERICS_LOOP_UNROLL
|
||||
, SPIRIT_NUMERIC_INNER_LOOP, _)
|
||||
}
|
||||
|
||||
if (count + leading_zeros >= MinDigits)
|
||||
{
|
||||
traits::assign_to(val, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
inline static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, unused_type)
|
||||
{
|
||||
T n = 0; // must calculate value to detect over/underflow
|
||||
return parse_main(first, last, n);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
return parse_main(first, last, attr);
|
||||
}
|
||||
};
|
||||
#undef SPIRIT_NUMERIC_INNER_LOOP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// extract_int: main code for extracting integers
|
||||
// common case where MinDigits == 1 and MaxDigits = -1
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#define SPIRIT_NUMERIC_INNER_LOOP(z, x, data) \
|
||||
if (it == last) \
|
||||
break; \
|
||||
ch = *it; \
|
||||
if (!radix_check::is_valid(ch)) \
|
||||
break; \
|
||||
if (!extractor::call(ch, count, val)) \
|
||||
{ \
|
||||
traits::assign_to(val, attr); \
|
||||
return false; \
|
||||
} \
|
||||
++it; \
|
||||
++count; \
|
||||
/**/
|
||||
|
||||
template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
|
||||
struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool
|
||||
parse_main(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
typedef radix_traits<Radix> radix_check;
|
||||
typedef int_extractor<Radix, Accumulator, -1, Accumulate> extractor;
|
||||
typedef typename
|
||||
boost::detail::iterator_traits<Iterator>::value_type
|
||||
char_type;
|
||||
|
||||
Iterator it = first;
|
||||
std::size_t count = 0;
|
||||
if (!Accumulate)
|
||||
{
|
||||
// skip leading zeros
|
||||
while (it != last && *it == '0')
|
||||
{
|
||||
++it;
|
||||
++count;
|
||||
}
|
||||
|
||||
if (it == last)
|
||||
{
|
||||
if (count == 0) // must have at least one digit
|
||||
return false;
|
||||
traits::assign_to(0, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
typedef typename
|
||||
traits::attribute_type<Attribute>::type
|
||||
attribute_type;
|
||||
|
||||
attribute_type val = Accumulate ? attr : attribute_type(0);
|
||||
char_type ch = *it;
|
||||
|
||||
if (!radix_check::is_valid(ch) || !extractor::call(ch, 0, val))
|
||||
{
|
||||
if (count == 0) // must have at least one digit
|
||||
return false;
|
||||
traits::assign_to(val, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
|
||||
// count = 0; $$$ verify: I think this is wrong $$$
|
||||
++it;
|
||||
while (true)
|
||||
{
|
||||
BOOST_PP_REPEAT(
|
||||
SPIRIT_NUMERICS_LOOP_UNROLL
|
||||
, SPIRIT_NUMERIC_INNER_LOOP, _)
|
||||
}
|
||||
|
||||
traits::assign_to(val, attr);
|
||||
first = it;
|
||||
return true;
|
||||
}
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <typename Iterator>
|
||||
inline static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, unused_type)
|
||||
{
|
||||
T n = 0; // must calculate value to detect over/underflow
|
||||
return parse_main(first, last, n);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator const& last
|
||||
, Attribute& attr)
|
||||
{
|
||||
return parse_main(first, last, attr);
|
||||
}
|
||||
};
|
||||
|
||||
#undef SPIRIT_NUMERIC_INNER_LOOP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Cast an signed integer to an unsigned integer
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T,
|
||||
bool force_unsigned
|
||||
= mpl::and_<is_integral<T>, is_signed<T> >::value>
|
||||
struct cast_unsigned;
|
||||
|
||||
template <typename T>
|
||||
struct cast_unsigned<T, true>
|
||||
{
|
||||
typedef typename make_unsigned<T>::type unsigned_type;
|
||||
typedef typename make_unsigned<T>::type& unsigned_type_ref;
|
||||
|
||||
inline static unsigned_type_ref call(T& n)
|
||||
{
|
||||
return unsigned_type_ref(n);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct cast_unsigned<T, false>
|
||||
{
|
||||
inline static T& call(T& n)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
};
|
||||
}}}}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/*=============================================================================
|
||||
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_REAL_IMPL_APRIL_18_2006_0901AM)
|
||||
#define SPIRIT_REAL_IMPL_APRIL_18_2006_0901AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/detail/pow10.hpp>
|
||||
#include <boost/spirit/home/support/detail/sign.hpp>
|
||||
#include <boost/integer.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
|
||||
# pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
using spirit::traits::pow10;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename T, typename AccT>
|
||||
void compensate_roundoff(T& n, AccT acc_n, mpl::true_)
|
||||
{
|
||||
// at the lowest extremes, we compensate for floating point
|
||||
// roundoff errors by doing imprecise computation using T
|
||||
int const comp = 10;
|
||||
n = T((acc_n / comp) * comp);
|
||||
n += T(acc_n % comp);
|
||||
}
|
||||
|
||||
template <typename T, typename AccT>
|
||||
void compensate_roundoff(T& n, AccT acc_n, mpl::false_)
|
||||
{
|
||||
// no need to compensate
|
||||
n = acc_n;
|
||||
}
|
||||
|
||||
template <typename T, typename AccT>
|
||||
void compensate_roundoff(T& n, AccT acc_n)
|
||||
{
|
||||
compensate_roundoff(n, acc_n, is_integral<AccT>());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename AccT>
|
||||
inline bool
|
||||
scale(int exp, T& n, AccT acc_n)
|
||||
{
|
||||
if (exp >= 0)
|
||||
{
|
||||
int max_exp = std::numeric_limits<T>::max_exponent10;
|
||||
|
||||
// return false if exp exceeds the max_exp
|
||||
// do this check only for primitive types!
|
||||
if (is_floating_point<T>() && exp > max_exp)
|
||||
return false;
|
||||
n = acc_n * pow10<T>(exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (exp < std::numeric_limits<T>::min_exponent10)
|
||||
{
|
||||
int min_exp = std::numeric_limits<T>::min_exponent10;
|
||||
detail::compensate_roundoff(n, acc_n);
|
||||
n /= pow10<T>(-min_exp);
|
||||
|
||||
// return false if (-exp + min_exp) exceeds the -min_exp
|
||||
// do this check only for primitive types!
|
||||
if (is_floating_point<T>() && (-exp + min_exp) > -min_exp)
|
||||
return false;
|
||||
|
||||
n /= pow10<T>(-exp + min_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = T(acc_n) / pow10<T>(-exp);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
scale(int /*exp*/, unused_type /*n*/, unused_type /*acc_n*/)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T, typename AccT>
|
||||
inline bool
|
||||
scale(int exp, int frac, T& n, AccT acc_n)
|
||||
{
|
||||
return scale(exp - frac, n, acc_n);
|
||||
}
|
||||
|
||||
inline bool
|
||||
scale(int /*exp*/, int /*frac*/, unused_type /*n*/)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return true;
|
||||
}
|
||||
|
||||
inline float
|
||||
negate(bool neg, float n)
|
||||
{
|
||||
return neg ? spirit::detail::changesign(n) : n;
|
||||
}
|
||||
|
||||
inline double
|
||||
negate(bool neg, double n)
|
||||
{
|
||||
return neg ? spirit::detail::changesign(n) : n;
|
||||
}
|
||||
|
||||
inline long double
|
||||
negate(bool neg, long double n)
|
||||
{
|
||||
return neg ? spirit::detail::changesign(n) : n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T
|
||||
negate(bool neg, T const& n)
|
||||
{
|
||||
return neg ? -n : n;
|
||||
}
|
||||
|
||||
inline unused_type
|
||||
negate(bool /*neg*/, unused_type n)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool
|
||||
is_equal_to_one(T const& value)
|
||||
{
|
||||
return value == 1.0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
is_equal_to_one(unused_type)
|
||||
{
|
||||
// no-op for unused_type
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct real_accumulator : mpl::identity<T> {};
|
||||
|
||||
template <>
|
||||
struct real_accumulator<float>
|
||||
: mpl::identity<uint_t<(sizeof(float)*CHAR_BIT)>::least> {};
|
||||
|
||||
template <>
|
||||
struct real_accumulator<double>
|
||||
: mpl::identity<uint_t<(sizeof(double)*CHAR_BIT)>::least> {};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
template <typename T, typename RealPolicies>
|
||||
struct real_impl
|
||||
{
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse(Iterator& first, Iterator const& last, Attribute& attr,
|
||||
RealPolicies const& p)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
Iterator save = first;
|
||||
|
||||
// Start by parsing the sign. neg will be true if
|
||||
// we got a "-" sign, false otherwise.
|
||||
bool neg = p.parse_sign(first, last);
|
||||
|
||||
// Now attempt to parse an integer
|
||||
T n;
|
||||
|
||||
typename traits::real_accumulator<T>::type acc_n = 0;
|
||||
bool got_a_number = p.parse_n(first, last, acc_n);
|
||||
|
||||
// If we did not get a number it might be a NaN, Inf or a leading
|
||||
// dot.
|
||||
if (!got_a_number)
|
||||
{
|
||||
// Check whether the number to parse is a NaN or Inf
|
||||
if (p.parse_nan(first, last, n) ||
|
||||
p.parse_inf(first, last, n))
|
||||
{
|
||||
// If we got a negative sign, negate the number
|
||||
traits::assign_to(traits::negate(neg, n), attr);
|
||||
return true; // got a NaN or Inf, return early
|
||||
}
|
||||
|
||||
// If we did not get a number and our policies do not
|
||||
// allow a leading dot, fail and return early (no-match)
|
||||
if (!p.allow_leading_dot)
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool e_hit = false;
|
||||
Iterator e_pos;
|
||||
int frac_digits = 0;
|
||||
|
||||
// Try to parse the dot ('.' decimal point)
|
||||
if (p.parse_dot(first, last))
|
||||
{
|
||||
// We got the decimal point. Now we will try to parse
|
||||
// the fraction if it is there. If not, it defaults
|
||||
// to zero (0) only if we already got a number.
|
||||
if (p.parse_frac_n(first, last, acc_n, frac_digits))
|
||||
{
|
||||
}
|
||||
else if (!got_a_number || !p.allow_trailing_dot)
|
||||
{
|
||||
// We did not get a fraction. If we still haven't got a
|
||||
// number and our policies do not allow a trailing dot,
|
||||
// return no-match.
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now, let's see if we can parse the exponent prefix
|
||||
e_pos = first;
|
||||
e_hit = p.parse_exp(first, last);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No dot and no number! Return no-match.
|
||||
if (!got_a_number)
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we must expect a dot and we didn't see an exponent
|
||||
// prefix, return no-match.
|
||||
e_pos = first;
|
||||
e_hit = p.parse_exp(first, last);
|
||||
if (p.expect_dot && !e_hit)
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (e_hit)
|
||||
{
|
||||
// We got the exponent prefix. Now we will try to parse the
|
||||
// actual exponent.
|
||||
int exp = 0;
|
||||
if (p.parse_exp_n(first, last, exp))
|
||||
{
|
||||
// Got the exponent value. Scale the number by
|
||||
// exp-frac_digits.
|
||||
if (!traits::scale(exp, frac_digits, n, acc_n))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If there is no number, disregard the exponent altogether.
|
||||
// by resetting 'first' prior to the exponent prefix (e|E)
|
||||
first = e_pos;
|
||||
n = static_cast<T>(acc_n);
|
||||
}
|
||||
}
|
||||
else if (frac_digits)
|
||||
{
|
||||
// No exponent found. Scale the number by -frac_digits.
|
||||
traits::scale(-frac_digits, n, acc_n);
|
||||
}
|
||||
else if (traits::is_equal_to_one(acc_n))
|
||||
{
|
||||
// There is a chance of having to parse one of the 1.0#...
|
||||
// styles some implementations use for representing NaN or Inf.
|
||||
|
||||
// Check whether the number to parse is a NaN or Inf
|
||||
if (p.parse_nan(first, last, n) ||
|
||||
p.parse_inf(first, last, n))
|
||||
{
|
||||
// If we got a negative sign, negate the number
|
||||
traits::assign_to(traits::negate(neg, n), attr);
|
||||
return true; // got a NaN or Inf, return immediately
|
||||
}
|
||||
|
||||
n = static_cast<T>(acc_n);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = static_cast<T>(acc_n);
|
||||
}
|
||||
|
||||
// If we got a negative sign, negate the number
|
||||
traits::assign_to(traits::negate(neg, n), attr);
|
||||
|
||||
// Success!!!
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,411 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2011 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_INT_APR_17_2006_0830AM)
|
||||
#define BOOST_SPIRIT_INT_APR_17_2006_0830AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace tag
|
||||
{
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct int_parser
|
||||
{
|
||||
BOOST_SPIRIT_IS_TAG()
|
||||
};
|
||||
}
|
||||
|
||||
namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This one is the class that the user can instantiate directly in
|
||||
// order to create a customized int parser
|
||||
template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct int_parser
|
||||
: spirit::terminal<tag::int_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_enable_short
|
||||
template <> // enables short_
|
||||
struct use_terminal<qi::domain, tag::short_> : mpl::true_ {};
|
||||
//]
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, signed short> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables short_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::short_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* short_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::short_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_enable_int
|
||||
template <> // enables int_
|
||||
struct use_terminal<qi::domain, tag::int_> : mpl::true_ {};
|
||||
//]
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, signed> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables int_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::int_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* int_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::int_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_enable_long
|
||||
template <> // enables long_
|
||||
struct use_terminal<qi::domain, tag::long_> : mpl::true_ {};
|
||||
//]
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, signed long> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables long_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::long_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* long_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::long_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
//[primitive_parsers_enable_long_long
|
||||
template <> // enables long_long
|
||||
struct use_terminal<qi::domain, tag::long_long> : mpl::true_ {};
|
||||
//]
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, boost::long_long_type> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables long_long(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::long_long, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* long_long(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::long_long, 1> : mpl::true_ {};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables any custom int_parser
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::int_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables any custom int_parser(n)
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
// enables *lazy* custom int_parser(n)
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct use_lazy_terminal<qi::domain
|
||||
, tag::int_parser<T, Radix, MinDigits, MaxDigits>, 1
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::short_;
|
||||
using spirit::int_;
|
||||
using spirit::long_;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using spirit::long_long;
|
||||
#endif
|
||||
using spirit::lit; // lit(1) is equivalent to 1
|
||||
#endif
|
||||
using spirit::short_type;
|
||||
using spirit::int_type;
|
||||
using spirit::long_type;
|
||||
using spirit::lit_type;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using spirit::long_long_type;
|
||||
#endif
|
||||
using spirit::lit_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is the actual int parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_int_parser
|
||||
template <
|
||||
typename T
|
||||
, unsigned Radix = 10
|
||||
, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct any_int_parser
|
||||
: primitive_parser<any_int_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::call(first, last, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("integer");
|
||||
}
|
||||
};
|
||||
//]
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1, bool no_attribute = true>
|
||||
struct literal_int_parser
|
||||
: primitive_parser<literal_int_parser<T, Radix, MinDigits, MaxDigits
|
||||
, no_attribute> >
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Value>
|
||||
literal_int_parser(Value const& n) : n_(n) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_c<no_attribute, unused_type, T>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
typedef extract_int<T, Radix, MinDigits, MaxDigits> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
Iterator save = first;
|
||||
T attr_;
|
||||
|
||||
if (extract::call(first, last, attr_) && (attr_ == n_))
|
||||
{
|
||||
traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("integer");
|
||||
}
|
||||
|
||||
T n_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_make_int
|
||||
template <
|
||||
typename T
|
||||
, unsigned Radix = 10
|
||||
, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_int
|
||||
{
|
||||
typedef any_int_parser<T, Radix, MinDigits, MaxDigits> result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
//]
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_direct_int
|
||||
{
|
||||
typedef literal_int_parser<T, Radix, MinDigits, MaxDigits, false>
|
||||
result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_literal_int
|
||||
{
|
||||
typedef literal_int_parser<T, Radix, MinDigits, MaxDigits> result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, signed short> >::type>
|
||||
: make_literal_int<signed short> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, signed> >::type>
|
||||
: make_literal_int<signed> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, signed long> >::type>
|
||||
: make_literal_int<signed long> {};
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, boost::long_long_type> >::type>
|
||||
: make_literal_int<boost::long_long_type> {};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::int_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, Modifiers>
|
||||
: make_int<T, Radix, MinDigits, MaxDigits> {};
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename A0, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::int_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_int<T, Radix, MinDigits, MaxDigits> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_short_primitive
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::short_, Modifiers>
|
||||
: make_int<short> {};
|
||||
//]
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::short_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_int<short> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_int_primitive
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::int_, Modifiers>
|
||||
: make_int<int> {};
|
||||
//]
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::int_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_int<int> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[primitive_parsers_long_primitive
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::long_, Modifiers>
|
||||
: make_int<long> {};
|
||||
//]
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::long_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_int<long> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
//[primitive_parsers_long_long_primitive
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::long_long, Modifiers>
|
||||
: make_int<boost::long_long_type> {};
|
||||
//]
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::long_long
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_int<boost::long_long_type> {};
|
||||
#endif
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2011 Jan Frederick Eick
|
||||
|
||||
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_NUMERIC_UTILS_APRIL_17_2006_0830AM)
|
||||
#define BOOST_SPIRIT_NUMERIC_UTILS_APRIL_17_2006_0830AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/assert_msg.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/detail/numeric_utils.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Extract the prefix sign (- or +), return true if a '-' was found
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator>
|
||||
inline bool
|
||||
extract_sign(Iterator& first, Iterator const& last)
|
||||
{
|
||||
(void)last; // silence unused warnings
|
||||
BOOST_ASSERT(first != last); // precondition
|
||||
|
||||
// Extract the sign
|
||||
bool neg = *first == '-';
|
||||
if (neg || (*first == '+'))
|
||||
{
|
||||
++first;
|
||||
return neg;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Low level unsigned integer parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, bool Accumulate = false, bool IgnoreOverflowDigits = false>
|
||||
struct extract_uint
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix >= 2 && Radix <= 36,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Iterator>
|
||||
inline static bool call(Iterator& first, Iterator const& last, T& attr_)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
typedef detail::extract_int<
|
||||
T
|
||||
, Radix
|
||||
, MinDigits
|
||||
, MaxDigits
|
||||
, detail::positive_accumulator<Radix>
|
||||
, Accumulate
|
||||
, IgnoreOverflowDigits>
|
||||
extract_type;
|
||||
|
||||
Iterator save = first;
|
||||
if (!extract_type::parse(first, last,
|
||||
detail::cast_unsigned<T>::call(attr_)))
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
// this case is called when Attribute is not T
|
||||
T attr_local;
|
||||
if (call(first, last, attr_local))
|
||||
{
|
||||
traits::assign_to(attr_local, attr_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Low level signed integer parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
|
||||
struct extract_int
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Iterator>
|
||||
inline static bool call(Iterator& first, Iterator const& last, T& attr_)
|
||||
{
|
||||
if (first == last)
|
||||
return false;
|
||||
|
||||
typedef detail::extract_int<
|
||||
T, Radix, MinDigits, MaxDigits>
|
||||
extract_pos_type;
|
||||
|
||||
typedef detail::extract_int<
|
||||
T, Radix, MinDigits, MaxDigits, detail::negative_accumulator<Radix> >
|
||||
extract_neg_type;
|
||||
|
||||
Iterator save = first;
|
||||
bool hit = extract_sign(first, last);
|
||||
if (hit)
|
||||
hit = extract_neg_type::parse(first, last, attr_);
|
||||
else
|
||||
hit = extract_pos_type::parse(first, last, attr_);
|
||||
|
||||
if (!hit)
|
||||
{
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
inline static bool call(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
// this case is called when Attribute is not T
|
||||
T attr_local;
|
||||
if (call(first, last, attr_local))
|
||||
{
|
||||
traits::assign_to(attr_local, attr_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,342 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2011 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_REAL_APRIL_18_2006_0850AM)
|
||||
#define BOOST_SPIRIT_REAL_APRIL_18_2006_0850AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/real_policies.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/detail/real_impl.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// forward declaration only
|
||||
template <typename T>
|
||||
struct real_policies;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This is the class that the user can instantiate directly in
|
||||
// order to create a customized real parser
|
||||
template <typename T = double, typename Policies = real_policies<T> >
|
||||
struct real_parser
|
||||
: spirit::terminal<tag::stateful_tag<Policies, tag::double_, T> >
|
||||
{
|
||||
typedef tag::stateful_tag<Policies, tag::double_, T> tag_type;
|
||||
|
||||
real_parser() {}
|
||||
real_parser(Policies const& p)
|
||||
: spirit::terminal<tag_type>(p) {}
|
||||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables float_
|
||||
struct use_terminal<qi::domain, tag::float_>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables double_
|
||||
struct use_terminal<qi::domain, tag::double_>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables long_double
|
||||
struct use_terminal<qi::domain, tag::long_double>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, float> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, double> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, long double> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename A0> // enables float_(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::float_, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables double_(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::double_, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables long_double(...)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::long_double, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* float_(...)
|
||||
struct use_lazy_terminal<qi::domain, tag::float_, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* double_(...)
|
||||
struct use_lazy_terminal<qi::domain, tag::double_, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <> // enables *lazy* long_double_(...)
|
||||
struct use_lazy_terminal<qi::domain, tag::long_double, 1>
|
||||
: mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables custom real_parser
|
||||
template <typename T, typename Policies>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::stateful_tag<Policies, tag::double_, T> >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables custom real_parser(...)
|
||||
template <typename T, typename Policies, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
|
||||
, fusion::vector1<A0> > >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables *lazy* custom real_parser(...)
|
||||
template <typename T, typename Policies>
|
||||
struct use_lazy_terminal<
|
||||
qi::domain
|
||||
, tag::stateful_tag<Policies, tag::double_, T>
|
||||
, 1 // arity
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::float_;
|
||||
using spirit::double_;
|
||||
using spirit::long_double;
|
||||
using spirit::lit; // lit(1.0) is equivalent to 1.0
|
||||
#endif
|
||||
|
||||
using spirit::float_type;
|
||||
using spirit::double_type;
|
||||
using spirit::long_double_type;
|
||||
using spirit::lit_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is the actual real number parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename RealPolicies = real_policies<T> >
|
||||
struct any_real_parser
|
||||
: primitive_parser<any_real_parser<T, RealPolicies> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, T& attr_) const
|
||||
{
|
||||
typedef detail::real_impl<T, RealPolicies> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::parse(first, last, attr_, RealPolicies());
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
// this case is called when Attribute is not T
|
||||
T attr_;
|
||||
if (parse(first, last, context, skipper, attr_))
|
||||
{
|
||||
traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("real");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename RealPolicies = real_policies<T>
|
||||
, bool no_attribute = true>
|
||||
struct literal_real_parser
|
||||
: primitive_parser<literal_real_parser<T, RealPolicies, no_attribute> >
|
||||
{
|
||||
template <typename Value>
|
||||
literal_real_parser(Value const& n) : n_(n) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_c<no_attribute, unused_type, T>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context&, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
typedef detail::real_impl<T, RealPolicies> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
Iterator save = first;
|
||||
T attr_;
|
||||
|
||||
if (extract::parse(first, last, attr_, RealPolicies()) &&
|
||||
(attr_ == n_))
|
||||
{
|
||||
traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("real");
|
||||
}
|
||||
|
||||
T n_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Policies = real_policies<T> >
|
||||
struct make_real
|
||||
{
|
||||
typedef any_real_parser<T, Policies> result_type;
|
||||
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Policies = real_policies<T> >
|
||||
struct make_direct_real
|
||||
{
|
||||
typedef literal_real_parser<T, Policies, false> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(T(fusion::at_c<0>(term.args)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Policies = real_policies<T> >
|
||||
struct make_literal_real
|
||||
{
|
||||
typedef literal_real_parser<T, Policies> result_type;
|
||||
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, float> >::type>
|
||||
: make_literal_real<float> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, double> >::type>
|
||||
: make_literal_real<double> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, long double> >::type>
|
||||
: make_literal_real<long double> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename Policies, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::stateful_tag<Policies, tag::double_, T>, Modifiers>
|
||||
: make_real<T, Policies> {};
|
||||
|
||||
template <typename T, typename Policies, typename A0, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::stateful_tag<Policies, tag::double_, T>
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_real<T, Policies> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::float_, Modifiers>
|
||||
: make_real<float> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::float_
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_real<float> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::double_, Modifiers>
|
||||
: make_real<double> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::double_
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_real<double> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::long_double, Modifiers>
|
||||
: make_real<long double> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::long_double
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_real<long double> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,198 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM)
|
||||
#define SPIRIT_REAL_POLICIES_APRIL_17_2006_1158PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/detail/string_parse.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Default (unsigned) real number policies
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct ureal_policies
|
||||
{
|
||||
// trailing dot policy suggested by Gustavo Guerra
|
||||
static bool const allow_leading_dot = true;
|
||||
static bool const allow_trailing_dot = true;
|
||||
static bool const expect_dot = false;
|
||||
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_sign(Iterator& /*first*/, Iterator const& /*last*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_n(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
return extract_uint<Attribute, 10, 1, -1>::call(first, last, attr_);
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_dot(Iterator& first, Iterator const& last)
|
||||
{
|
||||
if (first == last || *first != '.')
|
||||
return false;
|
||||
++first;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_frac_n(Iterator& first, Iterator const& last, Attribute& attr_, int& frac_digits)
|
||||
{
|
||||
Iterator savef = first;
|
||||
bool r = extract_uint<Attribute, 10, 1, -1, true, true>::call(first, last, attr_);
|
||||
if (r)
|
||||
{
|
||||
// Optimization note: don't compute frac_digits if T is
|
||||
// an unused_type. This should be optimized away by the compiler.
|
||||
if (!is_same<T, unused_type>::value)
|
||||
frac_digits =
|
||||
static_cast<int>(std::distance(savef, first));
|
||||
// ignore extra (non-significant digits)
|
||||
extract_uint<unused_type, 10, 1, -1>::call(first, last, unused);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_exp(Iterator& first, Iterator const& last)
|
||||
{
|
||||
if (first == last || (*first != 'e' && *first != 'E'))
|
||||
return false;
|
||||
++first;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_exp_n(Iterator& first, Iterator const& last, int& attr_)
|
||||
{
|
||||
return extract_int<int, 10, 1, -1>::call(first, last, attr_);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// The parse_nan() and parse_inf() functions get called whenever:
|
||||
//
|
||||
// - a number to parse does not start with a digit (after having
|
||||
// successfully parsed an optional sign)
|
||||
//
|
||||
// or
|
||||
//
|
||||
// - after a floating point number of the value 1 (having no
|
||||
// exponential part and a fractional part value of 0) has been
|
||||
// parsed.
|
||||
//
|
||||
// The first call allows to recognize representations of NaN or Inf
|
||||
// starting with a non-digit character (such as NaN, Inf, QNaN etc.).
|
||||
//
|
||||
// The second call allows to recognize representation formats starting
|
||||
// with a 1.0 (such as 1.0#NAN or 1.0#INF etc.).
|
||||
//
|
||||
// The functions should return true if a Nan or Inf has been found. In
|
||||
// this case the attr should be set to the matched value (NaN or
|
||||
// Inf). The optional sign will be automatically applied afterwards.
|
||||
//
|
||||
// The default implementation below recognizes representations of NaN
|
||||
// and Inf as mandated by the C99 Standard and as proposed for
|
||||
// inclusion into the C++0x Standard: nan, nan(...), inf and infinity
|
||||
// (the matching is performed case-insensitively).
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_nan(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (first == last)
|
||||
return false; // end of input reached
|
||||
|
||||
if (*first != 'n' && *first != 'N')
|
||||
return false; // not "nan"
|
||||
|
||||
// nan[(...)] ?
|
||||
if (detail::string_parse("nan", "NAN", first, last, unused))
|
||||
{
|
||||
if (first != last && *first == '(')
|
||||
{
|
||||
// skip trailing (...) part
|
||||
Iterator i = first;
|
||||
|
||||
while (++i != last && *i != ')')
|
||||
;
|
||||
if (i == last)
|
||||
return false; // no trailing ')' found, give up
|
||||
|
||||
first = ++i;
|
||||
}
|
||||
attr_ = std::numeric_limits<T>::quiet_NaN();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Attribute>
|
||||
static bool
|
||||
parse_inf(Iterator& first, Iterator const& last, Attribute& attr_)
|
||||
{
|
||||
if (first == last)
|
||||
return false; // end of input reached
|
||||
|
||||
if (*first != 'i' && *first != 'I')
|
||||
return false; // not "inf"
|
||||
|
||||
// inf or infinity ?
|
||||
if (detail::string_parse("inf", "INF", first, last, unused))
|
||||
{
|
||||
// skip allowed 'inity' part of infinity
|
||||
detail::string_parse("inity", "INITY", first, last, unused);
|
||||
attr_ = std::numeric_limits<T>::infinity();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Default (signed) real number policies
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct real_policies : ureal_policies<T>
|
||||
{
|
||||
template <typename Iterator>
|
||||
static bool
|
||||
parse_sign(Iterator& first, Iterator const& last)
|
||||
{
|
||||
return extract_sign(first, last);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct strict_ureal_policies : ureal_policies<T>
|
||||
{
|
||||
static bool const expect_dot = true;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct strict_real_policies : real_policies<T>
|
||||
{
|
||||
static bool const expect_dot = true;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,464 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2011 Bryce Lelbach
|
||||
Copyright (c) 2011 Jan Frederick Eick
|
||||
|
||||
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_UINT_APR_17_2006_0901AM)
|
||||
#define SPIRIT_UINT_APR_17_2006_0901AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/skip_over.hpp>
|
||||
#include <boost/spirit/home/qi/detail/enable_lit.hpp>
|
||||
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/common_terminals.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/detail/is_spirit_tag.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
namespace tag
|
||||
{
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct uint_parser
|
||||
{
|
||||
BOOST_SPIRIT_IS_TAG()
|
||||
};
|
||||
}
|
||||
|
||||
namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// This one is the class that the user can instantiate directly in
|
||||
// order to create a customized int parser
|
||||
template <typename T = int, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct uint_parser
|
||||
: spirit::terminal<tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables ushort_
|
||||
struct use_terminal<qi::domain, tag::ushort_> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, unsigned short> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables ushort_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::ushort_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* ushort_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::ushort_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables uint_
|
||||
struct use_terminal<qi::domain, tag::uint_> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, unsigned> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables uint_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::uint_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* uint_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::uint_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables ulong_
|
||||
struct use_terminal<qi::domain, tag::ulong_> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, unsigned long> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables ulong_(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::ulong_, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* ulong_(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::ulong_, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <> // enables ulong_long
|
||||
struct use_terminal<qi::domain, tag::ulong_long> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables lit(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables ulong_long(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::ulong_long, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* ulong_long(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::ulong_long, 1> : mpl::true_ {};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables bin
|
||||
struct use_terminal<qi::domain, tag::bin> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables bin(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::bin, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* bin(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::bin, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables oct
|
||||
struct use_terminal<qi::domain, tag::oct> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables oct(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::oct, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* oct(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::oct, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <> // enables hex
|
||||
struct use_terminal<qi::domain, tag::hex> : mpl::true_ {};
|
||||
|
||||
template <typename A0> // enables hex(n)
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::hex, fusion::vector1<A0> > >
|
||||
: is_arithmetic<A0> {};
|
||||
|
||||
template <> // enables *lazy* hex(n)
|
||||
struct use_lazy_terminal<qi::domain, tag::hex, 1> : mpl::true_ {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// enables any custom uint_parser
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct use_terminal<qi::domain
|
||||
, tag::uint_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
: mpl::true_ {};
|
||||
|
||||
// enables any custom uint_parser(n)
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits, typename A0>
|
||||
struct use_terminal<qi::domain
|
||||
, terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, fusion::vector1<A0> >
|
||||
> : mpl::true_ {};
|
||||
|
||||
// enables *lazy* custom uint_parser(n)
|
||||
template <typename T, unsigned Radix, unsigned MinDigits
|
||||
, int MaxDigits>
|
||||
struct use_lazy_terminal<qi::domain
|
||||
, tag::uint_parser<T, Radix, MinDigits, MaxDigits>, 1
|
||||
> : mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::bin;
|
||||
using spirit::oct;
|
||||
using spirit::hex;
|
||||
|
||||
using spirit::ushort_;
|
||||
using spirit::uint_;
|
||||
using spirit::ulong_;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using spirit::ulong_long;
|
||||
#endif
|
||||
using spirit::lit; // lit(1) is equivalent to 1
|
||||
#endif
|
||||
|
||||
using spirit::bin_type;
|
||||
using spirit::oct_type;
|
||||
using spirit::hex_type;
|
||||
|
||||
using spirit::ushort_type;
|
||||
using spirit::uint_type;
|
||||
using spirit::ulong_type;
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
using spirit::ulong_long_type;
|
||||
#endif
|
||||
using spirit::lit_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// This is the actual uint parser
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct any_uint_parser
|
||||
: primitive_parser<any_uint_parser<T, Radix, MinDigits, MaxDigits> >
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix >= 2 && Radix <= 36,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
return extract::call(first, last, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("unsigned-integer");
|
||||
}
|
||||
};
|
||||
//]
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1, bool no_attribute = true>
|
||||
struct literal_uint_parser
|
||||
: primitive_parser<literal_uint_parser<T, Radix, MinDigits, MaxDigits
|
||||
, no_attribute> >
|
||||
{
|
||||
// check template parameter 'Radix' for validity
|
||||
BOOST_SPIRIT_ASSERT_MSG(
|
||||
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
|
||||
not_supported_radix, ());
|
||||
|
||||
template <typename Value>
|
||||
literal_uint_parser(Value const& n) : n_(n) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
: mpl::if_c<no_attribute, unused_type, T>
|
||||
{};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_param) const
|
||||
{
|
||||
typedef extract_uint<T, Radix, MinDigits, MaxDigits> extract;
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
Iterator save = first;
|
||||
T attr_;
|
||||
|
||||
if (extract::call(first, last, attr_) && (attr_ == n_))
|
||||
{
|
||||
traits::assign_to(attr_, attr_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
first = save;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("unsigned-integer");
|
||||
}
|
||||
|
||||
T n_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_uint
|
||||
{
|
||||
typedef any_uint_parser<T, Radix, MinDigits, MaxDigits> result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_direct_uint
|
||||
{
|
||||
typedef literal_uint_parser<T, Radix, MinDigits, MaxDigits, false>
|
||||
result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, unsigned Radix = 10, unsigned MinDigits = 1
|
||||
, int MaxDigits = -1>
|
||||
struct make_literal_uint
|
||||
{
|
||||
typedef literal_uint_parser<T, Radix, MinDigits, MaxDigits> result_type;
|
||||
template <typename Terminal>
|
||||
result_type operator()(Terminal const& term, unused_type) const
|
||||
{
|
||||
return result_type(fusion::at_c<0>(term.args));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, unsigned short> >::type>
|
||||
: make_literal_uint<unsigned short> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, unsigned> >::type>
|
||||
: make_literal_uint<unsigned> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, unsigned long> >::type>
|
||||
: make_literal_uint<unsigned long> {};
|
||||
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::lit, fusion::vector1<A0> >
|
||||
, Modifiers, typename enable_if<is_same<A0, boost::ulong_long_type> >::type>
|
||||
: make_literal_uint<boost::ulong_long_type> {};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename Modifiers>
|
||||
struct make_primitive<
|
||||
tag::uint_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, Modifiers>
|
||||
: make_uint<T, Radix, MinDigits, MaxDigits> {};
|
||||
|
||||
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
|
||||
, typename A0, typename Modifiers>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::uint_parser<T, Radix, MinDigits, MaxDigits>
|
||||
, fusion::vector1<A0> >, Modifiers>
|
||||
: make_direct_uint<T, Radix, MinDigits, MaxDigits> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::bin, Modifiers>
|
||||
: make_uint<unsigned, 2> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::bin
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned, 2> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::oct, Modifiers>
|
||||
: make_uint<unsigned, 8> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::oct
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned, 8> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::hex, Modifiers>
|
||||
: make_uint<unsigned, 16> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::hex
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned, 16> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::ushort_, Modifiers>
|
||||
: make_uint<unsigned short> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::ushort_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned short> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::uint_, Modifiers>
|
||||
: make_uint<unsigned> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::uint_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::ulong_, Modifiers>
|
||||
: make_uint<unsigned long> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::ulong_
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<unsigned long> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::ulong_long, Modifiers>
|
||||
: make_uint<boost::ulong_long_type> {};
|
||||
|
||||
template <typename Modifiers, typename A0>
|
||||
struct make_primitive<
|
||||
terminal_ex<tag::ulong_long
|
||||
, fusion::vector1<A0> > , Modifiers>
|
||||
: make_direct_uint<boost::ulong_long_type> {};
|
||||
#endif
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
/*=============================================================================
|
||||
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_OPERATOR_FEBRUARY_02_2007_0558PM)
|
||||
#define BOOST_SPIRIT_OPERATOR_FEBRUARY_02_2007_0558PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/operator/sequence.hpp>
|
||||
#include <boost/spirit/home/qi/operator/expect.hpp>
|
||||
#include <boost/spirit/home/qi/operator/alternative.hpp>
|
||||
#include <boost/spirit/home/qi/operator/sequential_or.hpp>
|
||||
#include <boost/spirit/home/qi/operator/permutation.hpp>
|
||||
#include <boost/spirit/home/qi/operator/difference.hpp>
|
||||
#include <boost/spirit/home/qi/operator/list.hpp>
|
||||
#include <boost/spirit/home/qi/operator/optional.hpp>
|
||||
#include <boost/spirit/home/qi/operator/kleene.hpp>
|
||||
#include <boost/spirit/home/qi/operator/plus.hpp>
|
||||
#include <boost/spirit/home/qi/operator/and_predicate.hpp>
|
||||
#include <boost/spirit/home/qi/operator/not_predicate.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_ALTERNATIVE_FEBRUARY_05_2007_1153AM)
|
||||
#define SPIRIT_ALTERNATIVE_FEBRUARY_05_2007_1153AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/detail/alternative_function.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/detail/what_function.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/fusion/include/any.hpp>
|
||||
#include <boost/fusion/include/mpl.hpp>
|
||||
#include <boost/fusion/include/for_each.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::bitwise_or> // enables |
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct flatten_tree<qi::domain, proto::tag::bitwise_or> // flattens |
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Elements>
|
||||
struct alternative : nary_parser<alternative<Elements> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Put all the element attributes in a tuple
|
||||
typedef typename traits::build_attribute_sequence<
|
||||
Elements, Context, traits::alternative_attribute_transform
|
||||
, Iterator, qi::domain
|
||||
>::type all_attributes;
|
||||
|
||||
// Ok, now make a variant over the attribute sequence. Note that
|
||||
// build_variant makes sure that 1) all attributes in the variant
|
||||
// are unique 2) puts the unused attribute, if there is any, to
|
||||
// the front and 3) collapses single element variants, variant<T>
|
||||
// to T.
|
||||
typedef typename
|
||||
traits::build_variant<all_attributes>::type
|
||||
type;
|
||||
};
|
||||
|
||||
alternative(Elements const& elements_)
|
||||
: elements(elements_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
detail::alternative_function<Iterator, Context, Skipper, Attribute>
|
||||
f(first, last, context, skipper, attr_);
|
||||
|
||||
// return true if *any* of the parsers succeed
|
||||
return fusion::any(elements, f);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
info result("alternative");
|
||||
fusion::for_each(elements,
|
||||
spirit::detail::what_function<Context>(result, context));
|
||||
return result;
|
||||
}
|
||||
|
||||
Elements elements;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::bitwise_or, Elements, Modifiers>
|
||||
: make_nary_composite<Elements, alternative>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements>
|
||||
struct has_semantic_action<qi::alternative<Elements> >
|
||||
: nary_has_semantic_action<Elements> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::alternative<Elements>, Attribute, Context
|
||||
, Iterator>
|
||||
: nary_handles_container<Elements, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
/*=============================================================================
|
||||
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_AND_PREDICATE_MARCH_23_2007_0617PM)
|
||||
#define SPIRIT_AND_PREDICATE_MARCH_23_2007_0617PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::address_of> // enables &p
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Subject>
|
||||
struct and_predicate : unary_parser<and_predicate<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
and_predicate(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& /*attr*/) const
|
||||
{
|
||||
Iterator i = first;
|
||||
return subject.parse(i, last, context, skipper, unused);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("and-predicate", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::address_of, Elements, Modifiers>
|
||||
: make_unary_composite<Elements, and_predicate>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::and_predicate<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::and_predicate<Subject>, Attribute, Context
|
||||
, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,112 @@
|
||||
/*=============================================================================
|
||||
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_DIFFERENCE_FEBRUARY_11_2007_1250PM)
|
||||
#define SPIRIT_DIFFERENCE_FEBRUARY_11_2007_1250PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/fusion/include/at.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::minus> // enables -
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Left, typename Right>
|
||||
struct difference : binary_parser<difference<Left, Right> >
|
||||
{
|
||||
typedef Left left_type;
|
||||
typedef Right right_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef typename
|
||||
traits::attribute_of<left_type, Context, Iterator>::type
|
||||
type;
|
||||
};
|
||||
|
||||
difference(Left const& left_, Right const& right_)
|
||||
: left(left_), right(right_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
// Unlike classic Spirit, with this version of difference, the rule
|
||||
// lit("policeman") - "police" will always fail to match.
|
||||
|
||||
// Spirit2 does not count the matching chars while parsing and
|
||||
// there is no reliable and fast way to check if the LHS matches
|
||||
// more than the RHS.
|
||||
|
||||
// Try RHS first
|
||||
Iterator start = first;
|
||||
if (right.parse(first, last, context, skipper, unused))
|
||||
{
|
||||
// RHS succeeds, we fail.
|
||||
first = start;
|
||||
return false;
|
||||
}
|
||||
// RHS fails, now try LHS
|
||||
return left.parse(first, last, context, skipper, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("difference",
|
||||
std::make_pair(left.what(context), right.what(context)));
|
||||
}
|
||||
|
||||
Left left;
|
||||
Right right;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::minus, Elements, Modifiers>
|
||||
: make_binary_composite<Elements, difference>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Left, typename Right>
|
||||
struct has_semantic_action<qi::difference<Left, Right> >
|
||||
: binary_has_semantic_action<Left, Right> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Left, typename Right, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct handles_container<qi::difference<Left, Right>, Attribute, Context
|
||||
, Iterator>
|
||||
: binary_handles_container<Left, Right, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,103 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_EXPECT_APRIL_29_2007_0445PM)
|
||||
#define SPIRIT_EXPECT_APRIL_29_2007_0445PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/operator/sequence_base.hpp>
|
||||
#include <boost/spirit/home/qi/detail/expect_function.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::greater> // enables >
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct flatten_tree<qi::domain, proto::tag::greater> // flattens >
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Iterator>
|
||||
struct expectation_failure : std::runtime_error
|
||||
{
|
||||
expectation_failure(Iterator first_, Iterator last_, info const& what)
|
||||
: std::runtime_error("boost::spirit::qi::expectation_failure")
|
||||
, first(first_), last(last_), what_(what)
|
||||
{}
|
||||
~expectation_failure() throw() {}
|
||||
|
||||
Iterator first;
|
||||
Iterator last;
|
||||
info what_;
|
||||
};
|
||||
|
||||
template <typename Elements>
|
||||
struct expect : sequence_base<expect<Elements>, Elements>
|
||||
{
|
||||
friend struct sequence_base<expect<Elements>, Elements>;
|
||||
|
||||
expect(Elements const& elements)
|
||||
: sequence_base<expect<Elements>, Elements>(elements) {}
|
||||
|
||||
private:
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
static detail::expect_function<
|
||||
Iterator, Context, Skipper
|
||||
, expectation_failure<Iterator> >
|
||||
fail_function(
|
||||
Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper)
|
||||
{
|
||||
return detail::expect_function<
|
||||
Iterator, Context, Skipper, expectation_failure<Iterator> >
|
||||
(first, last, context, skipper);
|
||||
}
|
||||
|
||||
std::string id() const { return "expect"; }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::greater, Elements, Modifiers>
|
||||
: make_nary_composite<Elements, expect>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements>
|
||||
struct has_semantic_action<qi::expect<Elements> >
|
||||
: nary_has_semantic_action<Elements> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::expect<Elements>, Attribute, Context
|
||||
, Iterator>
|
||||
: mpl::true_ {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,134 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_KLEENE_JANUARY_07_2007_0818AM)
|
||||
#define SPIRIT_KLEENE_JANUARY_07_2007_0818AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/qi/detail/fail_function.hpp>
|
||||
#include <boost/spirit/home/qi/detail/pass_container.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[composite_parsers_kleene_enable_
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::dereference> // enables *p
|
||||
: mpl::true_ {};
|
||||
//]
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
//[composite_parsers_kleene
|
||||
template <typename Subject>
|
||||
struct kleene : unary_parser<kleene<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Build a std::vector from the subject's attribute. Note
|
||||
// that build_std_vector may return unused_type if the
|
||||
// subject's attribute is an unused_type.
|
||||
typedef typename
|
||||
traits::build_std_vector<
|
||||
typename traits::
|
||||
attribute_of<Subject, Context, Iterator>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
kleene(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename F>
|
||||
bool parse_container(F f) const
|
||||
{
|
||||
while (!f (subject))
|
||||
;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
// ensure the attribute is actually a container type
|
||||
traits::make_container(attr_);
|
||||
|
||||
typedef detail::fail_function<Iterator, Context, Skipper>
|
||||
fail_function;
|
||||
|
||||
Iterator iter = first;
|
||||
fail_function f(iter, last, context, skipper);
|
||||
parse_container(detail::make_pass_container(f, attr_));
|
||||
|
||||
first = f.first;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("kleene", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
//]
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//[composite_parsers_kleene_generator
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::dereference, Elements, Modifiers>
|
||||
: make_unary_composite<Elements, kleene>
|
||||
{};
|
||||
//]
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
// // Define what attributes are compatible with a kleene
|
||||
// template <typename Attribute, typename Subject, typename Context, typename Iterator>
|
||||
// struct is_attribute_compatible<Attribute, kleene<Subject>, Context, Iterator>
|
||||
// : traits::is_container_compatible<qi::domain, Attribute
|
||||
// , kleene<Subject>, Context, Iterator>
|
||||
// {};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::kleene<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::kleene<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: mpl::true_ {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(SPIRIT_LIST_MARCH_24_2007_1031AM)
|
||||
#define SPIRIT_LIST_MARCH_24_2007_1031AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/qi/detail/fail_function.hpp>
|
||||
#include <boost/spirit/home/qi/detail/pass_container.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::modulus> // enables p % d
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Left, typename Right>
|
||||
struct list : binary_parser<list<Left, Right> >
|
||||
{
|
||||
typedef Left left_type;
|
||||
typedef Right right_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Build a std::vector from the LHS's attribute. Note
|
||||
// that build_std_vector may return unused_type if the
|
||||
// subject's attribute is an unused_type.
|
||||
typedef typename
|
||||
traits::build_std_vector<
|
||||
typename traits::
|
||||
attribute_of<Left, Context, Iterator>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
list(Left const& left_, Right const& right_)
|
||||
: left(left_), right(right_) {}
|
||||
|
||||
template <typename F>
|
||||
bool parse_container(F f) const
|
||||
{
|
||||
// in order to succeed we need to match at least one element
|
||||
if (f (left))
|
||||
return false;
|
||||
|
||||
typename F::iterator_type save = f.f.first;
|
||||
while (right.parse(f.f.first, f.f.last, f.f.context, f.f.skipper, unused)
|
||||
&& !f (left))
|
||||
{
|
||||
save = f.f.first;
|
||||
}
|
||||
|
||||
f.f.first = save;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef detail::fail_function<Iterator, Context, Skipper>
|
||||
fail_function;
|
||||
|
||||
// ensure the attribute is actually a container type
|
||||
traits::make_container(attr_);
|
||||
|
||||
Iterator iter = first;
|
||||
fail_function f(iter, last, context, skipper);
|
||||
if (!parse_container(detail::make_pass_container(f, attr_)))
|
||||
return false;
|
||||
|
||||
first = f.first;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("list",
|
||||
std::make_pair(left.what(context), right.what(context)));
|
||||
}
|
||||
|
||||
Left left;
|
||||
Right right;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::modulus, Elements, Modifiers>
|
||||
: make_binary_composite<Elements, list>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Left, typename Right>
|
||||
struct has_semantic_action<qi::list<Left, Right> >
|
||||
: binary_has_semantic_action<Left, Right> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Left, typename Right, typename Attribute
|
||||
, typename Context, typename Iterator>
|
||||
struct handles_container<qi::list<Left, Right>, Attribute, Context
|
||||
, Iterator>
|
||||
: mpl::true_ {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*=============================================================================
|
||||
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_NOT_PREDICATE_MARCH_23_2007_0618PM)
|
||||
#define SPIRIT_NOT_PREDICATE_MARCH_23_2007_0618PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::logical_not> // enables !p
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Subject>
|
||||
struct not_predicate : unary_parser<not_predicate<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
|
||||
not_predicate(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& /*attr*/) const
|
||||
{
|
||||
Iterator i = first;
|
||||
return !subject.parse(i, last, context, skipper, unused);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("not-predicate", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::logical_not, Elements, Modifiers>
|
||||
: make_unary_composite<Elements, not_predicate>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::not_predicate<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::not_predicate<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: unary_handles_container<Subject, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,135 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
#if !defined(SPIRIT_OPTIONAL_MARCH_23_2007_1117PM)
|
||||
#define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/detail/assign_to.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::negate> // enables -p
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Subject>
|
||||
struct optional : unary_parser<optional<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Build a boost::optional from the subject's attribute. Note
|
||||
// that boost::optional may return unused_type if the
|
||||
// subject's attribute is an unused_type.
|
||||
typedef typename
|
||||
traits::build_optional<
|
||||
typename traits::
|
||||
attribute_of<Subject, Context, Iterator>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
optional(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse_impl(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_, mpl::false_) const
|
||||
{
|
||||
// create a local value if Attribute is not unused_type
|
||||
typename spirit::result_of::optional_value<Attribute>::type val =
|
||||
typename spirit::result_of::optional_value<Attribute>::type();
|
||||
|
||||
if (subject.parse(first, last, context, skipper, val))
|
||||
{
|
||||
// assign the parsed value into our attribute
|
||||
spirit::traits::assign_to(val, attr_);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse_impl(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_, mpl::true_) const
|
||||
{
|
||||
subject.parse(first, last, context, skipper, attr_);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef typename spirit::result_of::optional_value<Attribute>::type
|
||||
attribute_type;
|
||||
|
||||
return parse_impl(first, last, context, skipper, attr_
|
||||
, traits::is_container<attribute_type>());
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("optional", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::negate, Elements, Modifiers>
|
||||
: make_unary_composite<Elements, optional>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::optional<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::optional<Subject>, Attribute
|
||||
, Context, Iterator>
|
||||
: mpl::true_ {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,146 @@
|
||||
/*=============================================================================
|
||||
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_PERMUTATION_OR_MARCH_13_2007_1145PM)
|
||||
#define SPIRIT_PERMUTATION_OR_MARCH_13_2007_1145PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/detail/permute_function.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/algorithm/any_if_ns.hpp>
|
||||
#include <boost/spirit/home/support/detail/what_function.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/fusion/include/size.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/array.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::bitwise_xor> // enables ^
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct flatten_tree<qi::domain, proto::tag::bitwise_xor> // flattens ^
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Elements>
|
||||
struct permutation : nary_parser<permutation<Elements> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Put all the element attributes in a tuple,
|
||||
// wrapping each element in a boost::optional
|
||||
typedef typename traits::build_attribute_sequence<
|
||||
Elements, Context, traits::permutation_attribute_transform
|
||||
, Iterator, qi::domain
|
||||
>::type all_attributes;
|
||||
|
||||
// Now, build a fusion vector over the attributes. Note
|
||||
// that build_fusion_vector 1) removes all unused attributes
|
||||
// and 2) may return unused_type if all elements have
|
||||
// unused_type(s).
|
||||
typedef typename
|
||||
traits::build_fusion_vector<all_attributes>::type
|
||||
type;
|
||||
};
|
||||
|
||||
permutation(Elements const& elements_)
|
||||
: elements(elements_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef traits::attribute_not_unused<Context, Iterator> predicate;
|
||||
detail::permute_function<Iterator, Context, Skipper>
|
||||
f(first, last, context, skipper);
|
||||
|
||||
boost::array<bool, fusion::result_of::size<Elements>::value> flags;
|
||||
BOOST_FOREACH(bool& taken, flags)
|
||||
{
|
||||
taken = false;
|
||||
}
|
||||
|
||||
// wrap the attribute in a tuple if it is not a tuple
|
||||
typename traits::wrap_if_not_tuple<Attribute>::type attr_local(attr_);
|
||||
|
||||
// We have a bool array 'flags' with one flag for each parser.
|
||||
// permute_function sets the slot to true when the corresponding
|
||||
// parser successful matches. We loop until there are no more
|
||||
// successful parsers.
|
||||
|
||||
bool result = false;
|
||||
f.taken = flags.begin();
|
||||
while (spirit::any_if_ns(elements, attr_local, f, predicate()))
|
||||
{
|
||||
f.taken = flags.begin();
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
info result("permutation");
|
||||
fusion::for_each(elements,
|
||||
spirit::detail::what_function<Context>(result, context));
|
||||
return result;
|
||||
}
|
||||
|
||||
Elements elements;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::bitwise_xor, Elements, Modifiers>
|
||||
: make_nary_composite<Elements, permutation>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// We specialize this for permutation (see support/attributes.hpp).
|
||||
// For permutation, we only wrap the attribute in a tuple IFF
|
||||
// it is not already a fusion tuple.
|
||||
template <typename Elements, typename Attribute>
|
||||
struct pass_attribute<qi::permutation<Elements>, Attribute>
|
||||
: wrap_if_not_tuple<Attribute> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements>
|
||||
struct has_semantic_action<qi::permutation<Elements> >
|
||||
: nary_has_semantic_action<Elements> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::permutation<Elements>, Attribute, Context
|
||||
, Iterator>
|
||||
: nary_handles_container<Elements, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,125 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_PLUS_MARCH_13_2007_0127PM)
|
||||
#define SPIRIT_PLUS_MARCH_13_2007_0127PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/container.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/qi/detail/fail_function.hpp>
|
||||
#include <boost/spirit/home/qi/detail/pass_container.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::unary_plus> // enables +p
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Subject>
|
||||
struct plus : unary_parser<plus<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Build a std::vector from the subject's attribute. Note
|
||||
// that build_std_vector may return unused_type if the
|
||||
// subject's attribute is an unused_type.
|
||||
typedef typename
|
||||
traits::build_std_vector<
|
||||
typename traits::attribute_of<
|
||||
Subject, Context, Iterator>::type
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
|
||||
plus(Subject const& subject_)
|
||||
: subject(subject_) {}
|
||||
|
||||
template <typename F>
|
||||
bool parse_container(F f) const
|
||||
{
|
||||
// in order to succeed we need to match at least one element
|
||||
if (f (subject))
|
||||
return false;
|
||||
|
||||
while (!f (subject))
|
||||
;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef detail::fail_function<Iterator, Context, Skipper>
|
||||
fail_function;
|
||||
|
||||
// ensure the attribute is actually a container type
|
||||
traits::make_container(attr_);
|
||||
|
||||
Iterator iter = first;
|
||||
fail_function f(iter, last, context, skipper);
|
||||
if (!parse_container(detail::make_pass_container(f, attr_)))
|
||||
return false;
|
||||
|
||||
first = f.first;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
return info("plus", subject.what(context));
|
||||
}
|
||||
|
||||
Subject subject;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::unary_plus, Elements, Modifiers>
|
||||
: make_unary_composite<Elements, plus>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct has_semantic_action<qi::plus<Subject> >
|
||||
: unary_has_semantic_action<Subject> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::plus<Subject>, Attribute, Context
|
||||
, Iterator>
|
||||
: mpl::true_ {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_SEQUENCE_APR_22_2006_0811AM)
|
||||
#define SPIRIT_SEQUENCE_APR_22_2006_0811AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/operator/sequence_base.hpp>
|
||||
#include <boost/spirit/home/qi/detail/fail_function.hpp>
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::shift_right> // enables >>
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct flatten_tree<qi::domain, proto::tag::shift_right> // flattens >>
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Elements>
|
||||
struct sequence : sequence_base<sequence<Elements>, Elements>
|
||||
{
|
||||
friend struct sequence_base<sequence<Elements>, Elements>;
|
||||
|
||||
sequence(Elements const& elements)
|
||||
: sequence_base<sequence<Elements>, Elements>(elements) {}
|
||||
|
||||
private:
|
||||
|
||||
template <typename Iterator, typename Context, typename Skipper>
|
||||
static detail::fail_function<Iterator, Context, Skipper>
|
||||
fail_function(
|
||||
Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper)
|
||||
{
|
||||
return detail::fail_function<Iterator, Context, Skipper>
|
||||
(first, last, context, skipper);
|
||||
}
|
||||
|
||||
std::string id() const { return "sequence"; }
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::shift_right, Elements, Modifiers>
|
||||
: make_nary_composite<Elements, sequence>
|
||||
{};
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
// // Define what attributes are compatible with a sequence
|
||||
// template <typename Attribute, typename Elements, typename Context, typename Iterator>
|
||||
// struct is_attribute_compatible<Attribute, sequence<Elements>, Context, Iterator>
|
||||
// : mpl::or_<
|
||||
// is_convertible<Attribute
|
||||
// , typename traits::attribute_of<sequence<Elements>, Context, Iterator>::type>
|
||||
// , traits::is_fusion_sequence_compatible<qi::domain, Attribute
|
||||
// , sequence<Elements>, Context, Iterator>
|
||||
// , traits::is_container_compatible<qi::domain, Attribute
|
||||
// , sequence<Elements>, Context, Iterator>
|
||||
// >
|
||||
// {};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements>
|
||||
struct has_semantic_action<qi::sequence<Elements> >
|
||||
: nary_has_semantic_action<Elements> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::sequence<Elements>, Attribute, Context
|
||||
, Iterator>
|
||||
: mpl::true_ {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,140 @@
|
||||
/*=============================================================================
|
||||
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(SPIRIT_SEQUENCE_BASE_APRIL_22_2006_0811AM)
|
||||
#define SPIRIT_SEQUENCE_BASE_APRIL_22_2006_0811AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
#include <boost/spirit/home/qi/detail/pass_container.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/algorithm/any_if.hpp>
|
||||
#include <boost/spirit/home/support/detail/what_function.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/sequence_base_id.hpp>
|
||||
#include <boost/spirit/home/support/has_semantic_action.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/fusion/include/as_vector.hpp>
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/fusion/include/for_each.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Derived, typename Elements>
|
||||
struct sequence_base // this class is shared by sequence and expect
|
||||
: nary_parser<Derived>
|
||||
{
|
||||
typedef Elements elements_type;
|
||||
struct sequence_base_id;
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Put all the element attributes in a tuple
|
||||
typedef typename traits::build_attribute_sequence<
|
||||
Elements, Context, traits::sequence_attribute_transform
|
||||
, Iterator, qi::domain
|
||||
>::type all_attributes;
|
||||
|
||||
// Now, build a fusion vector over the attributes. Note
|
||||
// that build_fusion_vector 1) removes all unused attributes
|
||||
// and 2) may return unused_type if all elements have
|
||||
// unused_type(s).
|
||||
typedef typename
|
||||
traits::build_fusion_vector<all_attributes>::type
|
||||
type_;
|
||||
|
||||
// Finally, strip single element vectors into its
|
||||
// naked form: vector1<T> --> T
|
||||
typedef typename
|
||||
traits::strip_single_element_vector<type_>::type
|
||||
type;
|
||||
};
|
||||
|
||||
sequence_base(Elements const& elements_)
|
||||
: elements(elements_) {}
|
||||
|
||||
// standard case. Attribute is a fusion tuple
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse_impl(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_, mpl::false_) const
|
||||
{
|
||||
Iterator iter = first;
|
||||
typedef traits::attribute_not_unused<Context, Iterator> predicate;
|
||||
|
||||
// wrap the attribute in a tuple if it is not a tuple or if the
|
||||
// attribute of this sequence is a single element tuple
|
||||
typedef typename attribute<Context, Iterator>::type_ attr_type_;
|
||||
typename traits::wrap_if_not_tuple<Attribute
|
||||
, typename mpl::and_<
|
||||
traits::one_element_sequence<attr_type_>
|
||||
, mpl::not_<traits::one_element_sequence<Attribute> >
|
||||
>::type
|
||||
>::type attr_local(attr_);
|
||||
|
||||
// return false if *any* of the parsers fail
|
||||
if (spirit::any_if(elements, attr_local
|
||||
, Derived::fail_function(iter, last, context, skipper), predicate()))
|
||||
return false;
|
||||
first = iter;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Special case when Attribute is an stl container
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse_impl(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_, mpl::true_) const
|
||||
{
|
||||
// ensure the attribute is actually a container type
|
||||
traits::make_container(attr_);
|
||||
|
||||
Iterator iter = first;
|
||||
// return false if *any* of the parsers fail
|
||||
if (fusion::any(elements
|
||||
, detail::make_sequence_pass_container(
|
||||
Derived::fail_function(iter, last, context, skipper), attr_))
|
||||
)
|
||||
return false;
|
||||
first = iter;
|
||||
return true;
|
||||
}
|
||||
|
||||
// main parse function. Dispatches to parse_impl depending
|
||||
// on the Attribute type.
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
return parse_impl(first, last, context, skipper, attr_
|
||||
, traits::is_container<Attribute>());
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
info result(this->derived().id());
|
||||
fusion::for_each(elements,
|
||||
spirit::detail::what_function<Context>(result, context));
|
||||
return result;
|
||||
}
|
||||
|
||||
Elements elements;
|
||||
};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,127 @@
|
||||
/*=============================================================================
|
||||
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_SEQUENTIAL_OR_MARCH_12_2007_1130PM)
|
||||
#define SPIRIT_SEQUENTIAL_OR_MARCH_12_2007_1130PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/detail/pass_function.hpp>
|
||||
#include <boost/spirit/home/qi/detail/attributes.hpp>
|
||||
#include <boost/spirit/home/support/detail/what_function.hpp>
|
||||
#include <boost/spirit/home/support/algorithm/any_if_ns.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/fusion/include/as_vector.hpp>
|
||||
#include <boost/fusion/include/for_each.hpp>
|
||||
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_operator<qi::domain, proto::tag::logical_or> // enables ||
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct flatten_tree<qi::domain, proto::tag::logical_or> // flattens ||
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
template <typename Elements>
|
||||
struct sequential_or : nary_parser<sequential_or<Elements> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
// Put all the element attributes in a tuple,
|
||||
// wrapping each element in a boost::optional
|
||||
typedef typename traits::build_attribute_sequence<
|
||||
Elements, Context, traits::sequential_or_attribute_transform
|
||||
, Iterator, qi::domain
|
||||
>::type all_attributes;
|
||||
|
||||
// Now, build a fusion vector over the attributes. Note
|
||||
// that build_fusion_vector 1) removes all unused attributes
|
||||
// and 2) may return unused_type if all elements have
|
||||
// unused_type(s).
|
||||
typedef typename
|
||||
traits::build_fusion_vector<all_attributes>::type
|
||||
type;
|
||||
};
|
||||
|
||||
sequential_or(Elements const& elements_)
|
||||
: elements(elements_) {}
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef traits::attribute_not_unused<Context, Iterator> predicate;
|
||||
detail::pass_function<Iterator, Context, Skipper>
|
||||
f(first, last, context, skipper);
|
||||
|
||||
// wrap the attribute in a tuple if it is not a tuple
|
||||
typename traits::wrap_if_not_tuple<Attribute>::type attr_local(attr_);
|
||||
|
||||
// return true if *any* of the parsers succeed
|
||||
// (we use the non-short-circuiting version: any_if_ns
|
||||
// to force all elements to be tested)
|
||||
return spirit::any_if_ns(elements, attr_local, f, predicate());
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
info result("sequential-or");
|
||||
fusion::for_each(elements,
|
||||
spirit::detail::what_function<Context>(result, context));
|
||||
return result;
|
||||
}
|
||||
|
||||
Elements elements;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Modifiers>
|
||||
struct make_composite<proto::tag::logical_or, Elements, Modifiers>
|
||||
: make_nary_composite<Elements, sequential_or>
|
||||
{};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// We specialize this for sequential_or (see support/attributes.hpp).
|
||||
// For sequential_or, we only wrap the attribute in a tuple IFF
|
||||
// it is not already a fusion tuple.
|
||||
template <typename Elements, typename Attribute>
|
||||
struct pass_attribute<qi::sequential_or<Elements>, Attribute>
|
||||
: wrap_if_not_tuple<Attribute> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements>
|
||||
struct has_semantic_action<qi::sequential_or<Elements> >
|
||||
: nary_has_semantic_action<Elements> {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Elements, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::sequential_or<Elements>, Attribute, Context
|
||||
, Iterator>
|
||||
: nary_handles_container<Elements, Attribute, Context, Iterator> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,215 @@
|
||||
/*=============================================================================
|
||||
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_PARSE_APRIL_16_2006_0442PM)
|
||||
#define BOOST_SPIRIT_PARSE_APRIL_16_2006_0442PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/context.hpp>
|
||||
#include <boost/spirit/home/support/nonterminal/locals.hpp>
|
||||
#include <boost/spirit/home/qi/detail/parse.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr>
|
||||
inline bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr)
|
||||
{
|
||||
// Make sure the iterator is at least a forward_iterator. If you got a
|
||||
// compilation error here, then you are using an input_iterator while
|
||||
// calling this function, you need to supply at least a
|
||||
// forward_iterator instead.
|
||||
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
|
||||
|
||||
return detail::parse_impl<Expr>::call(first, last, expr);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr>
|
||||
inline bool
|
||||
parse(
|
||||
Iterator const& first_
|
||||
, Iterator last
|
||||
, Expr const& expr)
|
||||
{
|
||||
Iterator first = first_;
|
||||
return qi::parse(first, last, expr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
struct make_context
|
||||
{
|
||||
typedef context<fusion::cons<T&>, locals<> > type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_context<unused_type>
|
||||
{
|
||||
typedef unused_type type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr, typename Attr>
|
||||
inline bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Attr& attr)
|
||||
{
|
||||
// Make sure the iterator is at least a forward_iterator. If you got a
|
||||
// compilation error here, then you are using an input_iterator while
|
||||
// calling this function, you need to supply at least a
|
||||
// forward_iterator instead.
|
||||
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
|
||||
typename detail::make_context<Attr>::type context(attr);
|
||||
return compile<qi::domain>(expr).parse(first, last, context, unused, attr);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr, typename Attr>
|
||||
inline bool
|
||||
parse(
|
||||
Iterator const& first_
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Attr& attr)
|
||||
{
|
||||
Iterator first = first_;
|
||||
return qi::parse(first, last, expr, attr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr, typename Skipper>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
|
||||
{
|
||||
// Make sure the iterator is at least a forward_iterator. If you got a
|
||||
// compilation error here, then you are using an input_iterator while
|
||||
// calling this function, you need to supply at least a
|
||||
// forward_iterator instead.
|
||||
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
|
||||
|
||||
return detail::phrase_parse_impl<Expr>::call(
|
||||
first, last, expr, skipper, post_skip);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr, typename Skipper>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator const& first_
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
|
||||
{
|
||||
Iterator first = first_;
|
||||
return qi::phrase_parse(first, last, expr, skipper, post_skip);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip
|
||||
, Attr& attr)
|
||||
{
|
||||
// Make sure the iterator is at least a forward_iterator. If you got a
|
||||
// compilation error here, then you are using an input_iterator while
|
||||
// calling this function, you need to supply at least a
|
||||
// forward_iterator instead.
|
||||
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then either the expression (expr) or skipper is not a valid
|
||||
// spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
|
||||
typedef
|
||||
typename result_of::compile<qi::domain, Skipper>::type
|
||||
skipper_type;
|
||||
skipper_type const skipper_ = compile<qi::domain>(skipper);
|
||||
|
||||
typename detail::make_context<Attr>::type context(attr);
|
||||
if (!compile<qi::domain>(expr).parse(
|
||||
first, last, context, skipper_, attr))
|
||||
return false;
|
||||
|
||||
if (post_skip == skip_flag::postskip)
|
||||
qi::skip_over(first, last, skipper_);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator const& first_
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip
|
||||
, Attr& attr)
|
||||
{
|
||||
Iterator first = first_;
|
||||
return qi::phrase_parse(first, last, expr, skipper, post_skip, attr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, Attr& attr)
|
||||
{
|
||||
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr, typename Skipper, typename Attr>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator const& first_
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, Attr& attr)
|
||||
{
|
||||
Iterator first = first_;
|
||||
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip, attr);
|
||||
}
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
// Copyright (c) 2001-2011 Hartmut Kaiser
|
||||
// Copyright (c) 2001-2011 Joel de Guzman
|
||||
// Copyright (c) 2009 Carl Barron
|
||||
//
|
||||
// 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_PP_IS_ITERATING)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_PARSE_ATTR_APRIL_24_2009_1043AM)
|
||||
#define BOOST_SPIRIT_PARSE_ATTR_APRIL_24_2009_1043AM
|
||||
|
||||
#include <boost/spirit/home/qi/parse.hpp>
|
||||
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
|
||||
#define BOOST_PP_FILENAME_1 <boost/spirit/home/qi/parse_attr.hpp>
|
||||
#define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT)
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Preprocessor vertical repetition code
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#else // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
#define BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE(z, n, A) BOOST_PP_CAT(A, n)&
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr
|
||||
, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline bool
|
||||
parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
// Make sure the iterator is at least a forward_iterator. If you got an
|
||||
// compilation error here, then you are using an input_iterator while
|
||||
// calling this function, you need to supply at least a
|
||||
// forward_iterator instead.
|
||||
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
|
||||
typedef fusion::vector<
|
||||
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
|
||||
> vector_type;
|
||||
|
||||
vector_type lattr (BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
return compile<qi::domain>(expr).parse(first, last, unused, unused, lattr);
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr
|
||||
, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline bool
|
||||
parse(
|
||||
Iterator const& first_
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
Iterator first = first_;
|
||||
return qi::parse(first, last, expr, BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr, typename Skipper
|
||||
, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
// Make sure the iterator is at least a forward_iterator. If you got an
|
||||
// compilation error here, then you are using an input_iterator while
|
||||
// calling this function, you need to supply at least a
|
||||
// forward_iterator instead.
|
||||
BOOST_CONCEPT_ASSERT((ForwardIterator<Iterator>));
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then either the expression (expr) or skipper is not a valid
|
||||
// spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
|
||||
typedef
|
||||
typename result_of::compile<qi::domain, Skipper>::type
|
||||
skipper_type;
|
||||
skipper_type const skipper_ = compile<qi::domain>(skipper);
|
||||
|
||||
typedef fusion::vector<
|
||||
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
|
||||
> vector_type;
|
||||
|
||||
vector_type lattr (BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
if (!compile<qi::domain>(expr).parse(
|
||||
first, last, unused, skipper_, lattr))
|
||||
return false;
|
||||
|
||||
if (post_skip == skip_flag::postskip)
|
||||
qi::skip_over(first, last, skipper_);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr, typename Skipper
|
||||
, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator const& first_
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
Iterator first = first_;
|
||||
return qi::phrase_parse(first, last, expr, skipper, post_skip
|
||||
, BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename Expr, typename Skipper
|
||||
, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator& first
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip
|
||||
, BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Expr, typename Skipper
|
||||
, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline bool
|
||||
phrase_parse(
|
||||
Iterator const& first_
|
||||
, Iterator last
|
||||
, Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
Iterator first = first_;
|
||||
return qi::phrase_parse(first, last, expr, skipper, skip_flag::postskip
|
||||
, BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
}
|
||||
}}}
|
||||
|
||||
#undef BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*=============================================================================
|
||||
Copyright (c) 2001-2011 Joel de Guzman
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
==============================================================================*/
|
||||
#if !defined(BOOST_SPIRIT_PARSER_OCTOBER_16_2008_0254PM)
|
||||
#define BOOST_SPIRIT_PARSER_OCTOBER_16_2008_0254PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/spirit/home/qi/domain.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
|
||||
//[parser_base_parser
|
||||
template <typename Derived>
|
||||
struct parser
|
||||
{
|
||||
struct parser_id;
|
||||
typedef Derived derived_type;
|
||||
typedef qi::domain domain;
|
||||
|
||||
// Requirement: p.parse(f, l, context, skip, attr) -> bool
|
||||
//
|
||||
// p: a parser
|
||||
// f, l: first/last iterator pair
|
||||
// context: enclosing rule context (can be unused_type)
|
||||
// skip: skipper (can be unused_type)
|
||||
// attr: attribute (can be unused_type)
|
||||
|
||||
// Requirement: p.what(context) -> info
|
||||
//
|
||||
// p: a parser
|
||||
// context: enclosing rule context (can be unused_type)
|
||||
|
||||
// Requirement: P::template attribute<Ctx, Iter>::type
|
||||
//
|
||||
// P: a parser type
|
||||
// Ctx: A context type (can be unused_type)
|
||||
// Iter: An iterator type (can be unused_type)
|
||||
|
||||
Derived const& derived() const
|
||||
{
|
||||
return *static_cast<Derived const*>(this);
|
||||
}
|
||||
};
|
||||
//]
|
||||
|
||||
template <typename Derived>
|
||||
struct primitive_parser : parser<Derived>
|
||||
{
|
||||
struct primitive_parser_id;
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
struct nary_parser : parser<Derived>
|
||||
{
|
||||
struct nary_parser_id;
|
||||
|
||||
// Requirement: p.elements -> fusion sequence
|
||||
//
|
||||
// p: a composite parser
|
||||
|
||||
// Requirement: P::elements_type -> fusion sequence
|
||||
//
|
||||
// P: a composite parser type
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
struct unary_parser : parser<Derived>
|
||||
{
|
||||
struct unary_parser_id;
|
||||
|
||||
// Requirement: p.subject -> subject parser
|
||||
//
|
||||
// p: a unary parser
|
||||
|
||||
// Requirement: P::subject_type -> subject parser type
|
||||
//
|
||||
// P: a unary parser type
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
struct binary_parser : parser<Derived>
|
||||
{
|
||||
struct binary_parser_id;
|
||||
|
||||
// Requirement: p.left -> left parser
|
||||
//
|
||||
// p: a binary parser
|
||||
|
||||
// Requirement: P::left_type -> left parser type
|
||||
//
|
||||
// P: a binary parser type
|
||||
|
||||
// Requirement: p.right -> right parser
|
||||
//
|
||||
// p: a binary parser
|
||||
|
||||
// Requirement: P::right_type -> right parser type
|
||||
//
|
||||
// P: a binary parser type
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits // classification
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(parser_id)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(primitive_parser_id)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(nary_parser_id)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(unary_parser_id)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(binary_parser_id)
|
||||
}
|
||||
|
||||
// parser type identification
|
||||
template <typename T>
|
||||
struct is_parser : detail::has_parser_id<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_primitive_parser : detail::has_primitive_parser_id<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_nary_parser : detail::has_nary_parser_id<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_unary_parser : detail::has_unary_parser_id<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_binary_parser : detail::has_binary_parser_id<T> {};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
/*=============================================================================
|
||||
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_REFERENCE_OCTOBER_31_2008_1218AM)
|
||||
#define BOOST_SPIRIT_REFERENCE_OCTOBER_31_2008_1218AM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/meta_compiler.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/info.hpp>
|
||||
#include <boost/spirit/home/support/handles_container.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// reference is a parser that references another parser (its Subject)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject>
|
||||
struct reference : parser<reference<Subject> >
|
||||
{
|
||||
typedef Subject subject_type;
|
||||
|
||||
reference(Subject& subject)
|
||||
: ref(subject) {}
|
||||
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute : Subject::template attribute<Context, Iterator> {};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& context, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
return ref.get().parse(first, last, context, skipper, attr_);
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& context) const
|
||||
{
|
||||
// the reference is transparent (does not add any info)
|
||||
return ref.get().what(context);
|
||||
}
|
||||
|
||||
boost::reference_wrapper<Subject> ref;
|
||||
};
|
||||
}}}
|
||||
|
||||
namespace boost { namespace spirit { namespace traits
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Subject, typename Attribute, typename Context
|
||||
, typename Iterator>
|
||||
struct handles_container<qi::reference<Subject>, Attribute, Context
|
||||
, Iterator>
|
||||
: handles_container<typename remove_const<Subject>::type
|
||||
, Attribute, Context, Iterator>
|
||||
{};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
/*=============================================================================
|
||||
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_SKIP_FLAG_DEC_02_2009_0412PM)
|
||||
#define BOOST_SPIRIT_SKIP_FLAG_DEC_02_2009_0412PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/detail/scoped_enum_emulation.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
BOOST_SCOPED_ENUM_START(skip_flag)
|
||||
{
|
||||
postskip, // force post-skipping in phrase_parse()
|
||||
dont_postskip // inhibit post-skipping in phrase_parse()
|
||||
};
|
||||
BOOST_SCOPED_ENUM_END
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*=============================================================================
|
||||
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_SKIP_APRIL_16_2006_0625PM)
|
||||
#define BOOST_SPIRIT_SKIP_APRIL_16_2006_0625PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/detail/unused_skipper.hpp>
|
||||
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Move the /first/ iterator to the first non-matching position
|
||||
// given a skip-parser. The function is a no-op if unused_type is
|
||||
// passed as the skip-parser.
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator, typename T>
|
||||
inline void skip_over(Iterator& first, Iterator const& last, T const& skipper)
|
||||
{
|
||||
while (first != last && skipper.parse(first, last, unused, unused, unused))
|
||||
/***/;
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
inline void skip_over(Iterator&, Iterator const&, unused_type)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Iterator, typename Skipper>
|
||||
inline void skip_over(Iterator&, Iterator const&
|
||||
, detail::unused_skipper<Skipper> const&)
|
||||
{
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
/*=============================================================================
|
||||
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_STREAM_MAY_05_2007_1227PM)
|
||||
#define BOOST_SPIRIT_STREAM_MAY_05_2007_1227PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/stream/stream.hpp>
|
||||
|
||||
#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_ITERATOR_ISTREAM_MAY_05_2007_0110PM)
|
||||
#define BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Iterator>
|
||||
struct iterator_source
|
||||
{
|
||||
typedef typename
|
||||
boost::detail::iterator_traits<Iterator>::value_type
|
||||
char_type;
|
||||
typedef boost::iostreams::seekable_device_tag category;
|
||||
|
||||
iterator_source (Iterator const& first_, Iterator const& last_)
|
||||
: first(first_), last(last_), pos(0)
|
||||
{}
|
||||
|
||||
// Read up to n characters from the input sequence into the buffer s,
|
||||
// returning the number of characters read, or -1 to indicate
|
||||
// end-of-sequence.
|
||||
std::streamsize read (char_type* s, std::streamsize n)
|
||||
{
|
||||
if (first == last)
|
||||
return -1;
|
||||
|
||||
std::streamsize bytes_read = 0;
|
||||
while (n--) {
|
||||
*s = *first;
|
||||
++s; ++bytes_read;
|
||||
if (++first == last)
|
||||
break;
|
||||
}
|
||||
|
||||
pos += bytes_read;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
// Write is implemented only to satisfy the requirements of a
|
||||
// boost::iostreams::seekable_device. We need to have see support to
|
||||
// be able to figure out how many characters have been actually
|
||||
// consumed by the stream.
|
||||
std::streamsize write(const char_type*, std::streamsize)
|
||||
{
|
||||
BOOST_ASSERT(false); // not supported
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::streampos seek(boost::iostreams::stream_offset, std::ios_base::seekdir way)
|
||||
{
|
||||
BOOST_ASSERT(way == std::ios_base::cur); // only support queries
|
||||
return pos; // return current position
|
||||
}
|
||||
|
||||
Iterator first;
|
||||
Iterator const& last;
|
||||
std::streamsize pos;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
iterator_source& operator= (iterator_source const&);
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
/*=============================================================================
|
||||
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_MATCH_MANIP_MAY_05_2007_1203PM)
|
||||
#define BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1203PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/parse.hpp>
|
||||
#include <boost/spirit/home/support/iterators/istream_iterator.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr
|
||||
, typename CopyExpr = mpl::false_, typename CopyAttr = mpl::false_
|
||||
, typename Skipper = unused_type, typename Attribute = unused_type const>
|
||||
struct match_manip
|
||||
{
|
||||
// This assertion makes sure we don't hit the only code path which is
|
||||
// not implemented (because it isn't needed), where both, the
|
||||
// expression and the attribute need to be held as a copy.
|
||||
BOOST_SPIRIT_ASSERT_MSG(!CopyExpr::value || !CopyAttr::value
|
||||
, error_invalid_should_not_happen, ());
|
||||
|
||||
match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
|
||||
: expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
|
||||
|
||||
match_manip(Expr const& xpr, Skipper const& s
|
||||
, BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
|
||||
: expr(xpr), skipper(s), attr(a), post_skip(ps) {}
|
||||
|
||||
Expr const& expr;
|
||||
Skipper const& skipper;
|
||||
Attribute& attr;
|
||||
BOOST_SCOPED_ENUM(skip_flag) const post_skip;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
match_manip& operator= (match_manip const&);
|
||||
};
|
||||
|
||||
template <typename Expr, typename Skipper, typename Attribute>
|
||||
struct match_manip<Expr, mpl::false_, mpl::true_, Skipper, Attribute>
|
||||
{
|
||||
match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
|
||||
: expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
|
||||
|
||||
match_manip(Expr const& xpr, Skipper const& s
|
||||
, BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
|
||||
: expr(xpr), skipper(s), attr(a), post_skip(ps) {}
|
||||
|
||||
Expr const& expr;
|
||||
Skipper const& skipper;
|
||||
Attribute attr;
|
||||
BOOST_SCOPED_ENUM(skip_flag) const post_skip;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
match_manip& operator= (match_manip const&);
|
||||
};
|
||||
|
||||
template <typename Expr, typename Skipper, typename Attribute>
|
||||
struct match_manip<Expr, mpl::true_, mpl::false_, Skipper, Attribute>
|
||||
{
|
||||
match_manip(Expr const& xpr, Skipper const& s, Attribute& a)
|
||||
: expr(xpr), skipper(s), attr(a), post_skip(skip_flag::postskip) {}
|
||||
|
||||
match_manip(Expr const& xpr, Skipper const& s
|
||||
, BOOST_SCOPED_ENUM(skip_flag) ps, Attribute& a)
|
||||
: expr(xpr), skipper(s), attr(a), post_skip(ps) {}
|
||||
|
||||
Expr expr;
|
||||
Skipper const& skipper;
|
||||
Attribute& attr;
|
||||
BOOST_SCOPED_ENUM(skip_flag) const post_skip;
|
||||
|
||||
private:
|
||||
// silence MSVC warning C4512: assignment operator could not be generated
|
||||
match_manip& operator= (match_manip const&);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Enable = void>
|
||||
struct match
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
// Did you intend to use the auto_ facilities while forgetting to
|
||||
// #include <boost/spirit/include/qi_match_auto.hpp>?
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
};
|
||||
|
||||
template <typename Expr>
|
||||
struct match<Expr
|
||||
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
|
||||
{
|
||||
typedef match_manip<Expr> type;
|
||||
|
||||
static type call(Expr const& expr)
|
||||
{
|
||||
return type(expr, unused, unused);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Skipper, typename Enable = void>
|
||||
struct phrase_match
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
// Did you intend to use the auto_ facilities while forgetting to
|
||||
// #include <boost/spirit/include/qi_match_auto.hpp>?
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
};
|
||||
|
||||
template <typename Expr, typename Skipper>
|
||||
struct phrase_match<Expr, Skipper
|
||||
, typename enable_if<traits::matches<qi::domain, Expr> >::type>
|
||||
{
|
||||
typedef match_manip<Expr, mpl::false_, mpl::false_, Skipper> type;
|
||||
|
||||
static type call(
|
||||
Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the delimiter is not a valid spirit karma expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
return type(expr, skipper, post_skip, unused);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename Char, typename Traits, typename Expr
|
||||
, typename CopyExpr, typename CopyAttr>
|
||||
inline std::basic_istream<Char, Traits> &
|
||||
operator>>(std::basic_istream<Char, Traits> &is,
|
||||
match_manip<Expr, CopyExpr, CopyAttr> const& fm)
|
||||
{
|
||||
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
|
||||
|
||||
input_iterator f(is);
|
||||
input_iterator l;
|
||||
if (!qi::parse(f, l, fm.expr))
|
||||
{
|
||||
is.setstate(std::ios_base::failbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename Char, typename Traits, typename Expr
|
||||
, typename CopyExpr, typename CopyAttr
|
||||
, typename Attribute>
|
||||
inline std::basic_istream<Char, Traits> &
|
||||
operator>>(std::basic_istream<Char, Traits> &is,
|
||||
match_manip<Expr, CopyExpr, CopyAttr, unused_type, Attribute> const& fm)
|
||||
{
|
||||
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
|
||||
|
||||
input_iterator f(is);
|
||||
input_iterator l;
|
||||
if (!qi::parse(f, l, fm.expr, fm.attr))
|
||||
{
|
||||
is.setstate(std::ios_base::failbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename Char, typename Traits, typename Expr
|
||||
, typename CopyExpr, typename CopyAttr
|
||||
, typename Skipper>
|
||||
inline std::basic_istream<Char, Traits> &
|
||||
operator>>(std::basic_istream<Char, Traits> &is,
|
||||
match_manip<Expr, CopyExpr, CopyAttr, Skipper> const& fm)
|
||||
{
|
||||
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
|
||||
|
||||
input_iterator f(is);
|
||||
input_iterator l;
|
||||
if (!qi::phrase_parse(
|
||||
f, l, fm.expr, fm.skipper, fm.post_skip))
|
||||
{
|
||||
is.setstate(std::ios_base::failbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename Char, typename Traits, typename Expr
|
||||
, typename CopyExpr, typename CopyAttr
|
||||
, typename Attribute, typename Skipper
|
||||
>
|
||||
inline std::basic_istream<Char, Traits> &
|
||||
operator>>(
|
||||
std::basic_istream<Char, Traits> &is,
|
||||
match_manip<Expr, CopyExpr, CopyAttr, Attribute, Skipper> const& fm)
|
||||
{
|
||||
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
|
||||
|
||||
input_iterator f(is);
|
||||
input_iterator l;
|
||||
if (!qi::phrase_parse(
|
||||
f, l, fm.expr, fm.skipper, fm.post_skip, fm.attr))
|
||||
{
|
||||
is.setstate(std::ios_base::failbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*=============================================================================
|
||||
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_MATCH_MANIP_AUTO_DEC_02_2009_0813PM)
|
||||
#define BOOST_SPIRIT_MATCH_MANIP_AUTO_DEC_02_2009_0813PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
|
||||
#include <boost/spirit/home/qi/auto/create_parser.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
struct match<Expr
|
||||
, typename enable_if<traits::meta_create_exists<qi::domain, Expr> >::type>
|
||||
{
|
||||
typedef typename result_of::create_parser<Expr>::type expr_type;
|
||||
typedef match_manip<
|
||||
expr_type, mpl::true_, mpl::false_, unused_type, Expr
|
||||
> type;
|
||||
|
||||
static type call(Expr const& expr)
|
||||
{
|
||||
return type(create_parser<Expr>(), unused, const_cast<Expr&>(expr));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Skipper>
|
||||
struct phrase_match<Expr, Skipper
|
||||
, typename enable_if<traits::meta_create_exists<qi::domain, Expr> >::type>
|
||||
{
|
||||
typedef typename result_of::create_parser<Expr>::type expr_type;
|
||||
typedef match_manip<
|
||||
expr_type, mpl::true_, mpl::false_, Skipper, Expr
|
||||
> type;
|
||||
|
||||
static type call(
|
||||
Expr const& expr
|
||||
, Skipper const& skipper
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip)
|
||||
{
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the delimiter is not a valid spirit karma expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
return type(create_parser<Expr>(), skipper, post_skip
|
||||
, const_cast<Expr&>(expr));
|
||||
}
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,123 @@
|
||||
/*=============================================================================
|
||||
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_MATCH_MANIP_MAY_05_2007_1202PM)
|
||||
#define BOOST_SPIRIT_MATCH_MANIP_MAY_05_2007_1202PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/parse.hpp>
|
||||
#include <boost/spirit/home/qi/parser.hpp>
|
||||
#include <boost/spirit/home/support/unused.hpp>
|
||||
#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr>
|
||||
inline typename detail::match<Expr>::type
|
||||
match(
|
||||
Expr const& expr)
|
||||
{
|
||||
return detail::match<Expr>::call(expr);
|
||||
}
|
||||
|
||||
template <typename Expr, typename Attribute>
|
||||
inline detail::match_manip<
|
||||
Expr, mpl::false_, mpl::false_, unused_type, Attribute
|
||||
>
|
||||
match(
|
||||
Expr const& xpr
|
||||
, Attribute& p)
|
||||
{
|
||||
using qi::detail::match_manip;
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
return match_manip<Expr, mpl::false_, mpl::false_, unused_type, Attribute>(
|
||||
xpr, unused, p);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Skipper>
|
||||
inline typename detail::phrase_match<Expr, Skipper>::type
|
||||
phrase_match(
|
||||
Expr const& expr
|
||||
, Skipper const& s
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip = skip_flag::postskip)
|
||||
{
|
||||
return detail::phrase_match<Expr, Skipper>::call(expr, s, post_skip);
|
||||
}
|
||||
|
||||
template <typename Expr, typename Skipper, typename Attribute>
|
||||
inline detail::match_manip<
|
||||
Expr, mpl::false_, mpl::false_, Skipper, Attribute
|
||||
>
|
||||
phrase_match(
|
||||
Expr const& xpr
|
||||
, Skipper const& s
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip
|
||||
, Attribute& p)
|
||||
{
|
||||
using qi::detail::match_manip;
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then either the expression (expr) or skipper is not a valid
|
||||
// spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
return match_manip<Expr, mpl::false_, mpl::false_, Skipper, Attribute>(
|
||||
xpr, s, post_skip, p);
|
||||
}
|
||||
|
||||
template <typename Expr, typename Skipper, typename Attribute>
|
||||
inline detail::match_manip<
|
||||
Expr, mpl::false_, mpl::false_, Skipper, Attribute
|
||||
>
|
||||
phrase_match(
|
||||
Expr const& xpr
|
||||
, Skipper const& s
|
||||
, Attribute& p)
|
||||
{
|
||||
using qi::detail::match_manip;
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then either the expression (expr) or skipper is not a valid
|
||||
// spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
return match_manip<Expr, mpl::false_, mpl::false_, Skipper, Attribute>(
|
||||
xpr, s, p);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename Char, typename Traits, typename Derived>
|
||||
inline std::basic_istream<Char, Traits>&
|
||||
operator>>(std::basic_istream<Char, Traits>& is, parser<Derived> const& p)
|
||||
{
|
||||
typedef spirit::basic_istream_iterator<Char, Traits> input_iterator;
|
||||
|
||||
input_iterator f(is);
|
||||
input_iterator l;
|
||||
if (!p.derived().parse(f, l, unused, unused, unused))
|
||||
{
|
||||
is.setstate(std::ios_base::failbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/*=============================================================================
|
||||
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_PP_IS_ITERATING)
|
||||
|
||||
#if !defined(BOOST_SPIRIT_MATCH_MANIP_ATTR_MAY_05_2007_1202PM)
|
||||
#define BOOST_SPIRIT_MATCH_MANIP_ATTR_MAY_05_2007_1202PM
|
||||
|
||||
#include <boost/spirit/home/qi/stream/match_manip.hpp>
|
||||
|
||||
#include <boost/fusion/include/vector.hpp>
|
||||
#include <boost/preprocessor/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
|
||||
#define BOOST_PP_FILENAME_1 \
|
||||
<boost/spirit/home/qi/stream/match_manip_attr.hpp>
|
||||
#define BOOST_PP_ITERATION_LIMITS (2, SPIRIT_ARGUMENTS_LIMIT)
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Preprocessor vertical repetition code
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#else // defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
#define N BOOST_PP_ITERATION()
|
||||
#define BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE(z, n, A) BOOST_PP_CAT(A, n) &
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline detail::match_manip<Expr, mpl::false_, mpl::true_, unused_type
|
||||
, fusion::vector<
|
||||
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
|
||||
> >
|
||||
match(
|
||||
Expr const& xpr
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
using qi::detail::match_manip;
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then the expression (expr) is not a valid spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
|
||||
typedef fusion::vector<
|
||||
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
|
||||
> vector_type;
|
||||
|
||||
vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
return match_manip<Expr, mpl::false_, mpl::true_, unused_type, vector_type>(
|
||||
xpr, unused, attr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Expr, typename Skipper
|
||||
, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline detail::match_manip<Expr, mpl::false_, mpl::true_, Skipper
|
||||
, fusion::vector<
|
||||
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
|
||||
> >
|
||||
phrase_match(
|
||||
Expr const& xpr
|
||||
, Skipper const& s
|
||||
, BOOST_SCOPED_ENUM(skip_flag) post_skip
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
using qi::detail::match_manip;
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then either the expression (expr) or skipper is not a valid
|
||||
// spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
|
||||
typedef fusion::vector<
|
||||
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
|
||||
> vector_type;
|
||||
|
||||
vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
return match_manip<Expr, mpl::false_, mpl::true_, Skipper, vector_type>(
|
||||
xpr, s, post_skip, attr);
|
||||
}
|
||||
|
||||
template <typename Expr, typename Skipper
|
||||
, BOOST_PP_ENUM_PARAMS(N, typename A)>
|
||||
inline detail::match_manip<Expr, mpl::false_, mpl::true_, Skipper
|
||||
, fusion::vector<
|
||||
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
|
||||
> >
|
||||
phrase_match(
|
||||
Expr const& xpr
|
||||
, Skipper const& s
|
||||
, BOOST_PP_ENUM_BINARY_PARAMS(N, A, & attr))
|
||||
{
|
||||
using qi::detail::match_manip;
|
||||
|
||||
// Report invalid expression error as early as possible.
|
||||
// If you got an error_invalid_expression error message here,
|
||||
// then either the expression (expr) or skipper is not a valid
|
||||
// spirit qi expression.
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Expr);
|
||||
BOOST_SPIRIT_ASSERT_MATCH(qi::domain, Skipper);
|
||||
|
||||
typedef fusion::vector<
|
||||
BOOST_PP_ENUM(N, BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE, A)
|
||||
> vector_type;
|
||||
|
||||
vector_type attr (BOOST_PP_ENUM_PARAMS(N, attr));
|
||||
return match_manip<Expr, mpl::false_, mpl::true_, Skipper, vector_type>(
|
||||
xpr, s, attr);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#undef BOOST_SPIRIT_QI_ATTRIBUTE_REFERENCE
|
||||
#undef N
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*=============================================================================
|
||||
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_STREAM_MAY_05_2007_1228PM)
|
||||
#define BOOST_SPIRIT_STREAM_MAY_05_2007_1228PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/detail/string_parse.hpp>
|
||||
#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
|
||||
#include <boost/spirit/home/qi/stream/detail/iterator_source.hpp>
|
||||
#include <boost/spirit/home/support/detail/hold_any.hpp>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <sstream>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Enablers
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct use_terminal<qi::domain, tag::stream> // enables stream
|
||||
: mpl::true_ {};
|
||||
|
||||
template <>
|
||||
struct use_terminal<qi::domain, tag::wstream> // enables wstream
|
||||
: mpl::true_ {};
|
||||
}}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace spirit { namespace qi
|
||||
{
|
||||
#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
|
||||
using spirit::stream;
|
||||
using spirit::wstream;
|
||||
#endif
|
||||
using spirit::stream_type;
|
||||
using spirit::wstream_type;
|
||||
|
||||
template <typename Char = char, typename T = spirit::basic_hold_any<char> >
|
||||
struct stream_parser
|
||||
: primitive_parser<stream_parser<Char, T> >
|
||||
{
|
||||
template <typename Context, typename Iterator>
|
||||
struct attribute
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename Iterator, typename Context
|
||||
, typename Skipper, typename Attribute>
|
||||
bool parse(Iterator& first, Iterator const& last
|
||||
, Context& /*context*/, Skipper const& skipper
|
||||
, Attribute& attr_) const
|
||||
{
|
||||
typedef qi::detail::iterator_source<Iterator> source_device;
|
||||
typedef boost::iostreams::stream<source_device> instream;
|
||||
|
||||
qi::skip_over(first, last, skipper);
|
||||
|
||||
instream in(first, last); // copies 'first'
|
||||
in >> attr_; // use existing operator>>()
|
||||
|
||||
// advance the iterator if everything is ok
|
||||
if (in) {
|
||||
if (!in.eof()) {
|
||||
std::streamsize pos = in.tellg();
|
||||
std::advance(first, pos);
|
||||
} else {
|
||||
first = last;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Context>
|
||||
info what(Context& /*context*/) const
|
||||
{
|
||||
return info("stream");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Char = char>
|
||||
struct typed_stream
|
||||
: proto::terminal<stream_parser<Char, T> >::type
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Parser generators: make_xxx function (objects)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template <typename Char>
|
||||
struct make_stream
|
||||
{
|
||||
typedef stream_parser<Char> result_type;
|
||||
result_type operator()(unused_type, unused_type) const
|
||||
{
|
||||
return result_type();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::stream, Modifiers> : make_stream<char> {};
|
||||
|
||||
template <typename Modifiers>
|
||||
struct make_primitive<tag::wstream, Modifiers> : make_stream<wchar_t> {};
|
||||
}}}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,17 @@
|
||||
/*=============================================================================
|
||||
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_STRING_FEBRUARY_03_2007_0355PM)
|
||||
#define BOOST_SPIRIT_STRING_FEBRUARY_03_2007_0355PM
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/spirit/home/qi/string/lit.hpp>
|
||||
#include <boost/spirit/home/qi/string/symbols.hpp>
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user