stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -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>
|
||||
+402
@@ -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)
|
||||
+37
@@ -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
|
||||
|
||||
|
||||
+184
@@ -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
|
||||
+30
@@ -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
|
||||
|
||||
+77
@@ -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
|
||||
+69
@@ -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
|
||||
+307
@@ -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
|
||||
+52
@@ -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
|
||||
|
||||
+107
@@ -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>
|
||||
+246
@@ -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
|
||||
|
||||
+127
@@ -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>
|
||||
+218
@@ -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
|
||||
+592
@@ -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
|
||||
|
||||
+221
@@ -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
|
||||
|
||||
+224
@@ -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
|
||||
+1142
File diff suppressed because it is too large
Load Diff
+113
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user