stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -0,0 +1,187 @@
/*=============================================================================
Copyright (c) 2001-2003 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_CHSET_HPP
#define BOOST_SPIRIT_CHSET_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/shared_ptr.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
#include <boost/spirit/home/classic/utility/impl/chset/basic_chset.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace utility { namespace impl {
// This is here because some compilers choke on out-of-line member
// template functions. And we don't want to put the whole algorithm
// in the chset constructor in the class definition.
template <typename CharT, typename CharT2>
void construct_chset(boost::shared_ptr<basic_chset<CharT> >& ptr,
CharT2 const* definition);
}} // namespace utility::impl
///////////////////////////////////////////////////////////////////////////////
//
// chset class
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT = char>
class chset: public char_parser<chset<CharT> > {
public:
chset();
chset(chset const& arg_);
explicit chset(CharT arg_);
explicit chset(anychar_parser arg_);
explicit chset(nothing_parser arg_);
explicit chset(chlit<CharT> const& arg_);
explicit chset(range<CharT> const& arg_);
explicit chset(negated_char_parser<chlit<CharT> > const& arg_);
explicit chset(negated_char_parser<range<CharT> > const& arg_);
template <typename CharT2>
explicit chset(CharT2 const* definition)
: ptr(new basic_chset<CharT>())
{
utility::impl::construct_chset(ptr, definition);
}
~chset();
chset& operator=(chset const& rhs);
chset& operator=(CharT rhs);
chset& operator=(anychar_parser rhs);
chset& operator=(nothing_parser rhs);
chset& operator=(chlit<CharT> const& rhs);
chset& operator=(range<CharT> const& rhs);
chset& operator=(negated_char_parser<chlit<CharT> > const& rhs);
chset& operator=(negated_char_parser<range<CharT> > const& rhs);
void set(range<CharT> const& arg_);
void set(negated_char_parser<chlit<CharT> > const& arg_);
void set(negated_char_parser<range<CharT> > const& arg_);
void clear(range<CharT> const& arg_);
void clear(negated_char_parser<range<CharT> > const& arg_);
bool test(CharT ch) const;
chset& inverse();
void swap(chset& x);
chset& operator|=(chset const& x);
chset& operator&=(chset const& x);
chset& operator-=(chset const& x);
chset& operator^=(chset const& x);
private:
boost::shared_ptr<basic_chset<CharT> > ptr;
};
///////////////////////////////////////////////////////////////////////////////
//
// Generator functions
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline chset<CharT>
chset_p(chlit<CharT> const& arg_)
{ return chset<CharT>(arg_); }
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
chset_p(range<CharT> const& arg_)
{ return chset<CharT>(arg_); }
template <typename CharT>
inline chset<CharT>
chset_p(negated_char_parser<chlit<CharT> > const& arg_)
{ return chset<CharT>(arg_); }
template <typename CharT>
inline chset<CharT>
chset_p(negated_char_parser<range<CharT> > const& arg_)
{ return chset<CharT>(arg_); }
//////////////////////////////////
inline chset<char>
chset_p(char const* init)
{ return chset<char>(init); }
//////////////////////////////////
inline chset<wchar_t>
chset_p(wchar_t const* init)
{ return chset<wchar_t>(init); }
//////////////////////////////////
inline chset<char>
chset_p(char ch)
{ return chset<char>(ch); }
//////////////////////////////////
inline chset<wchar_t>
chset_p(wchar_t ch)
{ return chset<wchar_t>(ch); }
//////////////////////////////////
inline chset<int>
chset_p(int ch)
{ return chset<int>(ch); }
//////////////////////////////////
inline chset<unsigned int>
chset_p(unsigned int ch)
{ return chset<unsigned int>(ch); }
//////////////////////////////////
inline chset<short>
chset_p(short ch)
{ return chset<short>(ch); }
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
//////////////////////////////////
inline chset<unsigned short>
chset_p(unsigned short ch)
{ return chset<unsigned short>(ch); }
#endif
//////////////////////////////////
inline chset<long>
chset_p(long ch)
{ return chset<long>(ch); }
//////////////////////////////////
inline chset<unsigned long>
chset_p(unsigned long ch)
{ return chset<unsigned long>(ch); }
#ifdef BOOST_HAS_LONG_LONG
//////////////////////////////////
inline chset< ::boost::long_long_type>
chset_p( ::boost::long_long_type ch)
{ return chset< ::boost::long_long_type>(ch); }
//////////////////////////////////
inline chset< ::boost::ulong_long_type>
chset_p( ::boost::ulong_long_type ch)
{ return chset< ::boost::ulong_long_type>(ch); }
#endif
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
#include <boost/spirit/home/classic/utility/impl/chset.ipp>
#include <boost/spirit/home/classic/utility/chset_operators.hpp>
@@ -0,0 +1,402 @@
/*=============================================================================
Copyright (c) 2001-2003 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_CHSET_OPERATORS_HPP
#define BOOST_SPIRIT_CHSET_OPERATORS_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/utility/chset.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// chset free operators
//
// Where a and b are both chsets, implements:
//
// a | b, a & b, a - b, a ^ b
//
// Where a is a chset, implements:
//
// ~a
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
chset<CharT>
operator~(chset<CharT> const& a);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chset<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chset<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chset<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chset<CharT> const& a, chset<CharT> const& b);
///////////////////////////////////////////////////////////////////////////////
//
// range <--> chset free operators
//
// Where a is a chset and b is a range, and vice-versa, implements:
//
// a | b, a & b, a - b, a ^ b
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chset<CharT> const& a, range<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chset<CharT> const& a, range<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chset<CharT> const& a, range<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chset<CharT> const& a, range<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(range<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(range<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(range<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(range<CharT> const& a, chset<CharT> const& b);
///////////////////////////////////////////////////////////////////////////////
//
// chlit <--> chset free operators
//
// Where a is a chset and b is a chlit, and vice-versa, implements:
//
// a | b, a & b, a - b, a ^ b
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chset<CharT> const& a, chlit<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chset<CharT> const& a, chlit<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chset<CharT> const& a, chlit<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chset<CharT> const& a, chlit<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chlit<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chlit<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chlit<CharT> const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chlit<CharT> const& a, chset<CharT> const& b);
///////////////////////////////////////////////////////////////////////////////
//
// negated_char_parser<range> <--> chset free operators
//
// Where a is a chset and b is a range, and vice-versa, implements:
//
// a | b, a & b, a - b, a ^ b
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b);
///////////////////////////////////////////////////////////////////////////////
//
// negated_char_parser<chlit> <--> chset free operators
//
// Where a is a chset and b is a chlit, and vice-versa, implements:
//
// a | b, a & b, a - b, a ^ b
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b);
///////////////////////////////////////////////////////////////////////////////
//
// literal primitives <--> chset free operators
//
// Where a is a chset and b is a literal primitive,
// and vice-versa, implements:
//
// a | b, a & b, a - b, a ^ b
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chset<CharT> const& a, CharT b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chset<CharT> const& a, CharT b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chset<CharT> const& a, CharT b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chset<CharT> const& a, CharT b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(CharT a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(CharT a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(CharT a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(CharT a, chset<CharT> const& b);
///////////////////////////////////////////////////////////////////////////////
//
// anychar_parser <--> chset free operators
//
// Where a is chset and b is a anychar_parser, and vice-versa, implements:
//
// a | b, a & b, a - b, a ^ b
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chset<CharT> const& a, anychar_parser b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chset<CharT> const& a, anychar_parser b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chset<CharT> const& a, anychar_parser b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chset<CharT> const& a, anychar_parser b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(anychar_parser a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(anychar_parser a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(anychar_parser a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(anychar_parser a, chset<CharT> const& b);
///////////////////////////////////////////////////////////////////////////////
//
// nothing_parser <--> chset free operators
//
// Where a is chset and b is nothing_parser, and vice-versa, implements:
//
// a | b, a & b, a - b, a ^ b
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(chset<CharT> const& a, nothing_parser b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(chset<CharT> const& a, nothing_parser b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(chset<CharT> const& a, nothing_parser b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(chset<CharT> const& a, nothing_parser b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator|(nothing_parser a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator&(nothing_parser a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator-(nothing_parser a, chset<CharT> const& b);
//////////////////////////////////
template <typename CharT>
chset<CharT>
operator^(nothing_parser a, chset<CharT> const& b);
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
#include <boost/spirit/home/classic/utility/impl/chset_operators.ipp>
@@ -0,0 +1,405 @@
/*=============================================================================
Copyright (c) 2002-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_CONFIX_HPP
#define BOOST_SPIRIT_CONFIX_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/config.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/meta/as_parser.hpp>
#include <boost/spirit/home/classic/core/composite/operators.hpp>
#include <boost/spirit/home/classic/utility/confix_fwd.hpp>
#include <boost/spirit/home/classic/utility/impl/confix.ipp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// confix_parser class
//
// Parses a sequence of 3 sub-matches. This class may
// be used to parse structures, where the opening part is possibly
// contained in the expression part and the whole sequence is only
// parsed after seeing the closing part matching the first opening
// subsequence. Example: C-comments:
//
// /* This is a C-comment */
//
///////////////////////////////////////////////////////////////////////////////
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(push)
#pragma warning(disable:4512) //assignment operator could not be generated
#endif
template<typename NestedT = non_nested, typename LexemeT = non_lexeme>
struct confix_parser_gen;
template <
typename OpenT, typename ExprT, typename CloseT, typename CategoryT,
typename NestedT, typename LexemeT
>
struct confix_parser :
public parser<
confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT>
>
{
typedef
confix_parser<OpenT, ExprT, CloseT, CategoryT, NestedT, LexemeT>
self_t;
confix_parser(OpenT const &open_, ExprT const &expr_, CloseT const &close_)
: open(open_), expr(expr_), close(close_)
{}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
return impl::confix_parser_type<CategoryT>::
parse(NestedT(), LexemeT(), *this, scan, open, expr, close);
}
private:
typename as_parser<OpenT>::type::embed_t open;
typename as_parser<ExprT>::type::embed_t expr;
typename as_parser<CloseT>::type::embed_t close;
};
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
#pragma warning(pop)
#endif
///////////////////////////////////////////////////////////////////////////////
//
// Confix parser generator template
//
// This is a helper for generating a correct confix_parser<> from
// auxiliary parameters. There are the following types supported as
// parameters yet: parsers, single characters and strings (see
// as_parser).
//
// If the body parser is an action_parser_category type parser (a parser
// with an attached semantic action) we have to do something special. This
// happens, if the user wrote something like:
//
// confix_p(open, body[f], close)
//
// where 'body' is the parser matching the body of the confix sequence
// and 'f' is a functor to be called after matching the body. If we would
// do nothing, the resulting code would parse the sequence as follows:
//
// start >> (body[f] - close) >> close
//
// what in most cases is not what the user expects.
// (If this _is_ what you've expected, then please use the confix_p
// generator function 'direct()', which will inhibit
// re-attaching the actor to the body parser).
//
// To make the confix parser behave as expected:
//
// start >> (body - close)[f] >> close
//
// the actor attached to the 'body' parser has to be re-attached to the
// (body - close) parser construct, which will make the resulting confix
// parser 'do the right thing'. This refactoring is done by the help of
// the refactoring parsers (see the files refactoring.[hi]pp).
//
// Additionally special care must be taken, if the body parser is a
// unary_parser_category type parser as
//
// confix_p(open, *anychar_p, close)
//
// which without any refactoring would result in
//
// start >> (*anychar_p - close) >> close
//
// and will not give the expected result (*anychar_p will eat up all the
// input up to the end of the input stream). So we have to refactor this
// into:
//
// start >> *(anychar_p - close) >> close
//
// what will give the correct result.
//
// The case, where the body parser is a combination of the two mentioned
// problems (i.e. the body parser is a unary parser with an attached
// action), is handled accordingly too:
//
// confix_p(start, (*anychar_p)[f], end)
//
// will be parsed as expected:
//
// start >> (*(anychar_p - end))[f] >> end.
//
///////////////////////////////////////////////////////////////////////////////
template<typename NestedT, typename LexemeT>
struct confix_parser_gen
{
// Generic generator function for creation of concrete confix parsers
template<typename StartT, typename ExprT, typename EndT>
struct paren_op_result_type
{
typedef confix_parser<
typename as_parser<StartT>::type,
typename as_parser<ExprT>::type,
typename as_parser<EndT>::type,
typename as_parser<ExprT>::type::parser_category_t,
NestedT,
LexemeT
> type;
};
template<typename StartT, typename ExprT, typename EndT>
typename paren_op_result_type<StartT, ExprT, EndT>::type
operator()(StartT const &start_, ExprT const &expr_, EndT const &end_) const
{
typedef typename paren_op_result_type<StartT,ExprT,EndT>::type
return_t;
return return_t(
as_parser<StartT>::convert(start_),
as_parser<ExprT>::convert(expr_),
as_parser<EndT>::convert(end_)
);
}
// Generic generator function for creation of concrete confix parsers
// which have an action directly attached to the ExprT part of the
// parser (see comment above, no automatic refactoring)
template<typename StartT, typename ExprT, typename EndT>
struct direct_result_type
{
typedef confix_parser<
typename as_parser<StartT>::type,
typename as_parser<ExprT>::type,
typename as_parser<EndT>::type,
plain_parser_category, // do not re-attach action
NestedT,
LexemeT
> type;
};
template<typename StartT, typename ExprT, typename EndT>
typename direct_result_type<StartT,ExprT,EndT>::type
direct(StartT const &start_, ExprT const &expr_, EndT const &end_) const
{
typedef typename direct_result_type<StartT,ExprT,EndT>::type
return_t;
return return_t(
as_parser<StartT>::convert(start_),
as_parser<ExprT>::convert(expr_),
as_parser<EndT>::convert(end_)
);
}
};
///////////////////////////////////////////////////////////////////////////////
//
// Predefined non_nested confix parser generators
//
///////////////////////////////////////////////////////////////////////////////
const confix_parser_gen<non_nested, non_lexeme> confix_p =
confix_parser_gen<non_nested, non_lexeme>();
///////////////////////////////////////////////////////////////////////////////
//
// Comments are special types of confix parsers
//
// Comment parser generator template. This is a helper for generating a
// correct confix_parser<> from auxiliary parameters, which is able to
// parse comment constructs: (StartToken >> Comment text >> EndToken).
//
// There are the following types supported as parameters yet: parsers,
// single characters and strings (see as_parser).
//
// There are two diffenerent predefined comment parser generators
// (comment_p and comment_nest_p, see below), which may be used for
// creating special comment parsers in two different ways.
//
// If these are used with one parameter, a comment starting with the given
// first parser parameter up to the end of the line is matched. So for
// instance the following parser matches C++ style comments:
//
// comment_p("//").
//
// If these are used with two parameters, a comment starting with the
// first parser parameter up to the second parser parameter is matched.
// For instance a C style comment parser should be constrcuted as:
//
// comment_p("/*", "*/").
//
// Please note, that a comment is parsed implicitly as if the whole
// comment_p(...) statement were embedded into a lexeme_d[] directive.
//
///////////////////////////////////////////////////////////////////////////////
template<typename NestedT>
struct comment_parser_gen
{
// Generic generator function for creation of concrete comment parsers
// from an open token. The newline parser eol_p is used as the
// closing token.
template<typename StartT>
struct paren_op1_result_type
{
typedef confix_parser<
typename as_parser<StartT>::type,
kleene_star<anychar_parser>,
alternative<eol_parser, end_parser>,
unary_parser_category, // there is no action to re-attach
NestedT,
is_lexeme // insert implicit lexeme_d[]
>
type;
};
template<typename StartT>
typename paren_op1_result_type<StartT>::type
operator() (StartT const &start_) const
{
typedef typename paren_op1_result_type<StartT>::type
return_t;
return return_t(
as_parser<StartT>::convert(start_),
*anychar_p,
eol_p | end_p
);
}
// Generic generator function for creation of concrete comment parsers
// from an open and a close tokens.
template<typename StartT, typename EndT>
struct paren_op2_result_type
{
typedef confix_parser<
typename as_parser<StartT>::type,
kleene_star<anychar_parser>,
typename as_parser<EndT>::type,
unary_parser_category, // there is no action to re-attach
NestedT,
is_lexeme // insert implicit lexeme_d[]
> type;
};
template<typename StartT, typename EndT>
typename paren_op2_result_type<StartT,EndT>::type
operator() (StartT const &start_, EndT const &end_) const
{
typedef typename paren_op2_result_type<StartT,EndT>::type
return_t;
return return_t(
as_parser<StartT>::convert(start_),
*anychar_p,
as_parser<EndT>::convert(end_)
);
}
};
///////////////////////////////////////////////////////////////////////////////
//
// Predefined non_nested comment parser generator
//
///////////////////////////////////////////////////////////////////////////////
const comment_parser_gen<non_nested> comment_p =
comment_parser_gen<non_nested>();
///////////////////////////////////////////////////////////////////////////////
//
// comment_nest_parser class
//
// Parses a nested comments.
// Example: nested PASCAL-comments:
//
// { This is a { nested } PASCAL-comment }
//
///////////////////////////////////////////////////////////////////////////////
template<typename OpenT, typename CloseT>
struct comment_nest_parser:
public parser<comment_nest_parser<OpenT, CloseT> >
{
typedef comment_nest_parser<OpenT, CloseT> self_t;
comment_nest_parser(OpenT const &open_, CloseT const &close_):
open(open_), close(close_)
{}
template<typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const &scan) const
{
return do_parse(
open >> *(*this | (anychar_p - close)) >> close,
scan);
}
private:
template<typename ParserT, typename ScannerT>
typename parser_result<self_t, ScannerT>::type
do_parse(ParserT const &p, ScannerT const &scan) const
{
return
impl::contiguous_parser_parse<
typename parser_result<ParserT, ScannerT>::type
>(p, scan, scan);
}
typename as_parser<OpenT>::type::embed_t open;
typename as_parser<CloseT>::type::embed_t close;
};
///////////////////////////////////////////////////////////////////////////////
//
// Predefined nested comment parser generator
//
///////////////////////////////////////////////////////////////////////////////
template<typename OpenT, typename CloseT>
struct comment_nest_p_result
{
typedef comment_nest_parser<
typename as_parser<OpenT>::type,
typename as_parser<CloseT>::type
> type;
};
template<typename OpenT, typename CloseT>
inline typename comment_nest_p_result<OpenT,CloseT>::type
comment_nest_p(OpenT const &open, CloseT const &close)
{
typedef typename comment_nest_p_result<OpenT,CloseT>::type
result_t;
return result_t(
as_parser<OpenT>::convert(open),
as_parser<CloseT>::convert(close)
);
}
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,39 @@
/*=============================================================================
Copyright (c) 2006 Tobias Schwinger
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_CONFIX_FWD_HPP)
#define BOOST_SPIRIT_CONFIX_FWD_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
struct is_nested;
struct non_nested;
struct is_lexeme;
struct non_lexeme;
template <
typename OpenT, typename ExprT, typename CloseT,
typename CategoryT = plain_parser_category,
typename NestedT = non_nested, typename LexemeT = non_lexeme
>
struct confix_parser;
template<typename OpenT, typename CloseT>
struct comment_nest_parser;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,229 @@
/*=============================================================================
Copyright (c) 1998-2003 Joel de Guzman
Copyright (c) 2003 Vaclav Vesely
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_DISTINCT_HPP)
#define BOOST_SPIRIT_DISTINCT_HPP
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/primitives/primitives.hpp>
#include <boost/spirit/home/classic/core/composite/operators.hpp>
#include <boost/spirit/home/classic/core/composite/directives.hpp>
#include <boost/spirit/home/classic/core/composite/epsilon.hpp>
#include <boost/spirit/home/classic/core/non_terminal/rule.hpp>
#include <boost/spirit/home/classic/utility/chset.hpp>
#include <boost/spirit/home/classic/utility/distinct_fwd.hpp>
namespace boost {
namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
//-----------------------------------------------------------------------------
// distinct_parser class
template <typename CharT, typename TailT>
class distinct_parser
{
public:
typedef
contiguous<
sequence<
chseq<CharT const*>,
negated_empty_match_parser<
TailT
>
>
>
result_t;
distinct_parser()
: tail(chset<CharT>())
{
}
explicit distinct_parser(parser<TailT> const & tail_)
: tail(tail_.derived())
{
}
explicit distinct_parser(CharT const* letters)
: tail(chset_p(letters))
{
}
result_t operator()(CharT const* str) const
{
return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)];
}
TailT tail;
};
//-----------------------------------------------------------------------------
// distinct_directive class
template <typename CharT, typename TailT>
class distinct_directive
{
public:
template<typename ParserT>
struct result {
typedef
contiguous<
sequence<
ParserT,
negated_empty_match_parser<
TailT
>
>
>
type;
};
distinct_directive()
: tail(chset<CharT>())
{
}
explicit distinct_directive(CharT const* letters)
: tail(chset_p(letters))
{
}
explicit distinct_directive(parser<TailT> const & tail_)
: tail(tail_.derived())
{
}
template<typename ParserT>
typename result<typename as_parser<ParserT>::type>::type
operator[](ParserT const &subject) const
{
return
lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)];
}
TailT tail;
};
//-----------------------------------------------------------------------------
// dynamic_distinct_parser class
template <typename ScannerT>
class dynamic_distinct_parser
{
public:
typedef typename ScannerT::value_t char_t;
typedef
rule<
typename no_actions_scanner<
typename lexeme_scanner<ScannerT>::type
>::type
>
tail_t;
typedef
contiguous<
sequence<
chseq<char_t const*>,
negated_empty_match_parser<
tail_t
>
>
>
result_t;
dynamic_distinct_parser()
: tail(nothing_p)
{
}
template<typename ParserT>
explicit dynamic_distinct_parser(parser<ParserT> const & tail_)
: tail(tail_.derived())
{
}
explicit dynamic_distinct_parser(char_t const* letters)
: tail(chset_p(letters))
{
}
result_t operator()(char_t const* str) const
{
return lexeme_d[chseq_p(str) >> ~epsilon_p(tail)];
}
tail_t tail;
};
//-----------------------------------------------------------------------------
// dynamic_distinct_directive class
template <typename ScannerT>
class dynamic_distinct_directive
{
public:
typedef typename ScannerT::value_t char_t;
typedef
rule<
typename no_actions_scanner<
typename lexeme_scanner<ScannerT>::type
>::type
>
tail_t;
template<typename ParserT>
struct result {
typedef
contiguous<
sequence<
ParserT,
negated_empty_match_parser<
tail_t
>
>
>
type;
};
dynamic_distinct_directive()
: tail(nothing_p)
{
}
template<typename ParserT>
explicit dynamic_distinct_directive(parser<ParserT> const & tail_)
: tail(tail_.derived())
{
}
explicit dynamic_distinct_directive(char_t const* letters)
: tail(chset_p(letters))
{
}
template<typename ParserT>
typename result<typename as_parser<ParserT>::type>::type
operator[](ParserT const &subject) const
{
return
lexeme_d[as_parser<ParserT>::convert(subject) >> ~epsilon_p(tail)];
}
tail_t tail;
};
//-----------------------------------------------------------------------------
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
} // namespace spirit
} // namespace boost
#endif // !defined(BOOST_SPIRIT_DISTINCT_HPP)
@@ -0,0 +1,37 @@
/*=============================================================================
Copyright (c) 2006 Tobias Schwinger
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_DISTINCT_FWD_HPP)
#define BOOST_SPIRIT_DISTINCT_FWD_HPP
#include <boost/spirit/home/classic/namespace.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
template<typename CharT> class chset;
template <typename CharT = char, typename TailT = chset<CharT> >
class distinct_parser;
template <typename CharT = char, typename TailT = chset<CharT> >
class distinct_directive;
template <typename ScannerT = scanner<> >
class dynamic_distinct_parser;
template <typename ScannerT = scanner<> >
class dynamic_distinct_directive;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,184 @@
/*=============================================================================
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_ESCAPE_CHAR_HPP
#define BOOST_SPIRIT_ESCAPE_CHAR_HPP
///////////////////////////////////////////////////////////////////////////////
#include <string>
#include <iterator>
#include <cctype>
#include <boost/limits.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/debug.hpp>
#include <boost/spirit/home/classic/utility/escape_char_fwd.hpp>
#include <boost/spirit/home/classic/utility/impl/escape_char.ipp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// escape_char_action class
//
// Links an escape char parser with a user defined semantic action.
// The semantic action may be a function or a functor. A function
// should be compatible with the interface:
//
// void f(CharT ch);
//
// A functor should have a member operator() with a compatible signature
// as above. The matching character is passed into the function/functor.
// This is the default class that character parsers use when dealing with
// the construct:
//
// p[f]
//
// where p is a parser and f is a function or functor.
//
///////////////////////////////////////////////////////////////////////////////
template <
typename ParserT, typename ActionT,
unsigned long Flags, typename CharT
>
struct escape_char_action
: public unary<ParserT,
parser<escape_char_action<ParserT, ActionT, Flags, CharT> > >
{
typedef escape_char_action
<ParserT, ActionT, Flags, CharT> self_t;
typedef action_parser_category parser_category_t;
typedef unary<ParserT, parser<self_t> > base_t;
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, CharT>::type type;
};
escape_char_action(ParserT const& p, ActionT const& a)
: base_t(p), actor(a) {}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
return impl::escape_char_action_parse<Flags, CharT>::
parse(scan, *this);
}
ActionT const& predicate() const { return actor; }
private:
ActionT actor;
};
///////////////////////////////////////////////////////////////////////////////
//
// escape_char_parser class
//
// The escape_char_parser helps in conjunction with the escape_char_action
// template class (see above) in parsing escaped characters. There are two
// different variants of this parser: one for parsing C style escaped
// characters and one for parsing LEX style escaped characters.
//
// The C style escaped character parser is generated, when the template
// parameter 'Flags' is equal to 'c_escapes' (a constant defined in the
// file impl/escape_char.ipp). This parser recognizes all valid C escape
// character sequences: '\t', '\b', '\f', '\n', '\r', '\"', '\'', '\\'
// and the numeric style escapes '\120' (octal) and '\x2f' (hexadecimal)
// and converts these to their character equivalent, for instance the
// sequence of a backslash and a 'b' is parsed as the character '\b'.
// All other escaped characters are rejected by this parser.
//
// The LEX style escaped character parser is generated, when the template
// parameter 'Flags' is equal to 'lex_escapes' (a constant defined in the
// file impl/escape_char.ipp). This parser recognizes all the C style
// escaped character sequences (as described above) and additionally
// does not reject all other escape sequences. All not mentioned escape
// sequences are converted by the parser to the plain character, for
// instance '\a' will be parsed as 'a'.
//
// All not escaped characters are parsed without modification.
//
///////////////////////////////////////////////////////////////////////////////
template <unsigned long Flags, typename CharT>
struct escape_char_action_parser_gen;
template <unsigned long Flags, typename CharT>
struct escape_char_parser :
public parser<escape_char_parser<Flags, CharT> > {
// only the values c_escapes and lex_escapes are valid for Flags
BOOST_STATIC_ASSERT(Flags == c_escapes || Flags == lex_escapes);
typedef escape_char_parser<Flags, CharT> self_t;
typedef
escape_char_action_parser_gen<Flags, CharT>
action_parser_generator_t;
template <typename ScannerT>
struct result {
typedef typename match_result<ScannerT, CharT>::type type;
};
template <typename ActionT>
escape_char_action<self_t, ActionT, Flags, CharT>
operator[](ActionT const& actor) const
{
return escape_char_action<self_t, ActionT, Flags, CharT>(*this, actor);
}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const &scan) const
{
return impl::escape_char_parse<CharT>::parse(scan, *this);
}
};
template <unsigned long Flags, typename CharT>
struct escape_char_action_parser_gen {
template <typename ParserT, typename ActionT>
static escape_char_action<ParserT, ActionT, Flags, CharT>
generate (ParserT const &p, ActionT const &actor)
{
typedef
escape_char_action<ParserT, ActionT, Flags, CharT>
action_parser_t;
return action_parser_t(p, actor);
}
};
///////////////////////////////////////////////////////////////////////////////
//
// predefined escape_char_parser objects
//
// These objects should be used for generating correct escaped character
// parsers.
//
///////////////////////////////////////////////////////////////////////////////
const escape_char_parser<lex_escapes> lex_escape_ch_p =
escape_char_parser<lex_escapes>();
const escape_char_parser<c_escapes> c_escape_ch_p =
escape_char_parser<c_escapes>();
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,30 @@
/*=============================================================================
Copyright (c) 2006 Tobias Schwinger
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_ESCAPE_CHAR_FWD_HPP)
#define BOOST_SPIRIT_ESCAPE_CHAR_FWD_HPP
#include <boost/spirit/home/classic/namespace.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
template <unsigned long Flags, typename CharT = char>
struct escape_char_parser;
template <
class ParserT, typename ActionT,
unsigned long Flags, typename CharT = char>
struct escape_char_action;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,77 @@
/*=============================================================================
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_FLUSH_MULTI_PASS_HPP
#define BOOST_SPIRIT_FLUSH_MULTI_PASS_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core.hpp>
#include <boost/spirit/home/classic/iterator/multi_pass.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace impl {
template <typename T>
void flush_iterator(T &) {}
template <typename T1, typename T2, typename T3, typename T4>
void flush_iterator(BOOST_SPIRIT_CLASSIC_NS::multi_pass<
T1, T2, T3, T4, BOOST_SPIRIT_CLASSIC_NS::multi_pass_policies::std_deque> &i)
{
i.clear_queue();
}
} // namespace impl
///////////////////////////////////////////////////////////////////////////
//
// flush_multi_pass_parser
//
// The flush_multi_pass_parser flushes an underlying
// multi_pass_iterator during the normal parsing process. This may
// be used at certain points during the parsing process, when it is
// clear, that no backtracking is needed anymore and the input
// gathered so far may be discarded.
//
///////////////////////////////////////////////////////////////////////////
class flush_multi_pass_parser
: public parser<flush_multi_pass_parser>
{
public:
typedef flush_multi_pass_parser this_t;
template <typename ScannerT>
typename parser_result<this_t, ScannerT>::type
parse(ScannerT const& scan) const
{
impl::flush_iterator(scan.first);
return scan.empty_match();
}
};
///////////////////////////////////////////////////////////////////////////
//
// predefined flush_multi_pass_p object
//
// This object should may used to flush a multi_pass_iterator along
// the way during the normal parsing process.
//
///////////////////////////////////////////////////////////////////////////
flush_multi_pass_parser const
flush_multi_pass_p = flush_multi_pass_parser();
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_FLUSH_MULTI_PASS_HPP
@@ -0,0 +1,69 @@
/*=============================================================================
Copyright (c) 2002-2003 Joel de Guzman
Copyright (c) 2002-2003 Juan Carlos Arevalo-Baeza
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_FUNCTOR_PARSER_HPP
#define BOOST_SPIRIT_FUNCTOR_PARSER_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////
//
// functor_parser class
//
// Once a functor parser has been defined, you can build a real
// parser from it by passing it to this class as the template
// parameter.
//
///////////////////////////////////////////////////////////////////////////
template < class FunctorT >
struct functor_parser : public parser<functor_parser<FunctorT> >
{
FunctorT functor;
functor_parser(): functor() {}
functor_parser(FunctorT const& functor_): functor(functor_) {}
typedef typename FunctorT::result_t functor_result_t;
typedef functor_parser<FunctorT> self_t;
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, functor_result_t>::type
type;
};
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
typedef typename ScannerT::iterator_t iterator_t;
iterator_t const s(scan.first);
functor_result_t functor_result;
std::ptrdiff_t len = functor(scan, functor_result);
if (len < 0)
return scan.no_match();
else
return scan.create_match(std::size_t(len), functor_result, s, scan.first);
}
};
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,307 @@
/*=============================================================================
Copyright (c) 2003 Hartmut Kaiser
Copyright (c) 2003 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_GRAMMAR_DEF_HPP)
#define BOOST_SPIRIT_GRAMMAR_DEF_HPP
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/enum.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/repeat_from_to.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/phoenix/tuples.hpp>
#include <boost/spirit/home/classic/core/assert.hpp>
#include <boost/spirit/home/classic/utility/grammar_def_fwd.hpp>
///////////////////////////////////////////////////////////////////////////////
//
// Spirit predefined maximum grammar start parser limit. This limit defines
// the maximum number of possible different parsers exposed from a
// particular grammar. This number defaults to 3.
// The actual maximum is rounded up in multiples of 3. Thus, if this value
// is 4, the actual limit is 6. The ultimate maximum limit in this
// implementation is 15.
//
// It should NOT be greater than PHOENIX_LIMIT!
//
///////////////////////////////////////////////////////////////////////////////
#if !defined(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT)
#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT PHOENIX_LIMIT
#endif
///////////////////////////////////////////////////////////////////////////////
//
// ensure BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= PHOENIX_LIMIT and
// BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= 15 and
// BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 0
//
///////////////////////////////////////////////////////////////////////////////
BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= PHOENIX_LIMIT);
BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT <= 15);
BOOST_STATIC_ASSERT(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 0);
//////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
struct same {};
///////////////////////////////////////////////////////////////////////////////
namespace impl {
///////////////////////////////////////////////////////////////////////////
//
// The make_const_pointer meta function allows to generate a T const*
// needed to store the pointer to a given start parser from a grammar.
//
///////////////////////////////////////////////////////////////////////////
template <typename T0, typename T = T0>
struct make_const_pointer {
private:
// T0 shouldn't be of type 'same'
BOOST_STATIC_ASSERT((!boost::is_same<T0, same>::value));
typedef typename boost::mpl::if_c<
boost::is_same<T, same>::value,
T0 const *,
T const *
>::type
ptr_type;
public:
// If the type in question is phoenix::nil_t, then the returned type
// is still phoenix::nil_t, otherwise a constant pointer type to the
// inspected type is returned.
typedef typename boost::mpl::if_c<
boost::is_same<T, ::phoenix::nil_t>::value,
::phoenix::nil_t,
ptr_type
>::type
type;
};
///////////////////////////////////////////////////////////////////////////
template <int N, typename ElementT>
struct assign_zero_to_tuple_member {
template <typename TupleT>
static void do_(TupleT &t) { t[::phoenix::tuple_index<N>()] = 0; }
};
template <int N>
struct assign_zero_to_tuple_member<N, ::phoenix::nil_t> {
template <typename TupleT>
static void do_(TupleT& /*t*/) {}
};
struct phoenix_nil_type {
typedef ::phoenix::nil_t type;
};
template <int N>
struct init_tuple_member {
template <typename TupleT>
static void
do_(TupleT &t)
{
typedef typename boost::mpl::eval_if_c<
(N < TupleT::length),
::phoenix::tuple_element<N, TupleT>,
phoenix_nil_type
>::type
element_type;
assign_zero_to_tuple_member<N, element_type>::do_(t);
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
//
// grammar_def class
//
// This class may be used as a base class for the embedded definition
// class inside the grammar<> derived user grammar.
// It exposes the two functions needed for start rule access:
//
// rule<> const &start() const;
//
// and
//
// template <int N>
// rule<> const *get_start_parser() const;
//
// Additionally it exposes a set o 'start_parsers' functions, which are to
// be called by the user to define the parsers to use as start parsers
// of the given grammar.
//
///////////////////////////////////////////////////////////////////////////////
template <
typename T,
BOOST_PP_ENUM_PARAMS(
BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A), typename T)
>
class grammar_def {
private:
///////////////////////////////////////////////////////////////////////////
//
// This generates the full tuple type from the given template parameters
// T, T0, ...
//
// typedef ::phoenix::tuple<
// typename impl::make_const_pointer<T>::type,
// typename impl::make_const_pointer<T, T0>::type,
// ...
// > tuple_t;
//
///////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM(z, N, _) \
typename impl::make_const_pointer<T, BOOST_PP_CAT(T, N)>::type \
/**/
typedef ::phoenix::tuple<
typename impl::make_const_pointer<T>::type,
BOOST_PP_ENUM(
BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A),
BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM,
_
)
> tuple_t;
#undef BOOST_SPIRIT_GRAMMARDEF_TUPLE_PARAM
///////////////////////////////////////////////////////////////////////////
protected:
///////////////////////////////////////////////////////////////////////////
//
// This generates a sequence of 'start_parsers' functions with increasing
// number of arguments, which allow to initialize the tuple members with
// the pointers to the start parsers of the grammar:
//
// template <typename TC0, ...>
// void start_parsers (TC0 const &t0, ...)
// {
// using ::phoenix::tuple_index_names::_1;
// t[_1] = &t0;
// ...
// }
//
// where a TC0 const* must be convertible to a T0 const*
//
///////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS(z, N, _) \
BOOST_PP_CAT(TC, N) const &BOOST_PP_CAT(t, N) \
/**/
#define BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN(z, N, _) \
using ::phoenix::tuple_index_names::BOOST_PP_CAT(_, BOOST_PP_INC(N)); \
t[BOOST_PP_CAT(_, BOOST_PP_INC(N))] = &BOOST_PP_CAT(t, N); \
/**/
#define BOOST_SPIRIT_GRAMMARDEF_ENUM_START(z, N, _) \
template <BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), typename TC)> \
void \
start_parsers(BOOST_PP_ENUM_ ## z(BOOST_PP_INC(N), \
BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS, _) ) \
{ \
BOOST_PP_REPEAT_ ## z(BOOST_PP_INC(N), \
BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN, _) \
} \
/**/
BOOST_PP_REPEAT(
BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A,
BOOST_SPIRIT_GRAMMARDEF_ENUM_START, _)
#undef BOOST_SPIRIT_GRAMMARDEF_ENUM_START
#undef BOOST_SPIRIT_GRAMMARDEF_ENUM_ASSIGN
#undef BOOST_SPIRIT_GRAMMARDEF_ENUM_PARAMS
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
//
// This generates some initialization code, which allows to initialize all
// used tuple members to 0 (zero):
//
// t[_1] = 0;
// impl::init_tuple_member<1>::do_(t);
// ...
//
///////////////////////////////////////////////////////////////////////////
#define BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT(z, N, _) \
impl::init_tuple_member<N>::do_(t); \
/**/
grammar_def()
{
using ::phoenix::tuple_index_names::_1;
t[_1] = 0;
BOOST_PP_REPEAT_FROM_TO(
1, BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A,
BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT, _)
}
#undef BOOST_SPIRIT_GRAMMARDEF_ENUM_INIT
///////////////////////////////////////////////////////////////////////////
public:
T const &
start() const
{
// If the following assertion is fired, you have probably forgot to call
// the start_parser() function from inside the constructor of your
// embedded definition class to initialize the start parsers to be exposed
// from your grammar.
using ::phoenix::tuple_index_names::_1;
BOOST_SPIRIT_ASSERT(0 != t[_1]);
return *t[_1];
}
template <int N>
typename ::phoenix::tuple_element<N, tuple_t>::crtype
get_start_parser() const
{
// If the following expression yields a compiler error, you have probably
// tried to access a start rule, which isn't exposed as such from your
// grammar.
BOOST_STATIC_ASSERT(N > 0 && N < tuple_t::length);
// If the following assertion is fired, you have probably forgot to call
// the start_parser() function from inside the constructor of your
// embedded definition class to initialize the start parsers to be exposed
// from your grammar.
// Another reason may be, that there is a count mismatch between
// the number of template parameters to the grammar_def<> class and the
// number of parameters used while calling start_parsers().
BOOST_SPIRIT_ASSERT(0 != t[::phoenix::tuple_index<N>()]);
return t[::phoenix::tuple_index<N>()];
}
private:
tuple_t t;
};
#undef BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_GRAMMAR_DEF_HPP
@@ -0,0 +1,52 @@
/*=============================================================================
Copyright (c) 2006 Tobias Schwinger
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_GRAMMAR_DEF_FWD_HPP)
#define BOOST_SPIRIT_GRAMMAR_DEF_FWD_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/phoenix/tuples.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#if !defined(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT)
#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT PHOENIX_LIMIT
#endif
// Calculate an integer rounded up to the nearest integer dividable by 3
#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 12
#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 15
#elif BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 9
#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 12
#elif BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 6
#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 9
#elif BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 3
#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 6
#else
#define BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A 3
#endif
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
template <
typename T,
BOOST_PP_ENUM_BINARY_PARAMS(
BOOST_PP_DEC(BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT_A),
typename T, = ::phoenix::nil_t BOOST_PP_INTERCEPT
)
>
class grammar_def;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,322 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
Copyright (c) 2001-2003 Daniel Nuffer
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the 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_CHSET_IPP
#define BOOST_SPIRIT_CHSET_IPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/limits.hpp>
#include <boost/spirit/home/classic/utility/chset.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// chset class
//
///////////////////////////////////////////////////////////////////////////////
namespace utility { namespace impl {
template <typename CharT>
inline void
detach(boost::shared_ptr<basic_chset<CharT> >& ptr)
{
if (!ptr.unique())
ptr = boost::shared_ptr<basic_chset<CharT> >
(new basic_chset<CharT>(*ptr));
}
template <typename CharT>
inline void
detach_clear(boost::shared_ptr<basic_chset<CharT> >& ptr)
{
if (ptr.unique())
ptr->clear();
else
ptr.reset(new basic_chset<CharT>());
}
template <typename CharT, typename CharT2>
void construct_chset(boost::shared_ptr<basic_chset<CharT> >& ptr,
CharT2 const* definition)
{
CharT2 ch = *definition++;
while (ch)
{
CharT2 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;
}
}
}} // namespace utility::impl
template <typename CharT>
inline chset<CharT>::chset()
: ptr(new basic_chset<CharT>()) {}
template <typename CharT>
inline chset<CharT>::chset(chset const& arg_)
: ptr(new basic_chset<CharT>(*arg_.ptr)) {}
template <typename CharT>
inline chset<CharT>::chset(CharT arg_)
: ptr(new basic_chset<CharT>())
{ ptr->set(arg_); }
template <typename CharT>
inline chset<CharT>::chset(anychar_parser /*arg*/)
: ptr(new basic_chset<CharT>())
{
ptr->set(
(std::numeric_limits<CharT>::min)(),
(std::numeric_limits<CharT>::max)()
);
}
template <typename CharT>
inline chset<CharT>::chset(nothing_parser /*arg_*/)
: ptr(new basic_chset<CharT>()) {}
template <typename CharT>
inline chset<CharT>::chset(chlit<CharT> const& arg_)
: ptr(new basic_chset<CharT>())
{ ptr->set(arg_.ch); }
template <typename CharT>
inline chset<CharT>::chset(range<CharT> const& arg_)
: ptr(new basic_chset<CharT>())
{ ptr->set(arg_.first, arg_.last); }
template <typename CharT>
inline chset<CharT>::chset(negated_char_parser<chlit<CharT> > const& arg_)
: ptr(new basic_chset<CharT>())
{
set(arg_);
}
template <typename CharT>
inline chset<CharT>::chset(negated_char_parser<range<CharT> > const& arg_)
: ptr(new basic_chset<CharT>())
{
set(arg_);
}
template <typename CharT>
inline chset<CharT>::~chset() {}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator=(chset const& rhs)
{
ptr = rhs.ptr;
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator=(CharT rhs)
{
utility::impl::detach_clear(ptr);
ptr->set(rhs);
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator=(anychar_parser /*rhs*/)
{
utility::impl::detach_clear(ptr);
ptr->set(
(std::numeric_limits<CharT>::min)(),
(std::numeric_limits<CharT>::max)()
);
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator=(nothing_parser /*rhs*/)
{
utility::impl::detach_clear(ptr);
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator=(chlit<CharT> const& rhs)
{
utility::impl::detach_clear(ptr);
ptr->set(rhs.ch);
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator=(range<CharT> const& rhs)
{
utility::impl::detach_clear(ptr);
ptr->set(rhs.first, rhs.last);
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator=(negated_char_parser<chlit<CharT> > const& rhs)
{
utility::impl::detach_clear(ptr);
set(rhs);
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator=(negated_char_parser<range<CharT> > const& rhs)
{
utility::impl::detach_clear(ptr);
set(rhs);
return *this;
}
template <typename CharT>
inline void
chset<CharT>::set(range<CharT> const& arg_)
{
utility::impl::detach(ptr);
ptr->set(arg_.first, arg_.last);
}
template <typename CharT>
inline void
chset<CharT>::set(negated_char_parser<chlit<CharT> > const& arg_)
{
utility::impl::detach(ptr);
if(arg_.positive.ch != (std::numeric_limits<CharT>::min)()) {
ptr->set((std::numeric_limits<CharT>::min)(), arg_.positive.ch - 1);
}
if(arg_.positive.ch != (std::numeric_limits<CharT>::max)()) {
ptr->set(arg_.positive.ch + 1, (std::numeric_limits<CharT>::max)());
}
}
template <typename CharT>
inline void
chset<CharT>::set(negated_char_parser<range<CharT> > const& arg_)
{
utility::impl::detach(ptr);
if(arg_.positive.first != (std::numeric_limits<CharT>::min)()) {
ptr->set((std::numeric_limits<CharT>::min)(), arg_.positive.first - 1);
}
if(arg_.positive.last != (std::numeric_limits<CharT>::max)()) {
ptr->set(arg_.positive.last + 1, (std::numeric_limits<CharT>::max)());
}
}
template <typename CharT>
inline void
chset<CharT>::clear(range<CharT> const& arg_)
{
utility::impl::detach(ptr);
ptr->clear(arg_.first, arg_.last);
}
template <typename CharT>
inline void
chset<CharT>::clear(negated_char_parser<range<CharT> > const& arg_)
{
utility::impl::detach(ptr);
if(arg_.positive.first != (std::numeric_limits<CharT>::min)()) {
ptr->clear((std::numeric_limits<CharT>::min)(), arg_.positive.first - 1);
}
if(arg_.positive.last != (std::numeric_limits<CharT>::max)()) {
ptr->clear(arg_.positive.last + 1, (std::numeric_limits<CharT>::max)());
}
}
template <typename CharT>
inline bool
chset<CharT>::test(CharT ch) const
{ return ptr->test(ch); }
template <typename CharT>
inline chset<CharT>&
chset<CharT>::inverse()
{
utility::impl::detach(ptr);
ptr->inverse();
return *this;
}
template <typename CharT>
inline void
chset<CharT>::swap(chset& x)
{ ptr.swap(x.ptr); }
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator|=(chset const& x)
{
utility::impl::detach(ptr);
*ptr |= *x.ptr;
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator&=(chset const& x)
{
utility::impl::detach(ptr);
*ptr &= *x.ptr;
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator-=(chset const& x)
{
utility::impl::detach(ptr);
*ptr -= *x.ptr;
return *this;
}
template <typename CharT>
inline chset<CharT>&
chset<CharT>::operator^=(chset const& x)
{
utility::impl::detach(ptr);
*ptr ^= *x.ptr;
return *this;
}
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif
@@ -0,0 +1,107 @@
/*=============================================================================
Copyright (c) 2001-2003 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_HPP
#define BOOST_SPIRIT_BASIC_CHSET_HPP
///////////////////////////////////////////////////////////////////////////////
#include <bitset>
#include <climits>
#include <boost/spirit/home/classic/utility/impl/chset/range_run.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: basic character set implementation using range_run
//
///////////////////////////////////////////////////////////////////////////
template <typename CharT>
class basic_chset
{
public:
basic_chset();
basic_chset(basic_chset const& arg_);
bool test(CharT v) const;
void set(CharT from, CharT to);
void set(CharT c);
void clear(CharT from, CharT to);
void clear(CharT c);
void clear();
void inverse();
void swap(basic_chset& x);
basic_chset& operator|=(basic_chset const& x);
basic_chset& operator&=(basic_chset const& x);
basic_chset& operator-=(basic_chset const& x);
basic_chset& operator^=(basic_chset const& x);
private: utility::impl::range_run<CharT> rr;
};
#if (CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////
//
// basic_chset: specializations for 8 bit chars using std::bitset
//
///////////////////////////////////////////////////////////////////////////
template <typename CharT>
class basic_chset_8bit {
public:
basic_chset_8bit();
basic_chset_8bit(basic_chset_8bit const& arg_);
bool test(CharT v) const;
void set(CharT from, CharT to);
void set(CharT c);
void clear(CharT from, CharT to);
void clear(CharT c);
void clear();
void inverse();
void swap(basic_chset_8bit& x);
basic_chset_8bit& operator|=(basic_chset_8bit const& x);
basic_chset_8bit& operator&=(basic_chset_8bit const& x);
basic_chset_8bit& operator-=(basic_chset_8bit const& x);
basic_chset_8bit& operator^=(basic_chset_8bit const& x);
private: std::bitset<256> bset;
};
/////////////////////////////////
template <>
class basic_chset<char>
: public basic_chset_8bit<char> {};
/////////////////////////////////
template <>
class basic_chset<signed char>
: public basic_chset_8bit<signed char> {};
/////////////////////////////////
template <>
class basic_chset<unsigned char>
: public basic_chset_8bit<unsigned char> {};
#endif
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
#include <boost/spirit/home/classic/utility/impl/chset/basic_chset.ipp>
@@ -0,0 +1,246 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
Copyright (c) 2001-2003 Daniel Nuffer
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the 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_IPP
#define BOOST_SPIRIT_BASIC_CHSET_IPP
///////////////////////////////////////////////////////////////////////////////
#include <bitset>
#include <boost/spirit/home/classic/utility/impl/chset/basic_chset.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// basic_chset: character set implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline basic_chset<CharT>::basic_chset() {}
//////////////////////////////////
template <typename CharT>
inline basic_chset<CharT>::basic_chset(basic_chset const& arg_)
: rr(arg_.rr) {}
//////////////////////////////////
template <typename CharT>
inline bool
basic_chset<CharT>::test(CharT v) const
{ return rr.test(v); }
//////////////////////////////////
template <typename CharT>
inline void
basic_chset<CharT>::set(CharT from, CharT to)
{ rr.set(utility::impl::range<CharT>(from, to)); }
//////////////////////////////////
template <typename CharT>
inline void
basic_chset<CharT>::set(CharT c)
{ rr.set(utility::impl::range<CharT>(c, c)); }
//////////////////////////////////
template <typename CharT>
inline void
basic_chset<CharT>::clear(CharT from, CharT to)
{ rr.clear(utility::impl::range<CharT>(from, to)); }
//////////////////////////////////
template <typename CharT>
inline void
basic_chset<CharT>::clear()
{ rr.clear(); }
/////////////////////////////////
template <typename CharT>
inline void
basic_chset<CharT>::inverse()
{
basic_chset inv;
inv.set(
(std::numeric_limits<CharT>::min)(),
(std::numeric_limits<CharT>::max)()
);
inv -= *this;
swap(inv);
}
/////////////////////////////////
template <typename CharT>
inline void
basic_chset<CharT>::swap(basic_chset& x)
{ rr.swap(x.rr); }
/////////////////////////////////
template <typename CharT>
inline basic_chset<CharT>&
basic_chset<CharT>::operator|=(basic_chset<CharT> const& x)
{
typedef typename utility::impl::range_run<CharT>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.set(*iter);
return *this;
}
/////////////////////////////////
template <typename CharT>
inline basic_chset<CharT>&
basic_chset<CharT>::operator&=(basic_chset<CharT> const& x)
{
basic_chset inv;
inv.set(
(std::numeric_limits<CharT>::min)(),
(std::numeric_limits<CharT>::max)()
);
inv -= x;
*this -= inv;
return *this;
}
/////////////////////////////////
template <typename CharT>
inline basic_chset<CharT>&
basic_chset<CharT>::operator-=(basic_chset<CharT> const& x)
{
typedef typename utility::impl::range_run<CharT>::const_iterator const_iterator;
for (const_iterator iter = x.rr.begin(); iter != x.rr.end(); ++iter)
rr.clear(*iter);
return *this;
}
/////////////////////////////////
template <typename CharT>
inline basic_chset<CharT>&
basic_chset<CharT>::operator^=(basic_chset<CharT> const& x)
{
basic_chset bma = x;
bma -= *this;
*this -= x;
*this |= bma;
return *this;
}
#if (CHAR_BIT == 8)
///////////////////////////////////////////////////////////////////////////////
//
// basic_chset: specializations for 8 bit chars using std::bitset
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline basic_chset_8bit<CharT>::basic_chset_8bit() {}
/////////////////////////////////
template <typename CharT>
inline basic_chset_8bit<CharT>::basic_chset_8bit(basic_chset_8bit const& arg_)
: bset(arg_.bset) {}
/////////////////////////////////
template <typename CharT>
inline bool
basic_chset_8bit<CharT>::test(CharT v) const
{ return bset.test((unsigned char)v); }
/////////////////////////////////
template <typename CharT>
inline void
basic_chset_8bit<CharT>::set(CharT from, CharT to)
{
for (int i = from; i <= to; ++i)
bset.set((unsigned char)i);
}
/////////////////////////////////
template <typename CharT>
inline void
basic_chset_8bit<CharT>::set(CharT c)
{ bset.set((unsigned char)c); }
/////////////////////////////////
template <typename CharT>
inline void
basic_chset_8bit<CharT>::clear(CharT from, CharT to)
{
for (int i = from; i <= to; ++i)
bset.reset((unsigned char)i);
}
/////////////////////////////////
template <typename CharT>
inline void
basic_chset_8bit<CharT>::clear(CharT c)
{ bset.reset((unsigned char)c); }
/////////////////////////////////
template <typename CharT>
inline void
basic_chset_8bit<CharT>::clear()
{ bset.reset(); }
/////////////////////////////////
template <typename CharT>
inline void
basic_chset_8bit<CharT>::inverse()
{ bset.flip(); }
/////////////////////////////////
template <typename CharT>
inline void
basic_chset_8bit<CharT>::swap(basic_chset_8bit& x)
{ std::swap(bset, x.bset); }
/////////////////////////////////
template <typename CharT>
inline basic_chset_8bit<CharT>&
basic_chset_8bit<CharT>::operator|=(basic_chset_8bit const& x)
{
bset |= x.bset;
return *this;
}
/////////////////////////////////
template <typename CharT>
inline basic_chset_8bit<CharT>&
basic_chset_8bit<CharT>::operator&=(basic_chset_8bit const& x)
{
bset &= x.bset;
return *this;
}
/////////////////////////////////
template <typename CharT>
inline basic_chset_8bit<CharT>&
basic_chset_8bit<CharT>::operator-=(basic_chset_8bit const& x)
{
bset &= ~x.bset;
return *this;
}
/////////////////////////////////
template <typename CharT>
inline basic_chset_8bit<CharT>&
basic_chset_8bit<CharT>::operator^=(basic_chset_8bit const& x)
{
bset ^= x.bset;
return *this;
}
#endif
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif
@@ -0,0 +1,127 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_RANGE_RUN_HPP
#define BOOST_SPIRIT_RANGE_RUN_HPP
///////////////////////////////////////////////////////////////////////////////
#include <vector>
#include <boost/spirit/home/classic/namespace.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace utility { namespace impl {
///////////////////////////////////////////////////////////////////////////
//
// range class
//
// Implements a closed range of values. This class is used in
// the implementation of the range_run class.
//
// { Low level implementation detail }
// { Not to be confused with BOOST_SPIRIT_CLASSIC_NS::range }
//
///////////////////////////////////////////////////////////////////////////
template <typename CharT>
struct range {
range(CharT first, CharT last);
bool is_valid() const;
bool includes(CharT v) const;
bool includes(range const& r) const;
bool overlaps(range const& r) const;
void merge(range const& r);
CharT first;
CharT last;
};
//////////////////////////////////
template <typename CharT>
struct range_char_compare {
bool operator()(range<CharT> const& x, const CharT y) const
{ return x.first < y; }
bool operator()(const CharT x, range<CharT> const& y) const
{ return x < y.first; }
// This additional operator is required for the checked STL shipped
// with VC8 testing the ordering of the iterators passed to the
// std::lower_bound algo this range_char_compare<> predicate is passed
// to.
bool operator()(range<CharT> const& x, range<CharT> const& y) const
{ return x.first < y.first; }
};
//////////////////////////////////
template <typename CharT>
struct range_compare {
bool operator()(range<CharT> const& x, range<CharT> const& y) const
{ return x.first < y.first; }
};
///////////////////////////////////////////////////////////////////////////
//
// 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 implementation detail }
//
///////////////////////////////////////////////////////////////////////////
template <typename CharT>
class range_run {
public:
typedef range<CharT> range_t;
typedef std::vector<range_t> run_t;
typedef typename run_t::iterator iterator;
typedef typename run_t::const_iterator const_iterator;
void swap(range_run& rr);
bool test(CharT v) const;
void set(range_t const& r);
void clear(range_t const& r);
void clear();
const_iterator begin() const;
const_iterator end() const;
private:
void merge(iterator iter, range_t const& r);
run_t run;
};
}}
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS::utility::impl
#endif
#include <boost/spirit/home/classic/utility/impl/chset/range_run.ipp>
@@ -0,0 +1,218 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the 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_RANGE_RUN_IPP
#define BOOST_SPIRIT_RANGE_RUN_IPP
///////////////////////////////////////////////////////////////////////////////
#include <algorithm> // for std::lower_bound
#include <boost/spirit/home/classic/core/assert.hpp> // for BOOST_SPIRIT_ASSERT
#include <boost/spirit/home/classic/utility/impl/chset/range_run.hpp>
#include <boost/spirit/home/classic/debug.hpp>
#include <boost/limits.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace utility { namespace impl {
///////////////////////////////////////////////////////////////////////
//
// range class implementation
//
///////////////////////////////////////////////////////////////////////
template <typename CharT>
inline range<CharT>::range(CharT first_, CharT last_)
: first(first_), last(last_) {}
//////////////////////////////////
template <typename CharT>
inline bool
range<CharT>::is_valid() const
{ return first <= last; }
//////////////////////////////////
template <typename CharT>
inline bool
range<CharT>::includes(range const& r) const
{ return (first <= r.first) && (last >= r.last); }
//////////////////////////////////
template <typename CharT>
inline bool
range<CharT>::includes(CharT v) const
{ return (first <= v) && (last >= v); }
//////////////////////////////////
template <typename CharT>
inline bool
range<CharT>::overlaps(range const& r) const
{
CharT decr_first =
first == (std::numeric_limits<CharT>::min)() ? first : first-1;
CharT incr_last =
last == (std::numeric_limits<CharT>::max)() ? last : last+1;
return (decr_first <= r.last) && (incr_last >= r.first);
}
//////////////////////////////////
template <typename CharT>
inline void
range<CharT>::merge(range const& r)
{
first = (std::min)(first, r.first);
last = (std::max)(last, r.last);
}
///////////////////////////////////////////////////////////////////////
//
// range_run class implementation
//
///////////////////////////////////////////////////////////////////////
template <typename CharT>
inline bool
range_run<CharT>::test(CharT v) const
{
if (!run.empty())
{
const_iterator iter =
std::lower_bound(
run.begin(), run.end(), v,
range_char_compare<CharT>()
);
if (iter != run.end() && iter->includes(v))
return true;
if (iter != run.begin())
return (--iter)->includes(v);
}
return false;
}
//////////////////////////////////
template <typename CharT>
inline void
range_run<CharT>::swap(range_run& rr)
{ run.swap(rr.run); }
//////////////////////////////////
template <typename CharT>
void
range_run<CharT>::merge(iterator iter, range<CharT> const& r)
{
iter->merge(r);
iterator i = iter + 1;
while (i != run.end() && iter->overlaps(*i))
iter->merge(*i++);
run.erase(iter+1, i);
}
//////////////////////////////////
template <typename CharT>
void
range_run<CharT>::set(range<CharT> const& r)
{
BOOST_SPIRIT_ASSERT(r.is_valid());
if (!run.empty())
{
iterator iter =
std::lower_bound(
run.begin(), run.end(), r,
range_compare<CharT>()
);
if ((iter != run.end() && iter->includes(r)) ||
((iter != run.begin()) && (iter - 1)->includes(r)))
return;
if (iter != run.begin() && (iter - 1)->overlaps(r))
merge(--iter, r);
else if (iter != run.end() && iter->overlaps(r))
merge(iter, r);
else
run.insert(iter, r);
}
else
{
run.push_back(r);
}
}
//////////////////////////////////
template <typename CharT>
void
range_run<CharT>::clear(range<CharT> const& r)
{
BOOST_SPIRIT_ASSERT(r.is_valid());
if (!run.empty())
{
iterator iter =
std::lower_bound(
run.begin(), run.end(), r,
range_compare<CharT>()
);
iterator left_iter;
if ((iter != run.begin()) &&
(left_iter = (iter - 1))->includes(r.first))
{
if (left_iter->last > r.last)
{
CharT save_last = left_iter->last;
left_iter->last = r.first-1;
run.insert(iter, range<CharT>(r.last+1, save_last));
return;
}
else
{
left_iter->last = r.first-1;
}
}
iterator i = iter;
while (i != run.end() && r.includes(*i))
i++;
if (i != run.end() && i->includes(r.last))
i->first = r.last+1;
run.erase(iter, i);
}
}
//////////////////////////////////
template <typename CharT>
inline void
range_run<CharT>::clear()
{ run.clear(); }
//////////////////////////////////
template <typename CharT>
inline typename range_run<CharT>::const_iterator
range_run<CharT>::begin() const
{ return run.begin(); }
//////////////////////////////////
template <typename CharT>
inline typename range_run<CharT>::const_iterator
range_run<CharT>::end() const
{ return run.end(); }
}} // namespace utility::impl
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif
@@ -0,0 +1,592 @@
/*=============================================================================
Copyright (c) 2001-2003 Joel de Guzman
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the 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_CHSET_OPERATORS_IPP
#define BOOST_SPIRIT_CHSET_OPERATORS_IPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/limits.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// chset free operators implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chset<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) |= b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chset<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) -= b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator~(chset<CharT> const& a)
{
return chset<CharT>(a).inverse();
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chset<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) &= b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chset<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) ^= b;
}
///////////////////////////////////////////////////////////////////////////////
//
// range <--> chset free operators implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chset<CharT> const& a, range<CharT> const& b)
{
chset<CharT> a_(a);
a_.set(b);
return a_;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chset<CharT> const& a, range<CharT> const& b)
{
chset<CharT> a_(a);
if(b.first != (std::numeric_limits<CharT>::min)()) {
a_.clear(range<CharT>((std::numeric_limits<CharT>::min)(), b.first - 1));
}
if(b.last != (std::numeric_limits<CharT>::max)()) {
a_.clear(range<CharT>(b.last + 1, (std::numeric_limits<CharT>::max)()));
}
return a_;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chset<CharT> const& a, range<CharT> const& b)
{
chset<CharT> a_(a);
a_.clear(b);
return a_;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chset<CharT> const& a, range<CharT> const& b)
{
return a ^ chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(range<CharT> const& a, chset<CharT> const& b)
{
chset<CharT> b_(b);
b_.set(a);
return b_;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(range<CharT> const& a, chset<CharT> const& b)
{
chset<CharT> b_(b);
if(a.first != (std::numeric_limits<CharT>::min)()) {
b_.clear(range<CharT>((std::numeric_limits<CharT>::min)(), a.first - 1));
}
if(a.last != (std::numeric_limits<CharT>::max)()) {
b_.clear(range<CharT>(a.last + 1, (std::numeric_limits<CharT>::max)()));
}
return b_;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(range<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) - b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(range<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) ^ b;
}
///////////////////////////////////////////////////////////////////////////////
//
// literal primitives <--> chset free operators implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chset<CharT> const& a, CharT b)
{
return a | chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chset<CharT> const& a, CharT b)
{
return a & chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chset<CharT> const& a, CharT b)
{
return a - chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chset<CharT> const& a, CharT b)
{
return a ^ chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(CharT a, chset<CharT> const& b)
{
return chset<CharT>(a) | b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(CharT a, chset<CharT> const& b)
{
return chset<CharT>(a) & b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(CharT a, chset<CharT> const& b)
{
return chset<CharT>(a) - b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(CharT a, chset<CharT> const& b)
{
return chset<CharT>(a) ^ b;
}
///////////////////////////////////////////////////////////////////////////////
//
// chlit <--> chset free operators implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chset<CharT> const& a, chlit<CharT> const& b)
{
return a | chset<CharT>(b.ch);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chset<CharT> const& a, chlit<CharT> const& b)
{
return a & chset<CharT>(b.ch);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chset<CharT> const& a, chlit<CharT> const& b)
{
return a - chset<CharT>(b.ch);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chset<CharT> const& a, chlit<CharT> const& b)
{
return a ^ chset<CharT>(b.ch);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chlit<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a.ch) | b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chlit<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a.ch) & b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chlit<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a.ch) - b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chlit<CharT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a.ch) ^ b;
}
///////////////////////////////////////////////////////////////////////////////
//
// negated_char_parser<range> <--> chset free operators implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b)
{
return a | chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b)
{
return a & chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b)
{
return a - chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chset<CharT> const& a, negated_char_parser<range<CharT> > const& b)
{
return a ^ chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b)
{
return chset<CharT>(a) | b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b)
{
return chset<CharT>(a) & b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b)
{
return chset<CharT>(a) - b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(negated_char_parser<range<CharT> > const& a, chset<CharT> const& b)
{
return chset<CharT>(a) ^ b;
}
///////////////////////////////////////////////////////////////////////////////
//
// negated_char_parser<chlit> <--> chset free operators implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b)
{
return a | chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b)
{
return a & chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b)
{
return a - chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chset<CharT> const& a, negated_char_parser<chlit<CharT> > const& b)
{
return a ^ chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b)
{
return chset<CharT>(a) | b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b)
{
return chset<CharT>(a) & b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b)
{
return chset<CharT>(a) - b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(negated_char_parser<chlit<CharT> > const& a, chset<CharT> const& b)
{
return chset<CharT>(a) ^ b;
}
///////////////////////////////////////////////////////////////////////////////
//
// anychar_parser <--> chset free operators
//
// Where a is chset and b is a anychar_parser, and vice-versa, implements:
//
// a | b, a & b, a - b, a ^ b
//
///////////////////////////////////////////////////////////////////////////////
namespace impl {
template <typename CharT>
inline BOOST_SPIRIT_CLASSIC_NS::range<CharT> const&
full()
{
static BOOST_SPIRIT_CLASSIC_NS::range<CharT> full_(
(std::numeric_limits<CharT>::min)(),
(std::numeric_limits<CharT>::max)());
return full_;
}
template <typename CharT>
inline BOOST_SPIRIT_CLASSIC_NS::range<CharT> const&
empty()
{
static BOOST_SPIRIT_CLASSIC_NS::range<CharT> empty_;
return empty_;
}
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chset<CharT> const&, anychar_parser)
{
return chset<CharT>(impl::full<CharT>());
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chset<CharT> const& a, anychar_parser)
{
return a;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chset<CharT> const&, anychar_parser)
{
return chset<CharT>();
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chset<CharT> const& a, anychar_parser)
{
return ~a;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(anychar_parser, chset<CharT> const& /*b*/)
{
return chset<CharT>(impl::full<CharT>());
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(anychar_parser, chset<CharT> const& b)
{
return b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(anychar_parser, chset<CharT> const& b)
{
return ~b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(anychar_parser, chset<CharT> const& b)
{
return ~b;
}
///////////////////////////////////////////////////////////////////////////////
//
// nothing_parser <--> chset free operators implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(chset<CharT> const& a, nothing_parser)
{
return a;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(chset<CharT> const& /*a*/, nothing_parser)
{
return impl::empty<CharT>();
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(chset<CharT> const& a, nothing_parser)
{
return a;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(chset<CharT> const& a, nothing_parser)
{
return a;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator|(nothing_parser, chset<CharT> const& b)
{
return b;
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator&(nothing_parser, chset<CharT> const& /*b*/)
{
return impl::empty<CharT>();
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator-(nothing_parser, chset<CharT> const& /*b*/)
{
return impl::empty<CharT>();
}
//////////////////////////////////
template <typename CharT>
inline chset<CharT>
operator^(nothing_parser, chset<CharT> const& b)
{
return b;
}
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif
@@ -0,0 +1,221 @@
/*=============================================================================
Copyright (c) 2002-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the 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_CONFIX_IPP
#define BOOST_SPIRIT_CONFIX_IPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/meta/refactoring.hpp>
#include <boost/spirit/home/classic/core/composite/impl/directives.ipp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// Types to distinguish nested and non-nested confix parsers
//
///////////////////////////////////////////////////////////////////////////////
struct is_nested {};
struct non_nested {};
///////////////////////////////////////////////////////////////////////////////
//
// Types to distinguish between confix parsers, which are implicitly lexems
// and without this behaviour
//
///////////////////////////////////////////////////////////////////////////////
struct is_lexeme {};
struct non_lexeme {};
///////////////////////////////////////////////////////////////////////////////
//
// confix_parser_type class implementation
//
///////////////////////////////////////////////////////////////////////////////
namespace impl {
///////////////////////////////////////////////////////////////////////////
// implicitly insert a lexeme_d into the parsing process
template <typename LexemeT>
struct select_confix_parse_lexeme;
template <>
struct select_confix_parse_lexeme<is_lexeme> {
template <typename ParserT, typename ScannerT>
static typename parser_result<ParserT, ScannerT>::type
parse(ParserT const& p, ScannerT const& scan)
{
typedef typename parser_result<ParserT, ScannerT>::type result_t;
return contiguous_parser_parse<result_t>(p, scan, scan);
}
};
template <>
struct select_confix_parse_lexeme<non_lexeme> {
template <typename ParserT, typename ScannerT>
static typename parser_result<ParserT, ScannerT>::type
parse(ParserT const& p, ScannerT const& scan)
{
return p.parse(scan);
}
};
///////////////////////////////////////////////////////////////////////////
// parse confix sequences with refactoring
template <typename NestedT>
struct select_confix_parse_refactor;
template <>
struct select_confix_parse_refactor<is_nested> {
template <
typename LexemeT, typename ParserT, typename ScannerT,
typename OpenT, typename ExprT, typename CloseT
>
static typename parser_result<ParserT, ScannerT>::type
parse(
LexemeT const &, ParserT const& this_, ScannerT const& scan,
OpenT const& open, ExprT const& expr, CloseT const& close)
{
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
return select_confix_parse_lexeme<LexemeT>::parse((
open
>> (this_ | refactor_body_d[expr - close])
>> close
), scan);
}
};
template <>
struct select_confix_parse_refactor<non_nested> {
template <
typename LexemeT, typename ParserT, typename ScannerT,
typename OpenT, typename ExprT, typename CloseT
>
static typename parser_result<ParserT, ScannerT>::type
parse(
LexemeT const &, ParserT const& /*this_*/, ScannerT const& scan,
OpenT const& open, ExprT const& expr, CloseT const& close)
{
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
const refactor_t refactor_body_d = refactor_t(refactor_unary_d);
return select_confix_parse_lexeme<LexemeT>::parse((
open
>> refactor_body_d[expr - close]
>> close
), scan);
}
};
///////////////////////////////////////////////////////////////////////////
// parse confix sequences without refactoring
template <typename NestedT>
struct select_confix_parse_no_refactor;
template <>
struct select_confix_parse_no_refactor<is_nested> {
template <
typename LexemeT, typename ParserT, typename ScannerT,
typename OpenT, typename ExprT, typename CloseT
>
static typename parser_result<ParserT, ScannerT>::type
parse(
LexemeT const &, ParserT const& this_, ScannerT const& scan,
OpenT const& open, ExprT const& expr, CloseT const& close)
{
return select_confix_parse_lexeme<LexemeT>::parse((
open
>> (this_ | (expr - close))
>> close
), scan);
}
};
template <>
struct select_confix_parse_no_refactor<non_nested> {
template <
typename LexemeT, typename ParserT, typename ScannerT,
typename OpenT, typename ExprT, typename CloseT
>
static typename parser_result<ParserT, ScannerT>::type
parse(
LexemeT const &, ParserT const & /*this_*/, ScannerT const& scan,
OpenT const& open, ExprT const& expr, CloseT const& close)
{
return select_confix_parse_lexeme<LexemeT>::parse((
open
>> (expr - close)
>> close
), scan);
}
};
// the refactoring is handled by the refactoring parsers, so here there
// is no need to pay attention to these issues.
template <typename CategoryT>
struct confix_parser_type {
template <
typename NestedT, typename LexemeT,
typename ParserT, typename ScannerT,
typename OpenT, typename ExprT, typename CloseT
>
static typename parser_result<ParserT, ScannerT>::type
parse(
NestedT const &, LexemeT const &lexeme,
ParserT const& this_, ScannerT const& scan,
OpenT const& open, ExprT const& expr, CloseT const& close)
{
return select_confix_parse_refactor<NestedT>::
parse(lexeme, this_, scan, open, expr, close);
}
};
template <>
struct confix_parser_type<plain_parser_category> {
template <
typename NestedT, typename LexemeT,
typename ParserT, typename ScannerT,
typename OpenT, typename ExprT, typename CloseT
>
static typename parser_result<ParserT, ScannerT>::type
parse(
NestedT const &, LexemeT const &lexeme,
ParserT const& this_, ScannerT const& scan,
OpenT const& open, ExprT const& expr, CloseT const& close)
{
return select_confix_parse_no_refactor<NestedT>::
parse(lexeme, this_, scan, open, expr, close);
}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif
@@ -0,0 +1,224 @@
/*=============================================================================
Copyright (c) 2001-2003 Daniel Nuffer
Copyright (c) 2002-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the 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_ESCAPE_CHAR_IPP
#define BOOST_SPIRIT_ESCAPE_CHAR_IPP
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/primitives/numerics.hpp>
#include <boost/spirit/home/classic/core/composite/difference.hpp>
#include <boost/spirit/home/classic/core/composite/sequence.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// escape_char_parser class
//
///////////////////////////////////////////////////////////////////////////////
const unsigned long c_escapes = 1;
const unsigned long lex_escapes = c_escapes << 1;
//////////////////////////////////
namespace impl {
//////////////////////////////////
#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
#pragma warning(push)
#pragma warning(disable:4127)
#endif
template <unsigned long Flags, typename CharT>
struct escape_char_action_parse {
template <typename ParserT, typename ScannerT>
static typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const& scan, ParserT const &p)
{
// Actually decode the escape char.
typedef CharT char_t;
typedef typename ScannerT::iterator_t iterator_t;
typedef typename parser_result<ParserT, ScannerT>::type result_t;
if (scan.first != scan.last) {
iterator_t save = scan.first;
if (result_t hit = p.subject().parse(scan)) {
char_t unescaped;
scan.first = save;
if (*scan.first == '\\') {
++scan.first;
switch (*scan.first) {
case 'b': unescaped = '\b'; ++scan.first; break;
case 't': unescaped = '\t'; ++scan.first; break;
case 'n': unescaped = '\n'; ++scan.first; break;
case 'f': unescaped = '\f'; ++scan.first; break;
case 'r': unescaped = '\r'; ++scan.first; break;
case '"': unescaped = '"'; ++scan.first; break;
case '\'': unescaped = '\''; ++scan.first; break;
case '\\': unescaped = '\\'; ++scan.first; break;
case 'x': case 'X':
{
char_t hex = 0;
char_t const lim =
(std::numeric_limits<char_t>::max)() >> 4;
++scan.first;
while (scan.first != scan.last)
{
char_t c = *scan.first;
if (hex > lim && impl::isxdigit_(c))
{
// overflow detected
scan.first = save;
return scan.no_match();
}
if (impl::isdigit_(c))
{
hex <<= 4;
hex |= c - '0';
++scan.first;
}
else if (impl::isxdigit_(c))
{
hex <<= 4;
c = impl::toupper_(c);
hex |= c - 'A' + 0xA;
++scan.first;
}
else
{
break; // reached the end of the number
}
}
unescaped = hex;
}
break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
{
char_t oct = 0;
char_t const lim =
(std::numeric_limits<char_t>::max)() >> 3;
while (scan.first != scan.last)
{
char_t c = *scan.first;
if (oct > lim && (c >= '0' && c <= '7'))
{
// overflow detected
scan.first = save;
return scan.no_match();
}
if (c >= '0' && c <= '7')
{
oct <<= 3;
oct |= c - '0';
++scan.first;
}
else
{
break; // reached end of digits
}
}
unescaped = oct;
}
break;
default:
if (Flags & c_escapes)
{
// illegal C escape sequence
scan.first = save;
return scan.no_match();
}
else
{
unescaped = *scan.first;
++scan.first;
}
break;
}
}
else {
unescaped = *scan.first;
++scan.first;
}
scan.do_action(p.predicate(), unescaped, save, scan.first);
return hit;
}
}
return scan.no_match(); // overflow detected
}
};
#if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310))
#pragma warning(pop)
#endif
//////////////////////////////////
template <typename CharT>
struct escape_char_parse {
template <typename ScannerT, typename ParserT>
static typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const &scan, ParserT const &/*p*/)
{
typedef
uint_parser<CharT, 8, 1,
std::numeric_limits<CharT>::digits / 3 + 1
>
oct_parser_t;
typedef
uint_parser<CharT, 16, 1,
std::numeric_limits<CharT>::digits / 4 + 1
>
hex_parser_t;
typedef alternative<difference<anychar_parser, chlit<CharT> >,
sequence<chlit<CharT>, alternative<alternative<oct_parser_t,
sequence<inhibit_case<chlit<CharT> >, hex_parser_t > >,
difference<difference<anychar_parser,
inhibit_case<chlit<CharT> > >, oct_parser_t > > > >
parser_t;
static parser_t p =
( (anychar_p - chlit<CharT>(CharT('\\')))
| (chlit<CharT>(CharT('\\')) >>
( oct_parser_t()
| as_lower_d[chlit<CharT>(CharT('x'))] >> hex_parser_t()
| (anychar_p - as_lower_d[chlit<CharT>(CharT('x'))] - oct_parser_t())
)
));
BOOST_SPIRIT_DEBUG_TRACE_NODE(p,
(BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR) != 0);
return p.parse(scan);
}
};
///////////////////////////////////////////////////////////////////////////////
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif
@@ -0,0 +1,168 @@
/*=============================================================================
Copyright (c) 2002-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the 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_LISTS_IPP
#define BOOST_SPIRIT_LISTS_IPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/meta/refactoring.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// list_parser_type class implementation
//
///////////////////////////////////////////////////////////////////////////////
struct no_list_endtoken { typedef no_list_endtoken embed_t; };
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
// Refactor the original list item parser
//
///////////////////////////////////////////////////////////////////////////////
// match list with 'extended' syntax
template <typename EndT>
struct select_list_parse_refactor {
template <
typename ParserT, typename ScannerT,
typename ItemT, typename DelimT
>
static typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const& scan, ParserT const& /*p*/,
ItemT const &item, DelimT const &delim, EndT const &end)
{
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
return (
refactor_item_d[item - (end | delim)]
>> *(delim >> refactor_item_d[item - (end | delim)])
>> !(delim >> end)
).parse(scan);
}
};
// match list with 'normal' syntax (without an 'end' parser)
template <>
struct select_list_parse_refactor<no_list_endtoken> {
template <
typename ParserT, typename ScannerT,
typename ItemT, typename DelimT
>
static typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const& scan, ParserT const& /*p*/,
ItemT const &item, DelimT const &delim, no_list_endtoken const&)
{
typedef refactor_action_gen<refactor_unary_gen<> > refactor_t;
const refactor_t refactor_item_d = refactor_t(refactor_unary_d);
return (
refactor_item_d[item - delim]
>> *(delim >> refactor_item_d[item - delim])
).parse(scan);
}
};
///////////////////////////////////////////////////////////////////////////////
//
// Do not refactor the original list item parser.
//
///////////////////////////////////////////////////////////////////////////////
// match list with 'extended' syntax
template <typename EndT>
struct select_list_parse_no_refactor {
template <
typename ParserT, typename ScannerT,
typename ItemT, typename DelimT
>
static typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const& scan, ParserT const& /*p*/,
ItemT const &item, DelimT const &delim, EndT const &end)
{
return (
(item - (end | delim))
>> *(delim >> (item - (end | delim)))
>> !(delim >> end)
).parse(scan);
}
};
// match list with 'normal' syntax (without an 'end' parser)
template <>
struct select_list_parse_no_refactor<no_list_endtoken> {
template <
typename ParserT, typename ScannerT,
typename ItemT, typename DelimT
>
static typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const& scan, ParserT const& /*p*/,
ItemT const &item, DelimT const &delim, no_list_endtoken const&)
{
return (
(item - delim)
>> *(delim >> (item - delim))
).parse(scan);
}
};
// the refactoring is handled by the refactoring parsers, so here there
// is no need to pay attention to these issues.
template <typename CategoryT>
struct list_parser_type {
template <
typename ParserT, typename ScannerT,
typename ItemT, typename DelimT, typename EndT
>
static typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const& scan, ParserT const& p,
ItemT const &item, DelimT const &delim, EndT const &end)
{
return select_list_parse_refactor<EndT>::
parse(scan, p, item, delim, end);
}
};
template <>
struct list_parser_type<plain_parser_category> {
template <
typename ParserT, typename ScannerT,
typename ItemT, typename DelimT, typename EndT
>
static typename parser_result<ParserT, ScannerT>::type
parse(ScannerT const& scan, ParserT const& p,
ItemT const &item, DelimT const &delim, EndT const &end)
{
return select_list_parse_no_refactor<EndT>::
parse(scan, p, item, delim, end);
}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif
@@ -0,0 +1,81 @@
/*=============================================================================
Copyright (c) 2002-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the 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_REGEX_IPP
#define BOOST_SPIRIT_REGEX_IPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/core/primitives/impl/primitives.ipp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
namespace impl {
///////////////////////////////////////////////////////////////////////////////
//
inline const char* rx_prefix(char) { return "\\A"; }
inline const wchar_t* rx_prefix(wchar_t) { return L"\\A"; }
///////////////////////////////////////////////////////////////////////////////
//
// rx_parser class
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT = char>
class rx_parser : public parser<rx_parser<CharT> > {
public:
typedef std::basic_string<CharT> string_t;
typedef rx_parser<CharT> self_t;
rx_parser(CharT const *first, CharT const *last)
{
rxstr = string_t(rx_prefix(CharT())) + string_t(first, last);
}
rx_parser(CharT const *first)
{
rxstr = string_t(rx_prefix(CharT())) +
string_t(first, impl::get_last(first));
}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
boost::match_results<typename ScannerT::iterator_t> what;
boost::regex_search(scan.first, scan.last, what, rxstr,
boost::match_default);
if (!what[0].matched)
return scan.no_match();
scan.first = what[0].second;
return scan.create_match(what[0].length(), nil_t(),
what[0].first, scan.first);
}
private:
#if BOOST_VERSION >= 013300
boost::basic_regex<CharT> rxstr; // regular expression to match
#else
boost::reg_expression<CharT> rxstr; // regular expression to match
#endif
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace boost::spirit
#endif // BOOST_SPIRIT_REGEX_IPP
@@ -0,0 +1,340 @@
/*=============================================================================
Copyright (c) 2002-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_LISTS_HPP
#define BOOST_SPIRIT_LISTS_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/config.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/meta/as_parser.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
#include <boost/spirit/home/classic/utility/lists_fwd.hpp>
#include <boost/spirit/home/classic/utility/impl/lists.ipp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
//
// list_parser class
//
// List parsers allow to parse constructs like
//
// item >> *(delim >> item)
//
// where 'item' is an auxiliary expression to parse and 'delim' is an
// auxiliary delimiter to parse.
//
// The list_parser class also can match an optional closing delimiter
// represented by the 'end' parser at the end of the list:
//
// item >> *(delim >> item) >> !end.
//
// If ItemT is an action_parser_category type (parser with an attached
// semantic action) we have to do something special. This happens, if the
// user wrote something like:
//
// list_p(item[f], delim)
//
// where 'item' is the parser matching one item of the list sequence and
// 'f' is a functor to be called after matching one item. If we would do
// nothing, the resulting code would parse the sequence as follows:
//
// (item[f] - delim) >> *(delim >> (item[f] - delim))
//
// what in most cases is not what the user expects.
// (If this _is_ what you've expected, then please use one of the list_p
// generator functions 'direct()', which will inhibit re-attaching
// the actor to the item parser).
//
// To make the list parser behave as expected:
//
// (item - delim)[f] >> *(delim >> (item - delim)[f])
//
// the actor attached to the 'item' parser has to be re-attached to the
// *(item - delim) parser construct, which will make the resulting list
// parser 'do the right thing'.
//
// Additionally special care must be taken, if the item parser is a
// unary_parser_category type parser as
//
// list_p(*anychar_p, ',')
//
// which without any refactoring would result in
//
// (*anychar_p - ch_p(','))
// >> *( ch_p(',') >> (*anychar_p - ch_p(',')) )
//
// and will not give the expected result (the first *anychar_p will eat up
// all the input up to the end of the input stream). So we have to
// refactor this into:
//
// *(anychar_p - ch_p(','))
// >> *( ch_p(',') >> *(anychar_p - ch_p(',')) )
//
// what will give the correct result.
//
// The case, where the item parser is a combination of the two mentioned
// problems (i.e. the item parser is a unary parser with an attached
// action), is handled accordingly too:
//
// list_p((*anychar_p)[f], ',')
//
// will be parsed as expected:
//
// (*(anychar_p - ch_p(',')))[f]
// >> *( ch_p(',') >> (*(anychar_p - ch_p(',')))[f] ).
//
///////////////////////////////////////////////////////////////////////////////
template <
typename ItemT, typename DelimT, typename EndT, typename CategoryT
>
struct list_parser :
public parser<list_parser<ItemT, DelimT, EndT, CategoryT> > {
typedef list_parser<ItemT, DelimT, EndT, CategoryT> self_t;
typedef CategoryT parser_category_t;
list_parser(ItemT const &item_, DelimT const &delim_,
EndT const& end_ = no_list_endtoken())
: item(item_), delim(delim_), end(end_)
{}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
return impl::list_parser_type<CategoryT>
::parse(scan, *this, item, delim, end);
}
private:
typename as_parser<ItemT>::type::embed_t item;
typename as_parser<DelimT>::type::embed_t delim;
typename as_parser<EndT>::type::embed_t end;
};
///////////////////////////////////////////////////////////////////////////////
//
// List parser generator template
//
// This is a helper for generating a correct list_parser<> from
// auxiliary parameters. There are the following types supported as
// parameters yet: parsers, single characters and strings (see
// as_parser<> in meta/as_parser.hpp).
//
// The list_parser_gen by itself can be used for parsing comma separated
// lists without item formatting:
//
// list_p.parse(...)
// matches any comma separated list.
//
// If list_p is used with one parameter, this parameter is used to match
// the delimiter:
//
// list_p(';').parse(...)
// matches any semicolon separated list.
//
// If list_p is used with two parameters, the first parameter is used to
// match the items and the second parameter matches the delimiters:
//
// list_p(uint_p, ',').parse(...)
// matches comma separated unsigned integers.
//
// If list_p is used with three parameters, the first parameter is used
// to match the items, the second one is used to match the delimiters and
// the third one is used to match an optional ending token sequence:
//
// list_p(real_p, ';', eol_p).parse(...)
// matches a semicolon separated list of real numbers optionally
// followed by an end of line.
//
// The list_p in the previous examples denotes the predefined parser
// generator, which should be used to define list parsers (see below).
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT = char>
struct list_parser_gen :
public list_parser<kleene_star<anychar_parser>, chlit<CharT> >
{
typedef list_parser_gen<CharT> self_t;
// construct the list_parser_gen object as an list parser for comma separated
// lists without item formatting.
list_parser_gen()
: list_parser<kleene_star<anychar_parser>, chlit<CharT> >
(*anychar_p, chlit<CharT>(','))
{}
// The following generator functions should be used under normal circumstances.
// (the operator()(...) functions)
// Generic generator functions for creation of concrete list parsers, which
// support 'normal' syntax:
//
// item >> *(delim >> item)
//
// If item isn't given, everything between two delimiters is matched.
template<typename DelimT>
list_parser<
kleene_star<anychar_parser>,
typename as_parser<DelimT>::type,
no_list_endtoken,
unary_parser_category // there is no action to re-attach
>
operator()(DelimT const &delim_) const
{
typedef kleene_star<anychar_parser> item_t;
typedef typename as_parser<DelimT>::type delim_t;
typedef
list_parser<item_t, delim_t, no_list_endtoken, unary_parser_category>
return_t;
return return_t(*anychar_p, as_parser<DelimT>::convert(delim_));
}
template<typename ItemT, typename DelimT>
list_parser<
typename as_parser<ItemT>::type,
typename as_parser<DelimT>::type,
no_list_endtoken,
typename as_parser<ItemT>::type::parser_category_t
>
operator()(ItemT const &item_, DelimT const &delim_) const
{
typedef typename as_parser<ItemT>::type item_t;
typedef typename as_parser<DelimT>::type delim_t;
typedef list_parser<item_t, delim_t, no_list_endtoken,
BOOST_DEDUCED_TYPENAME item_t::parser_category_t>
return_t;
return return_t(
as_parser<ItemT>::convert(item_),
as_parser<DelimT>::convert(delim_)
);
}
// Generic generator function for creation of concrete list parsers, which
// support 'extended' syntax:
//
// item >> *(delim >> item) >> !end
template<typename ItemT, typename DelimT, typename EndT>
list_parser<
typename as_parser<ItemT>::type,
typename as_parser<DelimT>::type,
typename as_parser<EndT>::type,
typename as_parser<ItemT>::type::parser_category_t
>
operator()(
ItemT const &item_, DelimT const &delim_, EndT const &end_) const
{
typedef typename as_parser<ItemT>::type item_t;
typedef typename as_parser<DelimT>::type delim_t;
typedef typename as_parser<EndT>::type end_t;
typedef list_parser<item_t, delim_t, end_t,
BOOST_DEDUCED_TYPENAME item_t::parser_category_t>
return_t;
return return_t(
as_parser<ItemT>::convert(item_),
as_parser<DelimT>::convert(delim_),
as_parser<EndT>::convert(end_)
);
}
// The following functions should be used, if the 'item' parser has an attached
// semantic action or is a unary_parser_category type parser and the structure
// of the resulting list parser should _not_ be refactored during parser
// construction (see comment above).
// Generic generator function for creation of concrete list parsers, which
// support 'normal' syntax:
//
// item >> *(delim >> item)
template<typename ItemT, typename DelimT>
list_parser<
typename as_parser<ItemT>::type,
typename as_parser<DelimT>::type,
no_list_endtoken,
plain_parser_category // inhibit action re-attachment
>
direct(ItemT const &item_, DelimT const &delim_) const
{
typedef typename as_parser<ItemT>::type item_t;
typedef typename as_parser<DelimT>::type delim_t;
typedef list_parser<item_t, delim_t, no_list_endtoken,
plain_parser_category>
return_t;
return return_t(
as_parser<ItemT>::convert(item_),
as_parser<DelimT>::convert(delim_)
);
}
// Generic generator function for creation of concrete list parsers, which
// support 'extended' syntax:
//
// item >> *(delim >> item) >> !end
template<typename ItemT, typename DelimT, typename EndT>
list_parser<
typename as_parser<ItemT>::type,
typename as_parser<DelimT>::type,
typename as_parser<EndT>::type,
plain_parser_category // inhibit action re-attachment
>
direct(
ItemT const &item_, DelimT const &delim_, EndT const &end_) const
{
typedef typename as_parser<ItemT>::type item_t;
typedef typename as_parser<DelimT>::type delim_t;
typedef typename as_parser<EndT>::type end_t;
typedef
list_parser<item_t, delim_t, end_t, plain_parser_category>
return_t;
return return_t(
as_parser<ItemT>::convert(item_),
as_parser<DelimT>::convert(delim_),
as_parser<EndT>::convert(end_)
);
}
};
///////////////////////////////////////////////////////////////////////////////
//
// Predefined list parser generator
//
// The list_p parser generator can be used
// - by itself for parsing comma separated lists without item formatting
// or
// - for generating list parsers with auxiliary parser parameters
// for the 'item', 'delim' and 'end' subsequences.
// (see comment above)
//
///////////////////////////////////////////////////////////////////////////////
const list_parser_gen<> list_p = list_parser_gen<>();
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,31 @@
/*=============================================================================
Copyright (c) 2006 Tobias Schwinger
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_LISTS_FWD_HPP)
#define BOOST_SPIRIT_LISTS_FWD_HPP
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
struct no_list_endtoken;
template <
typename ItemT, typename DelimT, typename EndT = no_list_endtoken,
typename CategoryT = plain_parser_category
>
struct list_parser;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif
@@ -0,0 +1,317 @@
/*=============================================================================
Copyright (c) 1998-2003 Joel de Guzman
Copyright (c) 2002 Raghavendra Satish
Copyright (c) 2002 Jeff Westfahl
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_LOOPS_HPP)
#define BOOST_SPIRIT_LOOPS_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/core/composite/composite.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////
//
// fixed_loop class
//
// This class takes care of the construct:
//
// repeat_p (exact) [p]
//
// where 'p' is a parser and 'exact' is the number of times to
// repeat. The parser iterates over the input exactly 'exact' times.
// The parse function fails if the parser does not match the input
// exactly 'exact' times.
//
// This class is parametizable and can accept constant arguments
// (e.g. repeat_p (5) [p]) as well as references to variables (e.g.
// repeat_p (ref (n)) [p]).
//
///////////////////////////////////////////////////////////////////////////
template <typename ParserT, typename ExactT>
class fixed_loop
: public unary<ParserT, parser <fixed_loop <ParserT, ExactT> > >
{
public:
typedef fixed_loop<ParserT, ExactT> self_t;
typedef unary<ParserT, parser<self_t> > base_t;
fixed_loop (ParserT const & subject_, ExactT const & exact)
: base_t(subject_), m_exact(exact) {}
template <typename ScannerT>
typename parser_result <self_t, ScannerT>::type
parse (ScannerT const & scan) const
{
typedef typename parser_result<self_t, ScannerT>::type result_t;
result_t hit = scan.empty_match();
std::size_t n = m_exact;
for (std::size_t i = 0; i < n; ++i)
{
if (result_t next = this->subject().parse(scan))
{
scan.concat_match(hit, next);
}
else
{
return scan.no_match();
}
}
return hit;
}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
private:
ExactT m_exact;
};
///////////////////////////////////////////////////////////////////////////////
//
// finite_loop class
//
// This class takes care of the construct:
//
// repeat_p (min, max) [p]
//
// where 'p' is a parser, 'min' and 'max' specifies the minimum and
// maximum iterations over 'p'. The parser iterates over the input
// at least 'min' times and at most 'max' times. The parse function
// fails if the parser does not match the input at least 'min' times
// and at most 'max' times.
//
// This class is parametizable and can accept constant arguments
// (e.g. repeat_p (5, 10) [p]) as well as references to variables
// (e.g. repeat_p (ref (n1), ref (n2)) [p]).
//
///////////////////////////////////////////////////////////////////////////////
template <typename ParserT, typename MinT, typename MaxT>
class finite_loop
: public unary<ParserT, parser<finite_loop<ParserT, MinT, MaxT> > >
{
public:
typedef finite_loop <ParserT, MinT, MaxT> self_t;
typedef unary<ParserT, parser<self_t> > base_t;
finite_loop (ParserT const & subject_, MinT const & min, MaxT const & max)
: base_t(subject_), m_min(min), m_max(max) {}
template <typename ScannerT>
typename parser_result <self_t, ScannerT>::type
parse(ScannerT const & scan) const
{
BOOST_SPIRIT_ASSERT(m_min <= m_max);
typedef typename parser_result<self_t, ScannerT>::type result_t;
result_t hit = scan.empty_match();
std::size_t n1 = m_min;
std::size_t n2 = m_max;
for (std::size_t i = 0; i < n2; ++i)
{
typename ScannerT::iterator_t save = scan.first;
result_t next = this->subject().parse(scan);
if (!next)
{
if (i >= n1)
{
scan.first = save;
break;
}
else
{
return scan.no_match();
}
}
scan.concat_match(hit, next);
}
return hit;
}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
private:
MinT m_min;
MaxT m_max;
};
///////////////////////////////////////////////////////////////////////////////
//
// infinite_loop class
//
// This class takes care of the construct:
//
// repeat_p (min, more) [p]
//
// where 'p' is a parser, 'min' is the minimum iteration over 'p'
// and more specifies that the iteration should proceed
// indefinitely. The parser iterates over the input at least 'min'
// times and continues indefinitely until 'p' fails or all of the
// input is parsed. The parse function fails if the parser does not
// match the input at least 'min' times.
//
// This class is parametizable and can accept constant arguments
// (e.g. repeat_p (5, more) [p]) as well as references to variables
// (e.g. repeat_p (ref (n), more) [p]).
//
///////////////////////////////////////////////////////////////////////////////
struct more_t {};
more_t const more = more_t ();
template <typename ParserT, typename MinT>
class infinite_loop
: public unary<ParserT, parser<infinite_loop<ParserT, MinT> > >
{
public:
typedef infinite_loop <ParserT, MinT> self_t;
typedef unary<ParserT, parser<self_t> > base_t;
infinite_loop (
ParserT const& subject_,
MinT const& min,
more_t const&
)
: base_t(subject_), m_min(min) {}
template <typename ScannerT>
typename parser_result <self_t, ScannerT>::type
parse(ScannerT const & scan) const
{
typedef typename parser_result<self_t, ScannerT>::type result_t;
result_t hit = scan.empty_match();
std::size_t n = m_min;
for (std::size_t i = 0; ; ++i)
{
typename ScannerT::iterator_t save = scan.first;
result_t next = this->subject().parse(scan);
if (!next)
{
if (i >= n)
{
scan.first = save;
break;
}
else
{
return scan.no_match();
}
}
scan.concat_match(hit, next);
}
return hit;
}
template <typename ScannerT>
struct result
{
typedef typename match_result<ScannerT, nil_t>::type type;
};
private:
MinT m_min;
};
template <typename ExactT>
struct fixed_loop_gen
{
fixed_loop_gen (ExactT const & exact)
: m_exact (exact) {}
template <typename ParserT>
fixed_loop <ParserT, ExactT>
operator[](parser <ParserT> const & subject_) const
{
return fixed_loop <ParserT, ExactT> (subject_.derived (), m_exact);
}
ExactT m_exact;
};
namespace impl {
template <typename ParserT, typename MinT, typename MaxT>
struct loop_traits
{
typedef typename mpl::if_<
boost::is_same<MaxT, more_t>,
infinite_loop<ParserT, MinT>,
finite_loop<ParserT, MinT, MaxT>
>::type type;
};
} // namespace impl
template <typename MinT, typename MaxT>
struct nonfixed_loop_gen
{
nonfixed_loop_gen (MinT min, MaxT max)
: m_min (min), m_max (max) {}
template <typename ParserT>
typename impl::loop_traits<ParserT, MinT, MaxT>::type
operator[](parser <ParserT> const & subject_) const
{
typedef typename impl::loop_traits<ParserT, MinT, MaxT>::type ret_t;
return ret_t(
subject_.derived(),
m_min,
m_max);
}
MinT m_min;
MaxT m_max;
};
template <typename ExactT>
fixed_loop_gen <ExactT>
repeat_p(ExactT const & exact)
{
return fixed_loop_gen <ExactT> (exact);
}
template <typename MinT, typename MaxT>
nonfixed_loop_gen <MinT, MaxT>
repeat_p(MinT const & min, MaxT const & max)
{
return nonfixed_loop_gen <MinT, MaxT> (min, max);
}
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // #if !defined(BOOST_SPIRIT_LOOPS_HPP)
@@ -0,0 +1,112 @@
/*=============================================================================
Copyright (c) 2002-2003 Hartmut Kaiser
http://spirit.sourceforge.net/
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef BOOST_SPIRIT_REGEX_HPP
#define BOOST_SPIRIT_REGEX_HPP
#include <boost/version.hpp>
///////////////////////////////////////////////////////////////////////////////
//
// Include the regular expression library of boost (Boost.Regex)
//
// Note though, that this library is not distributed with Spirit. You have to
// obtain a separate copy from http://www.boost.org.
//
///////////////////////////////////////////////////////////////////////////////
#if defined(BOOST_SPIRIT_NO_REGEX_LIB) && BOOST_VERSION < 103300
//
// Include all the Boost.regex library. Please note that this will not work,
// if you are using the boost/spirit/regex.hpp header from more than one
// translation units.
//
#define BOOST_REGEX_NO_LIB
#define BOOST_REGEX_STATIC_LINK
#define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
#include <boost/regex.hpp>
#include <boost/regex/src.cpp>
#else
//
// Include the Boost.Regex headers only. Note, that you will have to link your
// application against the Boost.Regex library as described in the related
// documentation.
// This is the only way for Boost newer than V1.32.0
//
#include <boost/regex.hpp>
#endif // defined(BOOST_SPIRIT_NO_REGEX_LIB)
#include <boost/static_assert.hpp>
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/meta/as_parser.hpp>
#include <boost/spirit/home/classic/core/parser.hpp>
#include <boost/spirit/home/classic/utility/impl/regex.ipp>
#include <boost/detail/iterator.hpp> // for boost::detail::iterator_traits
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////////
// rxstrlit class
template <typename CharT = char>
struct rxstrlit : public parser<rxstrlit<CharT> > {
typedef rxstrlit self_t;
rxstrlit(CharT const *first, CharT const *last)
: rx(first, last) {}
rxstrlit(CharT const *first)
: rx(first) {}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const
{
// Due to limitations in the boost::regex library the iterators wrapped in
// the ScannerT object should be at least bidirectional iterators. Plain
// forward iterators do not work here.
typedef typename ScannerT::iterator_t iterator_t;
typedef
typename boost::detail::iterator_traits<iterator_t>::iterator_category
iterator_category;
BOOST_STATIC_ASSERT((
boost::is_convertible<iterator_category,
std::bidirectional_iterator_tag>::value
));
typedef typename parser_result<self_t, ScannerT>::type result_t;
return impl::contiguous_parser_parse<result_t>(rx, scan, scan);
}
private:
impl::rx_parser<CharT> rx; // contains the boost regular expression parser
};
///////////////////////////////////////////////////////////////////////////////
// Generator functions
template <typename CharT>
inline rxstrlit<CharT>
regex_p(CharT const *first)
{ return rxstrlit<CharT>(first); }
//////////////////////////////////
template <typename CharT>
inline rxstrlit<CharT>
regex_p(CharT const *first, CharT const *last)
{ return rxstrlit<CharT>(first, last); }
///////////////////////////////////////////////////////////////////////////////
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_REGEX_HPP
@@ -0,0 +1,113 @@
/*=============================================================================
Copyright (c) 2003 Martin Wille
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_UTILITY_SCOPED_LOCK_HPP
#define BOOST_SPIRIT_UTILITY_SCOPED_LOCK_HPP
///////////////////////////////////////////////////////////////////////////////
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/thread/lock_types.hpp>
#if !defined(BOOST_SPIRIT_COMPOSITE_HPP)
#include <boost/spirit/home/classic/core/composite.hpp>
#endif
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
///////////////////////////////////////////////////////////////////////////
//
// scoped_lock_parser class
//
// implements locking of a mutex during execution of
// the parse method of an embedded parser
//
///////////////////////////////////////////////////////////////////////////
template <typename MutexT, typename ParserT>
struct scoped_lock_parser
: public unary< ParserT, parser< scoped_lock_parser<MutexT, ParserT> > >
{
typedef scoped_lock_parser<MutexT, ParserT> self_t;
typedef MutexT mutex_t;
typedef ParserT parser_t;
template <typename ScannerT>
struct result
{
typedef typename parser_result<parser_t, ScannerT>::type type;
};
scoped_lock_parser(mutex_t &m, parser_t const &p)
: unary< ParserT, parser< scoped_lock_parser<MutexT, ParserT> > >(p)
, mutex(m)
{}
template <typename ScannerT>
typename parser_result<self_t, ScannerT>::type
parse(ScannerT const &scan) const
{
typedef boost::unique_lock<mutex_t> scoped_lock_t;
scoped_lock_t lock(mutex);
return this->subject().parse(scan);
}
mutex_t &mutex;
};
///////////////////////////////////////////////////////////////////////////
//
// scoped_lock_parser_gen
//
// generator for scoped_lock_parser objects
// operator[] returns scoped_lock_parser according to its argument
//
///////////////////////////////////////////////////////////////////////////
template <typename MutexT>
struct scoped_lock_parser_gen
{
typedef MutexT mutex_t;
explicit scoped_lock_parser_gen(mutex_t &m) : mutex(m) {}
template<typename ParserT>
scoped_lock_parser
<
MutexT,
typename as_parser<ParserT>::type
>
operator[](ParserT const &p) const
{
typedef ::BOOST_SPIRIT_CLASSIC_NS::as_parser<ParserT> as_parser_t;
typedef typename as_parser_t::type parser_t;
return scoped_lock_parser<mutex_t, parser_t>
(mutex, as_parser_t::convert(p));
}
mutex_t &mutex;
};
///////////////////////////////////////////////////////////////////////////
//
// scoped_lock_d parser directive
//
// constructs a scoped_lock_parser generator from its argument
//
///////////////////////////////////////////////////////////////////////////
template <typename MutexT>
scoped_lock_parser_gen<MutexT>
scoped_lock_d(MutexT &mutex)
{
return scoped_lock_parser_gen<MutexT>(mutex);
}
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#endif // BOOST_SPIRIT_UTILITY_SCOPED_LOCK_HPP
@@ -0,0 +1,150 @@
/*=============================================================================
Copyright (c) 2006 Tobias Schwinger
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_UTILITY_TYPEOF_HPP)
#define BOOST_SPIRIT_UTILITY_TYPEOF_HPP
#include <boost/typeof/typeof.hpp>
#include <boost/spirit/home/classic/namespace.hpp>
#include <boost/spirit/home/classic/core/typeof.hpp>
#include <boost/spirit/home/classic/utility/escape_char_fwd.hpp>
#include <boost/spirit/home/classic/utility/confix_fwd.hpp>
#include <boost/spirit/home/classic/utility/lists_fwd.hpp>
#include <boost/spirit/home/classic/utility/distinct_fwd.hpp>
#include <boost/spirit/home/classic/utility/grammar_def_fwd.hpp>
namespace boost { namespace spirit {
BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
// chset.hpp
template<typename CharT> class chset;
// functor_parser.hpp
template<typename FunctorT> struct functor_parser;
// loops.hpp
template<class ParserT, typename ExactT> class fixed_loop;
template<class ParserT, typename MinT, typename MaxT> class finite_loop;
template<class ParserT, typename MinT> class infinite_loop;
// regex.hpp
template<typename CharT> struct rxstrlit;
// flush_multi_pass.hpp
class flush_multi_pass_parser;
// scoped_lock.hpp
template<class MutexT, class ParserT> struct scoped_lock_parser;
BOOST_SPIRIT_CLASSIC_NAMESPACE_END
}} // namespace BOOST_SPIRIT_CLASSIC_NS
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
// chset.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::chset,1)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chset<char>)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::chset<wchar_t>)
// escape_char.hpp (has forward header)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::escape_char_parser,(BOOST_TYPEOF_INTEGRAL(unsigned long))(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::escape_char_action,(class)(typename)(BOOST_TYPEOF_INTEGRAL(unsigned long))(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::escape_char_parser,(BOOST_TYPEOF_INTEGRAL(unsigned long)))
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::escape_char_action,(class)(typename)(BOOST_TYPEOF_INTEGRAL(unsigned long)))
// functor_parser.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::functor_parser,1)
// loops.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::fixed_loop,2)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::finite_loop,3)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::infinite_loop,2)
// regex.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::rxstrlit,1)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::rxstrlit<char>)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::rxstrlit<wchar_t>)
// confix.hpp (has forward header)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::confix_parser, 6)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::confix_parser, 5)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::confix_parser, 4)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::confix_parser, 3)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::comment_nest_parser, 2)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::is_nested)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::non_nested)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::is_lexeme)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::non_lexeme)
// lists.hpp (has forward header)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::list_parser,4)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::list_parser,3)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::list_parser,2)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::no_list_endtoken)
// distinct.hpp (has forward header)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::distinct_parser,2)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::distinct_parser,1)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::dynamic_distinct_parser,1)
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::distinct_parser<>)
// flush_multi_pass.hpp
BOOST_TYPEOF_REGISTER_TYPE(BOOST_SPIRIT_CLASSIC_NS::flush_multi_pass_parser)
// scoped_lock.hpp
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::scoped_lock_parser,2)
// grammar_gen.hpp (has forward header)
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def,BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT)
#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 12
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def,12)
#endif
#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 9
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def, 9)
#endif
#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 6
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def, 6)
#endif
#if BOOST_SPIRIT_GRAMMAR_STARTRULE_TYPE_LIMIT > 3
BOOST_TYPEOF_REGISTER_TEMPLATE(BOOST_SPIRIT_CLASSIC_NS::grammar_def, 3)
#endif
#endif