Imported existing code

This commit is contained in:
Hazim Gazov
2010-04-02 02:48:44 -03:00
parent 48fbc5ae91
commit 7a86d01598
13996 changed files with 2468699 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
/*=============================================================================
Copyright (c) 2001-2007 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_JAN_07_2007_1233PM)
#define SPIRIT_ACTION_JAN_07_2007_1233PM
#include <boost/spirit/home/qi/action/action.hpp>
#include <boost/spirit/home/qi/action/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,96 @@
/*=============================================================================
Copyright (c) 2001-2007 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_JAN_07_2007_1128AM)
#define SPIRIT_ACTION_JAN_07_2007_1128AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <boost/spirit/home/support/detail/action_dispatch.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_same.hpp>
#include <vector>
namespace boost { namespace spirit { namespace qi
{
struct action
{
template <typename Component, typename Context, typename Iterator>
struct attribute
: traits::attribute_of<
qi::domain
, typename result_of::left<Component>::type
, Context
, Iterator
>
{
};
template <typename F, typename Attribute, typename Context>
static bool const_action_dispatch(
F const& f, Attribute const& attr, Context& context)
{
// This function makes Attribute a const reference
// before calling detail::action_dispatch whereby
// disallowing mutability of the attribute in semantic
// actions.
return spirit::detail::action_dispatch(f, attr, context,
mpl::true_());
}
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_)
{
typedef typename
result_of::left<Component>::type::director
director;
typedef typename
attribute<Component, Context, Iterator>::type
attr_type;
// create an attribute if one is not supplied
typename mpl::if_<
is_same<typename remove_const<Attribute>::type, unused_type>
, typename remove_const<attr_type>::type
, Attribute&>::type
attr = spirit::detail::make_value<attr_type>::call(attr_);
if (director::parse(
spirit::left(component), first, last, context, skipper, attr))
{
// call the function, passing the attribute, the context.
// The client can return false to fail parsing.
return const_action_dispatch(
spirit::right(component), attr, context);
}
return false;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
typedef typename
result_of::left<Component>::type::director
director;
return director::what(spirit::left(component), ctx);
}
};
}}}
#endif

View File

@@ -0,0 +1,58 @@
/*=============================================================================
Copyright (c) 2001-2007 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_GRAMMAR_FEB_07_2007_1100AM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_07_2007_1100AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
struct action;
struct main_meta_grammar;
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// action meta-grammar
///////////////////////////////////////////////////////////////////////////
struct action_meta_grammar :
meta_grammar::binary_rule<
qi::domain, proto::tag::subscript, action
, main_meta_grammar, proto::when<proto::_, proto::_child>
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, action_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, action_meta_grammar> >::type>
: mpl::identity<action_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,20 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2001-2009 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_FEB_03_2007_0355PM)
#define BOOST_SPIRIT_STRING_FEB_03_2007_0355PM
#include <boost/spirit/home/qi/auxiliary/none.hpp>
#include <boost/spirit/home/qi/auxiliary/confix.hpp>
#include <boost/spirit/home/qi/auxiliary/eps.hpp>
#include <boost/spirit/home/qi/auxiliary/lazy.hpp>
#include <boost/spirit/home/qi/auxiliary/functor.hpp>
#include <boost/spirit/home/qi/auxiliary/functor_director.hpp>
#include <boost/spirit/home/qi/auxiliary/primitives.hpp>
#include <boost/spirit/home/qi/auxiliary/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,127 @@
// Copyright (c) 2001-2008 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_CONFIX_AUG_26_2008_1012AM)
#define BOOST_SPIRIT_QI_CONFIX_AUG_26_2008_1012AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/auxiliary/confix.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// the director for a confix() generated parser
struct confix_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
traits::attribute_of<
qi::domain, subject_type, Context, Iterator>::type
type;
};
private:
///////////////////////////////////////////////////////////////////////
template <
typename Iterator, typename Context
, typename Skipper, typename Expr>
static void parse_helper(
Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper, Expr const& e)
{
BOOST_MPL_ASSERT_MSG(
(spirit::traits::is_component<qi::domain, Expr>::value),
expression_is_not_convertible_to_a_parser, (Context, Expr));
typedef
typename result_of::as_component<qi::domain, Expr>::type
expr;
expr eg = spirit::as_component(qi::domain(), e);
typedef typename expr::director director;
director::parse(eg, first, last, context, skipper, unused);
}
template <typename Context, typename Expr>
static std::string what_helper(Expr const& e, Context& ctx)
{
typedef
typename result_of::as_component<qi::domain, Expr>::type
expr;
expr eg = spirit::as_component(qi::domain(), e);
typedef typename expr::director director;
return director::what(eg, ctx);
}
public:
///////////////////////////////////////////////////////////////////////
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
// parse the prefix
parse_helper(first, last, context, skipper,
spirit::detail::confix_extractor::prefix(
proto::child_c<0>(spirit::argument1(component))));
// generate the embedded items
typedef typename
spirit::result_of::subject<Component>::type::director
director;
bool result = director::parse(spirit::subject(component),
first, last, context, skipper, attr);
// append the suffix
parse_helper(first, last, context, skipper,
spirit::detail::confix_extractor::suffix(
proto::child_c<0>(spirit::argument1(component))));
return result;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "confix(";
result += what_helper(spirit::detail::confix_extractor::prefix(
proto::child_c<0>(spirit::argument1(component))), ctx);
result += ", ";
result += what_helper(spirit::detail::confix_extractor::suffix(
proto::child_c<0>(spirit::argument1(component))), ctx);
result += ")[";
typedef typename
spirit::result_of::subject<Component>::type::director
director;
result += director::what(spirit::subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,76 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/at.hpp>
namespace boost { namespace spirit { namespace qi
{
struct eps_parser
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& /*attr*/)
{
qi::skip(first, last, skipper);
return true;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "eps";
}
};
struct semantic_predicate
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& /*attr*/)
{
qi::skip(first, last, skipper);
return fusion::at_c<0>(component.elements)(unused, context);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "semantic-predicate";
}
};
}}}
#endif

View File

@@ -0,0 +1,210 @@
// Copyright (c) 2001-2009 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_FUNCTOR_APR_01_2007_0817AM)
#define BOOST_SPIRIT_FUNCTOR_APR_01_2007_0817AM
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/detail/values.hpp>
#include <boost/spirit/home/support/auxiliary/functor_holder.hpp>
#include <boost/spirit/home/support/auxiliary/meta_function_holder.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
namespace qi
{
template <typename Functor, typename ParameterMF = Functor>
class functor_parser;
}
namespace result_of
{
template <typename Functor>
struct as_parser
{
typedef qi::functor_parser<Functor> type;
};
template <typename ParameterMF, typename Functor>
struct as_parser_mf
{
typedef qi::functor_parser<Functor, ParameterMF> type;
};
}
}} // boost::spirit
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// This struct may be used as a base class for a user defined functor
///////////////////////////////////////////////////////////////////////////
struct functor_base
{
///////////////////////////////////////////////////////////////////////
// The return value of a qi functor is always bool
///////////////////////////////////////////////////////////////////////
template <typename Attribute, typename Iterator, typename Context>
struct result
{
typedef bool type;
};
// FIXME: It will be possible to specify the return value as a typedef, but for
// that Phoenix will have to be fixed.
// typedef bool result_type;
///////////////////////////////////////////////////////////////////////
// The expected parameter type of a functor has to be defined using a
// embedded apply metafunction. Normally this will be overloaded by
// the derived class, but the default is unused type.
///////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Context>
struct apply
{
typedef spirit::unused_type type;
};
};
///////////////////////////////////////////////////////////////////////////
template <typename Functor, typename ParameterMF>
class functor_parser
: public proto::extends<
typename make_functor_holder<
functor_parser<Functor, ParameterMF> const*,
functor_parser<Functor, ParameterMF>
>::type,
functor_parser<Functor, ParameterMF>
>
{
private:
typedef functor_parser<Functor, ParameterMF> self_type;
typedef typename
make_functor_holder<self_type const*, self_type>::type
functor_tag;
typedef proto::extends<functor_tag, self_type> base_type;
public:
template <typename Iterator, typename Context>
struct result
: mpl::apply<ParameterMF, Iterator, Context>
{};
private:
// parse function just delegates to the functor supplied function
template <typename Iterator, typename Context, typename Attribute>
bool
parse (Iterator& first, Iterator const& last, Context& ctx,
Attribute& attr_) const
{
// create an attribute if none is supplied
typedef typename result<Iterator, Context>::type attr_type;
typename mpl::if_<
is_same<typename remove_const<Attribute>::type, unused_type>,
attr_type,
Attribute&
>::type
attr = spirit::detail::make_value<attr_type>::call(attr_);
return functor(attr, ctx, first, last);
}
friend struct functor_director;
public:
explicit functor_parser()
: base_type(make_tag())
{
}
functor_parser(Functor const& functor_)
: base_type(make_tag()), functor(functor_)
{
}
functor_parser(Functor const& functor_, ParameterMF const& mf)
: base_type(make_tag()), functor(functor_), mf_(mf)
{
}
private:
functor_tag make_tag() const
{
functor_tag xpr = {{ this }};
return xpr;
}
Functor functor;
meta_function_holder<Functor, ParameterMF> mf_;
};
///////////////////////////////////////////////////////////////////////////
// The as_parser generator function may be used to create a functor
// parser from a function object (some callable item).
// The supplied functor needs to expose
//
// - an embedded result meta function:
//
// template <typename Attribute, typename Iterator, typename Context>
// struct result
// {
// typedef bool type;
// };
//
// which declares 'bool' as the result type of the defined function
// operator and
//
// - an embedded apply meta function:
//
// template <typename Iterator, typename Context>
// struct apply
// {
// typedef unspecified type;
// };
//
// which declares the given type as the expected attribute type for
// the parser to create.
///////////////////////////////////////////////////////////////////////////
template <typename Functor>
inline typename result_of::as_parser<Functor>::type
as_parser(Functor const& func)
{
return functor_parser<Functor>(func);
}
///////////////////////////////////////////////////////////////////////////
// The as_parser_mf generator function is equivalent to the function
// as_parser above except that the user has to explicitly specify a
// type exposing an embedded apply meta function declaring the expected
// parameter type for the generator to create.
///////////////////////////////////////////////////////////////////////////
template <typename ParameterMF, typename Functor>
inline typename result_of::as_parser_mf<ParameterMF, Functor>::type
as_parser_mf(Functor const& func, ParameterMF const& mf)
{
return functor_parser<Functor, ParameterMF>(func, mf);
}
template <typename ParameterMF, typename Functor>
inline typename result_of::as_parser_mf<ParameterMF, Functor>::type
as_parser_mf(Functor const& func)
{
return functor_parser<Functor, ParameterMF>(func, ParameterMF());
}
}}}
#endif

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2001-2009 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_FUNCTOR_DIRECTOR_APR_01_2007_0847AM)
#define BOOST_SPIRIT_FUNCTOR_DIRECTOR_APR_01_2007_0847AM
#include <boost/spirit/home/support/auxiliary/functor_holder.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/qi/domain.hpp>
namespace boost { namespace spirit { namespace qi
{
// this is the director for all functor parsers
struct functor_director
{
// return value of the parser
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type::functor_type
functor_type;
typedef typename
functor_type::template result<Iterator, Context>::type
type;
};
// parse functionality, delegates back to the corresponding functor
template <typename Component, typename Iterator, typename Context,
typename Skipper, typename Attribute>
static bool parse(Component const& component,
Iterator& first, Iterator const& last, Context& context,
Skipper const& skipper, Attribute& attr)
{
// main entry point, just forward to the functor parse function
qi::skip(first, last, skipper); // always do a pre-skip
return subject(component).held->parse(first, last, context, attr);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "functor";
}
};
}}}
#endif

View File

@@ -0,0 +1,106 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace spirit { namespace qi
{
struct lazy_parser
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
remove_reference<
typename boost::result_of<subject_type(unused_type, Context)>::type
>::type
expr_type;
typedef typename
result_of::as_component<qi::domain, expr_type>::type
component_type;
typedef typename
traits::attribute_of<
qi::domain, component_type, Context, Iterator>::type
type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
remove_reference<
typename boost::result_of<subject_type(unused_type, Context)>::type
>::type
expr_type;
typedef typename
result_of::as_component<qi::domain, expr_type>::type
component_type;
component_type subject
= spirit::as_component(
qi::domain(), fusion::at_c<0>(component.elements)(unused, context));
return component_type::director::
parse(subject, first, last, context, skipper, attr);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
//~ typedef typename
//~ result_of::subject<Component>::type
//~ subject_type;
//~ typedef typename
//~ remove_reference<
//~ typename boost::result_of<subject_type(unused_type, unused_type)>::type
//~ >::type
//~ expr_type;
//~ typedef typename
//~ result_of::as_component<qi::domain, expr_type>::type
//~ component_type;
//~ component_type subject
//~ = spirit::as_component(
//~ qi::domain(), fusion::at_c<0>(component.elements)(unused, unused));
std::string result = "lazy[";
//~ result += component_type::director::what(subject, ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,134 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2001-2009 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_META_GRAMMAR_MARCH_23_2007_0537PM)
#define BOOST_SPIRIT_META_GRAMMAR_MARCH_23_2007_0537PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit
{
template <typename T, typename Functor>
struct functor_holder;
}}
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
struct main_meta_grammar;
struct none;
struct eps_parser;
struct semantic_predicate;
struct lazy_parser;
struct functor_director;
struct confix_director;
struct eol_director;
struct eoi_director;
template <typename Positive>
struct negated_end_director;
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// auxiliary parsers meta-grammar
///////////////////////////////////////////////////////////////////////////
// none, eps and eps(f)
struct auxiliary_meta_grammar1
: proto::or_<
// none
meta_grammar::empty_terminal_rule<
qi::domain, tag::none, none>
// eps
, meta_grammar::empty_terminal_rule<
qi::domain, tag::eps, eps_parser>
// eps()
, meta_grammar::function1_rule<
qi::domain, tag::eps, semantic_predicate>
// lazy()
, meta_grammar::function1_rule<
qi::domain, tag::lazy, lazy_parser>
// functor parser
, meta_grammar::terminal_rule<
qi::domain
, functor_holder<proto::_, proto::_>
, functor_director
>
// confix(..., ...)[...]
, meta_grammar::subscript_rule<
qi::domain, tag::confix_tag<proto::_, proto::_>,
confix_director, main_meta_grammar
>
>
{
};
// eol, eoi
struct auxiliary_end_meta_grammar
: proto::or_<
meta_grammar::terminal_rule<qi::domain, tag::eol, eol_director>
, meta_grammar::terminal_rule<qi::domain, tag::eoi, eoi_director>
>
{
};
struct negated_auxiliary_end_meta_grammar
: proto::or_<
auxiliary_end_meta_grammar
, meta_grammar::compose_single<
proto::unary_expr<
proto::tag::complement
, negated_auxiliary_end_meta_grammar
>
, qi::domain
, negated_end_director<mpl::_>
>
>
{
};
struct auxiliary_meta_grammar
: proto::or_<
auxiliary_meta_grammar1
, negated_auxiliary_end_meta_grammar
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, auxiliary_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, auxiliary_meta_grammar> >::type>
: mpl::identity<auxiliary_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,46 @@
/*=============================================================================
Copyright (c) 2001-2007 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_NONE_MARCH_23_2007_0454PM)
#define BOOST_SPIRIT_NONE_MARCH_23_2007_0454PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi
{
struct none
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& /*attr*/)
{
qi::skip(first, last, skipper);
return false;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "none";
}
};
}}}
#endif

View File

@@ -0,0 +1,165 @@
/*=============================================================================
Copyright (c) 2001-2008 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_PRIMITIVES_APR_18_2008_0751PM)
#define BOOST_SPIRIT_PRIMITIVES_APR_18_2008_0751PM
#include <boost/mpl/bool.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// the end_director_base is a base class for various end parsers
///////////////////////////////////////////////////////////////////////////
template <typename Parser, typename StoreIterator = mpl::false_>
struct end_director_base
{
typedef mpl::false_ stores_iterator;
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& /*attr*/)
{
qi::skip(first, last, skipper);
return Parser::test(first, last);
}
// subclasses are required to implement test:
template <typename Iterator>
bool test(Iterator& first, Iterator const& last);
};
///////////////////////////////////////////////////////////////////////////
// same as end_director_base above, but stores iterator
///////////////////////////////////////////////////////////////////////////
template <typename Parser>
struct end_director_base<Parser, mpl::true_>
{
typedef mpl::true_ stores_iterator;
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& /*attr*/)
{
qi::skip(first, last, skipper);
Iterator it = first;
if (!Parser::test(it, last))
return false;
first = it;
return true;
}
// subclasses are required to implement test:
template <typename Iterator>
bool test(Iterator& first, Iterator const& last);
};
///////////////////////////////////////////////////////////////////////////
// ~eoi, ~eol: 'not end of line' or 'not end of input'
template <typename Positive>
struct negated_end_director
: end_director_base<
negated_end_director<Positive>,
typename Positive::director::stores_iterator
>
{
template <typename Iterator>
static bool test (Iterator& first, Iterator const& last)
{
return !Positive::director::test(first, last);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "not " +
Positive::director::what(fusion::at_c<0>(component.elements), ctx);
}
};
///////////////////////////////////////////////////////////////////////////
// eoi: end of input
struct eoi_director : end_director_base<eoi_director>
{
template <typename Iterator>
static bool test (Iterator& first, Iterator const& last)
{
return first == last;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "eoi";
}
};
///////////////////////////////////////////////////////////////////////////
// the eol_director matches line endings
///////////////////////////////////////////////////////////////////////////
struct eol_director : end_director_base<eol_director, mpl::true_>
{
template <typename Iterator>
static bool test (Iterator& first, Iterator const& last)
{
bool matched = false;
if (first != last && *first == '\r') // CR
{
matched = true;
++first;
}
if (first != last && *first == '\n') // LF
{
matched = true;
++first;
}
return matched;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "eol";
}
};
///////////////////////////////////////////////////////////////////////////////
}}}
#endif

View File

@@ -0,0 +1,16 @@
// Copyright (c) 2001-2009 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) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
#include <boost/spirit/home/qi/binary/binary.hpp>
#include <boost/spirit/home/qi/binary/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,194 @@
// Copyright (c) 2001-2009 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_0808AM)
#define BOOST_SPIRIT_BINARY_MAY_08_2007_0808AM
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/detail/integer/endian.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/qi/skip.hpp>
namespace boost { namespace spirit { namespace qi
{
namespace detail
{
template <int bits>
struct integer
{
#ifdef BOOST_HAS_LONG_LONG
BOOST_MPL_ASSERT_MSG(
bits == 8 || bits == 16 || bits == 32 || bits == 64,
not_supported_binary_size, ());
#else
BOOST_MPL_ASSERT_MSG(
bits == 8 || bits == 16 || bits == 32,
not_supported_binary_size, ());
#endif
};
template <>
struct integer<8>
{
typedef uint_least8_t type;
};
template <>
struct integer<16>
{
typedef uint_least16_t type;
};
template <>
struct integer<32>
{
typedef uint_least32_t type;
};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct integer<64>
{
typedef uint_least64_t type;
};
#endif
///////////////////////////////////////////////////////////////////////
template <boost::integer::endianness bits>
struct what;
template <>
struct what<boost::integer::native>
{
static std::string is()
{
return "native-endian binary";
}
};
template <>
struct what<boost::integer::little>
{
static char const* is()
{
return "little-endian binary";
}
};
template <>
struct what<boost::integer::big>
{
static char const* is()
{
return "big-endian binary";
}
};
}
///////////////////////////////////////////////////////////////////////////
template <integer::endianness endian, int bits>
struct any_binary_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef boost::integer::endian<
endian, typename qi::detail::integer<bits>::type, bits
> type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const&
, Iterator& first, Iterator const& last
, Context&, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
typename
traits::attribute_of<
qi::domain, Component, 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;
detail::assign_to(attr_, attr);
return true;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return qi::detail::what<endian>::is();
}
};
///////////////////////////////////////////////////////////////////////////
template <integer::endianness endian, int bits>
struct binary_lit_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context&, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
boost::integer::endian<
endian, typename qi::detail::integer<bits>::type, bits
> attr_ (fusion::at_c<0>(component.elements));
unsigned char* bytes = reinterpret_cast<unsigned char*>(&attr_);
Iterator it = first;
for (unsigned int i = 0; i < sizeof(attr_); ++i)
{
if (it == last || *bytes++ != *it++)
return false;
}
first = it;
detail::assign_to(attr_, attr);
return true;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return qi::detail::what<endian>::is();
}
};
}}}
#endif

View File

