Imported existing code

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

View File

@@ -0,0 +1,366 @@
/*=============================================================================
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;
}
}
//////////////////////////////////
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <typename CharT, typename FakeT>
void chset_negated_set(boost::shared_ptr<basic_chset<CharT> > &ptr, chlit<CharT> const &ch,
FakeT)
{
if(ch.ch != (std::numeric_limits<CharT>::min)()) {
ptr->set((std::numeric_limits<CharT>::min)(), ch.ch - 1);
}
if(ch.ch != (std::numeric_limits<CharT>::max)()) {
ptr->set(ch.ch + 1, (std::numeric_limits<CharT>::max)());
}
}
template <typename CharT, typename FakeT>
void chset_negated_set(boost::shared_ptr<basic_chset<CharT> > &ptr,
spirit::range<CharT> const &rng, FakeT)
{
if(rng.first != (std::numeric_limits<CharT>::min)()) {
ptr->set((std::numeric_limits<CharT>::min)(), rng.first - 1);
}
if(rng.last != (std::numeric_limits<CharT>::max)()) {
ptr->set(rng.last + 1, (std::numeric_limits<CharT>::max)());
}
}
#endif // BOOST_WORKAROUND(BOOST_MSVC, < 1300)
//////////////////////////////////
}} // 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); }
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
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_);
}
#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
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;
}
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
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;
}
#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template <typename CharT>
inline void
chset<CharT>::set(range<CharT> const& arg_)
{
utility::impl::detach(ptr);
ptr->set(arg_.first, arg_.last);
}
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
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)());
}
}
#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
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

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -0,0 +1,666 @@
/*=============================================================================
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;
}
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
///////////////////////////////////////////////////////////////////////////////
//
// negated_char_parser <--> chset free operators implementation
//
///////////////////////////////////////////////////////////////////////////////
template <typename CharT, typename ParserT>
inline chset<CharT>
operator|(chset<CharT> const& a, negated_char_parser<ParserT> const& b)
{
return a | chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT, typename ParserT>
inline chset<CharT>
operator&(chset<CharT> const& a, negated_char_parser<ParserT> const& b)
{
return a & chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT, typename ParserT>
inline chset<CharT>
operator-(chset<CharT> const& a, negated_char_parser<ParserT> const& b)
{
return a - chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT, typename ParserT>
inline chset<CharT>
operator^(chset<CharT> const& a, negated_char_parser<ParserT> const& b)
{
return a ^ chset<CharT>(b);
}
//////////////////////////////////
template <typename CharT, typename ParserT>
inline chset<CharT>
operator|(negated_char_parser<ParserT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) | b;
}
//////////////////////////////////
template <typename CharT, typename ParserT>
inline chset<CharT>
operator&(negated_char_parser<ParserT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) & b;
}
//////////////////////////////////
template <typename CharT, typename ParserT>
inline chset<CharT>
operator-(negated_char_parser<ParserT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) - b;
}
//////////////////////////////////
template <typename CharT, typename ParserT>
inline chset<CharT>
operator^(negated_char_parser<ParserT> const& a, chset<CharT> const& b)
{
return chset<CharT>(a) ^ b;
}
#else // BOOST_WORKAROUND(BOOST_MSVC, < 1300)
///////////////////////////////////////////////////////////////////////////////
//
// 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;
}
#endif // BOOST_WORKAROUND(BOOST_MSVC, < 1300)
///////////////////////////////////////////////////////////////////////////////
//
// 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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