Added boost header
This commit is contained in:
337
test/external/boost/xpressive/detail/dynamic/dynamic.hpp
vendored
Normal file
337
test/external/boost/xpressive/detail/dynamic/dynamic.hpp
vendored
Normal file
@@ -0,0 +1,337 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// dynamic.hpp
|
||||
//
|
||||
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_DYNAMIC_DYNAMIC_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_DYNAMIC_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/matchable.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/sequence.hpp>
|
||||
#include <boost/xpressive/detail/core/icase.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// invalid_xpression
|
||||
template<typename BidiIter>
|
||||
struct invalid_xpression
|
||||
: matchable_ex<BidiIter>
|
||||
{
|
||||
invalid_xpression()
|
||||
: matchable_ex<BidiIter>()
|
||||
{
|
||||
intrusive_ptr_add_ref(this); // keep alive forever
|
||||
}
|
||||
|
||||
bool match(match_state<BidiIter> &) const
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get_invalid_xpression
|
||||
template<typename BidiIter>
|
||||
inline shared_matchable<BidiIter> const &get_invalid_xpression()
|
||||
{
|
||||
static invalid_xpression<BidiIter> const invalid_xpr;
|
||||
static intrusive_ptr<matchable_ex<BidiIter> const> const invalid_ptr(&invalid_xpr);
|
||||
static shared_matchable<BidiIter> const invalid_matchable(invalid_ptr);
|
||||
return invalid_matchable;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// dynamic_xpression
|
||||
template<typename Matcher, typename BidiIter>
|
||||
struct dynamic_xpression
|
||||
: Matcher
|
||||
, matchable_ex<BidiIter>
|
||||
{
|
||||
typedef typename iterator_value<BidiIter>::type char_type;
|
||||
|
||||
dynamic_xpression(Matcher const &matcher = Matcher())
|
||||
: Matcher(matcher)
|
||||
, next_(get_invalid_xpression<BidiIter>())
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool match(match_state<BidiIter> &state) const
|
||||
{
|
||||
return this->Matcher::match(state, *this->next_.matchable());
|
||||
}
|
||||
|
||||
virtual void link(xpression_linker<char_type> &linker) const
|
||||
{
|
||||
linker.accept(*static_cast<Matcher const *>(this), this->next_.matchable().get());
|
||||
this->next_.link(linker);
|
||||
}
|
||||
|
||||
virtual void peek(xpression_peeker<char_type> &peeker) const
|
||||
{
|
||||
this->peek_next_(peeker.accept(*static_cast<Matcher const *>(this)), peeker);
|
||||
}
|
||||
|
||||
virtual void repeat(quant_spec const &spec, sequence<BidiIter> &seq) const
|
||||
{
|
||||
this->repeat_(spec, seq, quant_type<Matcher>(), is_same<Matcher, mark_begin_matcher>());
|
||||
}
|
||||
|
||||
private:
|
||||
friend struct sequence<BidiIter>;
|
||||
|
||||
void peek_next_(mpl::true_, xpression_peeker<char_type> &peeker) const
|
||||
{
|
||||
this->next_.peek(peeker);
|
||||
}
|
||||
|
||||
void peek_next_(mpl::false_, xpression_peeker<char_type> &) const
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
void repeat_(quant_spec const &spec, sequence<BidiIter> &seq, mpl::int_<quant_none>, mpl::false_) const
|
||||
{
|
||||
if(quant_none == seq.quant())
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
regex_error(regex_constants::error_badrepeat, "expression cannot be quantified")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->repeat_(spec, seq, mpl::int_<quant_variable_width>(), mpl::false_());
|
||||
}
|
||||
}
|
||||
|
||||
void repeat_(quant_spec const &spec, sequence<BidiIter> &seq, mpl::int_<quant_fixed_width>, mpl::false_) const
|
||||
{
|
||||
if(this->next_ == get_invalid_xpression<BidiIter>())
|
||||
{
|
||||
make_simple_repeat(spec, seq, matcher_wrapper<Matcher>(*this));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->repeat_(spec, seq, mpl::int_<quant_variable_width>(), mpl::false_());
|
||||
}
|
||||
}
|
||||
|
||||
void repeat_(quant_spec const &spec, sequence<BidiIter> &seq, mpl::int_<quant_variable_width>, mpl::false_) const
|
||||
{
|
||||
if(!is_unknown(seq.width()) && seq.pure())
|
||||
{
|
||||
make_simple_repeat(spec, seq);
|
||||
}
|
||||
else
|
||||
{
|
||||
make_repeat(spec, seq);
|
||||
}
|
||||
}
|
||||
|
||||
void repeat_(quant_spec const &spec, sequence<BidiIter> &seq, mpl::int_<quant_fixed_width>, mpl::true_) const
|
||||
{
|
||||
make_repeat(spec, seq, this->mark_number_);
|
||||
}
|
||||
|
||||
shared_matchable<BidiIter> next_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_dynamic
|
||||
template<typename BidiIter, typename Matcher>
|
||||
inline sequence<BidiIter> make_dynamic(Matcher const &matcher)
|
||||
{
|
||||
typedef dynamic_xpression<Matcher, BidiIter> xpression_type;
|
||||
intrusive_ptr<xpression_type> xpr(new xpression_type(matcher));
|
||||
return sequence<BidiIter>(xpr);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alternates_vector
|
||||
template<typename BidiIter>
|
||||
struct alternates_vector
|
||||
: std::vector<shared_matchable<BidiIter> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(std::size_t, width = unknown_width::value);
|
||||
BOOST_STATIC_CONSTANT(bool, pure = false);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matcher_wrapper
|
||||
template<typename Matcher>
|
||||
struct matcher_wrapper
|
||||
: Matcher
|
||||
{
|
||||
matcher_wrapper(Matcher const &matcher = Matcher())
|
||||
: Matcher(matcher)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIter>
|
||||
bool match(match_state<BidiIter> &state) const
|
||||
{
|
||||
return this->Matcher::match(state, matcher_wrapper<true_matcher>());
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
void link(xpression_linker<Char> &linker) const
|
||||
{
|
||||
linker.accept(*static_cast<Matcher const *>(this), 0);
|
||||
}
|
||||
|
||||
template<typename Char>
|
||||
void peek(xpression_peeker<Char> &peeker) const
|
||||
{
|
||||
peeker.accept(*static_cast<Matcher const *>(this));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// make_simple_repeat
|
||||
template<typename BidiIter, typename Xpr>
|
||||
inline void
|
||||
make_simple_repeat(quant_spec const &spec, sequence<BidiIter> &seq, Xpr const &xpr)
|
||||
{
|
||||
if(spec.greedy_)
|
||||
{
|
||||
simple_repeat_matcher<Xpr, mpl::true_> quant(xpr, spec.min_, spec.max_, seq.width().value());
|
||||
seq = make_dynamic<BidiIter>(quant);
|
||||
}
|
||||
else
|
||||
{
|
||||
simple_repeat_matcher<Xpr, mpl::false_> quant(xpr, spec.min_, spec.max_, seq.width().value());
|
||||
seq = make_dynamic<BidiIter>(quant);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// make_simple_repeat
|
||||
template<typename BidiIter>
|
||||
inline void
|
||||
make_simple_repeat(quant_spec const &spec, sequence<BidiIter> &seq)
|
||||
{
|
||||
seq += make_dynamic<BidiIter>(true_matcher());
|
||||
make_simple_repeat(spec, seq, seq.xpr());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// make_optional
|
||||
template<typename BidiIter>
|
||||
inline void
|
||||
make_optional(quant_spec const &spec, sequence<BidiIter> &seq)
|
||||
{
|
||||
typedef shared_matchable<BidiIter> xpr_type;
|
||||
seq += make_dynamic<BidiIter>(alternate_end_matcher());
|
||||
if(spec.greedy_)
|
||||
{
|
||||
optional_matcher<xpr_type, mpl::true_> opt(seq.xpr());
|
||||
seq = make_dynamic<BidiIter>(opt);
|
||||
}
|
||||
else
|
||||
{
|
||||
optional_matcher<xpr_type, mpl::false_> opt(seq.xpr());
|
||||
seq = make_dynamic<BidiIter>(opt);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// make_optional
|
||||
template<typename BidiIter>
|
||||
inline void
|
||||
make_optional(quant_spec const &spec, sequence<BidiIter> &seq, int mark_nbr)
|
||||
{
|
||||
typedef shared_matchable<BidiIter> xpr_type;
|
||||
seq += make_dynamic<BidiIter>(alternate_end_matcher());
|
||||
if(spec.greedy_)
|
||||
{
|
||||
optional_mark_matcher<xpr_type, mpl::true_> opt(seq.xpr(), mark_nbr);
|
||||
seq = make_dynamic<BidiIter>(opt);
|
||||
}
|
||||
else
|
||||
{
|
||||
optional_mark_matcher<xpr_type, mpl::false_> opt(seq.xpr(), mark_nbr);
|
||||
seq = make_dynamic<BidiIter>(opt);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// make_repeat
|
||||
template<typename BidiIter>
|
||||
inline void
|
||||
make_repeat(quant_spec const &spec, sequence<BidiIter> &seq)
|
||||
{
|
||||
// only bother creating a repeater if max is greater than one
|
||||
if(1 < spec.max_)
|
||||
{
|
||||
// create a hidden mark so this expression can be quantified
|
||||
int mark_nbr = -static_cast<int>(++*spec.hidden_mark_count_);
|
||||
seq = make_dynamic<BidiIter>(mark_begin_matcher(mark_nbr)) + seq
|
||||
+ make_dynamic<BidiIter>(mark_end_matcher(mark_nbr));
|
||||
make_repeat(spec, seq, mark_nbr);
|
||||
return;
|
||||
}
|
||||
|
||||
// if min is 0, the repeat must be made optional
|
||||
if(0 == spec.min_)
|
||||
{
|
||||
make_optional(spec, seq);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// make_repeat
|
||||
template<typename BidiIter>
|
||||
inline void
|
||||
make_repeat(quant_spec const &spec, sequence<BidiIter> &seq, int mark_nbr)
|
||||
{
|
||||
BOOST_ASSERT(spec.max_); // we should never get here if max is 0
|
||||
|
||||
// only bother creating a repeater if max is greater than one
|
||||
if(1 < spec.max_)
|
||||
{
|
||||
// TODO: statically bind the repeat matchers to the mark matchers for better perf
|
||||
unsigned int min = spec.min_ ? spec.min_ : 1U;
|
||||
repeat_begin_matcher repeat_begin(mark_nbr);
|
||||
if(spec.greedy_)
|
||||
{
|
||||
repeat_end_matcher<mpl::true_> repeat_end(mark_nbr, min, spec.max_);
|
||||
seq = make_dynamic<BidiIter>(repeat_begin) + seq
|
||||
+ make_dynamic<BidiIter>(repeat_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
repeat_end_matcher<mpl::false_> repeat_end(mark_nbr, min, spec.max_);
|
||||
seq = make_dynamic<BidiIter>(repeat_begin) + seq
|
||||
+ make_dynamic<BidiIter>(repeat_end);
|
||||
}
|
||||
}
|
||||
|
||||
// if min is 0, the repeat must be made optional
|
||||
if(0 == spec.min_)
|
||||
{
|
||||
make_optional(spec, seq, mark_nbr);
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
177
test/external/boost/xpressive/detail/dynamic/matchable.hpp
vendored
Normal file
177
test/external/boost/xpressive/detail/dynamic/matchable.hpp
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matchable.hpp
|
||||
//
|
||||
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_MATCHABLE_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/utility/counted_base.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/sequence.hpp>
|
||||
#include <boost/xpressive/regex_error.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// quant_spec
|
||||
struct quant_spec
|
||||
{
|
||||
unsigned int min_;
|
||||
unsigned int max_;
|
||||
bool greedy_;
|
||||
std::size_t *hidden_mark_count_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matchable
|
||||
template<typename BidiIter>
|
||||
struct matchable
|
||||
{
|
||||
typedef BidiIter iterator_type;
|
||||
typedef typename iterator_value<iterator_type>::type char_type;
|
||||
virtual ~matchable() {}
|
||||
virtual bool match(match_state<BidiIter> &state) const = 0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matchable_ex
|
||||
template<typename BidiIter>
|
||||
struct matchable_ex
|
||||
: matchable<BidiIter>
|
||||
, counted_base<matchable_ex<BidiIter> >
|
||||
{
|
||||
typedef BidiIter iterator_type;
|
||||
typedef typename iterator_value<iterator_type>::type char_type;
|
||||
|
||||
virtual void link(xpression_linker<char_type> &) const
|
||||
{
|
||||
}
|
||||
|
||||
virtual void peek(xpression_peeker<char_type> &peeker) const
|
||||
{
|
||||
peeker.fail();
|
||||
}
|
||||
|
||||
virtual void repeat(quant_spec const &, sequence<BidiIter> &) const
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
regex_error(regex_constants::error_badrepeat, "expression cannot be quantified")
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// The following 4 functions (push_match, top_match, pop_match and skip_match) are
|
||||
// used to implement looping and branching across the matchers. Call push_match to record
|
||||
// a position. Then, another matcher further down the xpression chain has the
|
||||
// option to call either top_match, pop_match or skip_match. top_match and pop_match will
|
||||
// jump back to the place recorded by push_match, whereas skip_match will skip the jump and
|
||||
// pass execution down the xpression chain. top_match will leave the xpression on top of the
|
||||
// stack, whereas pop_match will remove it. Each function comes in 2 flavors: one for
|
||||
// statically bound xpressions and one for dynamically bound xpressions.
|
||||
//
|
||||
|
||||
template<typename Top>
|
||||
bool push_match(match_state<BidiIter> &state) const
|
||||
{
|
||||
BOOST_MPL_ASSERT((is_same<Top, matchable_ex<BidiIter> >));
|
||||
return this->match(state);
|
||||
}
|
||||
|
||||
static bool top_match(match_state<BidiIter> &state, void const *top)
|
||||
{
|
||||
return static_cast<matchable_ex<BidiIter> const *>(top)->match(state);
|
||||
}
|
||||
|
||||
static bool pop_match(match_state<BidiIter> &state, void const *top)
|
||||
{
|
||||
return static_cast<matchable_ex<BidiIter> const *>(top)->match(state);
|
||||
}
|
||||
|
||||
bool skip_match(match_state<BidiIter> &state) const
|
||||
{
|
||||
return this->match(state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// shared_matchable
|
||||
template<typename BidiIter>
|
||||
struct shared_matchable
|
||||
{
|
||||
typedef BidiIter iterator_type;
|
||||
typedef typename iterator_value<BidiIter>::type char_type;
|
||||
typedef intrusive_ptr<matchable_ex<BidiIter> const> matchable_ptr;
|
||||
|
||||
BOOST_STATIC_CONSTANT(std::size_t, width = unknown_width::value);
|
||||
BOOST_STATIC_CONSTANT(bool, pure = false);
|
||||
|
||||
shared_matchable(matchable_ptr const &xpr = matchable_ptr())
|
||||
: xpr_(xpr)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator !() const
|
||||
{
|
||||
return !this->xpr_;
|
||||
}
|
||||
|
||||
friend bool operator ==(shared_matchable<BidiIter> const &left, shared_matchable<BidiIter> const &right)
|
||||
{
|
||||
return left.xpr_ == right.xpr_;
|
||||
}
|
||||
|
||||
friend bool operator !=(shared_matchable<BidiIter> const &left, shared_matchable<BidiIter> const &right)
|
||||
{
|
||||
return left.xpr_ != right.xpr_;
|
||||
}
|
||||
|
||||
matchable_ptr const &matchable() const
|
||||
{
|
||||
return this->xpr_;
|
||||
}
|
||||
|
||||
bool match(match_state<BidiIter> &state) const
|
||||
{
|
||||
return this->xpr_->match(state);
|
||||
}
|
||||
|
||||
void link(xpression_linker<char_type> &linker) const
|
||||
{
|
||||
this->xpr_->link(linker);
|
||||
}
|
||||
|
||||
void peek(xpression_peeker<char_type> &peeker) const
|
||||
{
|
||||
this->xpr_->peek(peeker);
|
||||
}
|
||||
|
||||
// BUGBUG yuk!
|
||||
template<typename Top>
|
||||
bool push_match(match_state<BidiIter> &state) const
|
||||
{
|
||||
BOOST_MPL_ASSERT((is_same<Top, matchable_ex<BidiIter> >));
|
||||
return this->match(state);
|
||||
}
|
||||
|
||||
private:
|
||||
matchable_ptr xpr_;
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
365
test/external/boost/xpressive/detail/dynamic/parse_charset.hpp
vendored
Normal file
365
test/external/boost/xpressive/detail/dynamic/parse_charset.hpp
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// parse_charset.hpp
|
||||
//
|
||||
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_DYNAMIC_PARSE_CHARSET_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSE_CHARSET_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/integer.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/numeric/conversion/converter.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/parser_enum.hpp>
|
||||
#include <boost/xpressive/detail/utility/literals.hpp>
|
||||
#include <boost/xpressive/detail/utility/chset/chset.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
enum escape_type
|
||||
{
|
||||
escape_char
|
||||
, escape_mark
|
||||
, escape_class
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// escape_value
|
||||
//
|
||||
template<typename Char, typename Class>
|
||||
struct escape_value
|
||||
{
|
||||
Char ch_;
|
||||
int mark_nbr_;
|
||||
Class class_;
|
||||
escape_type type_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// char_overflow_handler
|
||||
//
|
||||
struct char_overflow_handler
|
||||
{
|
||||
void operator ()(numeric::range_check_result result) const // throw(regex_error)
|
||||
{
|
||||
if(numeric::cInRange != result)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(
|
||||
regex_error(
|
||||
regex_constants::error_escape
|
||||
, "character escape too large to fit in target character type"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// parse_escape
|
||||
//
|
||||
template<typename FwdIter, typename CompilerTraits>
|
||||
escape_value<typename iterator_value<FwdIter>::type, typename CompilerTraits::regex_traits::char_class_type>
|
||||
parse_escape(FwdIter &begin, FwdIter end, CompilerTraits &tr)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
typedef typename iterator_value<FwdIter>::type char_type;
|
||||
typedef typename CompilerTraits::regex_traits regex_traits;
|
||||
typedef typename regex_traits::char_class_type char_class_type;
|
||||
|
||||
// define an unsigned type the same size as char_type
|
||||
typedef typename boost::uint_t<CHAR_BIT * sizeof(char_type)>::least uchar_t;
|
||||
BOOST_MPL_ASSERT_RELATION(sizeof(uchar_t), ==, sizeof(char_type));
|
||||
typedef numeric::conversion_traits<uchar_t, int> converstion_traits;
|
||||
|
||||
BOOST_XPR_ENSURE_(begin != end, error_escape, "unexpected end of pattern found");
|
||||
numeric::converter<int, uchar_t, converstion_traits, char_overflow_handler> converter;
|
||||
escape_value<char_type,char_class_type> esc = { 0, 0, 0, escape_char };
|
||||
bool const icase = (0 != (regex_constants::icase_ & tr.flags()));
|
||||
regex_traits const &rxtraits = tr.traits();
|
||||
FwdIter tmp;
|
||||
|
||||
esc.class_ = rxtraits.lookup_classname(begin, begin + 1, icase);
|
||||
if(0 != esc.class_)
|
||||
{
|
||||
esc.type_ = escape_class;
|
||||
return esc;
|
||||
}
|
||||
|
||||
if(-1 != rxtraits.value(*begin, 8))
|
||||
{
|
||||
esc.ch_ = converter(toi(begin, end, rxtraits, 8, 0777));
|
||||
return esc;
|
||||
}
|
||||
|
||||
switch(*begin)
|
||||
{
|
||||
// bell character
|
||||
case BOOST_XPR_CHAR_(char_type, 'a'):
|
||||
esc.ch_ = BOOST_XPR_CHAR_(char_type, '\a');
|
||||
++begin;
|
||||
break;
|
||||
// escape character
|
||||
case BOOST_XPR_CHAR_(char_type, 'e'):
|
||||
esc.ch_ = converter(27);
|
||||
++begin;
|
||||
break;
|
||||
// control character
|
||||
case BOOST_XPR_CHAR_(char_type, 'c'):
|
||||
BOOST_XPR_ENSURE_(++begin != end, error_escape, "unexpected end of pattern found");
|
||||
BOOST_XPR_ENSURE_
|
||||
(
|
||||
rxtraits.in_range(BOOST_XPR_CHAR_(char_type, 'a'), BOOST_XPR_CHAR_(char_type, 'z'), *begin)
|
||||
|| rxtraits.in_range(BOOST_XPR_CHAR_(char_type, 'A'), BOOST_XPR_CHAR_(char_type, 'Z'), *begin)
|
||||
, error_escape
|
||||
, "invalid escape control letter; must be one of a-z or A-Z"
|
||||
);
|
||||
// Convert to character according to ECMA-262, section 15.10.2.10:
|
||||
esc.ch_ = converter(*begin % 32);
|
||||
++begin;
|
||||
break;
|
||||
// formfeed character
|
||||
case BOOST_XPR_CHAR_(char_type, 'f'):
|
||||
esc.ch_ = BOOST_XPR_CHAR_(char_type, '\f');
|
||||
++begin;
|
||||
break;
|
||||
// newline
|
||||
case BOOST_XPR_CHAR_(char_type, 'n'):
|
||||
esc.ch_ = BOOST_XPR_CHAR_(char_type, '\n');
|
||||
++begin;
|
||||
break;
|
||||
// return
|
||||
case BOOST_XPR_CHAR_(char_type, 'r'):
|
||||
esc.ch_ = BOOST_XPR_CHAR_(char_type, '\r');
|
||||
++begin;
|
||||
break;
|
||||
// horizontal tab
|
||||
case BOOST_XPR_CHAR_(char_type, 't'):
|
||||
esc.ch_ = BOOST_XPR_CHAR_(char_type, '\t');
|
||||
++begin;
|
||||
break;
|
||||
// vertical tab
|
||||
case BOOST_XPR_CHAR_(char_type, 'v'):
|
||||
esc.ch_ = BOOST_XPR_CHAR_(char_type, '\v');
|
||||
++begin;
|
||||
break;
|
||||
// hex escape sequence
|
||||
case BOOST_XPR_CHAR_(char_type, 'x'):
|
||||
BOOST_XPR_ENSURE_(++begin != end, error_escape, "unexpected end of pattern found");
|
||||
tmp = begin;
|
||||
esc.ch_ = converter(toi(begin, end, rxtraits, 16, 0xff));
|
||||
BOOST_XPR_ENSURE_(2 == std::distance(tmp, begin), error_escape, "invalid hex escape : "
|
||||
"must be \\x HexDigit HexDigit");
|
||||
break;
|
||||
// Unicode escape sequence
|
||||
case BOOST_XPR_CHAR_(char_type, 'u'):
|
||||
BOOST_XPR_ENSURE_(++begin != end, error_escape, "unexpected end of pattern found");
|
||||
tmp = begin;
|
||||
esc.ch_ = converter(toi(begin, end, rxtraits, 16, 0xffff));
|
||||
BOOST_XPR_ENSURE_(4 == std::distance(tmp, begin), error_escape, "invalid Unicode escape : "
|
||||
"must be \\u HexDigit HexDigit HexDigit HexDigit");
|
||||
break;
|
||||
// backslash
|
||||
case BOOST_XPR_CHAR_(char_type, '\\'):
|
||||
//esc.ch_ = BOOST_XPR_CHAR_(char_type, '\\');
|
||||
//++begin;
|
||||
//break;
|
||||
// all other escaped characters represent themselves
|
||||
default:
|
||||
esc.ch_ = *begin;
|
||||
++begin;
|
||||
break;
|
||||
}
|
||||
|
||||
return esc;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// parse_charset
|
||||
//
|
||||
template<typename FwdIter, typename RegexTraits, typename CompilerTraits>
|
||||
inline void parse_charset
|
||||
(
|
||||
FwdIter &begin
|
||||
, FwdIter end
|
||||
, compound_charset<RegexTraits> &chset
|
||||
, CompilerTraits &tr
|
||||
)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
typedef typename RegexTraits::char_type char_type;
|
||||
typedef typename RegexTraits::char_class_type char_class_type;
|
||||
BOOST_ASSERT(begin != end);
|
||||
RegexTraits const &rxtraits = tr.traits();
|
||||
bool const icase = (0 != (regex_constants::icase_ & tr.flags()));
|
||||
FwdIter iprev = FwdIter();
|
||||
escape_value<char_type, char_class_type> esc = {0, 0, 0, escape_char};
|
||||
bool invert = false;
|
||||
|
||||
// check to see if we have an inverse charset
|
||||
if(begin != end && token_charset_invert == tr.get_charset_token(iprev = begin, end))
|
||||
{
|
||||
begin = iprev;
|
||||
invert = true;
|
||||
}
|
||||
|
||||
// skip the end token if-and-only-if it is the first token in the charset
|
||||
if(begin != end && token_charset_end == tr.get_charset_token(iprev = begin, end))
|
||||
{
|
||||
for(; begin != iprev; ++begin)
|
||||
{
|
||||
chset.set_char(*begin, rxtraits, icase);
|
||||
}
|
||||
}
|
||||
|
||||
compiler_token_type tok;
|
||||
char_type ch_prev = char_type(), ch_next = char_type();
|
||||
bool have_prev = false;
|
||||
|
||||
BOOST_XPR_ENSURE_(begin != end, error_brack, "unexpected end of pattern found");
|
||||
|
||||
// remember the current position and grab the next token
|
||||
iprev = begin;
|
||||
tok = tr.get_charset_token(begin, end);
|
||||
do
|
||||
{
|
||||
BOOST_XPR_ENSURE_(begin != end, error_brack, "unexpected end of pattern found");
|
||||
|
||||
if(token_charset_hyphen == tok && have_prev)
|
||||
{
|
||||
// remember the current position
|
||||
FwdIter iprev2 = begin;
|
||||
have_prev = false;
|
||||
|
||||
// ch_prev is lower bound of a range
|
||||
switch(tr.get_charset_token(begin, end))
|
||||
{
|
||||
case token_charset_hyphen:
|
||||
case token_charset_invert:
|
||||
begin = iprev2; // un-get these tokens and fall through
|
||||
case token_literal:
|
||||
ch_next = *begin++;
|
||||
BOOST_XPR_ENSURE_(ch_prev <= ch_next, error_range, "invalid charset range");
|
||||
chset.set_range(ch_prev, ch_next, rxtraits, icase);
|
||||
continue;
|
||||
case token_charset_backspace:
|
||||
ch_next = char_type(8); // backspace
|
||||
BOOST_XPR_ENSURE_(ch_prev <= ch_next, error_range, "invalid charset range");
|
||||
chset.set_range(ch_prev, ch_next, rxtraits, icase);
|
||||
continue;
|
||||
case token_escape:
|
||||
esc = parse_escape(begin, end, tr);
|
||||
if(escape_char == esc.type_)
|
||||
{
|
||||
BOOST_XPR_ENSURE_(ch_prev <= esc.ch_, error_range, "invalid charset range");
|
||||
chset.set_range(ch_prev, esc.ch_, rxtraits, icase);
|
||||
continue;
|
||||
}
|
||||
case token_charset_end: // fall through
|
||||
default: // not a range.
|
||||
begin = iprev; // backup to hyphen token
|
||||
chset.set_char(ch_prev, rxtraits, icase);
|
||||
chset.set_char(*begin++, rxtraits, icase);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(have_prev)
|
||||
{
|
||||
chset.set_char(ch_prev, rxtraits, icase);
|
||||
have_prev = false;
|
||||
}
|
||||
|
||||
switch(tok)
|
||||
{
|
||||
case token_charset_hyphen:
|
||||
case token_charset_invert:
|
||||
case token_charset_end:
|
||||
case token_posix_charset_end:
|
||||
begin = iprev; // un-get these tokens
|
||||
ch_prev = *begin++;
|
||||
have_prev = true;
|
||||
continue;
|
||||
|
||||
case token_charset_backspace:
|
||||
ch_prev = char_type(8); // backspace
|
||||
have_prev = true;
|
||||
continue;
|
||||
|
||||
case token_posix_charset_begin:
|
||||
{
|
||||
FwdIter tmp = begin, start = begin;
|
||||
bool invert = (token_charset_invert == tr.get_charset_token(tmp, end));
|
||||
if(invert)
|
||||
{
|
||||
begin = start = tmp;
|
||||
}
|
||||
while(token_literal == (tok = tr.get_charset_token(begin, end)))
|
||||
{
|
||||
tmp = ++begin;
|
||||
BOOST_XPR_ENSURE_(begin != end, error_brack, "unexpected end of pattern found");
|
||||
}
|
||||
if(token_posix_charset_end == tok)
|
||||
{
|
||||
char_class_type chclass = rxtraits.lookup_classname(start, tmp, icase);
|
||||
BOOST_XPR_ENSURE_(0 != chclass, error_ctype, "unknown class name");
|
||||
chset.set_class(chclass, invert);
|
||||
continue;
|
||||
}
|
||||
begin = iprev; // un-get this token
|
||||
ch_prev = *begin++;
|
||||
have_prev = true;
|
||||
}
|
||||
continue;
|
||||
|
||||
case token_escape:
|
||||
esc = parse_escape(begin, end, tr);
|
||||
if(escape_char == esc.type_)
|
||||
{
|
||||
ch_prev = esc.ch_;
|
||||
have_prev = true;
|
||||
}
|
||||
else if(escape_class == esc.type_)
|
||||
{
|
||||
char_class_type upper_ = lookup_classname(rxtraits, "upper");
|
||||
BOOST_ASSERT(0 != upper_);
|
||||
chset.set_class(esc.class_, rxtraits.isctype(*begin++, upper_));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
continue;
|
||||
|
||||
default:
|
||||
ch_prev = *begin++;
|
||||
have_prev = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while(BOOST_XPR_ENSURE_((iprev = begin) != end, error_brack, "unexpected end of pattern found"),
|
||||
token_charset_end != (tok = tr.get_charset_token(begin, end)));
|
||||
|
||||
if(have_prev)
|
||||
{
|
||||
chset.set_char(ch_prev, rxtraits, icase);
|
||||
}
|
||||
|
||||
if(invert)
|
||||
{
|
||||
chset.inverse();
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
360
test/external/boost/xpressive/detail/dynamic/parser.hpp
vendored
Normal file
360
test/external/boost/xpressive/detail/dynamic/parser.hpp
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file parser.hpp
|
||||
/// Contains the definition of regex_compiler, a factory for building regex objects
|
||||
/// from strings.
|
||||
//
|
||||
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/matchers.hpp>
|
||||
#include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/dynamic.hpp>
|
||||
|
||||
// The Regular Expression grammar, in pseudo BNF:
|
||||
//
|
||||
// expression = alternates ;
|
||||
//
|
||||
// alternates = sequence, *('|', sequence) ;
|
||||
//
|
||||
// sequence = quant, *(quant) ;
|
||||
//
|
||||
// quant = atom, [*+?] ;
|
||||
//
|
||||
// atom = literal |
|
||||
// '.' |
|
||||
// '\' any |
|
||||
// '(' expression ')' ;
|
||||
//
|
||||
// literal = not a meta-character ;
|
||||
//
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_char_xpression
|
||||
//
|
||||
template<typename BidiIter, typename Char, typename Traits>
|
||||
inline sequence<BidiIter> make_char_xpression
|
||||
(
|
||||
Char ch
|
||||
, regex_constants::syntax_option_type flags
|
||||
, Traits const &tr
|
||||
)
|
||||
{
|
||||
if(0 != (regex_constants::icase_ & flags))
|
||||
{
|
||||
literal_matcher<Traits, mpl::true_, mpl::false_> matcher(ch, tr);
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
literal_matcher<Traits, mpl::false_, mpl::false_> matcher(ch, tr);
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_any_xpression
|
||||
//
|
||||
template<typename BidiIter, typename Traits>
|
||||
inline sequence<BidiIter> make_any_xpression
|
||||
(
|
||||
regex_constants::syntax_option_type flags
|
||||
, Traits const &tr
|
||||
)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
typedef typename iterator_value<BidiIter>::type char_type;
|
||||
typedef detail::set_matcher<Traits, mpl::int_<2> > set_matcher;
|
||||
typedef literal_matcher<Traits, mpl::false_, mpl::true_> literal_matcher;
|
||||
|
||||
char_type const newline = tr.widen('\n');
|
||||
set_matcher s;
|
||||
s.set_[0] = newline;
|
||||
s.set_[1] = 0;
|
||||
s.inverse();
|
||||
|
||||
switch(((int)not_dot_newline | not_dot_null) & flags)
|
||||
{
|
||||
case not_dot_null:
|
||||
return make_dynamic<BidiIter>(literal_matcher(char_type(0), tr));
|
||||
|
||||
case not_dot_newline:
|
||||
return make_dynamic<BidiIter>(literal_matcher(newline, tr));
|
||||
|
||||
case (int)not_dot_newline | not_dot_null:
|
||||
return make_dynamic<BidiIter>(s);
|
||||
|
||||
default:
|
||||
return make_dynamic<BidiIter>(any_matcher());
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_literal_xpression
|
||||
//
|
||||
template<typename BidiIter, typename Traits>
|
||||
inline sequence<BidiIter> make_literal_xpression
|
||||
(
|
||||
typename Traits::string_type const &literal
|
||||
, regex_constants::syntax_option_type flags
|
||||
, Traits const &tr
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT(0 != literal.size());
|
||||
if(1 == literal.size())
|
||||
{
|
||||
return make_char_xpression<BidiIter>(literal[0], flags, tr);
|
||||
}
|
||||
|
||||
if(0 != (regex_constants::icase_ & flags))
|
||||
{
|
||||
string_matcher<Traits, mpl::true_> matcher(literal, tr);
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
string_matcher<Traits, mpl::false_> matcher(literal, tr);
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_backref_xpression
|
||||
//
|
||||
template<typename BidiIter, typename Traits>
|
||||
inline sequence<BidiIter> make_backref_xpression
|
||||
(
|
||||
int mark_nbr
|
||||
, regex_constants::syntax_option_type flags
|
||||
, Traits const &tr
|
||||
)
|
||||
{
|
||||
if(0 != (regex_constants::icase_ & flags))
|
||||
{
|
||||
return make_dynamic<BidiIter>
|
||||
(
|
||||
mark_matcher<Traits, mpl::true_>(mark_nbr, tr)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return make_dynamic<BidiIter>
|
||||
(
|
||||
mark_matcher<Traits, mpl::false_>(mark_nbr, tr)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// merge_charset
|
||||
//
|
||||
template<typename Char, typename Traits>
|
||||
inline void merge_charset
|
||||
(
|
||||
basic_chset<Char> &basic
|
||||
, compound_charset<Traits> const &compound
|
||||
, Traits const &tr
|
||||
)
|
||||
{
|
||||
detail::ignore_unused(tr);
|
||||
if(0 != compound.posix_yes())
|
||||
{
|
||||
typename Traits::char_class_type mask = compound.posix_yes();
|
||||
for(int i = 0; i <= static_cast<int>(UCHAR_MAX); ++i)
|
||||
{
|
||||
if(tr.isctype((Char)i, mask))
|
||||
{
|
||||
basic.set((Char)i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!compound.posix_no().empty())
|
||||
{
|
||||
for(std::size_t j = 0; j < compound.posix_no().size(); ++j)
|
||||
{
|
||||
typename Traits::char_class_type mask = compound.posix_no()[j];
|
||||
for(int i = 0; i <= static_cast<int>(UCHAR_MAX); ++i)
|
||||
{
|
||||
if(!tr.isctype((Char)i, mask))
|
||||
{
|
||||
basic.set((Char)i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(compound.is_inverted())
|
||||
{
|
||||
basic.inverse();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_charset_xpression
|
||||
//
|
||||
template<typename BidiIter, typename Traits>
|
||||
inline sequence<BidiIter> make_charset_xpression
|
||||
(
|
||||
compound_charset<Traits> &chset
|
||||
, Traits const &tr
|
||||
, regex_constants::syntax_option_type flags
|
||||
)
|
||||
{
|
||||
typedef typename Traits::char_type char_type;
|
||||
bool const icase = (0 != (regex_constants::icase_ & flags));
|
||||
bool const optimize = is_narrow_char<char_type>::value && 0 != (regex_constants::optimize & flags);
|
||||
|
||||
// don't care about compile speed -- fold eveything into a bitset<256>
|
||||
if(optimize)
|
||||
{
|
||||
typedef basic_chset<char_type> charset_type;
|
||||
charset_type charset(chset.base());
|
||||
if(icase)
|
||||
{
|
||||
charset_matcher<Traits, mpl::true_, charset_type> matcher(charset);
|
||||
merge_charset(matcher.charset_, chset, tr);
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
charset_matcher<Traits, mpl::false_, charset_type> matcher(charset);
|
||||
merge_charset(matcher.charset_, chset, tr);
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
// special case to make [[:digit:]] fast
|
||||
else if(chset.base().empty() && chset.posix_no().empty())
|
||||
{
|
||||
BOOST_ASSERT(0 != chset.posix_yes());
|
||||
posix_charset_matcher<Traits> matcher(chset.posix_yes(), chset.is_inverted());
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
|
||||
// default, slow
|
||||
else
|
||||
{
|
||||
if(icase)
|
||||
{
|
||||
charset_matcher<Traits, mpl::true_> matcher(chset);
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
charset_matcher<Traits, mpl::false_> matcher(chset);
|
||||
return make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_posix_charset_xpression
|
||||
//
|
||||
template<typename BidiIter, typename Traits>
|
||||
inline sequence<BidiIter> make_posix_charset_xpression
|
||||
(
|
||||
typename Traits::char_class_type m
|
||||
, bool no
|
||||
, regex_constants::syntax_option_type //flags
|
||||
, Traits const & //traits
|
||||
)
|
||||
{
|
||||
posix_charset_matcher<Traits> charset(m, no);
|
||||
return make_dynamic<BidiIter>(charset);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_assert_begin_line
|
||||
//
|
||||
template<typename BidiIter, typename Traits>
|
||||
inline sequence<BidiIter> make_assert_begin_line
|
||||
(
|
||||
regex_constants::syntax_option_type flags
|
||||
, Traits const &tr
|
||||
)
|
||||
{
|
||||
if(0 != (regex_constants::single_line & flags))
|
||||
{
|
||||
return detail::make_dynamic<BidiIter>(detail::assert_bos_matcher());
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::assert_bol_matcher<Traits> matcher(tr);
|
||||
return detail::make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_assert_end_line
|
||||
//
|
||||
template<typename BidiIter, typename Traits>
|
||||
inline sequence<BidiIter> make_assert_end_line
|
||||
(
|
||||
regex_constants::syntax_option_type flags
|
||||
, Traits const &tr
|
||||
)
|
||||
{
|
||||
if(0 != (regex_constants::single_line & flags))
|
||||
{
|
||||
return detail::make_dynamic<BidiIter>(detail::assert_eos_matcher());
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::assert_eol_matcher<Traits> matcher(tr);
|
||||
return detail::make_dynamic<BidiIter>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_assert_word
|
||||
//
|
||||
template<typename BidiIter, typename Cond, typename Traits>
|
||||
inline sequence<BidiIter> make_assert_word(Cond, Traits const &tr)
|
||||
{
|
||||
typedef typename iterator_value<BidiIter>::type char_type;
|
||||
return detail::make_dynamic<BidiIter>
|
||||
(
|
||||
detail::assert_word_matcher<Cond, Traits>(tr)
|
||||
);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_independent_end_xpression
|
||||
//
|
||||
template<typename BidiIter>
|
||||
inline sequence<BidiIter> make_independent_end_xpression(bool pure)
|
||||
{
|
||||
if(pure)
|
||||
{
|
||||
return detail::make_dynamic<BidiIter>(detail::true_matcher());
|
||||
}
|
||||
else
|
||||
{
|
||||
return detail::make_dynamic<BidiIter>(detail::independent_end_matcher());
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
81
test/external/boost/xpressive/detail/dynamic/parser_enum.hpp
vendored
Normal file
81
test/external/boost/xpressive/detail/dynamic/parser_enum.hpp
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// parser_enum.hpp
|
||||
//
|
||||
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_DYNAMIC_PARSER_ENUM_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_ENUM_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace xpressive { namespace regex_constants
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compiler_token_type
|
||||
//
|
||||
enum compiler_token_type
|
||||
{
|
||||
token_literal,
|
||||
token_any, // .
|
||||
token_escape, //
|
||||
token_group_begin, // (
|
||||
token_group_end, // )
|
||||
token_alternate, // |
|
||||
token_invalid_quantifier, // {
|
||||
token_charset_begin, // [
|
||||
token_charset_end, // ]
|
||||
token_charset_invert, // ^
|
||||
token_charset_hyphen, // -
|
||||
token_charset_backspace, // \b
|
||||
token_posix_charset_begin, // [:
|
||||
token_posix_charset_end, // :]
|
||||
token_equivalence_class_begin, // [=
|
||||
token_equivalence_class_end, // =]
|
||||
token_collation_element_begin, // [.
|
||||
token_collation_element_end, // .]
|
||||
|
||||
token_quote_meta_begin, // \Q
|
||||
token_quote_meta_end, // \E
|
||||
|
||||
token_no_mark, // ?:
|
||||
token_positive_lookahead, // ?=
|
||||
token_negative_lookahead, // ?!
|
||||
token_positive_lookbehind, // ?<=
|
||||
token_negative_lookbehind, // ?<!
|
||||
token_independent_sub_expression, // ?>
|
||||
token_comment, // ?#
|
||||
token_recurse, // ?R
|
||||
token_rule_assign, // ?$[name]=
|
||||
token_rule_ref, // ?$[name]
|
||||
token_named_mark, // ?P<name>
|
||||
token_named_mark_ref, // ?P=name
|
||||
|
||||
token_assert_begin_sequence, // \A
|
||||
token_assert_end_sequence, // \Z
|
||||
token_assert_begin_line, // ^
|
||||
token_assert_end_line, // $
|
||||
token_assert_word_begin, // \<
|
||||
token_assert_word_end, // \>
|
||||
token_assert_word_boundary, // \b
|
||||
token_assert_not_word_boundary, // \B
|
||||
|
||||
token_escape_newline, // \n
|
||||
token_escape_escape, // \e
|
||||
token_escape_formfeed, // \f
|
||||
token_escape_horizontal_tab, // \t
|
||||
token_escape_vertical_tab, // \v
|
||||
token_escape_bell, // \a
|
||||
token_escape_control, // \c
|
||||
|
||||
token_end_of_pattern
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::regex_constants
|
||||
|
||||
#endif
|
||||
474
test/external/boost/xpressive/detail/dynamic/parser_traits.hpp
vendored
Normal file
474
test/external/boost/xpressive/detail/dynamic/parser_traits.hpp
vendored
Normal file
@@ -0,0 +1,474 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// detail/dynamic/parser_traits.hpp
|
||||
//
|
||||
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_DYNAMIC_PARSER_TRAITS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_PARSER_TRAITS_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <climits>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/xpressive/regex_error.hpp>
|
||||
#include <boost/xpressive/regex_traits.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/matchable.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/parser_enum.hpp>
|
||||
#include <boost/xpressive/detail/utility/literals.hpp>
|
||||
#include <boost/xpressive/detail/utility/algorithm.hpp>
|
||||
|
||||
namespace boost { namespace xpressive
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compiler_traits
|
||||
// this works for char and wchar_t. it must be specialized for anything else.
|
||||
//
|
||||
template<typename RegexTraits>
|
||||
struct compiler_traits
|
||||
{
|
||||
typedef RegexTraits regex_traits;
|
||||
typedef typename regex_traits::char_type char_type;
|
||||
typedef typename regex_traits::string_type string_type;
|
||||
typedef typename regex_traits::locale_type locale_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
explicit compiler_traits(RegexTraits const &traits = RegexTraits())
|
||||
: traits_(traits)
|
||||
, flags_(regex_constants::ECMAScript)
|
||||
, space_(lookup_classname(traits_, "space"))
|
||||
, alnum_(lookup_classname(traits_, "alnum"))
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// flags
|
||||
regex_constants::syntax_option_type flags() const
|
||||
{
|
||||
return this->flags_;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// flags
|
||||
void flags(regex_constants::syntax_option_type flags)
|
||||
{
|
||||
this->flags_ = flags;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// traits
|
||||
regex_traits &traits()
|
||||
{
|
||||
return this->traits_;
|
||||
}
|
||||
|
||||
regex_traits const &traits() const
|
||||
{
|
||||
return this->traits_;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// imbue
|
||||
locale_type imbue(locale_type const &loc)
|
||||
{
|
||||
locale_type oldloc = this->traits().imbue(loc);
|
||||
this->space_ = lookup_classname(this->traits(), "space");
|
||||
this->alnum_ = lookup_classname(this->traits(), "alnum");
|
||||
return oldloc;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// getloc
|
||||
locale_type getloc() const
|
||||
{
|
||||
return this->traits().getloc();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get_token
|
||||
// get a token and advance the iterator
|
||||
template<typename FwdIter>
|
||||
regex_constants::compiler_token_type get_token(FwdIter &begin, FwdIter end)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
if(this->eat_ws_(begin, end) == end)
|
||||
{
|
||||
return regex_constants::token_end_of_pattern;
|
||||
}
|
||||
|
||||
switch(*begin)
|
||||
{
|
||||
case BOOST_XPR_CHAR_(char_type, '\\'): return this->get_escape_token(++begin, end);
|
||||
case BOOST_XPR_CHAR_(char_type, '.'): ++begin; return token_any;
|
||||
case BOOST_XPR_CHAR_(char_type, '^'): ++begin; return token_assert_begin_line;
|
||||
case BOOST_XPR_CHAR_(char_type, '$'): ++begin; return token_assert_end_line;
|
||||
case BOOST_XPR_CHAR_(char_type, '('): ++begin; return token_group_begin;
|
||||
case BOOST_XPR_CHAR_(char_type, ')'): ++begin; return token_group_end;
|
||||
case BOOST_XPR_CHAR_(char_type, '|'): ++begin; return token_alternate;
|
||||
case BOOST_XPR_CHAR_(char_type, '['): ++begin; return token_charset_begin;
|
||||
|
||||
case BOOST_XPR_CHAR_(char_type, '*'):
|
||||
case BOOST_XPR_CHAR_(char_type, '+'):
|
||||
case BOOST_XPR_CHAR_(char_type, '?'):
|
||||
return token_invalid_quantifier;
|
||||
|
||||
case BOOST_XPR_CHAR_(char_type, ']'):
|
||||
case BOOST_XPR_CHAR_(char_type, '{'):
|
||||
default:
|
||||
return token_literal;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get_quant_spec
|
||||
template<typename FwdIter>
|
||||
bool get_quant_spec(FwdIter &begin, FwdIter end, detail::quant_spec &spec)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
FwdIter old_begin;
|
||||
|
||||
if(this->eat_ws_(begin, end) == end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(*begin)
|
||||
{
|
||||
case BOOST_XPR_CHAR_(char_type, '*'):
|
||||
spec.min_ = 0;
|
||||
spec.max_ = (std::numeric_limits<unsigned int>::max)();
|
||||
break;
|
||||
|
||||
case BOOST_XPR_CHAR_(char_type, '+'):
|
||||
spec.min_ = 1;
|
||||
spec.max_ = (std::numeric_limits<unsigned int>::max)();
|
||||
break;
|
||||
|
||||
case BOOST_XPR_CHAR_(char_type, '?'):
|
||||
spec.min_ = 0;
|
||||
spec.max_ = 1;
|
||||
break;
|
||||
|
||||
case BOOST_XPR_CHAR_(char_type, '{'):
|
||||
old_begin = this->eat_ws_(++begin, end);
|
||||
spec.min_ = spec.max_ = detail::toi(begin, end, this->traits());
|
||||
BOOST_XPR_ENSURE_
|
||||
(
|
||||
begin != old_begin && begin != end, error_brace, "invalid quantifier"
|
||||
);
|
||||
|
||||
if(*begin == BOOST_XPR_CHAR_(char_type, ','))
|
||||
{
|
||||
old_begin = this->eat_ws_(++begin, end);
|
||||
spec.max_ = detail::toi(begin, end, this->traits());
|
||||
BOOST_XPR_ENSURE_
|
||||
(
|
||||
begin != end && BOOST_XPR_CHAR_(char_type, '}') == *begin
|
||||
, error_brace, "invalid quantifier"
|
||||
);
|
||||
|
||||
if(begin == old_begin)
|
||||
{
|
||||
spec.max_ = (std::numeric_limits<unsigned int>::max)();
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_XPR_ENSURE_
|
||||
(
|
||||
spec.min_ <= spec.max_, error_badbrace, "invalid quantification range"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_XPR_ENSURE_
|
||||
(
|
||||
BOOST_XPR_CHAR_(char_type, '}') == *begin, error_brace, "invalid quantifier"
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
spec.greedy_ = true;
|
||||
if(this->eat_ws_(++begin, end) != end && BOOST_XPR_CHAR_(char_type, '?') == *begin)
|
||||
{
|
||||
++begin;
|
||||
spec.greedy_ = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// get_group_type
|
||||
template<typename FwdIter>
|
||||
regex_constants::compiler_token_type get_group_type(FwdIter &begin, FwdIter end, string_type &name)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
if(this->eat_ws_(begin, end) != end && BOOST_XPR_CHAR_(char_type, '?') == *begin)
|
||||
{
|
||||
this->eat_ws_(++begin, end);
|
||||
BOOST_XPR_ENSURE_(begin != end, error_paren, "incomplete extension");
|
||||
|
||||
switch(*begin)
|
||||
{
|
||||
case BOOST_XPR_CHAR_(char_type, ':'): ++begin; return token_no_mark;
|
||||
case BOOST_XPR_CHAR_(char_type, '>'): ++begin; return token_independent_sub_expression;
|
||||
case BOOST_XPR_CHAR_(char_type, '#'): ++begin; return token_comment;
|
||||
case BOOST_XPR_CHAR_(char_type, '='): ++begin; return token_positive_lookahead;
|
||||
case BOOST_XPR_CHAR_(char_type, '!'): ++begin; return token_negative_lookahead;
|
||||
case BOOST_XPR_CHAR_(char_type, 'R'): ++begin; return token_recurse;
|
||||
case BOOST_XPR_CHAR_(char_type, '$'):
|
||||
this->get_name_(++begin, end, name);
|
||||
BOOST_XPR_ENSURE_(begin != end, error_paren, "incomplete extension");
|
||||
if(BOOST_XPR_CHAR_(char_type, '=') == *begin)
|
||||
{
|
||||
++begin;
|
||||
return token_rule_assign;
|
||||
}
|
||||
return token_rule_ref;
|
||||
|
||||
case BOOST_XPR_CHAR_(char_type, '<'):
|
||||
this->eat_ws_(++begin, end);
|
||||
BOOST_XPR_ENSURE_(begin != end, error_paren, "incomplete extension");
|
||||
switch(*begin)
|
||||
{
|
||||
case BOOST_XPR_CHAR_(char_type, '='): ++begin; return token_positive_lookbehind;
|
||||
case BOOST_XPR_CHAR_(char_type, '!'): ++begin; return token_negative_lookbehind;
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(regex_error(error_badbrace, "unrecognized extension"));
|
||||
}
|
||||
|
||||
case BOOST_XPR_CHAR_(char_type, 'P'):
|
||||
this->eat_ws_(++begin, end);
|
||||
BOOST_XPR_ENSURE_(begin != end, error_paren, "incomplete extension");
|
||||
switch(*begin)
|
||||
{
|
||||
case BOOST_XPR_CHAR_(char_type, '<'):
|
||||
this->get_name_(++begin, end, name);
|
||||
BOOST_XPR_ENSURE_(begin != end && BOOST_XPR_CHAR_(char_type, '>') == *begin++, error_paren, "incomplete extension");
|
||||
return token_named_mark;
|
||||
case BOOST_XPR_CHAR_(char_type, '='):
|
||||
this->get_name_(++begin, end, name);
|
||||
BOOST_XPR_ENSURE_(begin != end, error_paren, "incomplete extension");
|
||||
return token_named_mark_ref;
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(regex_error(error_badbrace, "unrecognized extension"));
|
||||
}
|
||||
|
||||
case BOOST_XPR_CHAR_(char_type, 'i'):
|
||||
case BOOST_XPR_CHAR_(char_type, 'm'):
|
||||
case BOOST_XPR_CHAR_(char_type, 's'):
|
||||
case BOOST_XPR_CHAR_(char_type, 'x'):
|
||||
case BOOST_XPR_CHAR_(char_type, '-'):
|
||||
return this->parse_mods_(begin, end);
|
||||
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(regex_error(error_badbrace, "unrecognized extension"));
|
||||
}
|
||||
}
|
||||
|
||||
return token_literal;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// get_charset_token
|
||||
// NOTE: white-space is *never* ignored in a charset.
|
||||
template<typename FwdIter>
|
||||
regex_constants::compiler_token_type get_charset_token(FwdIter &begin, FwdIter end)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
BOOST_ASSERT(begin != end);
|
||||
switch(*begin)
|
||||
{
|
||||
case BOOST_XPR_CHAR_(char_type, '^'): ++begin; return token_charset_invert;
|
||||
case BOOST_XPR_CHAR_(char_type, '-'): ++begin; return token_charset_hyphen;
|
||||
case BOOST_XPR_CHAR_(char_type, ']'): ++begin; return token_charset_end;
|
||||
case BOOST_XPR_CHAR_(char_type, '['):
|
||||
{
|
||||
FwdIter next = begin; ++next;
|
||||
if(next != end)
|
||||
{
|
||||
BOOST_XPR_ENSURE_(
|
||||
*next != BOOST_XPR_CHAR_(char_type, '=')
|
||||
, error_collate
|
||||
, "equivalence classes are not yet supported"
|
||||
);
|
||||
|
||||
BOOST_XPR_ENSURE_(
|
||||
*next != BOOST_XPR_CHAR_(char_type, '.')
|
||||
, error_collate
|
||||
, "collation sequences are not yet supported"
|
||||
);
|
||||
|
||||
if(*next == BOOST_XPR_CHAR_(char_type, ':'))
|
||||
{
|
||||
begin = ++next;
|
||||
return token_posix_charset_begin;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOOST_XPR_CHAR_(char_type, ':'):
|
||||
{
|
||||
FwdIter next = begin; ++next;
|
||||
if(next != end && *next == BOOST_XPR_CHAR_(char_type, ']'))
|
||||
{
|
||||
begin = ++next;
|
||||
return token_posix_charset_end;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOOST_XPR_CHAR_(char_type, '\\'):
|
||||
if(++begin != end)
|
||||
{
|
||||
switch(*begin)
|
||||
{
|
||||
case BOOST_XPR_CHAR_(char_type, 'b'): ++begin; return token_charset_backspace;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
return token_escape;
|
||||
default:;
|
||||
}
|
||||
return token_literal;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// get_escape_token
|
||||
template<typename FwdIter>
|
||||
regex_constants::compiler_token_type get_escape_token(FwdIter &begin, FwdIter end)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
if(begin != end)
|
||||
{
|
||||
switch(*begin)
|
||||
{
|
||||
//case BOOST_XPR_CHAR_(char_type, 'a'): ++begin; return token_escape_bell;
|
||||
//case BOOST_XPR_CHAR_(char_type, 'c'): ++begin; return token_escape_control;
|
||||
//case BOOST_XPR_CHAR_(char_type, 'e'): ++begin; return token_escape_escape;
|
||||
//case BOOST_XPR_CHAR_(char_type, 'f'): ++begin; return token_escape_formfeed;
|
||||
//case BOOST_XPR_CHAR_(char_type, 'n'): ++begin; return token_escape_newline;
|
||||
//case BOOST_XPR_CHAR_(char_type, 't'): ++begin; return token_escape_horizontal_tab;
|
||||
//case BOOST_XPR_CHAR_(char_type, 'v'): ++begin; return token_escape_vertical_tab;
|
||||
case BOOST_XPR_CHAR_(char_type, 'A'): ++begin; return token_assert_begin_sequence;
|
||||
case BOOST_XPR_CHAR_(char_type, 'b'): ++begin; return token_assert_word_boundary;
|
||||
case BOOST_XPR_CHAR_(char_type, 'B'): ++begin; return token_assert_not_word_boundary;
|
||||
case BOOST_XPR_CHAR_(char_type, 'E'): ++begin; return token_quote_meta_end;
|
||||
case BOOST_XPR_CHAR_(char_type, 'Q'): ++begin; return token_quote_meta_begin;
|
||||
case BOOST_XPR_CHAR_(char_type, 'Z'): ++begin; return token_assert_end_sequence;
|
||||
// Non-standard extension to ECMAScript syntax
|
||||
case BOOST_XPR_CHAR_(char_type, '<'): ++begin; return token_assert_word_begin;
|
||||
case BOOST_XPR_CHAR_(char_type, '>'): ++begin; return token_assert_word_end;
|
||||
default:; // fall-through
|
||||
}
|
||||
}
|
||||
|
||||
return token_escape;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// parse_mods_
|
||||
template<typename FwdIter>
|
||||
regex_constants::compiler_token_type parse_mods_(FwdIter &begin, FwdIter end)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
bool set = true;
|
||||
do switch(*begin)
|
||||
{
|
||||
case BOOST_XPR_CHAR_(char_type, 'i'): this->flag_(set, icase_); break;
|
||||
case BOOST_XPR_CHAR_(char_type, 'm'): this->flag_(!set, single_line); break;
|
||||
case BOOST_XPR_CHAR_(char_type, 's'): this->flag_(!set, not_dot_newline); break;
|
||||
case BOOST_XPR_CHAR_(char_type, 'x'): this->flag_(set, ignore_white_space); break;
|
||||
case BOOST_XPR_CHAR_(char_type, ':'): ++begin; // fall-through
|
||||
case BOOST_XPR_CHAR_(char_type, ')'): return token_no_mark;
|
||||
case BOOST_XPR_CHAR_(char_type, '-'): if(false == (set = !set)) break; // else fall-through
|
||||
default: BOOST_THROW_EXCEPTION(regex_error(error_paren, "unknown pattern modifier"));
|
||||
}
|
||||
while(BOOST_XPR_ENSURE_(++begin != end, error_paren, "incomplete extension"));
|
||||
// this return is technically unreachable, but this must
|
||||
// be here to work around a bug in gcc 4.0
|
||||
return token_no_mark;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// flag_
|
||||
void flag_(bool set, regex_constants::syntax_option_type flag)
|
||||
{
|
||||
this->flags_ = set ? (this->flags_ | flag) : (this->flags_ & ~flag);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// is_space_
|
||||
bool is_space_(char_type ch) const
|
||||
{
|
||||
return 0 != this->space_ && this->traits().isctype(ch, this->space_);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// is_alnum_
|
||||
bool is_alnum_(char_type ch) const
|
||||
{
|
||||
return 0 != this->alnum_ && this->traits().isctype(ch, this->alnum_);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// get_name_
|
||||
template<typename FwdIter>
|
||||
void get_name_(FwdIter &begin, FwdIter end, string_type &name)
|
||||
{
|
||||
this->eat_ws_(begin, end);
|
||||
for(name.clear(); begin != end && this->is_alnum_(*begin); ++begin)
|
||||
{
|
||||
name.push_back(*begin);
|
||||
}
|
||||
this->eat_ws_(begin, end);
|
||||
BOOST_XPR_ENSURE_(!name.empty(), regex_constants::error_paren, "incomplete extension");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// eat_ws_
|
||||
template<typename FwdIter>
|
||||
FwdIter &eat_ws_(FwdIter &begin, FwdIter end)
|
||||
{
|
||||
if(0 != (regex_constants::ignore_white_space & this->flags()))
|
||||
{
|
||||
while(end != begin && (BOOST_XPR_CHAR_(char_type, '#') == *begin || this->is_space_(*begin)))
|
||||
{
|
||||
if(BOOST_XPR_CHAR_(char_type, '#') == *begin++)
|
||||
{
|
||||
while(end != begin && BOOST_XPR_CHAR_(char_type, '\n') != *begin++) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(; end != begin && this->is_space_(*begin); ++begin) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return begin;
|
||||
}
|
||||
|
||||
regex_traits traits_;
|
||||
regex_constants::syntax_option_type flags_;
|
||||
typename regex_traits::char_class_type space_;
|
||||
typename regex_traits::char_class_type alnum_;
|
||||
};
|
||||
|
||||
}} // namespace boost::xpressive
|
||||
|
||||
#endif
|
||||
175
test/external/boost/xpressive/detail/dynamic/sequence.hpp
vendored
Normal file
175
test/external/boost/xpressive/detail/dynamic/sequence.hpp
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// sequence.hpp
|
||||
//
|
||||
// Copyright 2008 Eric Niebler. 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_XPRESSIVE_DETAIL_DYNAMIC_SEQUENCE_HPP_EAN_04_10_2006
|
||||
#define BOOST_XPRESSIVE_DETAIL_DYNAMIC_SEQUENCE_HPP_EAN_04_10_2006
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/xpressive/detail/utility/width.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// sequence
|
||||
template<typename BidiIter>
|
||||
struct sequence
|
||||
{
|
||||
sequence()
|
||||
: pure_(true)
|
||||
, width_(0)
|
||||
, quant_(quant_none)
|
||||
, head_()
|
||||
, tail_(0)
|
||||
, alt_end_xpr_()
|
||||
, alternates_(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Matcher>
|
||||
sequence(intrusive_ptr<dynamic_xpression<Matcher, BidiIter> > const &xpr)
|
||||
: pure_(Matcher::pure)
|
||||
, width_(xpr->Matcher::get_width())
|
||||
, quant_(static_cast<quant_enum>(Matcher::quant))
|
||||
, head_(xpr)
|
||||
, tail_(&xpr->next_)
|
||||
, alt_end_xpr_()
|
||||
, alternates_(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Traits>
|
||||
sequence(intrusive_ptr<dynamic_xpression<alternate_matcher<alternates_vector<BidiIter>, Traits>, BidiIter> > const &xpr)
|
||||
: pure_(true)
|
||||
, width_(0)
|
||||
, quant_(quant_none)
|
||||
, head_(xpr)
|
||||
, tail_(&xpr->next_)
|
||||
, alt_end_xpr_()
|
||||
, alternates_(&xpr->alternates_)
|
||||
{
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return !this->head_;
|
||||
}
|
||||
|
||||
sequence<BidiIter> &operator +=(sequence<BidiIter> const &that)
|
||||
{
|
||||
if(this->empty())
|
||||
{
|
||||
*this = that;
|
||||
}
|
||||
else if(!that.empty())
|
||||
{
|
||||
*this->tail_ = that.head_;
|
||||
this->tail_ = that.tail_;
|
||||
// keep track of sequence width and purity
|
||||
this->width_ += that.width_;
|
||||
this->pure_ = this->pure_ && that.pure_;
|
||||
this->set_quant_();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
sequence<BidiIter> &operator |=(sequence<BidiIter> that)
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
BOOST_ASSERT(0 != this->alternates_);
|
||||
|
||||
// Keep track of width and purity
|
||||
if(this->alternates_->empty())
|
||||
{
|
||||
this->width_ = that.width_;
|
||||
this->pure_ = that.pure_;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->width_ |= that.width_;
|
||||
this->pure_ = this->pure_ && that.pure_;
|
||||
}
|
||||
|
||||
// through the wonders of reference counting, all alternates_ can share an end_alternate
|
||||
if(!this->alt_end_xpr_)
|
||||
{
|
||||
this->alt_end_xpr_ = new alt_end_xpr_type;
|
||||
}
|
||||
|
||||
// terminate each alternate with an alternate_end_matcher
|
||||
that += sequence(this->alt_end_xpr_);
|
||||
this->alternates_->push_back(that.head_);
|
||||
this->set_quant_();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void repeat(quant_spec const &spec)
|
||||
{
|
||||
this->xpr().matchable()->repeat(spec, *this);
|
||||
}
|
||||
|
||||
shared_matchable<BidiIter> const &xpr() const
|
||||
{
|
||||
return this->head_;
|
||||
}
|
||||
|
||||
detail::width width() const
|
||||
{
|
||||
return this->width_;
|
||||
}
|
||||
|
||||
bool pure() const
|
||||
{
|
||||
return this->pure_;
|
||||
}
|
||||
|
||||
quant_enum quant() const
|
||||
{
|
||||
return this->quant_;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef dynamic_xpression<alternate_end_matcher, BidiIter> alt_end_xpr_type;
|
||||
|
||||
void set_quant_()
|
||||
{
|
||||
this->quant_ = (!is_unknown(this->width_) && this->pure_)
|
||||
? (!this->width_ ? quant_none : quant_fixed_width)
|
||||
: quant_variable_width;
|
||||
}
|
||||
|
||||
bool pure_;
|
||||
detail::width width_;
|
||||
quant_enum quant_;
|
||||
shared_matchable<BidiIter> head_;
|
||||
shared_matchable<BidiIter> *tail_;
|
||||
intrusive_ptr<alt_end_xpr_type> alt_end_xpr_;
|
||||
alternates_vector<BidiIter> *alternates_;
|
||||
};
|
||||
|
||||
template<typename BidiIter>
|
||||
inline sequence<BidiIter> operator +(sequence<BidiIter> left, sequence<BidiIter> const &right)
|
||||
{
|
||||
return left += right;
|
||||
}
|
||||
|
||||
template<typename BidiIter>
|
||||
inline sequence<BidiIter> operator |(sequence<BidiIter> left, sequence<BidiIter> const &right)
|
||||
{
|
||||
return left |= right;
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user