@@ -0,0 +1,259 @@
// Copyright (c) 2001-2009 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_META_GRAMMAR_MAY_08_2007_0824AM)
#define BOOST_SPIRIT_META_GRAMMAR_MAY_08_2007_0824AM
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/spirit/home/support/detail/integer/endian.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
template <integer::endianness endian, int bits>
struct any_binary_director;
template <integer::endianness endian, int bits>
struct binary_lit_director;
struct main_meta_grammar;
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// get the director of an integer based binary literal type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct extract_literal_bin_director
{
typedef binary_lit_director<
boost::integer::native, sizeof(T)*CHAR_BIT
> type;
};
///////////////////////////////////////////////////////////////////////////
// get the director of a binary tag
///////////////////////////////////////////////////////////////////////////
template <typename Tag>
struct extract_binary_director;
// native endian binaries
template <>
struct extract_binary_director<tag::byte>
{
typedef any_binary_director<boost::integer::native, 8> type;
};
template <>
struct extract_binary_director<tag::word>
{
typedef any_binary_director<boost::integer::native, 16> type;
};
template <>
struct extract_binary_director<tag::dword>
{
typedef any_binary_director<boost::integer::native, 32> type;
};
// big endian binaries
template <>
struct extract_binary_director<tag::big_word>
{
typedef any_binary_director<boost::integer::big, 16> type;
};
template <>
struct extract_binary_director<tag::big_dword>
{
typedef any_binary_director<boost::integer::big, 32> type;
};
// little endian binaries
template <>
struct extract_binary_director<tag::little_word>
{
typedef any_binary_director<boost::integer::little, 16> type;
};
template <>
struct extract_binary_director<tag::little_dword>
{
typedef any_binary_director<boost::integer::little, 32> type;
};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct extract_binary_director<tag::qword>
{
typedef any_binary_director<boost::integer::native, 64> type;
};
template <>
struct extract_binary_director<tag::big_qword>
{
typedef any_binary_director<boost::integer::big, 64> type;
};
template <>
struct extract_binary_director<tag::little_qword>
{
typedef any_binary_director<boost::integer::little, 64> type;
};
#endif
///////////////////////////////////////////////////////////////////////////
// get the director of a binary literal tag
///////////////////////////////////////////////////////////////////////////
template <typename Tag, typename T>
struct extract_binary_lit_director;
// native endian binaries
template <typename T>
struct extract_binary_lit_director<tag::byte, T>
{
typedef binary_lit_director<boost::integer::native, 8> type;
};
template <typename T>
struct extract_binary_lit_director<tag::word, T>
{
typedef binary_lit_director<boost::integer::native, 16> type;
};
template <typename T>
struct extract_binary_lit_director<tag::dword, T>
{
typedef binary_lit_director<boost::integer::native, 32> type;
};
// big endian binaries
template <typename T>
struct extract_binary_lit_director<tag::big_word, T>
{
typedef binary_lit_director<boost::integer::big, 16> type;
};
template <typename T>
struct extract_binary_lit_director<tag::big_dword, T>
{
typedef binary_lit_director<boost::integer::big, 32> type;
};
// little endian binaries
template <typename T>
struct extract_binary_lit_director<tag::little_word, T>
{
typedef binary_lit_director<boost::integer::little, 16> type;
};
template <typename T>
struct extract_binary_lit_director<tag::little_dword, T>
{
typedef binary_lit_director<boost::integer::little, 32> type;
};
#ifdef BOOST_HAS_LONG_LONG
template <typename T>
struct extract_binary_lit_director<tag::qword, T>
{
typedef binary_lit_director<boost::integer::native, 64> type;
};
template <typename T>
struct extract_binary_lit_director<tag::big_qword, T>
{
typedef binary_lit_director<boost::integer::big, 64> type;
};
template <typename T>
struct extract_binary_lit_director<tag::little_qword, T>
{
typedef binary_lit_director<boost::integer::little, 64> type;
};
#endif
///////////////////////////////////////////////////////////////////////////
// binary meta-grammar
///////////////////////////////////////////////////////////////////////////
// literals: 10, 10L, 10LL
struct int_binary_meta_grammar
: meta_grammar::compose_empty<
proto::if_<
is_int_lit_tag<proto::_child, qi::domain>()
>,
qi::domain,
mpl::identity<extract_literal_bin_director<mpl::_> >
>
{
};
struct binary_meta_grammar
: proto::or_<
meta_grammar::compose_empty<
proto::if_<
is_binary_tag<proto::_child, qi::domain>()
>,
qi::domain,
mpl::identity<extract_binary_director<mpl::_> >
>,
meta_grammar::compose_function1_eval<
proto::function<
proto::if_<
is_binary_tag<proto::_child, qi::domain>()
>,
int_binary_meta_grammar
>,
qi::domain,
mpl::identity<extract_binary_lit_director<mpl::_, mpl::_> >
>
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the Qi meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<
Expr,
typename enable_if<
proto::matches<Expr, binary_meta_grammar>
>::type
>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<
Expr,
typename enable_if<
proto::matches<Expr, binary_meta_grammar>
>::type
>
: mpl::identity<binary_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,15 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_02_2007_0921AM)
#define BOOST_SPIRIT_CHAR_FEB_02_2007_0921AM
#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>
#include <boost/spirit/home/qi/char/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,369 @@
/*=============================================================================
Copyright (c) 2001-2007 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_APR_16_2006_1051AM)
#define BOOST_SPIRIT_CHAR_APR_16_2006_1051AM
#include <boost/spirit/home/qi/char/char_parser.hpp>
#include <boost/spirit/home/qi/char/detail/get_char.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/value_at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/support/detail/to_narrow.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/foreach.hpp>
#include <boost/mpl/print.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// parse any character
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct any_char : char_parser<any_char<Char>, Char>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const&, CharParam, Context&)
{
return true;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "any-char";
}
};
///////////////////////////////////////////////////////////////////////////
// parse a single character
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct literal_char : char_parser<literal_char<Char>, Char>
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type; // literal parsers have no attribute
};
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return detail::get_char(fusion::at_c<0>(component.elements)) == ch;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("'")
+ spirit::detail::to_narrow_char(
detail::get_char(fusion::at_c<0>(component.elements)))
+ '\'';
}
};
///////////////////////////////////////////////////////////////////////////
// parse a character set
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct char_set : char_parser<char_set<Char>, Char>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return component.ptr->test(ch);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "char-set";
}
};
///////////////////////////////////////////////////////////////////////////
// parse a lazy character
///////////////////////////////////////////////////////////////////////////
struct lazy_char : char_parser<lazy_char>
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
remove_reference<
typename boost::result_of<subject_type(unused_type, Context)>::type
>::type
type;
};
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context& context)
{
return fusion::at_c<0>(component.elements)(unused, context) == ch;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("'")
+ spirit::detail::to_narrow_char(
fusion::at_c<0>(component.elements)(unused, ctx))
+ '\'';
}
};
///////////////////////////////////////////////////////////////////////////
// parse a character range
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct char_range : char_parser<char_range<Char>, Char>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return
!(ch < fusion::at_c<0>(component.elements)) &&
!(fusion::at_c<1>(component.elements) < ch);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result;
result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
result += "...";
result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
return result;
}
};
///////////////////////////////////////////////////////////////////////////
// parse a lazy character range
///////////////////////////////////////////////////////////////////////////
struct lazy_char_range : char_parser<lazy_char_range>
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
remove_reference<
typename boost::result_of<subject_type(unused_type, Context)>::type
>::type
type;
};
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context& context)
{
return
!(ch < fusion::at_c<0>(component.elements)(unused, context)) &&
!(fusion::at_c<1>(component.elements)(unused, context) < ch);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "char-range";
}
};
///////////////////////////////////////////////////////////////////////////
// no_case literal_char version
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct no_case_literal_char : char_parser<no_case_literal_char<Char>, Char>
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type; // literal parsers have no attribute
};
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return detail::get_char(fusion::at_c<0>(component.elements)) == ch
|| detail::get_char(fusion::at_c<1>(component.elements)) == ch
;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result;
result += std::string("'")
+ spirit::detail::to_narrow_char(
detail::get_char(fusion::at_c<0>(component.elements))) + '\'';
result += " or ";
result += std::string("'") +
spirit::detail::to_narrow_char(
detail::get_char(fusion::at_c<1>(component.elements))) + '\'';
return result;
}
};
///////////////////////////////////////////////////////////////////////////
// no_case char_range version
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct no_case_char_range : char_parser<no_case_char_range<Char>, Char>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context&)
{
return
(!(ch < fusion::at_c<0>(component.elements)) &&
!(fusion::at_c<1>(component.elements) < ch))
|| (!(ch < fusion::at_c<2>(component.elements)) &&
!(fusion::at_c<3>(component.elements) < ch))
;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result;
result += std::string("'") + fusion::at_c<0>(component.elements) + '\'';
result += "...";
result += std::string("'") + fusion::at_c<1>(component.elements) + '\'';
result += " or ";
result += std::string("'") + fusion::at_c<2>(component.elements) + '\'';
result += "...";
result += std::string("'") + fusion::at_c<3>(component.elements) + '\'';
return result;
}
};
template <typename Char, typename Elements>
struct char_set_component;
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// char_set_component generator
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename Elements, typename Modifier>
struct make_component<qi::domain, qi::char_set<Char>, Elements, Modifier
, typename disable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
> : mpl::identity<qi::char_set_component<Char, Elements> >
{
static qi::char_set_component<Char, Elements>
call(Elements const& elements)
{
return qi::char_set_component<Char, Elements>(
fusion::at_c<0>(elements));
}
};
///////////////////////////////////////////////////////////////////////////
// no_case char_set_component generator
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Elements, typename Modifier, typename Char
>
struct make_modified_component<
Domain, qi::char_set<Char>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef qi::char_set_component<Char, Elements> type;
typedef typename Modifier::char_set char_set;
static type
call(Elements const& elements)
{
return qi::char_set_component<Char, Elements>(
fusion::at_c<0>(elements), char_set());
}
};
///////////////////////////////////////////////////////////////////////////
// no_case_literal_char generator
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Elements, typename Modifier, typename Char
>
struct make_modified_component<
Domain, qi::literal_char<Char>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef fusion::vector<Char, Char> vector_type;
typedef
component<qi::domain, qi::no_case_literal_char<Char>, vector_type>
type;
static type
call(Elements const& elements)
{
typedef typename Modifier::char_set char_set;
Char ch = qi::detail::get_char(fusion::at_c<0>(elements));
vector_type v(
char_set::tolower(ch)
, char_set::toupper(ch)
);
return type(v);
}
};
///////////////////////////////////////////////////////////////////////////
// no_case_char_range generator
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Elements, typename Modifier, typename Char
>
struct make_modified_component<
Domain, qi::char_range<Char>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef fusion::vector<Char, Char, Char, Char> vector_type;
typedef
component<qi::domain, qi::no_case_char_range<Char>, vector_type>
type;
static type
call(Elements const& elements)
{
typedef typename Modifier::char_set char_set;
Char first = fusion::at_c<0>(elements);
Char last = fusion::at_c<1>(elements);
vector_type v(
char_set::tolower(first)
, char_set::tolower(last)
, char_set::toupper(first)
, char_set::toupper(last)
);
return type(v);
}
};
}}}
#endif

View File

@@ -0,0 +1,93 @@
/*=============================================================================
Copyright (c) 2001-2007 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_APR_16_2006_1051AM)
#define BOOST_SPIRIT_CHAR_CLASS_APR_16_2006_1051AM
#include <boost/spirit/home/qi/char/char_parser.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/support/iso8859_1.hpp>
#include <boost/spirit/home/support/ascii.hpp>
#include <boost/spirit/home/support/standard.hpp>
#include <boost/spirit/home/support/standard_wide.hpp>
#include <boost/fusion/include/cons.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// generic isxxx parser (for alnum, alpha, graph, etc.)
///////////////////////////////////////////////////////////////////////////
template <typename Tag>
struct char_class
: char_parser<char_class<Tag>, typename Tag::char_set::char_type>
{
typedef typename Tag::char_set char_set;
typedef typename Tag::char_class char_class_;
template <typename Component, typename CharParam, typename Context>
static bool test(Component const&, CharParam ch, Context&)
{
using spirit::char_class::classify;
return classify<char_set>::is(char_class_(), ch);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
typedef spirit::char_class::what<char_set> what_;
return what_::is(char_class_());
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// no_case char_class conversions
///////////////////////////////////////////////////////////////////////////
namespace detail
{
using spirit::char_class::key;
using spirit::char_class::lower_case_tag;
using spirit::char_class::upper_case_tag;
using spirit::char_class::tag::alpha;
template <typename Tag>
struct make_no_case_char_class :
mpl::identity<qi::char_class<Tag> > {};
template <typename CharSet>
struct make_no_case_char_class<lower_case_tag<CharSet> >
: mpl::identity<qi::char_class<key<CharSet, alpha> > > {};
template <typename CharSet>
struct make_no_case_char_class<upper_case_tag<CharSet> >
: mpl::identity<qi::char_class<key<CharSet, alpha> > > {};
}
template <
typename Domain, typename Elements, typename Modifier, typename Tag
>
struct make_modified_component<
Domain, qi::char_class<Tag>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef typename detail::make_no_case_char_class<Tag>::type director;
typedef component<qi::domain, director, fusion::nil> type;
static type
call(Elements const&)
{
return type(fusion::nil());
}
};
}}}
#endif

View File

@@ -0,0 +1,82 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <string>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
namespace boost { namespace spirit { namespace qi
{
template <typename Derived, typename Char = unused_type>
struct char_parser
{
typedef Char char_type;
// if Char is unused_type, Derived must supply its own attribute metafunction
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef Char type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
if (first != last && Derived::test(component, *first, context))
{
qi::detail::assign_to(*first, attr);
++first;
return true;
}
return false;
}
// char_parser subclasses are required to
// implement test:
template <typename Component, typename CharParam, typename Context>
bool test(Component const& component, CharParam ch, Context& context);
};
template <typename Positive>
struct negated_char_parser :
char_parser<
negated_char_parser<Positive>, typename Positive::director::char_type
>
{
template <typename Component, typename CharParam, typename Context>
static bool test(Component const& component, CharParam ch, Context& context)
{
return !Positive::director::test(
fusion::at_c<0>(component.elements), ch, context);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("not ")
+ Positive::director::what(fusion::at_c<0>(component.elements), ctx);
}
};
}}}
#endif

View File

@@ -0,0 +1,244 @@
/*=============================================================================
Copyright (c) 2001-2008 Joel de Guzman
Copyright (c) 2001-2003 Daniel Nuffer
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
#define BOOST_SPIRIT_BASIC_CHSET_APRIL_17_2008
///////////////////////////////////////////////////////////////////////////////
#include <bitset>
#include <boost/spirit/home/qi/char/detail/range_run.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: basic character set implementation using range_run
//
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct basic_chset
{
basic_chset() {}
basic_chset(basic_chset const& arg_)
: rr(arg_.rr) {}
bool
test(Char v) const
{
return rr.test(v);
}
void
set(Char from, Char to)
{
rr.set(range<Char>(from, to));
}
void
set(Char c)
{
rr.set(range<Char>(c, c));
}
void
clear(Char from, Char to)
{
rr.clear(range<Char>(from, to));
}
void
clear(Char c)
{
rr.clear(range<Char>(c, c));
}
void
clear()
{
rr.clear();
}
void
inverse()
{
basic_chset inv;
inv.set(
(std::numeric_limits<Char>::min)(),
(std::numeric_limits<Char>::max)()
);
inv -= *this;
swap(inv);
}
void
swap(basic_chset& x)
{
rr.swap(x.rr);
}
basic_chset&
operator|=(basic_chset const& x)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.set(*iter);
return *this;
}
basic_chset&
operator&=(basic_chset const& x)
{
basic_chset inv;
inv.set(
(std::numeric_limits<Char>::min)(),
(std::numeric_limits<Char>::max)()
);
inv -= x;
*this -= inv;
return *this;
}
basic_chset&
operator-=(basic_chset const& x)
{
typedef typename range_run<Char>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.clear(*iter);
return *this;
}
basic_chset&
operator^=(basic_chset const& x)
{
basic_chset bma = x;
bma -= *this;
*this -= x;
*this |= bma;
return *this;
}
private: range_run<Char> rr;
};
#if (CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: specializations for 8 bit chars using std::bitset
//
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct basic_chset_8bit
{
basic_chset_8bit() {}
basic_chset_8bit(basic_chset_8bit const& arg_)
: bset(arg_.bset) {}
bool
test(Char v) const
{
return bset.test((unsigned char)v);
}
void
set(Char from, Char to)
{
for (int i = from; i <= to; ++i)
bset.set((unsigned char)i);
}
void
set(Char c)
{
bset.set((unsigned char)c);
}
void
clear(Char from, Char to)
{
for (int i = from; i <= to; ++i)
bset.reset((unsigned char)i);
}
void
clear(Char c)
{
bset.reset((unsigned char)c);
}
void
clear()
{
bset.reset();
}
void
inverse()
{
bset.flip();
}
void
swap(basic_chset_8bit& x)
{
std::swap(bset, x.bset);
}
basic_chset_8bit&
operator|=(basic_chset_8bit const& x)
{
bset |= x.bset;
return *this;
}
basic_chset_8bit&
operator&=(basic_chset_8bit const& x)
{
bset &= x.bset;
return *this;
}
basic_chset_8bit&
operator-=(basic_chset_8bit const& x)
{
bset &= ~x.bset;
return *this;
}
basic_chset_8bit&
operator^=(basic_chset_8bit const& x)
{
bset ^= x.bset;
return *this;
}
private: std::bitset<256> bset;
};
/////////////////////////////////
template <>
struct basic_chset<char>
: basic_chset_8bit<char> {};
/////////////////////////////////
template <>
struct basic_chset<signed char>
: basic_chset_8bit<signed char> {};
/////////////////////////////////
template <>
struct basic_chset<unsigned char>
: basic_chset_8bit<unsigned char> {};
#endif // #if (CHAR_BIT == 8)
}}}}
#endif

View File

@@ -0,0 +1,36 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_GET_CHAR_APR_20_2008_0618_PM)
#define BOOST_SPIRIT_GET_CHAR_APR_20_2008_0618_PM
#include <string>
namespace boost { namespace spirit { namespace qi { namespace detail
{
// utility to get the (first) character from a primitive char,
// a null terminated string and a std::basic_string
template <typename Char>
static Char get_char(Char ch)
{
return ch;
}
template <typename Char>
static Char get_char(Char const* str)
{
return *str;
}
template <typename Char>
static Char get_char(std::basic_string<Char> const& str)
{
return str[0];
}
}}}}
#endif

View File

@@ -0,0 +1,35 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM)
#define BOOST_SPIRIT_RANGE_MAY_16_2006_0720_PM
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// A closed range (first, last)
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct range
{
typedef T value_type;
range()
: first(), last()
{
}
range(T first, T last)
: first(first), last(last)
{
}
T first;
T last;
};
}}}}
#endif

View File

@@ -0,0 +1,94 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM)
#define BOOST_SPIRIT_RANGE_FUNCTIONS_MAY_16_2006_0720_PM
#include <boost/integer_traits.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Range>
inline bool
is_valid(Range const& range)
{
// test for valid ranges
return range.first <= range.last;
}
template <typename Range>
inline bool
includes(Range const& range, Range const& other)
{
// see if two ranges intersect
return (range.first <= other.first) && (range.last >= other.last);
}
template <typename Range>
inline bool
includes(Range const& range, typename Range::value_type val)
{
// see if val is in range
return (range.first <= val) && (range.last >= val);
}
template <typename Range>
inline bool
can_merge(Range const& range, Range const& other)
{
// see if a 'range' overlaps, or is adjacent to
// another range 'other', so we can merge them
typedef typename Range::value_type value_type;
typedef integer_traits<value_type> integer_traits;
value_type decr_first =
range.first == integer_traits::const_min
? range.first : range.first-1;
value_type incr_last =
range.last == integer_traits::const_max
? range.last : range.last+1;
return (decr_first <= other.last) && (incr_last >= other.first);
}
template <typename Range>
inline void
merge(Range& result, Range const& other)
{
// merge two ranges
if (result.first > other.first)
result.first = other.first;
if (result.last < other.last)
result.last = other.last;
}
template <typename Range>
struct range_compare
{
// compare functor with a value or another range
typedef typename Range::value_type value_type;
bool operator()(Range const& x, const value_type y) const
{
return x.first < y;
}
bool operator()(value_type const x, Range const& y) const
{
return x < y.first;
}
bool operator()(Range const& x, Range const& y) const
{
return x.first < y.first;
}
};
}}}}
#endif

View File

@@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM)
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0801_PM
#include <boost/spirit/home/qi/char/detail/range.hpp>
#include <vector>
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
// range_run
//
// An implementation of a sparse bit (boolean) set. The set uses
// a sorted vector of disjoint ranges. This class implements the
// bare minimum essentials from which the full range of set
// operators can be implemented. The set is constructed from
// ranges. Internally, adjacent or overlapping ranges are
// coalesced.
//
// range_runs are very space-economical in situations where there
// are lots of ranges and a few individual disjoint values.
// Searching is O(log n) where n is the number of ranges.
//
// { Low level interface }
///////////////////////////////////////////////////////////////////////////
template <typename Char>
class range_run
{
public:
typedef range<Char> range_type;
typedef std::vector<range_type> storage_type;
void swap(range_run& other);
bool test(Char v) const;
void set(range_type const& range);
void clear(range_type const& range);
void clear();
private:
storage_type run;
};
}}}}
#include <boost/spirit/home/qi/char/detail/range_run_impl.hpp>
#endif

View File

@@ -0,0 +1,178 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM)
#define BOOST_SPIRIT_RANGE_RUN_MAY_16_2006_0807_PM
#include <boost/spirit/home/qi/char/detail/range_functions.hpp>
#include <boost/assert.hpp>
#include <boost/integer_traits.hpp>
#include <algorithm>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <typename Run, typename Iterator, typename Range>
inline bool
try_merge(Run& run, Iterator iter, Range const& range)
{
// if *iter intersects with, or is adjacent to, 'range'...
if (can_merge(*iter, range))
{
typedef typename Range::value_type value_type;
typedef integer_traits<value_type> integer_traits;
// merge range and *iter
merge(*iter, range);
// collapse all subsequent ranges that can merge with *iter
Iterator i;
value_type last =
iter->last == integer_traits::const_max
? iter->last : iter->last+1;
for (i = iter+1; i != run.end() && last >= i->first; ++i)
{
iter->last = i->last;
}
// erase all ranges that were collapsed
run.erase(iter+1, i);
return true;
}
return false;
}
template <typename Char>
inline bool
range_run<Char>::test(Char val) const
{
if (run.empty())
return false;
// search the ranges for one that potentially includes val
typename storage_type::const_iterator iter =
std::upper_bound(
run.begin(), run.end(), val,
range_compare<range_type>()
);
// return true if *(iter-1) includes val
return iter != run.begin() && includes(*(--iter), val);
}
template <typename Char>
inline void
range_run<Char>::swap(range_run& other)
{
run.swap(other.run);
}
template <typename Char>
void
range_run<Char>::set(range_type const& range)
{
BOOST_ASSERT(is_valid(range));
if (run.empty())
{
// the vector is empty, insert 'range'
run.push_back(range);
return;
}
// search the ranges for one that potentially includes 'range'
typename storage_type::iterator iter =
std::upper_bound(
run.begin(), run.end(), range,
range_compare<range_type>()
);
if (iter != run.begin())
{
// if *(iter-1) includes 'range', return early
if (includes(*(iter-1), range))
{
return;
}
// if *(iter-1) can merge with 'range', merge them and return
if (try_merge(run, iter-1, range))
{
return;
}
}
// if *iter can merge with with 'range', merge them
if (iter == run.end() || !try_merge(run, iter, range))
{
// no overlap, insert 'range'
run.insert(iter, range);
}
}
template <typename Char>
void
range_run<Char>::clear(range_type const& range)
{
BOOST_ASSERT(is_valid(range));
if (!run.empty())
{
// search the ranges for one that potentially includes 'range'
typename storage_type::iterator iter =
std::upper_bound(
run.begin(), run.end(), range,
range_compare<range_type>()
);
typename storage_type::iterator left_iter;
// if *(iter-1) includes the 'range.first',
if ((iter != run.begin()) &&
includes(*(left_iter = (iter-1)), range.first))
{
// if the 'range' is in the middle,
if (left_iter->last > range.last)
{
// break it apart into two ranges (punch a hole)
Char save_last = left_iter->last;
left_iter->last = range.first-1;
run.insert(iter, range_type(range.last+1, save_last));
return;
}
else // if it is not in the middle,
{
// truncate it (clip its right)
left_iter->last = range.first-1;
}
}
// position i to the first range that 'range'
// does not intersect with
typename storage_type::iterator i = iter;
while (i != run.end() && includes(range, *i))
{
i++;
}
// if *i includes 'range.last', truncate it (clip its left)
if (i != run.end() && includes(*i, range.last))
{
i->first = range.last+1;
}
// cleanup... erase all subsequent ranges that the
// 'range' includes
run.erase(iter, i);
}
}
template <typename Char>
inline void
range_run<Char>::clear()
{
run.clear();
}
}}}}
#endif

View File

@@ -0,0 +1,396 @@
/*=============================================================================
Copyright (c) 2001-2007 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_GRAMMAR_FEB_02_2007_0925AM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0925AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/qi/char/detail/basic_chset.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/shared_ptr.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct any_char;
template <typename Char>
struct literal_char;
struct lazy_char;
template <typename Char>
struct char_range;
struct lazy_char_range;
template <typename Positive>
struct negated_char_parser;
template <typename Tag>
struct char_class;
struct char_meta_grammar;
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// get the director of an any_char
///////////////////////////////////////////////////////////////////////////
template <typename Tag>
struct extract_any_char_director;
template <>
struct extract_any_char_director<tag::char_>
{
typedef any_char<char> type;
};
template <>
struct extract_any_char_director<tag::wchar>
{
typedef any_char<wchar_t> type;
};
///////////////////////////////////////////////////////////////////////////
// get the director of a character literal type
///////////////////////////////////////////////////////////////////////////
template <typename Tag, typename T>
struct extract_literal_char_director;
template <typename T>
struct extract_literal_char_director<tag::char_, T>
{
typedef literal_char<T> type;
};
template <typename T>
struct extract_literal_char_director<tag::wchar, T>
{
typedef literal_char<wchar_t> type;
};
template <typename T>
struct extract_literal_char_director<tag::lit, T>
{
typedef literal_char<T> type;
};
template <typename T>
struct extract_literal_char_director<tag::wlit, T>
{
typedef literal_char<wchar_t> type;
};
///////////////////////////////////////////////////////////////////////////
// get the director of a character range type
///////////////////////////////////////////////////////////////////////////
template <typename Tag, typename T>
struct extract_char_range_director;
template <typename T>
struct extract_char_range_director<tag::char_, T>
{
typedef char_range<T> type;
};
template <typename T>
struct extract_char_range_director<tag::wchar, T>
{
typedef char_range<wchar_t> type;
};
///////////////////////////////////////////////////////////////////////////
// char parser meta-grammars
///////////////////////////////////////////////////////////////////////////
// literals: 'x', L'x'
struct basic_char_literal_meta_grammar
: proto::or_<
proto::terminal<char>
, proto::terminal<wchar_t>
>
{
};
// literals: 'x', L'x' and single char strings: "x", L"x"
struct single_char_literal_meta_grammar
: proto::or_<
// plain chars:
proto::terminal<char>
, proto::terminal<wchar_t>
// single char null terminates strings:
, proto::terminal<char[2]>
, proto::terminal<char(&)[2]>
, proto::terminal<wchar_t[2]>
, proto::terminal<wchar_t(&)[2]>
>
{
};
// literals: 'x', L'x'
struct char_literal_meta_grammar
: proto::or_<
meta_grammar::terminal_rule<
qi::domain, char, literal_char<char>
>
, meta_grammar::terminal_rule<
qi::domain, wchar_t, literal_char<wchar_t>
>
>
{
};
// literal strings: "hello" (defined in qi/string/meta_grammar.hpp)
struct basic_string_literal_meta_grammar;
// std::string(s) (defined in qi/string/meta_grammar.hpp)
struct basic_std_string_meta_grammar;
template <typename T>
struct extract_char; // (defined in qi/string/metagrammar.hpp)
template <typename Tag, typename T>
struct extract_chset_director;
template <typename T>
struct extract_chset_director<tag::char_, T>
{
typedef typename extract_char<T>::type char_type;
typedef char_set<char_type> type;
};
template <typename T>
struct extract_chset_director<tag::wchar, T>
{
typedef typename extract_char<T>::type char_type;
typedef char_set<char_type> type;
};
template <typename Char, typename Elements>
struct char_set_component
{
typedef qi::domain domain;
typedef char_set<Char> director;
typedef Elements elements_type;
char_set_component(Char const* definition)
: ptr(new detail::basic_chset<Char>())
{
Char ch = *definition++;
while (ch)
{
Char next = *definition++;
if (next == '-')
{
next = *definition++;
if (next == 0)
{
ptr->set(ch);
ptr->set('-');
break;
}
ptr->set(ch, next);
}
else
{
ptr->set(ch);
}
ch = next;
}
}
template <typename CharSetClass> // no-case version
char_set_component(Char const* definition, CharSetClass)
: ptr(new detail::basic_chset<Char>())
{
Char ch = *definition++;
while (ch)
{
Char next = *definition++;
if (next == '-')
{
next = *definition++;
if (next == 0)
{
ptr->set(CharSetClass::tolower(ch));
ptr->set(CharSetClass::tolower('-'));
ptr->set(CharSetClass::toupper(ch));
ptr->set(CharSetClass::toupper('-'));
break;
}
ptr->set(CharSetClass::tolower(ch)
, CharSetClass::tolower(next));
ptr->set(CharSetClass::toupper(ch)
, CharSetClass::toupper(next));
}
else
{
ptr->set(CharSetClass::tolower(ch));
ptr->set(CharSetClass::toupper(ch));
}
ch = next;
}
}
boost::shared_ptr<detail::basic_chset<Char> > ptr;
};
// char_, char_('x'), char_("x"), char_(f), char_('x', 'z'),
// char_(L'x'), char_(L'x', L'z'),
// wchar, wchar('x'), wchar("x"), wchar('x', 'z'),
// wchar(L'x'), wchar(L'x', L'z')
// char_("a-z"), wchar("a-z")
// [w]lit('x'), [w]lit(L'x')
struct char_meta_grammar1
: proto::or_<
// char_, wchar --> any_char
meta_grammar::compose_empty<
proto::if_<
is_char_tag<proto::_child, qi::domain>()
>
, qi::domain
, mpl::identity<extract_any_char_director<mpl::_> >
>
// char_('x'), wchar(L'x'), char_("x"), wchar(L"x")--> literal_char
, meta_grammar::compose_function1_eval<
proto::function<
proto::if_<
is_char_tag<proto::_child, qi::domain>()
>
, single_char_literal_meta_grammar
>
, qi::domain
, mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
>
// lit("x"), wlit(L"x") --> literal_char
, meta_grammar::compose_function1_eval<
proto::function<
proto::if_<
is_lit_tag<proto::_child, qi::domain>()
>
, basic_char_literal_meta_grammar
>
, qi::domain
, mpl::identity<extract_literal_char_director<mpl::_, mpl::_> >
>
// char_("a-z"), char_(L"a-z"), wchar(L"a-z") --> char_set
, meta_grammar::compose_function1_eval<
proto::function<
proto::if_<
is_char_tag<proto::_child, qi::domain>()>
, proto::or_<basic_string_literal_meta_grammar, basic_std_string_meta_grammar>
>
, qi::domain
, mpl::identity<extract_chset_director<mpl::_, mpl::_> >
>
// char_(F()) --> lazy_char
, meta_grammar::function1_rule<
qi::domain
, tag::char_
, lazy_char
>
// char_('x', 'z'), wchar(L'x', L'z') --> char_range
, meta_grammar::compose_function2_eval<
proto::function<
proto::if_<
is_char_tag<proto::_child, qi::domain>()
>
, basic_char_literal_meta_grammar
, basic_char_literal_meta_grammar
>
, qi::domain
, mpl::identity<extract_char_range_director<mpl::_, mpl::_> >
>
// char_(F1(), F2()) --> lazy_char_range
, meta_grammar::function2_rule<
qi::domain
, tag::char_
, lazy_char_range
>
>
{
};
// char_classes: alnum, alpha, cntrl, ... etc.
struct char_class_meta_grammar
: proto::or_<
// alnum, alpha, cntrl, ... etc.
meta_grammar::compose_empty<
proto::terminal<spirit::char_class::key<proto::_, proto::_> >
, qi::domain
, char_class<mpl::_>
>
, meta_grammar::compose_empty<
proto::terminal<spirit::char_class::lower_case_tag<proto::_> >
, qi::domain
, char_class<mpl::_>
>
, meta_grammar::compose_empty<
proto::terminal<spirit::char_class::upper_case_tag<proto::_> >
, qi::domain
, char_class<mpl::_>
>
>
{};
// ~x (where x is a char_parser)
struct negated_char_meta_grammar
: meta_grammar::compose_single<
proto::unary_expr<
proto::tag::complement
, char_meta_grammar
>
, qi::domain
, negated_char_parser<mpl::_>
>
{
};
// main char_meta_grammar
struct char_meta_grammar
: proto::or_<
char_meta_grammar1
, char_class_meta_grammar
, char_literal_meta_grammar
, negated_char_meta_grammar
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, char_meta_grammar> >::type>
: mpl::identity<char_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,17 @@
/*=============================================================================
Copyright (c) 2001-2009 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_DEBUG_NOV_12_2007_0827AM)
#define BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM
#if defined(BOOST_SPIRIT_DEBUG)
#include <boost/spirit/home/qi/debug/simple_debug_macros.hpp>
#include <boost/spirit/home/qi/debug/simple_debug.hpp>
#else
#include <boost/spirit/home/qi/debug/minimal_macros.hpp>
#endif
#endif

View File

@@ -0,0 +1,122 @@
/*=============================================================================
Copyright (c) 2001-2009 Hartmut Kaiser
Copyright (c) 2001-2007 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_NOV_12_2007_0926AM)
#define BOOST_SPIRIT_DEBUG_HANDLER_NOV_12_2007_0926AM
#include <boost/spirit/home/qi/nonterminal/virtual_component_base.hpp>
namespace boost { namespace spirit { namespace qi { namespace debug
{
namespace detail
{
///////////////////////////////////////////////////////////////////////////
// This class is to avoid linker problems and to ensure a real singleton
// 'level' variable
static int& get_trace_level()
{
static int level = 0;
return level;
}
struct trace_level
{
trace_level(int &level)
: level(level)
{
++level;
}
~trace_level()
{
--level;
}
int& level;
};
///////////////////////////////////////////////////////////////////////////
template <
typename Iterator, typename Context, typename Skipper,
typename PreParseF, typename PostParseF
>
struct debug_handler
: virtual_component_base<Iterator, Context, Skipper>
{
typedef
virtual_component_base<Iterator, Context, Skipper>
base_type;
typedef intrusive_ptr<base_type> pointer_type;
typedef typename base_type::skipper_type skipper_type;
debug_handler(pointer_type subject, std::string const& name,
bool trace, PreParseF preF, PostParseF postF)
: subject(subject), name(name), trace(trace),
preF(preF), postF(postF)
{
}
template <typename Skipper_>
bool parse_main(
Iterator& first
, Iterator const& last
, Context& context
, Skipper_ const& skipper)
{
// execute embedded parser if tracing is disabled or if the
// pre-parse hook returns true
bool r = false;
if (!trace || preF(name, subject, get_trace_level(), first, last))
{
{
trace_level level(get_trace_level());
// do the actual parsing
Iterator i = first;
r = subject->parse(i, last, context, skipper);
if (r)
first = i;
}
// the post-parse hook gets executed only if tracing is enabled
if (trace)
postF(r, name, subject, get_trace_level(), first, last);
}
return r;
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, skipper_type const& skipper)
{
return parse_main(first, last, context, skipper);
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, no_skipper)
{
return parse_main(first, last, context, unused);
}
pointer_type subject;
std::string const& name;
bool trace;
PreParseF preF;
PostParseF postF;
};
}
}}}}
#endif

View File

@@ -0,0 +1,129 @@
/*=============================================================================
Copyright (c) 2001-2009 Hartmut Kaiser
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2003 Gustavo Guerra
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_PRINT_NODE_INFO_NOV_12_2007_1045AM)
#define BOOST_SPIRIT_PRINT_NODE_INFO_NOV_12_2007_1045AM
#include <cctype> // iscntrl
#include <iostream>
#include <iomanip>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
namespace boost { namespace spirit { namespace qi { namespace debug
{
namespace detail
{
struct token_printer_aux_for_chars
{
template<typename Char>
static void print(std::ostream& o, Char c)
{
using namespace std; // allow for ADL to find the proper iscntrl
if (c == static_cast<Char>('\a'))
o << "\\a";
else if (c == static_cast<Char>('\b'))
o << "\\b";
else if (c == static_cast<Char>('\f'))
o << "\\f";
else if (c == static_cast<Char>('\n'))
o << "\\n";
else if (c == static_cast<Char>('\r'))
o << "\\r";
else if (c == static_cast<Char>('\t'))
o << "\\t";
else if (c == static_cast<Char>('\v'))
o << "\\v";
else if (iscntrl(c))
o << "\\" << std::oct << static_cast<int>(c);
else
o << static_cast<char>(c);
}
};
// for token types where the comparison with char constants wouldn't work
struct token_printer_aux_for_other_types
{
template<typename Char>
static void print(std::ostream& o, Char c)
{
o << c;
}
};
template <typename Char>
struct token_printer_aux
: mpl::if_<
mpl::and_<
is_convertible<Char, char>,
is_convertible<char, Char>
>,
token_printer_aux_for_chars,
token_printer_aux_for_other_types
>::type
{};
template<typename Char>
inline void token_printer(std::ostream& o, Char c)
{
// allow to customize the token printer routine
#if !defined(BOOST_SPIRIT_DEBUG_TOKEN_PRINTER)
token_printer_aux<Char>::print(o, c);
#else
BOOST_SPIRIT_DEBUG_TOKEN_PRINTER(o, c);
#endif
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator>
inline void
print_node_info(bool hit, int level, bool close, std::string const& name,
Iterator /*first*/, Iterator const& /*last*/)
{
if (!name.empty())
{
for (int i = 0; i < level; ++i)
BOOST_SPIRIT_DEBUG_OUT << " ";
if (close) {
if (hit)
BOOST_SPIRIT_DEBUG_OUT << "/";
else
BOOST_SPIRIT_DEBUG_OUT << "#";
}
// BOOST_SPIRIT_DEBUG_OUT << name << ":\t\"";
// for (int j = 0; j < BOOST_SPIRIT_DEBUG_PRINT_SOME; ++j)
// {
// if (first == last)
// break;
//
// token_printer(BOOST_SPIRIT_DEBUG_OUT, *first);
// ++first;
// }
// BOOST_SPIRIT_DEBUG_OUT << "\"\n";
BOOST_SPIRIT_DEBUG_OUT << name << "\n";
}
}
}
}}}}
#endif

View File

@@ -0,0 +1,37 @@
/*=============================================================================
Copyright (c) 2001-2009 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_MINIMAL_MACROS_NOV_12_2007_1047AM)
#define BOOST_SPIRIT_MINIMAL_MACROS_NOV_12_2007_1047AM
#if !defined(BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM)
#error "You must include boost/spirit/home/qi/debug.hpp, not this file"
#endif
///////////////////////////////////////////////////////////////////////////////
// Minimum debugging tools support
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#endif
///////////////////////////////////////////////////////////////////////////////
// Empty implementations of the debug macros above, if no debug support is
// required
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t)
#endif
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t)
#endif
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
#define BOOST_SPIRIT_DEBUG_NODE(r)
#endif
#endif

View File

@@ -0,0 +1,72 @@
/*=============================================================================
Copyright (c) 2001-2009 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_DEBUG_NOV_12_2007_1155AM)
#define BOOST_SPIRIT_SIMPLE_DEBUG_NOV_12_2007_1155AM
#include <boost/spirit/home/qi/debug/detail/debug_handler.hpp>
#include <boost/spirit/home/qi/debug/detail/print_node_info.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <string>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi { namespace debug
{
///////////////////////////////////////////////////////////////////////////
// Simple pre-parse hook allowing to print the context before a rule is
// parsed.
template <typename Subject, typename Iterator>
inline bool
simple_pre_parse(std::string const& name, Subject subject,
unsigned level, Iterator first, Iterator const& last)
{
detail::print_node_info(false, level, false, name, first, last);
return true;
}
///////////////////////////////////////////////////////////////////////////
// Simple post-parse hook allowing to print the context after a rule is
// parsed.
template <typename Subject, typename Iterator>
inline void
simple_post_parse(bool hit, std::string const& name, Subject subject,
unsigned level, Iterator first, Iterator const& last)
{
detail::print_node_info(hit, level, true, name, first, last);
}
///////////////////////////////////////////////////////////////////////////
template <typename Nonterminal>
inline void
enable_simple_debug_support(Nonterminal& r, bool trace)
{
typedef typename Nonterminal::iterator_type iterator_type;
typedef typename Nonterminal::pointer_type pointer_type;
typedef bool (*pre_parse_functor_type)(std::string const&,
pointer_type, unsigned, iterator_type, iterator_type const&);
typedef void (*post_parse_functor_type)(bool, std::string const&,
pointer_type, unsigned, iterator_type, iterator_type const&);
typedef
detail::debug_handler<
iterator_type,
typename Nonterminal::base_type::context_type,
typename Nonterminal::skipper_type,
pre_parse_functor_type,
post_parse_functor_type>
simple_debug_handler;
pre_parse_functor_type pre =
&simple_pre_parse<pointer_type, iterator_type>;
post_parse_functor_type post =
&simple_post_parse<pointer_type, iterator_type>;
decorate<simple_debug_handler>(r, r.name(), trace, pre, post);
}
}}}}
#endif

View File

@@ -0,0 +1,46 @@
/*=============================================================================
Copyright (c) 2001-2009 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_DEBUG_MACROS_NOV_12_2007_0828AM)
#define BOOST_SPIRIT_SIMPLE_DEBUG_MACROS_NOV_12_2007_0828AM
#if !defined(BOOST_SPIRIT_DEBUG_NOV_12_2007_0827AM)
#error "You must include boost/spirit/home/qi/debug.hpp, not this file"
#endif
///////////////////////////////////////////////////////////////////////////////
// Make sure all required debug helper macros are defined properly
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME)
#define BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(r, n, t) \
r.name(n); \
boost::spirit::qi::debug::enable_simple_debug_support(r, t) \
/**/
#endif
#if !defined(BOOST_SPIRIT_DEBUG_TRACE_NODE)
#define BOOST_SPIRIT_DEBUG_TRACE_NODE(r, t) \
if (r.name().empty()) r.name(#r); \
boost::spirit::qi::debug::enable_simple_debug_support(r, t) \
/**/
#endif
#if !defined(BOOST_SPIRIT_DEBUG_NODE)
#define BOOST_SPIRIT_DEBUG_NODE(r) \
BOOST_SPIRIT_DEBUG_TRACE_NODE(r, true) \
/**/
#endif
// number of input tokens to print while debugging
#if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
#define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
#endif
// The stream to use for debug output
#if !defined(BOOST_SPIRIT_DEBUG_OUT)
#define BOOST_SPIRIT_DEBUG_OUT std::cerr
#endif
#endif

View File

@@ -0,0 +1,81 @@
/*=============================================================================
Copyright (c) 2001-2009 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_APR_23_2007_1046AM)
#define SPIRIT_ALTERNATIVE_FUNCTION_APR_23_2007_1046AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <boost/variant.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
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 operator()(Component const& component)
{
// return true if the parser succeeds
typedef typename Component::director director;
typename
traits::attribute_of<
qi::domain, Component, Context, Iterator>::type
val;
if (director::parse(component, first, last, context, skipper, val))
{
attr = val;
return true;
}
return false;
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
Attribute& attr;
};
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)
{
// return true if the parser succeeds
typedef typename Component::director director;
return director::parse(component, first, last, context, skipper,
unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
};
}}}}
#endif

View File

@@ -0,0 +1,126 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2001-2009 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
#include <boost/spirit/home/qi/detail/construct_fwd.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/ref.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
namespace construct_
{
///////////////////////////////////////////////////////////////////////
// This is used to allow to overload of the attribute creation for
// arbitrary types
///////////////////////////////////////////////////////////////////////
template <typename Attribute, typename Iterator>
inline void
construct(Attribute& attr, Iterator const& first, Iterator const& last)
{
attr = Attribute(first, last);
}
template <typename Attribute, typename T>
inline void
construct(Attribute& attr, T const& val)
{
attr = val;
}
template <typename Attribute, typename T>
inline void
construct(Attribute& attr, T& val)
{
attr = val;
}
template <typename Attribute, typename T>
inline void
construct(reference_wrapper<Attribute> attr, T const& val)
{
attr = val;
}
template <typename Attribute, typename T>
inline void
construct(reference_wrapper<Attribute> attr, T& val)
{
attr = val;
}
}
///////////////////////////////////////////////////////////////////////////
// This file contains assignment utilities. The utilities provided also
// accept spirit's unused_type; all no-ops. Compiler optimization will
// easily strip these away.
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Attribute>
inline void
assign_to(Iterator const& first, Iterator const& last, Attribute& attr)
{
using namespace construct_;
construct(attr, first, last);
}
template <typename Iterator>
inline void
assign_to(Iterator const& /*first*/, Iterator const& /*last*/, unused_type)
{
}
template <typename T, typename Attribute>
inline void
assign_to(T const& val, Attribute& attr)
{
using namespace construct_;
construct(attr, val);
}
template <typename T, typename Attribute>
inline void
assign_to(T& val, Attribute& attr)
{
using namespace construct_;
construct(attr, val);
}
template <typename T, typename Attribute>
inline void
assign_to(T const& val, reference_wrapper<Attribute> attr)
{
using namespace construct_;
construct(attr, val);
}
template <typename T, typename Attribute>
inline void
assign_to(T& val, reference_wrapper<Attribute> attr)
{
using namespace construct_;
construct(attr, val);
}
template <typename T>
inline void
assign_to(T const& /*val*/, unused_type)
{
}
template <typename T>
inline void
assign_to(T& /*val*/, unused_type)
{
}
}}}}
#endif

View File

@@ -0,0 +1,144 @@
// Copyright (c) 2001-2009 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_CONSTRUCT_MAR_24_2007_0629PM)
#define BOOST_SPIRIT_CONSTRUCT_MAR_24_2007_0629PM
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/qi/numeric.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
namespace construct_
{
///////////////////////////////////////////////////////////////////////
// We provide overloads for the construct customization point for all
// built in types
///////////////////////////////////////////////////////////////////////
template <typename Iterator>
inline void
construct(char& attr, Iterator const& first, Iterator const& last)
{
attr = *first;
}
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
// wchar_t is intrinsic
template <typename Iterator>
inline void
construct(wchar_t& attr, Iterator const& first, Iterator const& last)
{
attr = *first;
}
template <typename Iterator>
inline void
construct(unsigned short& attr, Iterator const& first,
Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, ushort, attr);
}
#else
// is wchar_t is not an intrinsic type, treat wchar_t only
template <typename Iterator>
inline void
construct(wchar_t& attr, Iterator const& first, Iterator const& last)
{
attr = *first;
}
#endif
template <typename Iterator>
inline void
construct(short& attr, Iterator const& first, Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, short_, attr);
}
template <typename Iterator>
inline void
construct(int& attr, Iterator const& first, Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, int_, attr);
}
template <typename Iterator>
inline void
construct(unsigned int& attr, Iterator const& first,
Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, uint_, attr);
}
template <typename Iterator>
inline void
construct(long& attr, Iterator const& first, Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, long_, attr);
}
template <typename Iterator>
inline void
construct(unsigned long& attr, Iterator const& first,
Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, ulong, attr);
}
#ifdef BOOST_HAS_LONG_LONG
template <typename Iterator>
inline void
construct(boost::long_long_type& attr, Iterator const& first,
Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, long_long, attr);
}
template <typename Iterator>
inline void
construct(boost::ulong_long_type& attr, Iterator const& first,
Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, ulong_long, attr);
}
#endif
template <typename Iterator>
inline void
construct(float& attr, Iterator const& first, Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, float_, attr);
}
template <typename Iterator>
inline void
construct(double& attr, Iterator const& first, Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, double_, attr);
}
template <typename Iterator>
inline void
construct(long double& attr, Iterator const& first,
Iterator const& last)
{
Iterator first_ = first;
parse(first_, last, long_double, attr);
}
}
}}}}
#endif

View File

@@ -0,0 +1,91 @@
// Copyright (c) 2001-2008 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_CONSTRUCT_FWD_MAY_29_2008_0318PM)
#define BOOST_SPIRIT_CONSTRUCT_FWD_MAR_29_2008_0318PM
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
namespace boost { namespace spirit { namespace qi { namespace detail
{
namespace construct_
{
///////////////////////////////////////////////////////////////////////
// Forward declarations of overloads for the construct customization
// point for all built in types
///////////////////////////////////////////////////////////////////////
template <typename Iterator>
inline void
construct(char& attr, Iterator const& first, Iterator const& last);
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
// wchar_t is intrinsic
template <typename Iterator>
inline void
construct(wchar_t& attr, Iterator const& first, Iterator const& last);
template <typename Iterator>
inline void
construct(unsigned short& attr, Iterator const& first, Iterator const& last);
#else
// is wchar_t is not an intrinsic type, treat wchar_t only
template <typename Iterator>
inline void
construct(wchar_t& attr, Iterator const& first, Iterator const& last);
#endif
template <typename Iterator>
inline void
construct(short& attr, Iterator const& first, Iterator const& last);
template <typename Iterator>
inline void
construct(int& attr, Iterator const& first, Iterator const& last);
template <typename Iterator>
inline void
construct(unsigned int& attr, Iterator const& first,
Iterator const& last);
template <typename Iterator>
inline void
construct(long& attr, Iterator const& first, Iterator const& last);
template <typename Iterator>
inline void
construct(unsigned long& attr, Iterator const& first,
Iterator const& last);
#ifdef BOOST_HAS_LONG_LONG
template <typename Iterator>
inline void
construct(boost::long_long_type& attr, Iterator const& first,
Iterator const& last);
template <typename Iterator>
inline void
construct(boost::ulong_long_type& attr, Iterator const& first,
Iterator const& last);
#endif
template <typename Iterator>
inline void
construct(float& attr, Iterator const& first, Iterator const& last);
template <typename Iterator>
inline void
construct(double& attr, Iterator const& first, Iterator const& last);
template <typename Iterator>
inline void
construct(long double& attr, Iterator const& first,
Iterator const& last);
}
}}}}
#endif

View File

@@ -0,0 +1,80 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <
typename Iterator, typename Context
, typename Skipper, typename Exception>
struct expect_function
{
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)
{
// 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
typedef typename Component::director director;
if (!director::parse(component, first, last, context, skipper, attr))
{
if (is_first)
{
is_first = false;
return true;
}
Exception x = {first, last, director::what(component, context) };
throw x;
}
is_first = false;
return false;
}
template <typename Component>
bool operator()(Component const& component)
{
// 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
typedef typename Component::director director;
if (!director::parse(component, first, last, context, skipper, unused))
{
if (is_first)
{
is_first = false;
return true;
}
Exception x = {first, last, director::what(component, context) };
throw x;
}
is_first = false;
return false;
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
bool is_first;
};
}}}}
#endif

View File

@@ -0,0 +1,50 @@
/*=============================================================================
Copyright (c) 2001-2007 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_APR_22_2006_0159PM)
#define SPIRIT_FAIL_FUNCTION_APR_22_2006_0159PM
#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
{
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)
{
// return true if the parser fails
typedef typename Component::director director;
return !director::parse(component, first, last, context, skipper, attr);
}
template <typename Component>
bool operator()(Component const& component)
{
// return true if the parser fails
typedef typename Component::director director;
return !director::parse(component, first, last, context, skipper, unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
};
}}}}
#endif

View File

@@ -0,0 +1,65 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_05_2007_1138AM)
#define SPIRIT_PASS_FUNCTION_FEB_05_2007_1138AM
#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
typedef typename Component::director director;
return director::parse(component, 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
typedef typename Component::director director;
Attribute val;
if (director::parse(component, 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
typedef typename Component::director director;
return director::parse(component, first, last, context, skipper, unused);
}
Iterator& first;
Iterator const& last;
Context& context;
Skipper const& skipper;
};
}}}}
#endif

View File

@@ -0,0 +1,86 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#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
typedef typename Component::director director;
if (!*taken
&& director::parse(component, 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
typedef typename Component::director director;
Attribute val;
if (!*taken
&& director::parse(component, 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
typedef typename Component::director director;
if (!*taken
&& director::parse(component, 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;
};
}}}}
#endif

View File

@@ -0,0 +1,81 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#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;
for (; !!(ch = *str); ++str, ++i)
if (i == last || (ch != *i))
return false;
detail::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;
detail::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;
detail::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;
detail::assign_to(first, i, attr);
first = i;
return true;
}
}}}}
#endif

View File

@@ -0,0 +1,15 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_05_2007_0313PM)
#define BOOST_SPIRIT_DIRECTIVE_FEB_05_2007_0313PM
#include <boost/spirit/home/qi/directive/lexeme.hpp>
#include <boost/spirit/home/qi/directive/omit.hpp>
#include <boost/spirit/home/qi/directive/raw.hpp>
#include <boost/spirit/home/qi/directive/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,68 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
namespace boost { namespace spirit { namespace qi
{
struct lexeme_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
traits::attribute_of<
qi::domain, subject_type, Context, Iterator>::type
type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::subject<Component>::type::director
director;
qi::skip(first, last, skipper);
return director::parse(
spirit::subject(component), first, last, context, unused, attr);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "lexeme[";
typedef typename
result_of::subject<Component>::type::director
director;
result += director::what(subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2001-2007 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_GRAMMAR_FEB_05_2007_0320PM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0320PM
#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/iso8859_1.hpp>
#include <boost/spirit/home/support/ascii.hpp>
#include <boost/spirit/home/support/standard.hpp>
#include <boost/spirit/home/support/standard_wide.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
struct lexeme_director;
struct omit_director;
struct raw_director;
struct main_meta_grammar;
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// directive meta-grammars
///////////////////////////////////////////////////////////////////////////
struct directive_meta_grammar
: proto::or_<
meta_grammar::deep_directive_meta_grammar<
spirit::char_class::no_case_tag<proto::_>
, main_meta_grammar
>
, meta_grammar::binary_rule_rhs<
qi::domain, proto::tag::subscript, lexeme_director
, proto::terminal<tag::lexeme>, main_meta_grammar
>
, meta_grammar::binary_rule_rhs<
qi::domain, proto::tag::subscript, omit_director
, proto::terminal<tag::omit>, main_meta_grammar
>
, meta_grammar::binary_rule_rhs<
qi::domain, proto::tag::subscript, raw_director
, proto::terminal<tag::raw>, main_meta_grammar
>
>
{};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, directive_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, directive_meta_grammar> >::type>
: mpl::identity<directive_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/skip.hpp>
namespace boost { namespace spirit { namespace qi
{
struct omit_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute&)
{
typedef typename
result_of::subject<Component>::type::director
director;
qi::skip(first, last, skipper);
return director::parse(
spirit::subject(component), first, last, context, skipper, unused);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "omit[";
typedef typename
result_of::subject<Component>::type::director
director;
result += director::what(subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,66 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/range/iterator_range.hpp>
namespace boost { namespace spirit { namespace qi
{
struct raw_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef iterator_range<Iterator> type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::subject<Component>::type::director
director;
qi::skip(first, last, skipper);
Iterator i = first;
if (director::parse(
spirit::subject(component), i, last, context, skipper, unused))
{
attr = Attribute(first, i);
first = i;
return true;
}
return false;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "raw[";
typedef typename
result_of::subject<Component>::type::director
director;
result += director::what(subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,15 @@
/*=============================================================================
Copyright (c) 2001-2007 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_JAN_29_2007_0954AM)
#define BOOST_SPIRIT_DOMAIN_JAN_29_2007_0954AM
namespace boost { namespace spirit { namespace qi
{
struct domain {};
}}}
#endif

View File

@@ -0,0 +1,47 @@
/*=============================================================================
Copyright (c) 2001-2007 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_GRAMMAR_JAN_29_2007_0937AM)
#define BOOST_SPIRIT_META_GRAMMAR_JAN_29_2007_0937AM
#include <boost/spirit/home/support/meta_grammar/grammar.hpp>
#include <boost/spirit/home/support/meta_grammar/basic_transforms.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/placeholders.hpp>
namespace boost { namespace spirit { namespace qi
{
// Check if Expr is a valid RD expression
template <typename Expr, typename Enable = void>
struct is_valid_expr : mpl::false_ {};
// Return a suitable transform for the given Expr
template <typename Expr, typename Enable = void>
struct expr_transform;
struct main_meta_grammar
: meta_grammar::if_transform<
is_valid_expr<proto::_>()
, expr_transform<proto::_>
>
{
};
}}}
namespace boost { namespace spirit { namespace meta_grammar
{
///////////////////////////////////////////////////////////////////////////
// The spirit qi domain meta-grammar
///////////////////////////////////////////////////////////////////////////
template <>
struct grammar<qi::domain>
{
typedef qi::main_meta_grammar type;
};
}}}
#endif

View File

@@ -0,0 +1,14 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_12_2007_1018AM)
#define BOOST_SPIRIT_NONTERMINAL_FEB_12_2007_1018AM
#include <boost/spirit/home/qi/nonterminal/meta_grammar.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/grammar.hpp>
#endif

View File

@@ -0,0 +1,100 @@
/*=============================================================================
Copyright (c) 2001-2007 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_APR_29_2007_1042PM)
#define BOOST_SPIRIT_ERROR_HANDLER_APR_29_2007_1042PM
#include <boost/spirit/home/qi/nonterminal/virtual_component_base.hpp>
#include <boost/spirit/home/qi/nonterminal/error_handler_result.hpp>
#include <boost/spirit/home/qi/operator/expect.hpp>
#include <boost/fusion/include/vector.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <
typename Iterator, typename Context
, typename Skipper, typename F, error_handler_result action
>
struct error_handler : virtual_component_base<Iterator, Context, Skipper>
{
typedef virtual_component_base<Iterator, Context, Skipper> base_type;
typedef intrusive_ptr<base_type> pointer_type;
typedef typename base_type::skipper_type skipper_type;
error_handler(pointer_type subject, F f)
: subject(subject)
, f(f)
{
}
template <typename Skipper_>
bool parse_main(
Iterator& first
, Iterator const& last
, Context& context
, Skipper_ const& skipper)
{
while (true)
{
try
{
Iterator i = first;
bool r = subject->parse(i, last, context, skipper);
if (r)
first = i;
return r;
}
catch (expectation_failure<Iterator> const& x)
{
typedef
fusion::vector<
Iterator&
, Iterator const&
, Iterator const&
, std::string>
params;
error_handler_result r = action;
params args(first, last, x.first, x.what);
f(args, context, r);
switch (r)
{
case fail: return false;
case retry: continue;
case accept: return true;
case rethrow: throw x;
}
}
}
return false;
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, skipper_type const& skipper)
{
return parse_main(first, last, context, skipper);
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, no_skipper)
{
return parse_main(first, last, context, unused);
}
pointer_type subject;
F f;
};
}}}}
#endif

View File

@@ -0,0 +1,133 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_12_2007_0440PM)
#define BOOST_SPIRIT_RULE_FEB_12_2007_0440PM
#include <boost/spirit/home/qi/nonterminal/virtual_component_base.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
template <
typename Iterator, typename Component
, typename Context, typename Skipper
, typename Auto
>
struct virtual_component : virtual_component_base<Iterator, Context, Skipper>
{
typedef virtual_component_base<Iterator, Context, Skipper> base_type;
typedef typename base_type::skipper_type skipper_type;
typedef typename base_type::take_no_skipper take_no_skipper;
virtual_component(Component const& component)
: component(component)
{
}
virtual ~virtual_component()
{
}
template <typename T>
static void clear(T& attr)
{
attr = T();
}
template <typename Skipper_>
bool parse_main(
Iterator& first
, Iterator const& last
, Context& context
, Skipper_ const& skipper
, mpl::false_)
{
// If Auto is false, the component's attribute is unused.
typedef typename Component::director director;
return director::parse(
component, first, last, context, skipper, unused);
}
template <typename Skipper_>
bool parse_main(
Iterator& first
, Iterator const& last
, Context& context
, Skipper_ const& skipper
, mpl::true_)
{
// If Auto is true, we synthesize the rule's attribute and pass
// it on to the component. On successful parse, this attribute
// is swapped back to the the rule's attribute.
typename
remove_reference<
typename fusion::result_of::value_at_c<
typename fusion::result_of::value_at_c<Context, 0>::type
, 0
>::type
>::type
attribute; // default constructed
typedef typename Component::director director;
if (director::parse(
component, first, last, context, skipper, attribute))
{
// $$$ need to optimize this for fusion sequences $$$
std::swap(fusion::at_c<0>(fusion::at_c<0>(context)), attribute);
return true;
}
return false;
}
bool parse_main(
Iterator& /*first*/
, Iterator const& /*last*/
, Context&
, take_no_skipper
, mpl::false_)
{
BOOST_ASSERT(false); // this should never be called
return false;
}
bool parse_main(
Iterator& /*first*/
, Iterator const& /*last*/
, Context& /*context*/
, take_no_skipper
, mpl::true_)
{
BOOST_ASSERT(false); // this should never be called
return false;
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, skipper_type const& skipper)
{
return parse_main(first, last, context, skipper, Auto());
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, no_skipper)
{
return parse_main(first, last, context, unused, Auto());
}
Component component;
};
}}}}
#endif

View File

@@ -0,0 +1,21 @@
/*=============================================================================
Copyright (c) 2001-2007 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_RESULT_APR_29_2007_1042PM)
#define BOOST_SPIRIT_ERROR_HANDLER_RESULT_APR_29_2007_1042PM
namespace boost { namespace spirit { namespace qi
{
enum error_handler_result
{
fail
, retry
, accept
, rethrow
};
}}}
#endif

View File

@@ -0,0 +1,79 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_19_2007_0236PM)
#define BOOST_SPIRIT_GRAMMAR_FEB_19_2007_0236PM
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/nonterminal/nonterminal.hpp>
#include <boost/spirit/home/qi/nonterminal/grammar_fwd.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/nonterminal_director.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/noncopyable.hpp>
#include <boost/type_traits/is_convertible.hpp>
namespace boost { namespace spirit { namespace qi
{
template <typename Iterator, typename T0 , typename T1 , typename T2>
struct grammar
: nonterminal<
grammar<Iterator, T0, T1, T2>
, typename qi::rule<Iterator, T0, T1, T2>::sig_type
, typename qi::rule<Iterator, T0, T1, T2>::locals_type
>, noncopyable
{
typedef Iterator iterator_type;
typedef qi::rule<Iterator, T0, T1, T2> 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 grammar<Iterator, T0, T1, T2> base_type;
grammar(start_type const& start, std::string const& name_ = std::string())
: start(start), name_(name_) {}
std::string name() const
{
return name_;
}
void name(std::string const& name__)
{
name_ = name__;
}
start_type const& start;
std::string name_;
private:
template <typename Iterator_, typename Context, typename Skipper>
bool parse(
Iterator_& first, Iterator_ const& last
, Context& context, Skipper const& skipper) const
{
return start.parse(first, last, context, skipper);
}
std::string what() const
{
if (name().empty())
{
return start.what();
}
else
{
return name();
}
}
friend struct nonterminal_director;
};
}}}
#endif

View File

@@ -0,0 +1,24 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FWD_JULY_11_2008_1034AM)
#define BOOST_SPIRIT_GRAMMAR_FWD_JULY_11_2008_1034AM
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi
{
// forward declaration
template <
typename Iterator
, typename T0 = unused_type
, typename T1 = unused_type
, typename T2 = unused_type
>
struct grammar;
}}}
#endif

View File

@@ -0,0 +1,61 @@
/*=============================================================================
Copyright (c) 2001-2007 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_GRAMMAR_FEB_12_2007_0534PM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_12_2007_0534PM
#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/nonterminal/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/grammar.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// nonterminal meta-grammar
///////////////////////////////////////////////////////////////////////////
struct nonterminal_meta_grammar
: meta_grammar::terminal_rule<
qi::domain
, nonterminal_holder<proto::_, proto::_>
, nonterminal_director
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, nonterminal_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, nonterminal_meta_grammar> >::type>
: mpl::identity<nonterminal_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,142 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_19_2007_0236PM)
#define BOOST_SPIRIT_NONTERMINAL_FEB_19_2007_0236PM
#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
#include <boost/spirit/home/support/nonterminal/locals.hpp>
#include <boost/spirit/home/support/argument.hpp>
#include <boost/proto/core.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/is_function.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/joint_view.hpp>
#include <boost/fusion/include/single_view.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/filter_view.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/enum_params_with_a_default.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace qi
{
template <typename Derived, typename Sig, typename Locals>
struct nonterminal
: proto::extends<
typename make_nonterminal_holder<
Derived const*, Derived
>::type
, Derived
>
{
typedef Sig sig_type;
typedef typename function_types::result_type<sig_type>::type attr_type_;
// This is the nonterminal return type
typedef typename
mpl::if_<
is_same<attr_type_, void>
, unused_type
, attr_type_
>::type
attr_type;
typedef typename add_reference<attr_type>::type attr_reference_type;
// param_types is a sequence of types passed as parameters to the nonterminal
typedef typename function_types::parameter_types<sig_type>::type param_types;
// locals_type is a sequence of types to be used as local variables
typedef typename fusion::result_of::as_vector<Locals>::type locals_type;
// The overall context_type consist of a tuple with:
// 1) a tuple of the return value and parameters
// 2) the locals
typedef fusion::vector<
typename fusion::result_of::as_vector<
fusion::joint_view<
fusion::single_view<attr_reference_type>
, param_types
>
>::type
, typename fusion::result_of::as_vector<locals_type>::type
>
context_type;
typedef nonterminal<Derived, Sig, Locals> self_type;
typedef nonterminal_holder<Derived const*, Derived> nonterminal_holder_;
typedef typename proto::terminal<nonterminal_holder_>::type nonterminal_tag;
typedef proto::extends<nonterminal_tag, Derived> base_type;
explicit nonterminal()
: base_type(make_tag())
{
}
// bring in the operator() overloads
#include <boost/spirit/home/support/nonterminal/detail/nonterminal_fcall.hpp>
private:
nonterminal_tag make_tag() const
{
nonterminal_tag xpr = {{static_cast<Derived const*>(this)}};
return xpr;
}
};
template <typename Derived, typename T0, typename T1, typename T2>
struct make_nonterminal
{
typedef mpl::vector<T0, T1, T2> types;
typedef function_types::is_function<mpl::_> is_function;
typedef spirit::detail::is_locals<mpl::_> is_locals;
typedef spirit::traits::is_component<qi::domain, mpl::_> is_skipper;
typedef typename mpl::find_if<types, is_function>::type sig_;
typedef typename mpl::find_if<types, is_locals>::type locals_;
typedef typename mpl::find_if<types, is_skipper>::type skipper_;
typedef typename
mpl::eval_if<
is_same<sig_, typename mpl::end<types>::type>
, mpl::identity<unused_type()>
, mpl::deref<sig_>
>::type
sig_type;
typedef typename
mpl::eval_if<
is_same<locals_, typename mpl::end<types>::type>
, mpl::identity<locals<> >
, mpl::deref<locals_>
>::type
locals_type;
typedef typename
mpl::eval_if<
is_same<skipper_, typename mpl::end<types>::type>
, mpl::identity<unused_type>
, mpl::deref<skipper_>
>::type
skipper_type;
typedef nonterminal<Derived, sig_type, locals_type> type;
};
}}}
#endif

View File

@@ -0,0 +1,170 @@
/*=============================================================================
Copyright (c) 2001-2007 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_DIRECTOR_FEB_19_2007_0259PM)
#define BOOST_SPIRIT_NONTERMINAL_DIRECTOR_FEB_19_2007_0259PM
#include <boost/spirit/home/support/nonterminal/nonterminal.hpp>
#include <boost/spirit/home/support/nonterminal/detail/expand_arg.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/detail/values.hpp>
#include <boost/fusion/include/transform.hpp>
#include <boost/fusion/include/join.hpp>
#include <boost/fusion/include/single_view.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/mpl/at.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
namespace boost { namespace spirit { namespace qi
{
struct nonterminal_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename result_of::subject<Component>::type nonterminal_holder;
typedef typename nonterminal_holder::nonterminal_type::attr_type type;
};
template <
typename NonterminalContext, typename Nonterminal
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse_nonterminal(
nonterminal_object<Nonterminal> const& x
, Iterator& first, Iterator const& last
, Context& /*caller_context*/, Skipper const& skipper
, Attribute& attr)
{
// the nonterminal_holder holds an actual nonterminal_object
typedef typename Nonterminal::locals_type locals_type;
fusion::single_view<Attribute&> front(attr);
NonterminalContext context(front, locals_type());
return x.obj.parse(first, last, context, skipper);
}
template <
typename NonterminalContext, typename Nonterminal
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse_nonterminal(
Nonterminal const* ptr
, Iterator& first, Iterator const& last
, Context& /*caller_context*/, Skipper const& skipper
, Attribute& attr)
{
// the nonterminal_holder holds a pointer to a nonterminal
typedef typename Nonterminal::locals_type locals_type;
fusion::single_view<Attribute&> front(attr);
NonterminalContext context(front, locals_type());
return ptr->parse(first, last, context, skipper);
}
template <
typename NonterminalContext, typename Nonterminal, typename FSequence
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse_nonterminal(
parameterized_nonterminal<Nonterminal, FSequence> const& x
, Iterator& first, Iterator const& last
, Context& caller_context, Skipper const& skipper
, Attribute& attr)
{
// the nonterminal_holder holds a parameterized_nonterminal
typedef typename Nonterminal::locals_type locals_type;
fusion::single_view<Attribute&> front(attr);
NonterminalContext context(
fusion::join(
front
, fusion::transform(
x.fseq
, spirit::detail::expand_arg<Context>(caller_context)
)
)
, locals_type()
);
return x.ptr->parse(first, last, context, skipper);
}
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr_)
{
// main entry point
typedef typename
result_of::subject<Component>::type
nonterminal_holder;
// The overall context_type consist of a tuple with:
// 1) a tuple of the return value and parameters
// 2) the locals
// if no signature is specified the first tuple contains
// an unused_type element at position zero only.
typedef typename
nonterminal_holder::nonterminal_type::context_type
context_type;
// attr_type is the return type as specified by the associated
// nonterminal signature, if no signature is specified this is
// the unused_type
typedef typename
nonterminal_holder::nonterminal_type::attr_type
attr_type;
// create an attribute if one is not supplied
typename mpl::if_<
is_same<typename remove_const<Attribute>::type, unused_type>
, attr_type
, Attribute&>::type
attr = spirit::detail::make_value<attr_type>::call(attr_);
return parse_nonterminal<context_type>(
subject(component).held
, first, last, context, skipper, attr
);
}
template <typename Nonterminal>
static std::string what_nonterminal(nonterminal_object<Nonterminal> const& x)
{
// the nonterminal_holder holds an actual nonterminal_object
return x.obj.what();
}
template <typename Nonterminal>
static std::string what_nonterminal(Nonterminal const* ptr)
{
// the nonterminal_holder holds a pointer to a nonterminal
return ptr->what();
}
template <typename Nonterminal, typename FSequence>
static std::string what_nonterminal(
parameterized_nonterminal<Nonterminal, FSequence> const& x)
{
// the nonterminal_holder holds a parameterized_nonterminal
return x.ptr->what();
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return what_nonterminal(subject(component).held);
}
};
}}}
#endif

View File

@@ -0,0 +1,369 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_12_2007_1020AM)
#define BOOST_SPIRIT_RULE_FEB_12_2007_1020AM
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/nonterminal/nonterminal.hpp>
#include <boost/spirit/home/qi/nonterminal/grammar_fwd.hpp>
#include <boost/spirit/home/qi/nonterminal/detail/rule.hpp>
#include <boost/spirit/home/qi/nonterminal/detail/error_handler.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif
namespace boost { namespace spirit { namespace qi
{
namespace detail { struct rule_decorator; }
template <
typename Iterator
, typename T0 = unused_type
, typename T1 = unused_type
, typename T2 = unused_type
>
struct rule
: make_nonterminal<rule<Iterator, T0, T1, T2>, T0, T1, T2>::type
{
typedef
make_nonterminal<rule<Iterator, T0, T1, T2>, T0, T1, T2>
make_nonterminal_;
typedef typename make_nonterminal_::skipper_type skipper_type;
typedef typename make_nonterminal_::type base_type;
typedef Iterator iterator_type;
typedef rule<Iterator, T0, T1, T2> self_type;
typedef
virtual_component_base<
Iterator
, typename base_type::context_type
, skipper_type
>
virtual_component;
typedef intrusive_ptr<virtual_component> pointer_type;
rule(std::string const& name_ = std::string())
: name_(name_) {}
~rule() {}
rule(rule const& rhs)
: ptr(rhs.ptr)
, name_(rhs.name_)
{
}
rule& operator=(rule const& rhs)
{
ptr = rhs.ptr;
name_ = rhs.name_;
return *this;
}
template <typename Expr>
rule& operator=(Expr const& xpr)
{
typedef spirit::traits::is_component<qi::domain, Expr> is_component;
// report invalid expression error as early as possible
// BOOST_MPL_ASSERT_MSG(
// is_component::value,
// xpr_is_not_convertible_to_a_parser, ());
// temp workaround for mpl problem
BOOST_STATIC_ASSERT(is_component::value);
define(xpr, mpl::false_());
return *this;
}
template <typename Expr>
friend rule& operator%=(rule& r, Expr const& xpr)
{
typedef spirit::traits::is_component<qi::domain, Expr> is_component;
// report invalid expression error as early as possible
//~ BOOST_MPL_ASSERT_MSG(
//~ is_component::value,
//~ xpr_is_not_convertible_to_a_parser, ());
// temp workaround for mpl problem
BOOST_STATIC_ASSERT(is_component::value);
r.define(xpr, mpl::true_());
return r;
}
self_type alias() const
{
self_type result;
result.define(*this, mpl::false_());
return result;
}
typename
make_nonterminal_holder<
nonterminal_object<self_type>
, self_type
>::type
copy() const
{
typename
make_nonterminal_holder<
nonterminal_object<self_type>
, self_type
>::type
result = {{*this}};
return result;
}
std::string const& name() const
{
return name_;
}
void name(std::string const& str)
{
name_ = str;
}
private:
template <typename Iterator_, typename T0_, typename T1_, typename T2_>
friend struct grammar;
friend struct detail::rule_decorator;
template <typename Expr, typename Auto>
void define(Expr const& xpr, Auto)
{
typedef typename
result_of::as_component<qi::domain, Expr>::type
component;
typedef
detail::virtual_component<
Iterator
, component
, typename base_type::context_type
, skipper_type
, Auto
>
virtual_component;
ptr = new virtual_component(spirit::as_component(qi::domain(), xpr));
}
template <typename Iterator_, typename Context, typename Skipper>
bool parse(
Iterator_& first, Iterator_ const& last
, Context& context, Skipper const& skipper) const
{
// If the following line produces a compilation error stating the
// 4th parameter is not convertible to the expected type, then you
// are probably trying to use this rule instance with a skipper
// which is not compatible with the skipper type used while
// defining the type of this rule instance.
return ptr->parse(first, last, context, skipper);
}
std::string what() const
{
if (name_.empty())
{
if (ptr)
{
return "unnamed-rule";
}
else
{
return "empty-rule";
}
}
else
{
return name_;
}
}
friend struct nonterminal_director;
pointer_type ptr;
std::string name_;
};
// Decoration support: create a new virtual component and link it as
// first element in the chain of virtual components associated with this
// rule. Returns the previous topmost virtual component in the chain.
// We provide support from 1 to 5 arguments.
namespace detail
{
struct rule_decorator
{
template <typename Decorator, typename Rule, typename A1>
typename Rule::pointer_type
static call(Rule& r, A1 const& a1)
{
typename Rule::pointer_type old (r.ptr);
r.ptr.reset(new Decorator(r.ptr, a1));
return old;
}
template <typename Decorator, typename Rule, typename A1, typename A2>
typename Rule::pointer_type
static call(Rule& r, A1 const& a1, A2 const& a2)
{
typename Rule::pointer_type old (r.ptr);
r.ptr.reset(new Decorator(r.ptr, a1, a2));
return old;
}
template <typename Decorator, typename Rule
, typename A1, typename A2, typename A3
>
typename Rule::pointer_type
static call(Rule& r
, A1 const& a1, A2 const& a2, A3 const& a3)
{
typename Rule::pointer_type old (r.ptr);
r.ptr.reset(new Decorator(r.ptr, a1, a2, a3));
return old;
}
template <typename Decorator, typename Rule
, typename A1, typename A2, typename A3, typename A4
>
typename Rule::pointer_type
static call(Rule& r
, A1 const& a1, A2 const& a2
, A3 const& a3, A4 const& a4)
{
typename Rule::pointer_type old (r.ptr);
r.ptr.reset(new Decorator(r.ptr, a1, a2, a3, a4));
return old;
}
template <typename Decorator, typename Rule
, typename A1, typename A2, typename A3, typename A4, typename A5
>
typename Rule::pointer_type
static call(Rule& r
, A1 const& a1, A2 const& a2
, A3 const& a3, A4 const& a4, A5 const& a5)
{
typename Rule::pointer_type old (r.ptr);
r.ptr.reset(new Decorator(r.ptr, a1, a2, a3, a4, a5));
return old;
}
};
}
template <typename Decorator
, typename Iterator, typename T0, typename T1, typename T2
, typename A1>
typename rule<Iterator, T0, T1, T2>::pointer_type
decorate(rule<Iterator, T0, T1, T2>& r
, A1 const& a1)
{
return detail::rule_decorator::
template call<Decorator>(r, a1);
}
template <typename Decorator
, typename Iterator, typename T0, typename T1, typename T2
, typename A1, typename A2
>
typename rule<Iterator, T0, T1, T2>::pointer_type
decorate(rule<Iterator, T0, T1, T2>& r
, A1 const& a1, A2 const& a2)
{
return detail::rule_decorator::
template call<Decorator>(r, a1, a2);
}
template <typename Decorator
, typename Iterator, typename T0, typename T1, typename T2
, typename A1, typename A2, typename A3
>
typename rule<Iterator, T0, T1, T2>::pointer_type
decorate(rule<Iterator, T0, T1, T2>& r
, A1 const& a1, A2 const& a2, A3 const& a3)
{
return detail::rule_decorator::
template call<Decorator>(r, a1, a2, a3);
}
template <typename Decorator
, typename Iterator, typename T0, typename T1, typename T2
, typename A1, typename A2, typename A3, typename A4
>
typename rule<Iterator, T0, T1, T2>::pointer_type
decorate(rule<Iterator, T0, T1, T2>& r
, A1 const& a1, A2 const& a2
, A3 const& a3, A4 const& a4)
{
return detail::rule_decorator::
template call<Decorator>(r, a1, a2, a3, a4);
}
template <typename Decorator
, typename Iterator, typename T0, typename T1, typename T2
, typename A1, typename A2, typename A3, typename A4, typename A5
>
typename rule<Iterator, T0, T1, T2>::pointer_type
decorate(rule<Iterator, T0, T1, T2>& r
, A1 const& a1, A2 const& a2
, A3 const& a3, A4 const& a4, A5 const& a5)
{
return detail::rule_decorator::
template call<Decorator>(r, a1, a2, a3, a4, a5);
}
// Error handling support
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
detail::error_handler<
Iterator
, typename rule_type::base_type::context_type
, typename rule_type::skipper_type
, F
, action>
error_handler;
decorate<error_handler>(r, 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);
}
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,85 @@
/*=============================================================================
Copyright (c) 2001-2007 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_VIRTUAL_COMPONENT_BASE_FEB_12_2007_0440PM)
#define BOOST_SPIRIT_VIRTUAL_COMPONENT_BASE_FEB_12_2007_0440PM
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/detail/atomic_count.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace spirit { namespace qi
{
struct no_skipper
{
// this struct accepts only unused types and
// nothing else. This is used by the second
// pure virtual parse member function of
// virtual_component_base below.
no_skipper(unused_type) {}
};
template <typename Iterator, typename Context, typename Skipper>
struct virtual_component_base
{
struct take_no_skipper {};
typedef typename
mpl::eval_if<
is_same<Skipper, unused_type>
, mpl::identity<take_no_skipper>
, result_of::as_component<qi::domain, Skipper>
>::type
skipper_type;
virtual_component_base()
: use_count(0)
{
}
virtual ~virtual_component_base()
{
}
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, skipper_type const& skipper) = 0;
virtual bool
parse(
Iterator& first
, Iterator const& last
, Context& context
, no_skipper) = 0;
boost::detail::atomic_count use_count;
};
template <typename Iterator, typename Context, typename Skipper>
inline void
intrusive_ptr_add_ref(virtual_component_base<Iterator, Context, Skipper>* p)
{
++p->use_count;
}
template <typename Iterator, typename Context, typename Skipper>
inline void
intrusive_ptr_release(virtual_component_base<Iterator, Context, Skipper>* p)
{
if (--p->use_count == 0)
delete p;
}
}}}
#endif

View File

@@ -0,0 +1,15 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_05_2007_1231PM)
#define BOOST_SPIRIT_NUMERIC_FEB_05_2007_1231PM
#include <boost/spirit/home/qi/numeric/int.hpp>
#include <boost/spirit/home/qi/numeric/uint.hpp>
#include <boost/spirit/home/qi/numeric/real.hpp>
#include <boost/spirit/home/qi/numeric/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,504 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2001-2009 Hartmut Kaiser
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_APR_17_2006_0816AM)
#define SPIRIT_NUMERIC_UTILS_APR_17_2006_0816AM
#include <boost/detail/iterator.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/char_class/ascii.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <limits>
#include <boost/limits.hpp>
#if !defined(SPIRIT_NUMERICS_LOOP_UNROLL)
# define SPIRIT_NUMERICS_LOOP_UNROLL 3
#endif
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
//
// 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);
//
// The maximum radix digits that can be represented without
// overflow:
//
// template<typename T> struct digits::value;
//
///////////////////////////////////////////////////////////////////////////
template <unsigned Radix>
struct radix_traits;
// Binary
template <>
struct radix_traits<2>
{
template<typename Char>
static bool is_valid(Char ch)
{
return ('0' == ch || '1' == ch);
}
template<typename Char>
static unsigned digit(Char ch)
{
return ch - '0';
}
template<typename T>
struct digits
{
typedef std::numeric_limits<T> numeric_limits_;
BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits);
};
};
// Octal
template <>
struct radix_traits<8>
{
template<typename Char>
static bool is_valid(Char ch)
{
return ch >= '0' && ch <= '7';
}
template<typename Char>
static unsigned digit(Char ch)
{
return ch - '0';
}
template<typename T>
struct digits
{
typedef std::numeric_limits<T> numeric_limits_;
BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits / 3);
};
};
// Decimal
template <>
struct radix_traits<10>
{
template<typename Char>
static bool is_valid(Char ch)
{
return ch >= '0' && ch <= '9';
}
template<typename Char>
static unsigned digit(Char ch)
{
return ch - '0';
}
template<typename T>
struct digits
{
typedef std::numeric_limits<T> numeric_limits_;
BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits10);
};
};
// Hexadecimal
template <>
struct radix_traits<16>
{
template<typename Char>
static bool is_valid(Char ch)
{
return (ch >= '0' && ch <= '9')
|| (ch >= 'a' && ch <= 'f')
|| (ch >= 'A' && ch <= 'F');
}
template<typename Char>
static unsigned digit(Char ch)
{
if (ch >= '0' && ch <= '9')
return ch - '0';
return spirit::char_class::ascii::tolower(ch) - 'a' + 10;
}
template<typename T>
struct digits
{
typedef std::numeric_limits<T> numeric_limits_;
BOOST_STATIC_CONSTANT(int, value = numeric_limits_::digits / 4);
};
};
///////////////////////////////////////////////////////////////////////////
// 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>
static void add(T& n, Char ch, mpl::false_) // unchecked add
{
const int digit = radix_traits<Radix>::digit(ch);
n = n * Radix + digit;
}
template <typename T, typename Char>
static bool add(T& n, Char ch, mpl::true_) // checked add
{
// Ensure n *= Radix will not overflow
static T const max = (std::numeric_limits<T>::max)();
static T const val = (max - 1) / Radix;
if (n > val)
return false;
n *= Radix;
// Ensure n += digit will not overflow
const int digit = radix_traits<Radix>::digit(ch);
if (n > max - digit)
return false;
n += digit;
return true;
}
};
template <unsigned Radix>
struct negative_accumulator
{
template <typename T, typename Char>
static void add(T& n, Char ch, mpl::false_) // unchecked subtract
{
const int digit = radix_traits<Radix>::digit(ch);
n = n * Radix - digit;
}
template <typename T, typename Char>
static bool add(T& n, Char ch, mpl::true_) // checked subtract
{
// Ensure n *= Radix will not underflow
static T const min = (std::numeric_limits<T>::min)();
static T const val = (min + 1) / T(Radix);
if (n < val)
return false;
n *= Radix;
// Ensure n -= digit will not underflow
int const digit = radix_traits<Radix>::digit(ch);
if (n < min + digit)
return false;
n -= digit;
return true;
}
};
///////////////////////////////////////////////////////////////////////////
// Common code for extract_int::parse specializations
///////////////////////////////////////////////////////////////////////////
template <unsigned Radix, typename Accumulator, int MaxDigits>
struct int_extractor
{
template <typename Char, typename T>
static bool
call(Char ch, std::size_t count, T& n, mpl::true_)
{
static std::size_t const
overflow_free = radix_traits<Radix>::template digits<T>::value - 1;
if (count < overflow_free)
{
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>
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>
static bool
call(Char /*ch*/, std::size_t /*count*/, unused_type, mpl::false_)
{
return true;
}
template <typename Char, typename T>
static bool
call(Char ch, std::size_t count, T& n)
{
return call(ch, count, n
, mpl::bool_<
( (MaxDigits < 0)
|| (MaxDigits > radix_traits<Radix>::template digits<T>::value)
)
&& std::numeric_limits<T>::is_modulo
>()
);
}
};
///////////////////////////////////////////////////////////////////////////
// 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
{
static bool
call(std::size_t count)
{
return count < MaxDigits; // bounded
}
};
template <>
struct check_max_digits<-1>
{
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) || !extractor::call(ch, count, val)) \
break; \
++it; \
++count; \
/**/
template <
typename T, unsigned Radix, unsigned MinDigits, int MaxDigits
, typename Accumulator = positive_accumulator<Radix>
, bool Accumulate = 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>
static bool
parse_main(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
typedef radix_traits<Radix> radix_check;
typedef int_extractor<Radix, Accumulator, MaxDigits> 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' && leading_zeros < MaxDigits)
{
++it;
++leading_zeros;
}
}
Attribute val = Accumulate ? attr : 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)
{
attr = val;
first = it;
return true;
}
return false;
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
template <typename Iterator>
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>
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) || !extractor::call(ch, count, val)) \
break; \
++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>
static bool
parse_main(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
typedef radix_traits<Radix> radix_check;
typedef int_extractor<Radix, Accumulator, -1> 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;
attr = 0;
first = it;
return true;
}
}
Attribute val = Accumulate ? attr : 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;
attr = val;
first = it;
return true;
}
count = 0;
++it;
while (true)
{
BOOST_PP_REPEAT(
SPIRIT_NUMERICS_LOOP_UNROLL
, SPIRIT_NUMERIC_INNER_LOOP, _)
}
attr = val;
first = it;
return true;
}
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
template <typename Iterator>
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>
static bool
parse(
Iterator& first
, Iterator const& last
, Attribute& attr)
{
return parse_main(first, last, attr);
}
};
#undef SPIRIT_NUMERIC_INNER_LOOP
}}}}
#endif

View File

@@ -0,0 +1,225 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2001-2009 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_APR_18_2006_0901AM)
#define SPIRIT_REAL_IMPL_APR_18_2006_0901AM
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
namespace
{
template <typename T>
inline void
scale_number(T const& exp, T& n)
{
using namespace std; // allow for ADL to find the correct overload
n *= pow(T(10), exp);
}
inline void
scale_number(unused_type /*exp*/, unused_type /*n*/)
{
// no-op for unused_type
}
template <typename T>
inline void
scale_number(T const& exp, int frac, T& n)
{
scale_number(exp - T(frac), n);
}
inline void
scale_number(unused_type /*exp*/, int /*frac*/, unused_type /*n*/)
{
// no-op for unused_type
}
template <typename T>
inline T
negate_number(bool neg, T const& n)
{
return neg ? -n : n;
}
inline unused_type
negate_number(bool /*neg*/, unused_type n)
{
// no-op for unused_type
return n;
}
template <typename T>
inline bool
number_equal_to_one(T const& value)
{
return value == 1.0;
}
inline bool
number_equal_to_one(unused_type)
{
// no-op for unused_type
return false;
}
}
#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
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
Attribute n = 0;
bool got_a_number = p.parse_n(first, last, 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, attr) ||
p.parse_inf(first, last, attr))
{
// If we got a negative sign, negate the number
attr = negate_number(neg, 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;
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.
Iterator savef = first;
if (p.parse_frac_n(first, last, n))
{
// 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));
}
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_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_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. It is an error if it is not there.
Attribute exp = 0;
if (p.parse_exp_n(first, last, exp))
{
// Got the exponent value. Scale the number by
// exp-frac_digits.
scale_number(exp, frac_digits, n);
}
else
{
// Oops, no exponent, return no-match.
first = save;
return false;
}
}
else if (frac_digits)
{
// No exponent found. Scale the number by -frac_digits.
scale_number(Attribute(-frac_digits), n);
}
else if (number_equal_to_one(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, attr) ||
p.parse_inf(first, last, attr))
{
// If we got a negative sign, negate the number
attr = negate_number(neg, attr);
return true; // got a NaN or Inf, return immediately
}
}
// If we got a negative sign, negate the number
attr = negate_number(neg, n);
// Success!!!
return true;
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif
}}}}
#endif

View File

@@ -0,0 +1,53 @@
/*=============================================================================
Copyright (c) 2001-2007 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_INT_APR_17_2006_0830AM)
#define BOOST_SPIRIT_INT_APR_17_2006_0830AM
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
#include <boost/mpl/assert.hpp>
namespace boost { namespace spirit { namespace qi
{
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct int_parser
{
// check template parameter 'Radix' for validity
BOOST_MPL_ASSERT_MSG(
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
not_supported_radix, ());
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef T type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
return extract_int<T, Radix, MinDigits, MaxDigits>
::call(first, last, attr);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "integer";
}
};
}}}
#endif

View File

@@ -0,0 +1,312 @@
/*=============================================================================
Copyright (c) 2001-2007 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_GRAMMAR_FEB_05_2007_0951AM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_05_2007_0951AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/spirit/home/qi/numeric/real_policies.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit
{
namespace qi
{
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct int_tag;
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct uint_tag;
template <typename T, typename RealPolicies>
struct real_tag;
}
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct is_int_tag<qi::int_tag<T, Radix, MinDigits, MaxDigits>, qi::domain>
: mpl::true_ {};
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct is_int_tag<qi::uint_tag<T, Radix, MinDigits, MaxDigits>, qi::domain>
: mpl::true_ {};
template <typename T, typename RealPolicies>
struct is_real_tag<qi::real_tag<T, RealPolicies>, qi::domain>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct int_parser;
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct uint_parser;
template <typename T, typename RealPolicies>
struct real_parser;
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// numeric tags
///////////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct int_tag
{
};
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct uint_tag
{
};
template <typename T, typename RealPolicies>
struct real_tag
{
RealPolicies policies;
};
///////////////////////////////////////////////////////////////////////////
// numeric specs
///////////////////////////////////////////////////////////////////////////
template <
typename T = int
, unsigned Radix = 10
, unsigned MinDigits = 1
, int MaxDigits = -1
>
struct int_spec
: proto::terminal<
int_tag<T, Radix, MinDigits, MaxDigits>
>::type
{
};
template <
typename T = int
, unsigned Radix = 10
, unsigned MinDigits = 1
, int MaxDigits = -1
>
struct uint_spec
: proto::terminal<
uint_tag<T, Radix, MinDigits, MaxDigits>
>::type
{
};
///////////////////////////////////////////////////////////////////////////
template <
typename T = double,
typename RealPolicies = real_policies<T>
>
struct real_spec
: proto::terminal<
real_tag<T, RealPolicies>
>::type
{
private:
typedef typename
proto::terminal<real_tag<T, RealPolicies> >::type
base_type;
base_type make_tag(RealPolicies const& p) const
{
base_type xpr = {{p}};
return xpr;
}
public:
real_spec(RealPolicies const& p = RealPolicies())
: base_type(make_tag(p))
{}
};
///////////////////////////////////////////////////////////////////////////
namespace detail
{
template <typename RealPolicies>
struct real_policy
{
template <typename Tag>
static RealPolicies get(Tag) { return RealPolicies(); }
template <typename T>
static RealPolicies const& get(real_tag<T, RealPolicies> const& p)
{ return p.policies; }
};
}
///////////////////////////////////////////////////////////////////////////
// get the director of an int tag
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct extract_int_director;
template <>
struct extract_int_director<tag::bin>
{
typedef uint_parser<unsigned, 2, 1, -1> type;
};
template <>
struct extract_int_director<tag::oct>
{
typedef uint_parser<unsigned, 8, 1, -1> type;
};
template <>
struct extract_int_director<tag::hex>
{
typedef uint_parser<unsigned, 16, 1, -1> type;
};
template <>
struct extract_int_director<tag::ushort>
{
typedef uint_parser<unsigned short, 10, 1, -1> type;
};
template <>
struct extract_int_director<tag::ulong>
{
typedef uint_parser<unsigned long, 10, 1, -1> type;
};
template <>
struct extract_int_director<tag::uint>
{
typedef uint_parser<unsigned int, 10, 1, -1> type;
};
template <>
struct extract_int_director<tag::short_>
{
typedef int_parser<short, 10, 1, -1> type;
};
template <>
struct extract_int_director<tag::long_>
{
typedef int_parser<long, 10, 1, -1> type;
};
template <>
struct extract_int_director<tag::int_>
{
typedef int_parser<int, 10, 1, -1> type;
};
#ifdef BOOST_HAS_LONG_LONG
template <>
struct extract_int_director<tag::ulong_long>
{
typedef uint_parser<unsigned long long, 10, 1, -1> type;
};
template <>
struct extract_int_director<tag::long_long>
{
typedef int_parser<long long, 10, 1, -1> type;
};
#endif
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct extract_int_director<int_tag<T, Radix, MinDigits, MaxDigits> >
{
typedef int_parser<T, Radix, MinDigits, MaxDigits> type;
};
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct extract_int_director<uint_tag<T, Radix, MinDigits, MaxDigits> >
{
typedef uint_parser<T, Radix, MinDigits, MaxDigits> type;
};
///////////////////////////////////////////////////////////////////////////
// get the director of a real tag
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct extract_real_director;
template <>
struct extract_real_director<tag::float_>
{
typedef real_parser<float, real_policies<float> > type;
};
template <>
struct extract_real_director<tag::double_>
{
typedef real_parser<double, real_policies<double> > type;
};
template <>
struct extract_real_director<tag::long_double>
{
typedef real_parser<long double, real_policies<long double> > type;
};
template <typename T, typename RealPolicies>
struct extract_real_director<real_tag<T, RealPolicies> >
{
typedef real_parser<T, RealPolicies> type;
};
///////////////////////////////////////////////////////////////////////////
// numeric parser meta-grammar
///////////////////////////////////////////////////////////////////////////
struct int_meta_grammar
: meta_grammar::compose_empty<
proto::if_<is_int_tag<proto::_child, qi::domain>()>
, qi::domain
, mpl::identity<extract_int_director<mpl::_> >
>
{};
struct real_meta_grammar
: meta_grammar::compose_single<
proto::if_<is_real_tag<proto::_child, qi::domain>()>
, qi::domain
, mpl::identity<extract_real_director<mpl::_> >
>
{};
struct numeric_meta_grammar
: proto::or_<int_meta_grammar, real_meta_grammar>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, numeric_meta_grammar> >::type>
: mpl::identity<numeric_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,111 @@
/*=============================================================================
Copyright (c) 2001-2007 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_UTILS_APR_17_2006_0830AM)
#define BOOST_SPIRIT_NUMERIC_UTILS_APR_17_2006_0830AM
#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)
{
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>
struct extract_uint
{
// check template parameter 'Radix' for validity
BOOST_MPL_ASSERT_MSG(
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
not_supported_radix, ());
template <typename Iterator, typename Attribute>
static bool call(Iterator& first, Iterator const& last, Attribute& attr)
{
typedef detail::extract_int<
T
, Radix
, MinDigits
, MaxDigits
, detail::positive_accumulator<Radix>
, Accumulate>
extract_type;
Iterator save = first;
if (!extract_type::parse(first, last, attr))
{
first = save;
return false;
}
return true;
}
};
///////////////////////////////////////////////////////////////////////
// Low level signed integer parser
///////////////////////////////////////////////////////////////////////
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct extract_int
{
// check template parameter 'Radix' for validity
BOOST_MPL_ASSERT_MSG(
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
not_supported_radix, ());
template <typename Iterator, typename Attribute>
static bool call(Iterator& first, Iterator const& last, Attribute& 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;
}
};
}}}
#endif

View File

@@ -0,0 +1,60 @@
/*=============================================================================
Copyright (c) 2001-2007 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_REAL_APR_18_2006_0850AM)
#define BOOST_SPIRIT_REAL_APR_18_2006_0850AM
#include <boost/spirit/home/qi/skip.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>
namespace boost { namespace spirit { namespace qi
{
namespace detail
{
template <typename RealPolicies>
struct real_policy;
}
template <
typename T = double,
typename RealPolicies = real_policies<T>
>
struct real_parser
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef T type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
RealPolicies const& p = detail::real_policy<RealPolicies>::get(
fusion::at_c<0>(component.elements));
qi::skip(first, last, skipper);
return detail::real_impl<T, RealPolicies>::parse(first, last, attr, p);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "real number";
}
};
}}}
#endif

View File

@@ -0,0 +1,182 @@
/*=============================================================================
Copyright (c) 2001-2007 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_REAL_POLICIES_APR_17_2006_1158PM)
#define SPIRIT_REAL_POLICIES_APR_17_2006_1158PM
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
#include <boost/spirit/home/qi/detail/string_parse.hpp>
#include <boost/detail/iterator.hpp> // boost::iterator_traits<>
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<T, 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)
{
return extract_uint<T, 10, 1, -1, true>::call(first, last, attr);
}
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, typename Attribute>
static bool
parse_exp_n(Iterator& first, Iterator const& last, Attribute& attr)
{
return extract_int<T, 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#QNAN 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 == '(')
{
// 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

View File

@@ -0,0 +1,53 @@
/*=============================================================================
Copyright (c) 2001-2007 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_UINT_APR_17_2006_0901AM)
#define SPIRIT_UINT_APR_17_2006_0901AM
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/qi/numeric/numeric_utils.hpp>
#include <boost/mpl/assert.hpp>
namespace boost { namespace spirit { namespace qi
{
template <typename T, unsigned Radix, unsigned MinDigits, int MaxDigits>
struct uint_parser
{
// check template parameter 'Radix' for validity
BOOST_MPL_ASSERT_MSG(
Radix == 2 || Radix == 8 || Radix == 10 || Radix == 16,
not_supported_radix, ());
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef T type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
return extract_uint<T, Radix, MinDigits, MaxDigits>
::call(first, last, attr);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "unsigned integer";
}
};
}}}
#endif

View File

@@ -0,0 +1,24 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_02_2007_0558PM)
#define BOOST_SPIRIT_OPERATOR_FEB_02_2007_0558PM
#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>
#include <boost/spirit/home/qi/operator/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,97 @@
/*=============================================================================
Copyright (c) 2001-2007 Joel de Guzman
Copyright (c) 2001-2009 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_FEB_05_2007_1153AM)
#define SPIRIT_ALTERNATIVE_FEB_05_2007_1153AM
#include <boost/spirit/home/qi/detail/alternative_function.hpp>
#include <boost/spirit/home/support/attribute_transform.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/as_variant.hpp>
#include <boost/fusion/include/any.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/push_front.hpp>
#include <boost/variant.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace qi
{
struct alternative
{
template <typename T>
struct transform_child : mpl::identity<T> {};
template <typename All, typename Filtered>
struct build_container
{
// if the original attribute list does not contain any unused
// attributes it is used, otherwise a single unused_type is
// pushed to the front the list. This is to make sure that if
// there is an unused in the list it is the first one.
typedef typename
mpl::find_if<All, is_same<mpl::_, unused_type> >::type
unused_;
typedef typename
mpl::eval_if<
is_same<unused_, typename mpl::end<All>::type>,
mpl::identity<All>,
fusion::result_of::push_front<Filtered, unused_type>
>::type
attribute_sequence;
// Ok, now make a variant over the attribute_sequence. It's
// a pity that make_variant_over does not support forward MPL
// sequences. We use our own conversion metaprogram (as_variant).
typedef typename
as_variant<attribute_sequence>::type
type;
};
template <typename Component, typename Context, typename Iterator>
struct attribute :
build_fusion_sequence<alternative, Component, Iterator, Context>
{
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
detail::alternative_function<Iterator, Context, Skipper, Attribute>
f(first, last, context, skipper, attr);
// return true if *any* of the parsers succeed
return fusion::any(component.elements, f);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "alternatives[";
fusion::for_each(component.elements,
spirit::detail::what_function<Context>(result, ctx));
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,58 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi
{
struct and_predicate
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& /*attr*/)
{
typedef typename
result_of::subject<Component>::type::director
director;
Iterator i = first;
return director::parse(
subject(component), i, last, context, skipper, unused);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "and-predicate[";
typedef typename
result_of::subject<Component>::type::director
director;
result += director::what(subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,93 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_11_2007_1250PM)
#define SPIRIT_DIFFERENCE_FEB_11_2007_1250PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <vector>
namespace boost { namespace spirit { namespace qi
{
struct difference
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::left<Component>::type
left_type;
typedef typename
traits::attribute_of<
qi::domain, left_type, Context, Iterator>::type
type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::left<Component>::type::director
ldirector;
typedef typename
result_of::right<Component>::type::director
rdirector;
// 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 (rdirector::parse(spirit::right(component), first, last, context,
skipper, unused))
{
// RHS succeeds, we fail.
first = start;
return false;
}
// RHS fails, now try LHS
return ldirector::parse(spirit::left(component), first, last,
context, skipper, attr);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "difference[";
typedef typename
result_of::left<Component>::type::director
ldirector;
typedef typename
result_of::right<Component>::type::director
rdirector;
result += ldirector::what(spirit::left(component), ctx);
result += ", ";
result += rdirector::what(spirit::right(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,49 @@
/*=============================================================================
Copyright (c) 2001-2007 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_APRIL_29_2007_0445PM)
#define SPIRIT_EXPECT_APRIL_29_2007_0445PM
#include <boost/spirit/home/qi/operator/sequence_base.hpp>
#include <boost/spirit/home/qi/detail/expect_function.hpp>
namespace boost { namespace spirit { namespace qi
{
template <typename Iterator>
struct expectation_failure
{
Iterator first;
Iterator last;
std::string what;
};
struct expect : sequence_base<expect>
{
friend struct sequence_base<expect>;
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);
}
static std::string what_()
{
return "expect[";
}
};
}}}
#endif

View File

@@ -0,0 +1,85 @@
/*=============================================================================
Copyright (c) 2001-2007 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_KLEENE_JAN_07_2007_0818AM)
#define SPIRIT_KLEENE_JAN_07_2007_0818AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/detail/container.hpp>
#include <boost/spirit/home/support/attribute_transform.hpp>
#include <vector>
namespace boost { namespace spirit { namespace qi
{
struct kleene
{
template <typename T>
struct build_attribute_container
{
typedef std::vector<T> type;
};
template <typename Component, typename Context, typename Iterator>
struct attribute :
build_container<kleene, Component, Iterator, Context>
{
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
traits::attribute_of<
qi::domain, subject_type, Context, Iterator>::type
attr_type;
typedef typename subject_type::director director;
// create a value if Attribute is not unused_type
typename mpl::if_<
is_same<typename remove_const<Attribute>::type, unused_type>
, unused_type
, attr_type>::type
val;
while(
director::parse(
subject(component)
, first, last, context, skipper, val)
)
{
container::push_back(attr, val);
}
return true;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "kleene[";
typedef typename
result_of::subject<Component>::type::director
director;
result += director::what(subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,97 @@
/*=============================================================================
Copyright (c) 2001-2007 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_LIST_MARCH_24_2007_1031AM)
#define SPIRIT_LIST_MARCH_24_2007_1031AM
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/detail/container.hpp>
#include <boost/spirit/home/support/attribute_transform.hpp>
#include <vector>
namespace boost { namespace spirit { namespace qi
{
struct list
{
template <typename T>
struct build_attribute_container
{
typedef std::vector<T> type;
};
template <typename Component, typename Context, typename Iterator>
struct attribute :
build_container<list, Component, Iterator, Context>
{
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::left<Component>::type::director
ldirector;
typedef typename
result_of::right<Component>::type::director
rdirector;
typename container::result_of::value<Attribute>::type val;
if (ldirector::parse(
spirit::left(component)
, first, last, context, skipper, val)
)
{
container::push_back(attr, val);
Iterator i = first;
while(
rdirector::parse(
spirit::right(component)
, i, last, context, skipper, unused)
&& ldirector::parse(
spirit::left(component)
, i, last, context, skipper, val)
)
{
container::push_back(attr, val);
first = i;
}
return true;
}
return false;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "list[";
typedef typename
result_of::left<Component>::type::director
ldirector;
typedef typename
result_of::right<Component>::type::director
rdirector;
result += ldirector::what(spirit::left(component), ctx);
result += ", ";
result += rdirector::what(spirit::right(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,146 @@
/*=============================================================================
Copyright (c) 2001-2007 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_GRAMMAR_FEB_02_2007_0620PM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_02_2007_0620PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
struct sequence;
struct expect;
struct alternative;
struct sequential_or;
struct permutation;
struct difference;
struct list;
struct optional;
struct kleene;
struct plus;
struct and_predicate;
struct not_predicate;
struct main_meta_grammar;
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// operator meta-grammars
///////////////////////////////////////////////////////////////////////////
struct binary_meta_grammar
: proto::or_<
// a >> b
meta_grammar::binary_rule_flat<
qi::domain, proto::tag::shift_right, sequence
, main_meta_grammar
>
// a + b
, meta_grammar::binary_rule_flat<
qi::domain, proto::tag::plus, sequence
, main_meta_grammar
>
// a > b
, meta_grammar::binary_rule_flat<
qi::domain, proto::tag::greater, expect
, main_meta_grammar
>
// a | b
, meta_grammar::binary_rule_flat<
qi::domain, proto::tag::bitwise_or, alternative
, main_meta_grammar
>
// a || b
, meta_grammar::binary_rule_flat<
qi::domain, proto::tag::logical_or, sequential_or
, main_meta_grammar
>
// a ^ b
, meta_grammar::binary_rule_flat<
qi::domain, proto::tag::bitwise_xor, permutation
, main_meta_grammar
>
// a - b
, meta_grammar::binary_rule<
qi::domain, proto::tag::minus, difference
, main_meta_grammar, main_meta_grammar
>
// a % b
, meta_grammar::binary_rule<
qi::domain, proto::tag::modulus, list
, main_meta_grammar, main_meta_grammar
>
>
{
};
struct unary_meta_grammar
: proto::or_<
// -a
meta_grammar::unary_rule<
qi::domain, proto::tag::negate, optional
, main_meta_grammar
>
// *a
, meta_grammar::unary_rule<
qi::domain, proto::tag::dereference, kleene
, main_meta_grammar
>
// +a
, meta_grammar::unary_rule<
qi::domain, proto::tag::unary_plus, plus
, main_meta_grammar
>
// &a
, meta_grammar::unary_rule<
qi::domain, proto::tag::address_of, and_predicate
, main_meta_grammar
>
// !a
, meta_grammar::unary_rule<
qi::domain, proto::tag::logical_not, not_predicate
, main_meta_grammar
>
>
{
};
struct operator_meta_grammar
: proto::or_<
binary_meta_grammar
, unary_meta_grammar
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, operator_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, operator_meta_grammar> >::type>
: mpl::identity<operator_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,58 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/unused.hpp>
namespace boost { namespace spirit { namespace qi
{
struct not_predicate
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& /*attr*/)
{
typedef typename
result_of::subject<Component>::type::director
director;
Iterator i = first;
return !director::parse(
subject(component), i, last, context, skipper, unused);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "not-predicate[";
typedef typename
result_of::subject<Component>::type::director
director;
result += director::what(subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,86 @@
/*=============================================================================
Copyright (c) 2001-2007 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_OPTIONAL_MARCH_23_2007_1117PM)
#define SPIRIT_OPTIONAL_MARCH_23_2007_1117PM
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/attribute_transform.hpp>
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/optional.hpp>
#include <vector>
namespace boost { namespace spirit { namespace qi
{
struct optional
{
template <typename T>
struct build_attribute_container
{
typedef boost::optional<T> type;
};
template <typename Component, typename Context, typename Iterator>
struct attribute :
build_container<optional, Component, Iterator, Context>
{
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
traits::attribute_of<
qi::domain, subject_type, Context, Iterator>::type
attr_type;
typedef typename subject_type::director director;
// create a value if Attribute is not unused_type
typename mpl::if_<
is_same<typename remove_const<Attribute>::type, unused_type>
, unused_type
, attr_type>::type
val;
if (director::parse(
subject(component), first, last, context, skipper, val))
{
qi::detail::assign_to(val, attr);
}
return true;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "optional[";
typedef typename
result_of::subject<Component>::type::director
director;
result += director::what(subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,96 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/qi/detail/permute_function.hpp>
#include <boost/spirit/home/support/attribute_transform.hpp>
#include <boost/spirit/home/support/algorithm/any.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/optional.hpp>
#include <boost/foreach.hpp>
#include <boost/array.hpp>
namespace boost { namespace spirit { namespace qi
{
struct permutation
{
template <typename T>
struct transform_child
{
typedef boost::optional<T> type;
};
template <typename All, typename Filtered>
struct build_container
{
typedef
typename fusion::result_of::as_vector<Filtered>::type
type;
};
template <typename Component, typename Context, typename Iterator>
struct attribute :
build_fusion_sequence<permutation, Component, Iterator, Context>
{
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
detail::permute_function<Iterator, Context, Skipper>
f(first, last, context, skipper);
boost::array<
bool
, fusion::result_of::size<typename Component::elements_type>::value
>
slots;
BOOST_FOREACH(bool& taken, slots)
{
taken = false;
}
// We have a bool array 'slots' 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 = slots.begin();
while (spirit::any_ns(component.elements, attr, f))
{
f.taken = slots.begin();
result = true;
}
return result;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "permutation[";
fusion::for_each(component.elements,
spirit::detail::what_function<Context>(result, ctx));
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,92 @@
/*=============================================================================
Copyright (c) 2001-2007 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_PLUS_MARCH_13_2007_0127PM)
#define SPIRIT_PLUS_MARCH_13_2007_0127PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/detail/container.hpp>
#include <boost/spirit/home/support/attribute_transform.hpp>
#include <vector>
namespace boost { namespace spirit { namespace qi
{
struct plus
{
template <typename T>
struct build_attribute_container
{
typedef std::vector<T> type;
};
template <typename Component, typename Context, typename Iterator>
struct attribute :
build_container<plus, Component, Iterator, Context>
{
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
traits::attribute_of<
qi::domain, subject_type, Context, Iterator>::type
attr_type;
typedef typename subject_type::director director;
// create a value if Attribute is not unused_type
typename mpl::if_<
is_same<typename remove_const<Attribute>::type, unused_type>
, unused_type
, attr_type>::type
val;
if (director::parse(
subject(component)
, first, last, context, skipper, val)
)
{
container::push_back(attr, val);
while(director::parse(
subject(component)
, first, last, context, skipper, val)
)
{
container::push_back(attr, val);
}
return true;
}
return false;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "plus[";
typedef typename
result_of::subject<Component>::type::director
director;
result += director::what(subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,38 @@
/*=============================================================================
Copyright (c) 2001-2007 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_SEQUENCE_APR_22_2006_0811AM)
#define SPIRIT_SEQUENCE_APR_22_2006_0811AM
#include <boost/spirit/home/qi/operator/sequence_base.hpp>
#include <boost/spirit/home/qi/detail/fail_function.hpp>
namespace boost { namespace spirit { namespace qi
{
struct sequence : sequence_base<sequence>
{
friend struct sequence_base<sequence>;
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);
}
static std::string what_()
{
return "sequence[";
}
};
}}}
#endif

View File

@@ -0,0 +1,90 @@
/*=============================================================================
Copyright (c) 2001-2007 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_SEQUENCE_BASE_APR_22_2006_0811AM)
#define SPIRIT_SEQUENCE_BASE_APR_22_2006_0811AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/attribute_transform.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/detail/values.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/mpl/identity.hpp>
namespace boost { namespace spirit { namespace qi
{
template <typename Derived>
struct sequence_base // this class is shared by sequence and expect
{
template <typename T>
struct transform_child : mpl::identity<T> {};
template <typename All, typename Filtered>
struct build_container
{
typedef
typename fusion::result_of::as_vector<Filtered>::type
type;
};
template <typename Component, typename Context, typename Iterator>
struct attribute :
build_fusion_sequence<
sequence_base<Derived>, Component, Iterator, Context
>
{
};
template <typename Iterator, typename Context>
struct attribute_not_unused
{
template <typename Component>
struct apply
: spirit::traits::is_not_unused<typename
traits::attribute_of<
qi::domain, Component, Context, Iterator>::type
>
{};
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
Iterator iter = first;
typedef attribute_not_unused<Iterator, Context> predicate;
// return false if *any* of the parsers fail
if (spirit::any_if(
component.elements, attr
, Derived::fail_function(iter, last, context, skipper), predicate()))
return false;
first = iter;
return true;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = Derived::what_();
fusion::for_each(component.elements,
spirit::detail::what_function<Context>(result, ctx));
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,75 @@
/*=============================================================================
Copyright (c) 2001-2007 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
#include <boost/spirit/home/qi/detail/pass_function.hpp>
#include <boost/spirit/home/support/attribute_transform.hpp>
#include <boost/spirit/home/support/detail/what_function.hpp>
#include <boost/spirit/home/support/algorithm/any_ns.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <boost/fusion/include/for_each.hpp>
namespace boost { namespace spirit { namespace qi
{
struct sequential_or
{
template <typename T>
struct transform_child
{
typedef boost::optional<T> type;
};
template <typename All, typename Filtered>
struct build_container
{
typedef
typename fusion::result_of::as_vector<Filtered>::type
type;
};
template <typename Component, typename Context, typename Iterator>
struct attribute :
build_fusion_sequence<
sequential_or, Component, Iterator, Context
>
{
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
qi::detail::pass_function<Iterator, Context, Skipper>
f(first, last, context, skipper);
// return true if *any* of the parsers succeed
// (we use the non-short-circuiting version: any_ns
// to force all elements to be tested)
return spirit::any_ns(component.elements, attr, f);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "sequential-or[";
fusion::for_each(component.elements,
spirit::detail::what_function<Context>(result, ctx));
result += "]";
return result;
}
};
}}}
#endif

View File

@@ -0,0 +1,136 @@
/*=============================================================================
Copyright (c) 2001-2007 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_PARSE_APR_16_2006_0442PM)
#define BOOST_SPIRIT_PARSE_APR_16_2006_0442PM
#include <boost/spirit/home/qi/meta_grammar.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
namespace boost { namespace spirit { namespace qi
{
template <typename Iterator, typename Expr>
inline bool
parse(
Iterator& first
, Iterator last
, Expr const& xpr)
{
typedef spirit::traits::is_component<qi::domain, Expr> is_component;
// report invalid expression error as early as possible
BOOST_MPL_ASSERT_MSG(
is_component::value,
xpr_is_not_convertible_to_a_parser, (Iterator, Expr));
typedef typename result_of::as_component<qi::domain, Expr>::type component;
typedef typename component::director director;
component c = spirit::as_component(qi::domain(), xpr);
return director::parse(c, first, last, unused, unused, unused);
}
template <typename Iterator, typename Expr, typename Attr>
inline bool
parse(
Iterator& first
, Iterator last
, Expr const& xpr
, Attr& attr)
{
typedef spirit::traits::is_component<qi::domain, Expr> is_component;
// report invalid expression error as early as possible
BOOST_MPL_ASSERT_MSG(
is_component::value,
xpr_is_not_convertible_to_a_parser, (Iterator, Expr, Attr));
typedef typename result_of::as_component<qi::domain, Expr>::type component;
typedef typename component::director director;
component c = spirit::as_component(qi::domain(), xpr);
return director::parse(c, first, last, unused, unused, attr);
}
///////////////////////////////////////////////////////////////////////////
template <typename Iterator, typename Expr, typename Skipper>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr const& xpr
, Skipper const& skipper_)
{
typedef spirit::traits::is_component<qi::domain, Expr> expr_is_component;
typedef spirit::traits::is_component<qi::domain, Skipper> skipper_is_component;
// report invalid expressions error as early as possible
BOOST_MPL_ASSERT_MSG(
expr_is_component::value,
xpr_is_not_convertible_to_a_parser, (Iterator, Expr, Skipper));
BOOST_MPL_ASSERT_MSG(
skipper_is_component::value,
skipper_is_not_convertible_to_a_parser, (Iterator, Expr, Skipper));
typedef typename result_of::as_component<qi::domain, Expr>::type component;
typedef typename component::director director;
component c = spirit::as_component(qi::domain(), xpr);
typename result_of::as_component<qi::domain, Skipper>::type
skipper = spirit::as_component(qi::domain(), skipper_);
if (!director::parse(c, first, last, unused, skipper, unused))
return false;
// do a final post-skip
skip(first, last, skipper);
return true;
}
template <typename Iterator, typename Expr, typename Attr, typename Skipper>
inline bool
phrase_parse(
Iterator& first
, Iterator last
, Expr const& xpr
, Attr& attr
, Skipper const& skipper_)
{
typedef spirit::traits::is_component<qi::domain, Expr> expr_is_component;
typedef spirit::traits::is_component<qi::domain, Skipper> skipper_is_component;
// report invalid expressions error as early as possible
BOOST_MPL_ASSERT_MSG(
expr_is_component::value,
xpr_is_not_convertible_to_a_parser,
(Iterator, Expr, Attr, Skipper));
BOOST_MPL_ASSERT_MSG(
skipper_is_component::value,
skipper_is_not_convertible_to_a_parser,
(Iterator, Expr, Attr, Skipper));
typedef typename result_of::as_component<qi::domain, Expr>::type component;
typedef typename component::director director;
component c = spirit::as_component(qi::domain(), xpr);
typename result_of::as_component<qi::domain, Skipper>::type
skipper = spirit::as_component(qi::domain(), skipper_);
if (!director::parse(c, first, last, unused, skipper, attr))
return false;
// do a final post-skip
skip(first, last, skipper);
return true;
}
}}}
#endif

View File

@@ -0,0 +1,34 @@
/*=============================================================================
Copyright (c) 2001-2007 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_APR_16_2006_0625PM)
#define BOOST_SPIRIT_SKIP_APR_16_2006_0625PM
#include <boost/spirit/home/qi/meta_grammar.hpp>
#include <boost/spirit/home/support/unused.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(Iterator& first, Iterator const& last, T const& skipper)
{
while (first != last &&
T::director::parse(skipper, first, last, unused, unused, unused))
;
}
template <typename Iterator>
inline void skip(Iterator&, Iterator const&, unused_type)
{
}
}}}
#endif

View File

@@ -0,0 +1,17 @@
// Copyright (c) 2001-2009 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) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
#include <boost/spirit/home/qi/stream/match_manip.hpp>
#include <boost/spirit/home/qi/stream/stream.hpp>
#include <boost/spirit/home/qi/stream/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,52 @@
// Copyright (c) 2001-2009 Hartmut Kaiser
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boist.org/LICENSE_1_0.txt)
#if !defined(BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM)
#define BOOST_SPIRIT_ITERATOR_ISTREAM_MAY_05_2007_0110PM
#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::source_tag category;
iterator_source (Iterator& first_, Iterator const& last_)
: first(first_), last(last_)
{}
// 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;
}
return bytes_read;
}
Iterator& first;
Iterator const& last;
};
}}}}
#endif

View File

@@ -0,0 +1,104 @@
// Copyright (c) 2001-2009 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_FORMAT_MANIP_MAY_05_2007_1203PM)
#define BOOST_SPIRIT_FORMAT_MANIP_MAY_05_2007_1203PM
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <iterator>
#include <string>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi { namespace detail
{
///////////////////////////////////////////////////////////////////////////
template <
typename Expr,
typename Attribute = unused_type const,
typename Skipper = unused_type
>
struct match_manip
{
match_manip(Expr const& xpr, Attribute& a, Skipper const& s)
: expr(xpr), attr(a), skipper(s)
{}
Expr const& expr;
Attribute& attr;
Skipper const& skipper;
};
///////////////////////////////////////////////////////////////////////////
template<typename Char, typename Traits, typename Expr>
inline std::basic_istream<Char, Traits> &
operator>> (std::basic_istream<Char, Traits> &is,
match_manip<Expr> const& fm)
{
typedef std::istream_iterator<Char, 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 Attribute>
inline std::basic_istream<Char, Traits> &
operator>> (std::basic_istream<Char, Traits> &is,
match_manip<Expr, Attribute> const& fm)
{
typedef std::istream_iterator<Char, 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 Skipper>
inline std::basic_istream<Char, Traits> &
operator>> (std::basic_istream<Char, Traits> &is,
match_manip<Expr, unused_type, Skipper> const& fm)
{
typedef std::istream_iterator<Char, Char, Traits> input_iterator;
input_iterator f(is);
input_iterator l;
if (!qi::phrase_parse(f, l, fm.expr, fm.skipper))
{
is.setstate(std::ios_base::failbit);
}
return is;
}
///////////////////////////////////////////////////////////////////////////
template<
typename Char, typename Traits,
typename Expr, typename Attribute, typename Skipper
>
inline std::basic_istream<Char, Traits> &
operator>> (
std::basic_istream<Char, Traits> &is,
match_manip<Expr, Attribute, Skipper> const& fm)
{
typedef std::istream_iterator<Char, Char, Traits> input_iterator;
input_iterator f(is);
input_iterator l;
if (!qi::phrase_parse(f, l, fm.expr, fm.attr, fm.skipper))
{
is.setstate(std::ios_base::failbit);
}
return is;
}
}}}}
#endif

View File

@@ -0,0 +1,112 @@
// Copyright (c) 2001-2009 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_FORMAT_MANIP_MAY_05_2007_1202PM)
#define BOOST_SPIRIT_FORMAT_MANIP_MAY_05_2007_1202PM
#include <boost/spirit/home/qi/parse.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/qi/stream/detail/match_manip.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/utility/enable_if.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
inline detail::match_manip<Expr>
match(Expr const& xpr)
{
typedef spirit::traits::is_component<qi::domain, Expr> is_component;
// report invalid expression error as early as possible
BOOST_MPL_ASSERT_MSG(is_component::value,
xpr_is_not_convertible_to_a_parser, (Expr));
return qi::detail::match_manip<Expr>(xpr, unused, unused);
}
template <typename Expr, typename Attribute>
inline detail::match_manip<Expr, Attribute>
match(Expr const& xpr, Attribute& p)
{
typedef spirit::traits::is_component<qi::domain, Expr> is_component;
// report invalid expression error as early as possible
BOOST_MPL_ASSERT_MSG(is_component::value,
xpr_is_not_convertible_to_a_parser, (Expr, Attribute));
return qi::detail::match_manip<Expr, Attribute>(xpr, p, unused);
}
///////////////////////////////////////////////////////////////////////////
template <typename Expr, typename Skipper>
inline detail::match_manip<Expr, unused_type const, Skipper>
phrase_match(Expr const& xpr, Skipper const& s)
{
typedef
spirit::traits::is_component<qi::domain, Expr>
expr_is_component;
typedef
spirit::traits::is_component<qi::domain, Skipper>
skipper_is_component;
// report invalid expression errors as early as possible
BOOST_MPL_ASSERT_MSG(expr_is_component::value,
xpr_is_not_convertible_to_a_parser, (Expr, Skipper));
BOOST_MPL_ASSERT_MSG(skipper_is_component::value,
skipper_is_not_convertible_to_a_parser, (Expr, Skipper));
return qi::detail::match_manip<Expr, unused_type const, Skipper>(
xpr, unused, s);
}
template <typename Expr, typename Attribute, typename Skipper>
inline detail::match_manip<Expr, Attribute, Skipper>
phrase_match(Expr const& xpr, Attribute& p, Skipper const& s)
{
typedef
spirit::traits::is_component<qi::domain, Expr>
expr_is_component;
typedef
spirit::traits::is_component<qi::domain, Skipper>
skipper_is_component;
// report invalid expression errors as early as possible
BOOST_MPL_ASSERT_MSG(expr_is_component::value,
xpr_is_not_convertible_to_a_parser, (Expr, Attribute, Skipper));
BOOST_MPL_ASSERT_MSG(skipper_is_component::value,
skipper_is_not_convertible_to_a_parser, (Expr, Attribute, Skipper));
return qi::detail::match_manip<Expr, Attribute, Skipper>(xpr, p, s);
}
///////////////////////////////////////////////////////////////////////////
template<typename Char, typename Traits, typename Expr>
inline typename
enable_if<
spirit::traits::is_component<qi::domain, Expr>,
std::basic_istream<Char, Traits> &
>::type
operator>> (std::basic_istream<Char, Traits> &is, Expr& xpr)
{
typedef std::istream_iterator<Char, Char, Traits> input_iterator;
input_iterator f(is);
input_iterator l;
if (!qi::parse (f, l, xpr))
{
is.setstate(std::ios_base::failbit);
}
return is;
}
}}}
#endif

View File

@@ -0,0 +1,134 @@
// Copyright (c) 2001-2009 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_META_GRAMMAR_MAY_05_2007_1230PM)
#define BOOST_SPIRIT_META_GRAMMAR_MAY_05_2007_1230PM
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace spirit
{
namespace qi
{
template <typename T, typename Char>
struct stream_tag;
}
template <typename T, typename Char>
struct is_stream_tag<qi::stream_tag<T, Char>, qi::domain>
: mpl::true_ {};
}}
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
template <typename Char, typename T>
struct any_stream;
template <typename Char>
struct stream_director;
struct main_meta_grammar;
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
///////////////////////////////////////////////////////////////////////////
// stream tag
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Char>
struct stream_tag
{
};
///////////////////////////////////////////////////////////////////////////
// stream specs
///////////////////////////////////////////////////////////////////////////
template <typename T, typename Char = char>
struct typed_stream
: proto::terminal<stream_tag<T, Char> >::type
{
};
///////////////////////////////////////////////////////////////////////////
// get the director for a stream
///////////////////////////////////////////////////////////////////////////
template <typename Tag>
struct extract_stream_director;
template <>
struct extract_stream_director<tag::stream>
{
typedef any_stream<char> type;
};
template <>
struct extract_stream_director<tag::wstream>
{
typedef any_stream<wchar_t> type;
};
template <typename T, typename Char>
struct extract_stream_director<stream_tag<T, Char> >
{
typedef any_stream<Char, T> type;
};
///////////////////////////////////////////////////////////////////////////
// utility meta-grammar
///////////////////////////////////////////////////////////////////////////
struct utility_meta_grammar :
// stream, wstream
meta_grammar::compose_empty<
proto::if_<
is_stream_tag<proto::_child, qi::domain>()
>,
qi::domain,
mpl::identity<extract_stream_director<mpl::_> >
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the Qi meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<
Expr,
typename enable_if<
proto::matches<Expr, utility_meta_grammar>
>::type
>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<
Expr,
typename enable_if<
proto::matches<Expr, utility_meta_grammar>
>::type
>
: mpl::identity<utility_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,73 @@
// Copyright (c) 2001-2009 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) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #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_istream.hpp>
#include <boost/spirit/home/support/detail/hold_any.hpp>
#include <iosfwd>
#include <sstream>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
// overload the streaming operators for the unused_type
template <typename Char, typename Traits>
inline std::basic_istream<Char, Traits>&
operator>> (std::basic_istream<Char, Traits>& is, unused_type&)
{
return is;
}
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace qi
{
template <typename Char, typename T = spirit::hold_any>
struct any_stream
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef T type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& /*component*/
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
typedef qi::detail::iterator_source<Iterator> source_device;
typedef boost::iostreams::stream<source_device> instream;
qi::skip(first, last, skipper);
instream in (first, last);
in >> attr; // use existing operator>>()
return in.good() || in.eof();
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "any-stream";
}
};
}}}
#endif

View File

@@ -0,0 +1,14 @@
/*=============================================================================
Copyright (c) 2001-2007 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_FEB_03_2007_0355PM)
#define BOOST_SPIRIT_STRING_FEB_03_2007_0355PM
#include <boost/spirit/home/qi/string/lit.hpp>
#include <boost/spirit/home/qi/string/symbols.hpp>
#include <boost/spirit/home/qi/string/meta_grammar.hpp>
#endif

View File

@@ -0,0 +1,404 @@
/*=============================================================================
Copyright (c) 2001-2007 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_TST_MARCH_09_2007_0905AM)
#define BOOST_SPIRIT_TST_MARCH_09_2007_0905AM
#include <boost/call_traits.hpp>
#include <boost/detail/iterator.hpp>
#include <boost/foreach.hpp>
#include <boost/assert.hpp>
namespace boost { namespace spirit { namespace qi { namespace detail
{
// This file contains low level TST routines, not for
// public consumption.
template <typename Char, typename T>
struct tst_node
{
tst_node(Char id)
: id(id), data(0), lt(0), eq(0), gt(0)
{
}
template <typename Alloc>
static void
destruct_node(tst_node* p, Alloc* alloc)
{
if (p)
{
if (p->data)
alloc->delete_data(p->data);
destruct_node(p->lt, alloc);
destruct_node(p->eq, alloc);
destruct_node(p->gt, alloc);
alloc->delete_node(p);
}
}
template <typename Alloc>
static tst_node*
clone_node(tst_node* p, Alloc* alloc)
{
if (p)
{
tst_node* clone = alloc->new_node(p->id);
if (p->data)
clone->data = alloc->new_data(*p->data);
clone->lt = clone_node(p->lt, alloc);
clone->eq = clone_node(p->eq, alloc);
clone->gt = clone_node(p->gt, alloc);
return clone;
}
return 0;
}
template <typename Iterator, typename Filter>
static T*
find(tst_node* start, Iterator& first, Iterator last, Filter filter)
{
if (first == last)
return false;
Iterator i = first;
Iterator latest = first;
tst_node* p = start;
T* found = 0;
while (p && i != last)
{
typename
boost::detail::iterator_traits<Iterator>::value_type
c = filter(*i); // filter only the input
if (c == p->id)
{
if (p->data)
{
found = p->data;
latest = i;
}
p = p->eq;
i++;
}
else if (c < p->id)
{
p = p->lt;
}
else
{
p = p->gt;
}
}
if (found)
first = ++latest; // one past the last matching char
return found;
}
template <typename Iterator, typename Alloc>
static bool
add(
tst_node*& start
, Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val
, Alloc* alloc)
{
if (first == last)
return false;
tst_node** pp = &start;
while (true)
{
typename
boost::detail::iterator_traits<Iterator>::value_type
c = *first;
if (*pp == 0)
*pp = alloc->new_node(c);
tst_node* p = *pp;
if (c == p->id)
{
if (++first == last)
{
if (p->data == 0)
{
p->data = alloc->new_data(val);
return true;
}
return false;
}
pp = &p->eq;
}
else if (c < p->id)
{
pp = &p->lt;
}
else
{
pp = &p->gt;
}
}
}
template <typename Iterator, typename Alloc>
static void
remove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)
{
if (p == 0 || first == last)
return;
typename
boost::detail::iterator_traits<Iterator>::value_type
c = *first;
if (c == p->id)
{
if (++first == last)
{
if (p->data)
{
alloc->delete_data(p->data);
p->data = 0;
}
}
remove(p->eq, first, last, alloc);
}
else if (c < p->id)
{
remove(p->lt, first, last, alloc);
}
else
{
remove(p->gt, first, last, alloc);
}
if (p->lt == 0 && p->eq == 0 && p->gt == 0)
{
alloc->delete_node(p);
p = 0;
}
}
template <typename F>
static void
for_each(tst_node* p, std::basic_string<Char> prefix, F f)
{
if (p)
{
for_each(p->lt, prefix, f);
std::basic_string<Char> s = prefix + p->id;
for_each(p->eq, s, f);
if (p->data)
f(s, *p->data);
for_each(p->gt, prefix, f);
}
}
Char id; // the node's identity character
T* data; // optional data
tst_node* lt; // left pointer
tst_node* eq; // middle pointer
tst_node* gt; // right pointer
};
/*
template <typename Char, typename T>
struct tst
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef tst_node<Char, T> tst_node;
tst()
{
}
~tst()
{
// Nothing to do here.
// The pools do the right thing for us
}
tst(tst const& rhs)
{
copy(rhs);
}
tst& operator=(tst const& rhs)
{
return assign(rhs);
}
template <typename Iterator, typename Filter>
T* find(Iterator& first, Iterator last, Filter filter) const
{
if (first != last)
{
Iterator save = first;
typename map_type::const_iterator
i = map.find(filter(*first++));
if (i == map.end())
{
first = save;
return 0;
}
if (T* p = detail::find(i->second.root, first, last, filter))
{
return p;
}
return i->second.data;
}
return 0;
}
template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
return find(first, last, tst_pass_through());
}
template <typename Iterator>
bool add(
Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val)
{
if (first != last)
{
map_data x = {0, 0};
std::pair<typename map_type::iterator, bool>
r = map.insert(std::pair<Char, map_data>(*first++, x));
if (first != last)
{
return detail::add(r.first->second.root, first, last, val, this);
}
else
{
if (r.first->second.data)
return false;
r.first->second.data = this->new_data(val);
}
return true;
}
return false;
}
template <typename Iterator>
void remove(Iterator first, Iterator last)
{
if (first != last)
{
typename map_type::iterator i = map.find(*first++);
if (i != map.end())
{
if (first != last)
{
detail::remove(i->second.root, first, last, this);
}
else if (i->second.data)
{
this->delete_data(i->second.data);
i->second.data = 0;
}
if (i->second.data == 0 && i->second.root == 0)
{
map.erase(i);
}
}
}
}
void clear()
{
BOOST_FOREACH(typename map_type::value_type& x, map)
{
destruct_node(x.second.root, this);
if (x.second.data)
this->delete_data(x.second.data);
}
map.clear();
}
template <typename F>
void for_each(F f) const
{
BOOST_FOREACH(typename map_type::value_type const& x, map)
{
std::basic_string<Char> s(1, x.first);
detail::for_each(x.second.root, s, f);
if (x.second.data)
f(s, *x.second.data);
}
}
tst_node* new_node(Char id)
{
return node_pool.construct(id);
}
T* new_data(typename boost::call_traits<T>::param_type val)
{
return data_pool.construct(val);
}
void delete_node(tst_node* p)
{
node_pool.destroy(p);
}
void delete_data(T* p)
{
data_pool.destroy(p);
}
private:
struct map_data
{
tst_node* root;
T* data;
};
typedef unordered_map<Char, map_data> map_type;
void copy(tst const& rhs)
{
BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
{
map_data xx = {clone_node(x.second.root, this), 0};
if (x.second.data)
xx.data = data_pool.construct(*x.second.data);
map[x.first] = xx;
}
}
tst& assign(tst const& rhs)
{
if (this != &rhs)
{
BOOST_FOREACH(typename map_type::value_type& x, map)
{
destruct_node(x.second.root, this);
}
map.clear();
copy(rhs);
}
return *this;
}
map_type map;
object_pool<tst_node> node_pool;
object_pool<T> data_pool;
};
*/
}}}}
#endif

View File

@@ -0,0 +1,204 @@
/*=============================================================================
Copyright (c) 2001-2007 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_LIT_APR_18_2006_1125PM)
#define BOOST_SPIRIT_LIT_APR_18_2006_1125PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/qi/detail/string_parse.hpp>
#include <boost/spirit/home/support/char_class.hpp>
#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/detail/to_narrow.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/value_at.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <string>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// parse literal strings
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct literal_string
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type; // literal parsers have no attribute
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
return detail::string_parse(
fusion::at_c<0>(component.elements)
, first
, last
, attr
);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("\"")
+ spirit::detail::to_narrow_string(
fusion::at_c<0>(component.elements))
+ std::string("\"")
;
}
};
///////////////////////////////////////////////////////////////////////////
// parse lazy strings
///////////////////////////////////////////////////////////////////////////
struct lazy_string
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
remove_reference<
typename boost::result_of<subject_type(unused_type, Context)>::type
>::type
type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& context, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
return detail::string_parse(
fusion::at_c<0>(component.elements)(unused, context)
, first
, last
, attr
);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("\"")
+ spirit::detail::to_narrow_string(
fusion::at_c<0>(component.elements)(unused, ctx))
+ std::string("\"")
;
}
};
///////////////////////////////////////////////////////////////////////////
// no_case literal_string version
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct no_case_literal_string
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef unused_type type; // literal parsers have no attribute
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
qi::skip(first, last, skipper);
return detail::string_parse(
fusion::at_c<0>(component.elements)
, fusion::at_c<1>(component.elements)
, first
, last
, attr
);
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return std::string("case-insensitive \"")
+ spirit::detail::to_narrow_string(
fusion::at_c<0>(component.elements))
+ std::string("\"")
;
}
};
}}}
namespace boost { namespace spirit { namespace traits
{
///////////////////////////////////////////////////////////////////////////
// no_case_literal_string generator
///////////////////////////////////////////////////////////////////////////
template <
typename Domain, typename Elements, typename Modifier, typename Char
>
struct make_modified_component<
Domain, qi::literal_string<Char>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef std::basic_string<Char> string_type;
typedef fusion::vector<string_type, string_type> vector_type;
typedef
component<qi::domain, qi::no_case_literal_string<Char>, vector_type>
type;
static type
call(Elements const& elements)
{
typedef typename Modifier::char_set char_set;
Char const* in = fusion::at_c<0>(elements);
string_type lo(in);
string_type hi(in);
typename string_type::iterator loi = lo.begin();
typename string_type::iterator hii = hi.begin();
for (; loi != lo.end(); ++loi, ++hii, ++in)
{
*loi = char_set::tolower(*loi);
*hii = char_set::toupper(*hii);
}
return type(vector_type(lo, hi));
}
};
}}}
#endif

View File

@@ -0,0 +1,203 @@
/*=============================================================================
Copyright (c) 2001-2007 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_GRAMMAR_FEB_03_2007_0356PM)
#define BOOST_SPIRIT_META_GRAMMAR_FEB_03_2007_0356PM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/support/placeholders.hpp>
#include <boost/spirit/home/support/meta_grammar.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <string>
namespace boost { namespace spirit { namespace qi
{
///////////////////////////////////////////////////////////////////////////
// forwards
///////////////////////////////////////////////////////////////////////////
template<typename Char>
struct literal_string;
struct lazy_string;
template <typename Filter>
struct symbols_director;
struct string_meta_grammar;
template <typename Expr, typename Enable>
struct is_valid_expr;
template <typename Expr, typename Enable>
struct expr_transform;
template <typename Lookup>
struct symbols_lookup;
///////////////////////////////////////////////////////////////////////////
// get the director of a string literal type
///////////////////////////////////////////////////////////////////////////
template <typename T>
struct extract_char;
template <typename Char, typename Traits, typename Alloc>
struct extract_char<std::basic_string<Char, Traits, Alloc> >
{
typedef Char type;
};
template <typename Char, int N>
struct extract_char<Char[N]>
{
typedef typename remove_const<Char>::type type;
};
template <typename Char, int N>
struct extract_char<Char(&)[N]>
{
typedef typename remove_const<Char>::type type;
};
template <typename Char>
struct extract_char<Char*>
{
typedef typename remove_const<Char>::type type;
};
template <typename Tag, typename T>
struct extract_lit_director;
template <typename T>
struct extract_lit_director<tag::lit, T>
{
typedef typename extract_char<T>::type char_type;
typedef literal_string<char_type> type;
};
template <typename T>
struct extract_lit_director<tag::wlit, T>
{
typedef typename extract_char<T>::type char_type;
typedef literal_string<char_type> type;
};
///////////////////////////////////////////////////////////////////////////
// string parser meta-grammars
///////////////////////////////////////////////////////////////////////////
// literal strings: "hello"
struct string_literal_meta_grammar
: proto::or_<
meta_grammar::terminal_rule<
qi::domain, char const*, literal_string<char> >
, meta_grammar::terminal_rule<
qi::domain, char*, literal_string<char> >
, meta_grammar::terminal_rule<
qi::domain, wchar_t const*, literal_string<wchar_t> >
, meta_grammar::terminal_rule<
qi::domain, wchar_t*, literal_string<wchar_t> >
>
{
};
// literal strings: "hello"
struct basic_string_literal_meta_grammar
: proto::or_<
proto::terminal<char const*>
, proto::terminal<wchar_t const*>
>
{
};
// std::string(s)
struct basic_std_string_meta_grammar
: proto::or_<
proto::terminal<std::basic_string<char, proto::_, proto::_> >
, proto::terminal<std::basic_string<wchar_t, proto::_, proto::_> >
>
{
};
// std::string(s)
struct std_string_meta_grammar
: proto::or_<
meta_grammar::terminal_rule<
qi::domain
, std::basic_string<char, proto::_, proto::_>
, literal_string<char> >
, meta_grammar::terminal_rule<
qi::domain
, std::basic_string<wchar_t, proto::_, proto::_>
, literal_string<wchar_t> >
>
{
};
namespace detail
{
// we use this test to detect if the argument to lit is a callable
// function or not. Only types convertible to int or function/
// function objects are allowed. Therefore, if T is not convertible
// to an int, then we have a function/function object.
template <typename T>
struct is_not_convertible_to_int
: mpl::not_<is_convertible<T, int> >
{};
}
// strings: "hello", lit("hello"), lit(str), lit(f), symbols
struct string_meta_grammar
: proto::or_<
string_literal_meta_grammar
, std_string_meta_grammar
, meta_grammar::compose_function1_eval<
proto::function<
proto::if_<
is_lit_tag<proto::_child, qi::domain>()>
, proto::or_<basic_string_literal_meta_grammar, basic_std_string_meta_grammar>
>
, qi::domain
, mpl::identity<extract_lit_director<mpl::_, mpl::_> >
>
, meta_grammar::function1_rule<
qi::domain
, tag::lit
, lazy_string
, proto::if_<
detail::is_not_convertible_to_int<proto::_child >() >
>
, meta_grammar::terminal_rule<
qi::domain
, symbols_lookup<proto::_>
, symbols_director<>
>
>
{
};
///////////////////////////////////////////////////////////////////////////
// These specializations non-intrusively hooks into the RD meta-grammar.
// (see qi/meta_grammar.hpp)
///////////////////////////////////////////////////////////////////////////
template <typename Expr>
struct is_valid_expr<Expr
, typename enable_if<proto::matches<Expr, string_meta_grammar> >::type>
: mpl::true_
{
};
template <typename Expr>
struct expr_transform<Expr
, typename enable_if<proto::matches<Expr, string_meta_grammar> >::type>
: mpl::identity<string_meta_grammar>
{
};
}}}
#endif

View File

@@ -0,0 +1,297 @@
/*=============================================================================
Copyright (c) 2001-2007 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_SYMBOL_MARCH_11_2007_1055AM)
#define BOOST_SPIRIT_SYMBOL_MARCH_11_2007_1055AM
#include <boost/spirit/home/qi/domain.hpp>
#include <boost/spirit/home/qi/skip.hpp>
#include <boost/spirit/home/qi/string/tst.hpp>
#include <boost/spirit/home/support/modifier.hpp>
#include <boost/spirit/home/qi/detail/assign_to.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/proto/core.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/range.hpp>
#include <boost/type_traits/add_reference.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
#endif
namespace boost { namespace spirit { namespace qi
{
template <typename Filter = tst_pass_through>
struct symbols_director
{
template <typename Component, typename Context, typename Iterator>
struct attribute
{
typedef typename
result_of::subject<Component>::type::ptr_type::element_type::value_type
type;
};
template <
typename Component
, typename Iterator, typename Context
, typename Skipper, typename Attribute>
static bool parse(
Component const& component
, Iterator& first, Iterator const& last
, Context& /*context*/, Skipper const& skipper
, Attribute& attr)
{
typedef typename
result_of::subject<Component>::type::ptr_type::element_type::value_type
value_type;
qi::skip(first, last, skipper);
if (value_type* val_ptr
= fusion::at_c<0>(component.elements)
.lookup->find(first, last, Filter()))
{
detail::assign_to(*val_ptr, attr);
return true;
}
return false;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
// perhaps we should show some of the contents?
return "symbols";
}
};
template <typename Lookup>
struct symbols_lookup
{
typedef shared_ptr<Lookup> ptr_type;
ptr_type lookup;
};
template <typename Char, typename T, typename Lookup = tst<Char, T> >
struct symbols
: proto::extends<
typename proto::terminal<symbols_lookup<Lookup> >::type
, symbols<Char, T>
>
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef shared_ptr<Lookup> ptr_type;
symbols()
: add(*this)
, remove(*this)
{
proto::child(*this).lookup = ptr_type(new Lookup());
}
template <typename Symbols>
symbols(Symbols const& syms)
: add(*this)
, remove(*this)
{
proto::child(*this).lookup = ptr_type(new Lookup());
typename range_const_iterator<Symbols>::type si = boost::begin(syms);
while (si != boost::end(syms))
add(*si++);
}
template <typename Symbols, typename Data>
symbols(Symbols const& syms, Data const& data)
: add(*this)
, remove(*this)
{
proto::child(*this).lookup = ptr_type(new Lookup());
typename range_const_iterator<Symbols>::type si = boost::begin(syms);
typename range_const_iterator<Data>::type di = boost::begin(data);
while (si != boost::end(syms))
add(*si++, *di++);
}
symbols&
operator=(symbols const& rhs)
{
proto::child(*this) = proto::child(rhs);
return *this;
}
void clear()
{
lookup()->clear();
}
struct adder;
struct remover;
adder const&
operator=(Char const* str)
{
lookup()->clear();
return add(str);
}
adder const&
operator+=(Char const* str)
{
return add(str);
}
remover const&
operator-=(Char const* str)
{
return remove(str);
}
ptr_type lookup() const
{
return proto::child(*this).lookup;
}
template <typename F>
void for_each(F f) const
{
lookup()->for_each(f);
}
struct adder
{
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef adder const& type; };
adder(symbols& sym)
: sym(sym)
{
}
template <typename Iterator>
adder const&
operator()(Iterator const& first, Iterator const& last, T const& val = T()) const
{
sym.lookup()->add(first, last, val);
return *this;
}
adder const&
operator()(Char const* s, T const& val = T()) const
{
Char const* last = s;
while (*last)
last++;
sym.lookup()->add(s, last, val);
return *this;
}
adder const&
operator,(Char const* s) const
{
Char const* last = s;
while (*last)
last++;
sym.lookup()->add(s, last, T());
return *this;
}
symbols& sym;
};
struct remover
{
template <typename, typename = unused_type, typename = unused_type>
struct result { typedef adder const& type; };
remover(symbols& sym)
: sym(sym)
{
}
template <typename Iterator>
remover const&
operator()(Iterator const& first, Iterator const& last) const
{
sym.lookup()->remove(first, last);
return *this;
}
remover const&
operator()(Char const* s) const
{
Char const* last = s;
while (*last)
last++;
sym.lookup()->remove(s, last);
return *this;
}
remover const&
operator,(Char const* s) const
{
Char const* last = s;
while (*last)
last++;
sym.lookup()->remove(s, last);
return *this;
}
symbols& sym;
};
adder add;
remover remove;
};
}}}
namespace boost { namespace spirit { namespace traits
{
namespace detail
{
template <typename CharSet>
struct no_case_filter
{
template <typename Char>
Char operator()(Char ch) const
{
return CharSet::tolower(ch);
}
};
}
///////////////////////////////////////////////////////////////////////////
// generator for no-case symbols
///////////////////////////////////////////////////////////////////////////
template <typename Domain, typename Elements, typename Modifier>
struct make_modified_component<Domain, qi::symbols_director<>, Elements, Modifier
, typename enable_if<
is_member_of_modifier<Modifier, spirit::char_class::no_case_base_tag>
>::type
>
{
typedef detail::no_case_filter<typename Modifier::char_set> filter;
typedef component<qi::domain, qi::symbols_director<filter>, Elements> type;
static type
call(Elements const& elements)
{
// we return the same lookup but this time we use a director
// with a filter that converts to lower-case.
return elements;
}
};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,133 @@
/*=============================================================================
Copyright (c) 2001-2007 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_TST_JUNE_03_2007_1031AM)
#define BOOST_SPIRIT_TST_JUNE_03_2007_1031AM
#include <boost/spirit/home/qi/string/detail/tst.hpp>
namespace boost { namespace spirit { namespace qi
{
struct tst_pass_through
{
template <typename Char>
Char operator()(Char ch) const
{
return ch;
}
};
template <typename Char, typename T>
struct tst
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef detail::tst_node<Char, T> node;
tst()
: root(0)
{
}
~tst()
{
clear();
}
tst(tst const& rhs)
: root(0)
{
copy(rhs);
}
tst& operator=(tst const& rhs)
{
return assign(rhs);
}
template <typename Iterator, typename Filter>
T* find(Iterator& first, Iterator last, Filter filter) const
{
return node::find(root, first, last, filter);
}
template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
return find(first, last, tst_pass_through());
}
template <typename Iterator>
bool add(
Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val)
{
return node::add(root, first, last, val, this);
}
template <typename Iterator>
void remove(Iterator first, Iterator last)
{
node::remove(root, first, last, this);
}
void clear()
{
node::destruct_node(root, this);
root = 0;
}
template <typename F>
void for_each(F f) const
{
node::for_each(root, std::basic_string<Char>(), f);
}
private:
friend struct detail::tst_node<Char, T>;
void copy(tst const& rhs)
{
root = node::clone_node(rhs.root, this);
}
tst& assign(tst const& rhs)
{
if (this != &rhs)
{
clear();
copy(rhs);
}
return *this;
}
node* root;
node* new_node(Char id)
{
return new node(id);
}
T* new_data(typename boost::call_traits<T>::param_type val)
{
return new T(val);
}
void delete_node(node* p)
{
delete p;
}
void delete_data(T* p)
{
delete p;
}
};
}}}
#endif

View File

@@ -0,0 +1,211 @@
/*=============================================================================
Copyright (c) 2001-2007 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_TST_MAP_JUNE_03_2007_1143AM)
#define BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM
#include <boost/spirit/home/qi/string/detail/tst.hpp>
#include <boost/unordered_map.hpp>
#include <boost/pool/object_pool.hpp>
namespace boost { namespace spirit { namespace qi
{
struct tst_pass_through; // declared in tst.hpp
template <typename Char, typename T>
struct tst_map
{
typedef Char char_type; // the character type
typedef T value_type; // the value associated with each entry
typedef detail::tst_node<Char, T> node;
tst_map()
{
}
~tst_map()
{
// Nothing to do here.
// The pools do the right thing for us
}
tst_map(tst_map const& rhs)
{
copy(rhs);
}
tst_map& operator=(tst_map const& rhs)
{
return assign(rhs);
}
template <typename Iterator, typename Filter>
T* find(Iterator& first, Iterator last, Filter filter) const
{
if (first != last)
{
Iterator save = first;
typename map_type::const_iterator
i = map.find(filter(*first++));
if (i == map.end())
{
first = save;
return 0;
}
if (T* p = node::find(i->second.root, first, last, filter))
{
return p;
}
return i->second.data;
}
return 0;
}
template <typename Iterator>
T* find(Iterator& first, Iterator last) const
{
return find(first, last, tst_pass_through());
}
template <typename Iterator>
bool add(
Iterator first
, Iterator last
, typename boost::call_traits<T>::param_type val)
{
if (first != last)
{
map_data x = {0, 0};
std::pair<typename map_type::iterator, bool>
r = map.insert(std::pair<Char, map_data>(*first++, x));
if (first != last)
{
return node::add(r.first->second.root, first, last, val, this);
}
else
{
if (r.first->second.data)
return false;
r.first->second.data = this->new_data(val);
}
return true;
}
return false;
}
template <typename Iterator>
void remove(Iterator first, Iterator last)
{
if (first != last)
{
typename map_type::iterator i = map.find(*first++);
if (i != map.end())
{
if (first != last)
{
node::remove(i->second.root, first, last, this);
}
else if (i->second.data)
{
this->delete_data(i->second.data);
i->second.data = 0;
}
if (i->second.data == 0 && i->second.root == 0)
{
map.erase(i);
}
}
}
}
void clear()
{
BOOST_FOREACH(typename map_type::value_type& x, map)
{
node::destruct_node(x.second.root, this);
if (x.second.data)
this->delete_data(x.second.data);
}
map.clear();
}
template <typename F>
void for_each(F f) const
{
BOOST_FOREACH(typename map_type::value_type const& x, map)
{
std::basic_string<Char> s(1, x.first);
node::for_each(x.second.root, s, f);
if (x.second.data)
f(s, *x.second.data);
}
}
private:
friend struct detail::tst_node<Char, T>;
struct map_data
{
node* root;
T* data;
};
typedef unordered_map<Char, map_data> map_type;
void copy(tst_map const& rhs)
{
BOOST_FOREACH(typename map_type::value_type const& x, rhs.map)
{
map_data xx = {node::clone_node(x.second.root, this), 0};
if (x.second.data)
xx.data = data_pool.construct(*x.second.data);
map[x.first] = xx;
}
}
tst_map& assign(tst_map const& rhs)
{
if (this != &rhs)
{
BOOST_FOREACH(typename map_type::value_type& x, map)
{
node::destruct_node(x.second.root, this);
}
map.clear();
copy(rhs);
}
return *this;
}
node* new_node(Char id)
{
return node_pool.construct(id);
}
T* new_data(typename boost::call_traits<T>::param_type val)
{
return data_pool.construct(val);
}
void delete_node(node* p)
{
node_pool.destroy(p);
}
void delete_data(T* p)
{
data_pool.destroy(p);
}
map_type map;
object_pool<node> node_pool;
object_pool<T> data_pool;
};
}}}
#endif

View File

@@ -0,0 +1,34 @@
/*=============================================================================
Copyright (c) 2001-2007 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_WHAT_APRIL_21_2007_0732AM)
#define BOOST_SPIRIT_WHAT_APRIL_21_2007_0732AM
#include <boost/spirit/home/qi/meta_grammar.hpp>
#include <boost/mpl/assert.hpp>
#include <string>
namespace boost { namespace spirit { namespace qi
{
template <typename Expr>
inline std::string what(Expr const& xpr)
{
typedef spirit::traits::is_component<qi::domain, Expr> is_component;
// report invalid expression error as early as possible
BOOST_MPL_ASSERT_MSG(
is_component::value,
xpr_is_not_convertible_to_a_parser, ());
typedef typename result_of::as_component<qi::domain, Expr>::type component;
typedef typename component::director director;
component c = spirit::as_component(qi::domain(), xpr);
return director::what(c, unused);
}
}}}
#endif