mirror of
https://github.com/boostorg/xpressive.git
synced 2026-01-19 04:52:07 +00:00
xpressive 0.9.8
[SVN r31203]
This commit is contained in:
96
.gitattributes
vendored
Normal file
96
.gitattributes
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
* text=auto !eol svneol=native#text/plain
|
||||
*.gitattributes text svneol=native#text/plain
|
||||
|
||||
# Scriptish formats
|
||||
*.bat text svneol=native#text/plain
|
||||
*.bsh text svneol=native#text/x-beanshell
|
||||
*.cgi text svneol=native#text/plain
|
||||
*.cmd text svneol=native#text/plain
|
||||
*.js text svneol=native#text/javascript
|
||||
*.php text svneol=native#text/x-php
|
||||
*.pl text svneol=native#text/x-perl
|
||||
*.pm text svneol=native#text/x-perl
|
||||
*.py text svneol=native#text/x-python
|
||||
*.sh eol=lf svneol=LF#text/x-sh
|
||||
configure eol=lf svneol=LF#text/x-sh
|
||||
|
||||
# Image formats
|
||||
*.bmp binary svneol=unset#image/bmp
|
||||
*.gif binary svneol=unset#image/gif
|
||||
*.ico binary svneol=unset#image/ico
|
||||
*.jpeg binary svneol=unset#image/jpeg
|
||||
*.jpg binary svneol=unset#image/jpeg
|
||||
*.png binary svneol=unset#image/png
|
||||
*.tif binary svneol=unset#image/tiff
|
||||
*.tiff binary svneol=unset#image/tiff
|
||||
*.svg text svneol=native#image/svg%2Bxml
|
||||
|
||||
# Data formats
|
||||
*.pdf binary svneol=unset#application/pdf
|
||||
*.avi binary svneol=unset#video/avi
|
||||
*.doc binary svneol=unset#application/msword
|
||||
*.dsp text svneol=crlf#text/plain
|
||||
*.dsw text svneol=crlf#text/plain
|
||||
*.eps binary svneol=unset#application/postscript
|
||||
*.gz binary svneol=unset#application/gzip
|
||||
*.mov binary svneol=unset#video/quicktime
|
||||
*.mp3 binary svneol=unset#audio/mpeg
|
||||
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
|
||||
*.ps binary svneol=unset#application/postscript
|
||||
*.psd binary svneol=unset#application/photoshop
|
||||
*.rdf binary svneol=unset#text/rdf
|
||||
*.rss text svneol=unset#text/xml
|
||||
*.rtf binary svneol=unset#text/rtf
|
||||
*.sln text svneol=native#text/plain
|
||||
*.swf binary svneol=unset#application/x-shockwave-flash
|
||||
*.tgz binary svneol=unset#application/gzip
|
||||
*.vcproj text svneol=native#text/xml
|
||||
*.vcxproj text svneol=native#text/xml
|
||||
*.vsprops text svneol=native#text/xml
|
||||
*.wav binary svneol=unset#audio/wav
|
||||
*.xls binary svneol=unset#application/vnd.ms-excel
|
||||
*.zip binary svneol=unset#application/zip
|
||||
|
||||
# Text formats
|
||||
.htaccess text svneol=native#text/plain
|
||||
*.bbk text svneol=native#text/xml
|
||||
*.cmake text svneol=native#text/plain
|
||||
*.css text svneol=native#text/css
|
||||
*.dtd text svneol=native#text/xml
|
||||
*.htm text svneol=native#text/html
|
||||
*.html text svneol=native#text/html
|
||||
*.ini text svneol=native#text/plain
|
||||
*.log text svneol=native#text/plain
|
||||
*.mak text svneol=native#text/plain
|
||||
*.qbk text svneol=native#text/plain
|
||||
*.rst text svneol=native#text/plain
|
||||
*.sql text svneol=native#text/x-sql
|
||||
*.txt text svneol=native#text/plain
|
||||
*.xhtml text svneol=native#text/xhtml%2Bxml
|
||||
*.xml text svneol=native#text/xml
|
||||
*.xsd text svneol=native#text/xml
|
||||
*.xsl text svneol=native#text/xml
|
||||
*.xslt text svneol=native#text/xml
|
||||
*.xul text svneol=native#text/xul
|
||||
*.yml text svneol=native#text/plain
|
||||
boost-no-inspect text svneol=native#text/plain
|
||||
CHANGES text svneol=native#text/plain
|
||||
COPYING text svneol=native#text/plain
|
||||
INSTALL text svneol=native#text/plain
|
||||
Jamfile text svneol=native#text/plain
|
||||
Jamroot text svneol=native#text/plain
|
||||
Jamfile.v2 text svneol=native#text/plain
|
||||
Jamrules text svneol=native#text/plain
|
||||
Makefile* text svneol=native#text/plain
|
||||
README text svneol=native#text/plain
|
||||
TODO text svneol=native#text/plain
|
||||
|
||||
# Code formats
|
||||
*.c text svneol=native#text/plain
|
||||
*.cpp text svneol=native#text/plain
|
||||
*.h text svneol=native#text/plain
|
||||
*.hpp text svneol=native#text/plain
|
||||
*.ipp text svneol=native#text/plain
|
||||
*.tpp text svneol=native#text/plain
|
||||
*.jam text svneol=native#text/plain
|
||||
*.java text svneol=native#text/plain
|
||||
360
include/boost/xpressive/basic_regex.hpp
Executable file
360
include/boost/xpressive/basic_regex.hpp
Executable file
@@ -0,0 +1,360 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file basic_regex.hpp
|
||||
/// Contains the definition of the basic_regex\<\> class template and its
|
||||
/// associated helper functions.
|
||||
//
|
||||
// Copyright 2004 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_BASIC_REGEX_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
# include <iosfwd>
|
||||
#endif
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/xpressive/proto/proto_fwd.hpp>
|
||||
#include <boost/xpressive/regex_traits.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/finder.hpp>
|
||||
#include <boost/xpressive/detail/core/adaptor.hpp>
|
||||
#include <boost/xpressive/detail/core/regex_impl.hpp>
|
||||
#include <boost/xpressive/detail/static/type_traits.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/visitor.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
#include <boost/xpressive/detail/utility/hash_peek_bitset.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// optimize_regex
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
inline typename enable_if<is_random<BidiIterT> >::type
|
||||
optimize_regex(regex_impl<BidiIterT> &impl, TraitsT const &traits)
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
// optimization: get the peek chars OR the boyer-moore search string
|
||||
hash_peek_bitset<char_type> bset;
|
||||
xpression_peeker<char_type> peeker(&bset, traits);
|
||||
impl.xpr_->peek(peeker);
|
||||
|
||||
// if we have a leading string literal, initialize a boyer-moore struct with it
|
||||
std::pair<std::basic_string<char_type> const *, bool> str = peeker.get_string();
|
||||
if(0 != str.first)
|
||||
{
|
||||
impl.finder_.reset
|
||||
(
|
||||
new boyer_moore_finder<BidiIterT, TraitsT>
|
||||
(
|
||||
str.first->data()
|
||||
, str.first->data() + str.first->size()
|
||||
, traits
|
||||
, str.second
|
||||
)
|
||||
);
|
||||
}
|
||||
else if(peeker.line_start())
|
||||
{
|
||||
impl.finder_.reset
|
||||
(
|
||||
new line_start_finder<BidiIterT, TraitsT>(traits)
|
||||
);
|
||||
}
|
||||
else if(256 != bset.count())
|
||||
{
|
||||
impl.finder_.reset
|
||||
(
|
||||
new hash_peek_finder<BidiIterT, TraitsT>(bset)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// optimize_regex
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
inline typename disable_if<is_random<BidiIterT> >::type
|
||||
optimize_regex(regex_impl<BidiIterT> &impl, TraitsT const &traits)
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
// optimization: get the peek chars OR the line start finder
|
||||
hash_peek_bitset<char_type> bset;
|
||||
xpression_peeker<char_type> peeker(&bset, traits);
|
||||
impl.xpr_->peek(peeker);
|
||||
|
||||
if(peeker.line_start())
|
||||
{
|
||||
impl.finder_.reset
|
||||
(
|
||||
new line_start_finder<BidiIterT, TraitsT>(traits)
|
||||
);
|
||||
}
|
||||
else if(256 != bset.count())
|
||||
{
|
||||
impl.finder_.reset
|
||||
(
|
||||
new hash_peek_finder<BidiIterT, TraitsT>(bset)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// basic_regex
|
||||
//
|
||||
/// \brief Class template basic_regex\<\> is a class for holding a compiled regular expression.
|
||||
template<typename BidiIterT>
|
||||
struct basic_regex
|
||||
{
|
||||
typedef BidiIterT iterator_type;
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
typedef regex_constants::syntax_option_type flag_type;
|
||||
|
||||
/// \post regex_id() == 0
|
||||
/// \post mark_count() == 0
|
||||
basic_regex()
|
||||
: impl_()
|
||||
{
|
||||
}
|
||||
|
||||
/// \param that The basic_regex object to copy.
|
||||
/// \post regex_id() == that.regex_id()
|
||||
/// \post mark_count() == that.mark_count()
|
||||
basic_regex(basic_regex<BidiIterT> const &that)
|
||||
: impl_(that.impl_)
|
||||
{
|
||||
}
|
||||
|
||||
/// \param that The basic_regex object to copy.
|
||||
/// \post regex_id() == that.regex_id()
|
||||
/// \post mark_count() == that.mark_count()
|
||||
/// \return *this
|
||||
basic_regex<BidiIterT> &operator =(basic_regex<BidiIterT> const &that)
|
||||
{
|
||||
this->impl_ = that.impl_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/// Construct from a static regular expression.
|
||||
///
|
||||
/// \param xpr The static regular expression
|
||||
/// \pre XprT is the type of a static regular expression.
|
||||
/// \post regex_id() != 0
|
||||
/// \post mark_count() \>= 0
|
||||
template<typename XprT>
|
||||
basic_regex(XprT const &xpr)
|
||||
: impl_()
|
||||
{
|
||||
this->operator =(xpr);
|
||||
}
|
||||
|
||||
/// Construct from a static regular expression.
|
||||
///
|
||||
/// \param xpr The static regular expression.
|
||||
/// \pre XprT is the type of a static regular expression.
|
||||
/// \post regex_id() != 0
|
||||
/// \post mark_count() \>= 0
|
||||
/// \throw std::bad_alloc on out of memory
|
||||
/// \return *this
|
||||
template<typename XprT>
|
||||
basic_regex<BidiIterT> &operator =(XprT const &xpr)
|
||||
{
|
||||
// use default traits
|
||||
typedef regex_traits<char_type> traits_type;
|
||||
this->compile_(xpr, traits_type());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename LocaleT, typename XprT>
|
||||
basic_regex<BidiIterT> &operator =
|
||||
(
|
||||
proto::binary_op<detail::locale_modifier<LocaleT>, XprT, detail::modifier_tag> const &xpr
|
||||
)
|
||||
{
|
||||
// use specified traits
|
||||
typedef typename detail::regex_traits_type<LocaleT, BidiIterT>::type traits_type;
|
||||
this->compile_(proto::right(xpr), traits_type(proto::left(xpr).getloc()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Returns the count of capturing sub-expressions in this regular expression
|
||||
///
|
||||
std::size_t mark_count() const
|
||||
{
|
||||
return this->impl_ ? this->impl_->mark_count_ : 0;
|
||||
}
|
||||
|
||||
/// Returns a token which uniquely identifies this regular expression.
|
||||
///
|
||||
regex_id_type regex_id() const
|
||||
{
|
||||
return this->impl_ ? this->impl_->xpr_.get() : 0;
|
||||
}
|
||||
|
||||
/// Swaps the contents of this basic_regex object with another.
|
||||
///
|
||||
/// \param that The other basic_regex object.
|
||||
/// \attention This is a shallow swap that does not do reference tracking. If you embed
|
||||
/// a basic_regex object by reference in another regular expression and then swap its
|
||||
/// contents with another basic_regex object, the change will not be visible to the enclosing
|
||||
/// regular expression. It is done this way to ensure that swap() cannot throw.
|
||||
/// \throw nothrow
|
||||
void swap(basic_regex<BidiIterT> &that) // throw()
|
||||
{
|
||||
this->impl_.swap(that.impl_);
|
||||
}
|
||||
|
||||
/// Factory method for building a regex object from a string.
|
||||
/// Equivalent to regex_compiler\< BidiIterT \>().compile(str, flags);
|
||||
///
|
||||
/// \param str The std::basic_string containing the regular expression.
|
||||
/// \param flags Optional bitmask of type syntax_option_type to control how str is interpreted.
|
||||
static basic_regex<BidiIterT> compile(string_type const &str, flag_type flags = regex_constants::ECMAScript)
|
||||
{
|
||||
return regex_compiler<BidiIterT>().compile(str, flags);
|
||||
}
|
||||
|
||||
// for binding actions to this regex when it is nested statically in another regex
|
||||
/// INTERNAL ONLY
|
||||
template<typename ActionT>
|
||||
proto::binary_op
|
||||
<
|
||||
proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::unary_op<ActionT, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
> const
|
||||
operator [](detail::action_matcher<ActionT> const &action) const
|
||||
{
|
||||
return proto::noop(*this) >> proto::noop(*static_cast<ActionT const *>(&action));
|
||||
}
|
||||
|
||||
//{{AFX_DEBUG
|
||||
#ifndef NDEBUG
|
||||
// BUGBUG debug only
|
||||
/// INTERNAL ONLY
|
||||
friend std::ostream &operator <<(std::ostream &sout, basic_regex<BidiIterT> const &rex)
|
||||
{
|
||||
rex.dump_(sout);
|
||||
return sout;
|
||||
}
|
||||
#endif
|
||||
//}}AFX_DEBUG
|
||||
|
||||
private:
|
||||
friend struct detail::core_access<BidiIterT>;
|
||||
|
||||
// Avoid a common programming mistake. Construction from a string is ambiguous. It could mean
|
||||
// sregex rx = sregex::compile(str); // compile the string into a regex
|
||||
// or
|
||||
// sregex rx = str >> epsilon; // treat the string as a literal
|
||||
// Since there is no easy way to disambiguate, disallow it and force users to say what they mean
|
||||
/// INTERNAL ONLY
|
||||
basic_regex(char_type const *);
|
||||
/// INTERNAL ONLY
|
||||
basic_regex(string_type const &);
|
||||
|
||||
// used from parser, via core_access
|
||||
/// INTERNAL ONLY
|
||||
explicit basic_regex(detail::regex_impl<BidiIterT> const &that)
|
||||
: impl_()
|
||||
{
|
||||
this->impl_.tracking_copy(that);
|
||||
}
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename XprT, typename TraitsT>
|
||||
void compile_(XprT const &xpr, TraitsT const &traits)
|
||||
{
|
||||
// "compile" the regex and wrap it in an xpression_adaptor
|
||||
detail::xpression_visitor<BidiIterT, mpl::false_, TraitsT> visitor(traits, this->impl_.get());
|
||||
visitor.impl().traits_.reset(new TraitsT(visitor.traits()));
|
||||
visitor.impl().xpr_ =
|
||||
detail::make_adaptor<BidiIterT>(proto::compile(xpr, detail::end_xpression(), visitor, detail::seq_tag()));
|
||||
|
||||
// "link" the regex
|
||||
detail::xpression_linker<char_type> linker(visitor.traits());
|
||||
visitor.impl().xpr_->link(linker);
|
||||
|
||||
// optimization: get the peek chars OR the boyer-moore search string
|
||||
detail::optimize_regex(visitor.impl(), visitor.traits());
|
||||
|
||||
// copy the implementation
|
||||
this->impl_.tracking_copy(visitor.impl());
|
||||
}
|
||||
|
||||
/// INTERNAL ONLY
|
||||
bool match_(detail::state_type<BidiIterT> &state) const
|
||||
{
|
||||
return this->impl_->xpr_->match(state);
|
||||
}
|
||||
|
||||
// Returns true if this basic_regex object does not contain a valid regular expression.
|
||||
/// INTERNAL ONLY
|
||||
bool invalid_() const
|
||||
{
|
||||
return !this->impl_ || !this->impl_->xpr_;
|
||||
}
|
||||
|
||||
/// INTERNAL ONLY
|
||||
void dump_(std::ostream &sout) const;
|
||||
|
||||
// the tracking_ptr manages lazy-init, COW, cycle-breaking, and
|
||||
// reference/dependency tracking.
|
||||
detail::tracking_ptr<detail::regex_impl<BidiIterT> > impl_;
|
||||
};
|
||||
|
||||
//{{AFX_DEBUG
|
||||
#ifndef NDEBUG
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// dump_
|
||||
/// INTERNAL ONLY
|
||||
template<typename BidiIterT>
|
||||
inline void basic_regex<BidiIterT>::dump_(std::ostream &sout) const
|
||||
{
|
||||
if(!this->impl_)
|
||||
{
|
||||
sout << "<null> refs={} deps={}";
|
||||
}
|
||||
else
|
||||
{
|
||||
sout << *this->impl_;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//}}AFX_DEBUG
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// swap
|
||||
/// \brief Swaps the contents of two basic_regex objects.
|
||||
/// \param left The first basic_regex object.
|
||||
/// \param right The second basic_regex object.
|
||||
/// \attention This is a shallow swap that does not do reference tracking.
|
||||
/// If you embed a basic_regex object by reference in another regular expression
|
||||
/// and then swap its contents with another basic_regex object, the change will
|
||||
/// not be visible to the enclosing regular expression. It is done this way to
|
||||
/// ensure that swap() cannot throw.
|
||||
/// \throw nothrow
|
||||
template<typename BidiIterT>
|
||||
inline void swap(basic_regex<BidiIterT> &left, basic_regex<BidiIterT> &right) // throw()
|
||||
{
|
||||
left.swap(right);
|
||||
}
|
||||
|
||||
}} // namespace boost::xpressive
|
||||
|
||||
#endif // BOOST_XPRESSIVE_REGEX_HPP_EAN_10_04_2005
|
||||
131
include/boost/xpressive/detail/core/access.hpp
Executable file
131
include/boost/xpressive/detail/core/access.hpp
Executable file
@@ -0,0 +1,131 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// accesss.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_ACCESS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_ACCESS_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/matchable.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// core_access
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct core_access
|
||||
{
|
||||
// BUGBUG give basic_regex move semantics!
|
||||
static basic_regex<BidiIterT> make_regex(regex_impl<BidiIterT> const &impl)
|
||||
{
|
||||
return basic_regex<BidiIterT>(impl);
|
||||
}
|
||||
|
||||
static std::size_t get_hidden_mark_count(basic_regex<BidiIterT> const &rex)
|
||||
{
|
||||
return rex.impl_->hidden_mark_count_;
|
||||
}
|
||||
|
||||
static bool invalid(basic_regex<BidiIterT> const &rex)
|
||||
{
|
||||
return rex.invalid_();
|
||||
}
|
||||
|
||||
static bool match(basic_regex<BidiIterT> const &rex, state_type<BidiIterT> &state)
|
||||
{
|
||||
return rex.match_(state);
|
||||
}
|
||||
|
||||
static shared_ptr<detail::regex_impl<BidiIterT> > const &
|
||||
get_regex_impl(basic_regex<BidiIterT> const &rex)
|
||||
{
|
||||
return rex.impl_.get();
|
||||
}
|
||||
|
||||
static void init_sub_match_vector
|
||||
(
|
||||
sub_match_vector<BidiIterT> &subs_vect
|
||||
, sub_match_impl<BidiIterT> *subs_ptr
|
||||
, std::size_t size
|
||||
)
|
||||
{
|
||||
subs_vect.init_(subs_ptr, size);
|
||||
}
|
||||
|
||||
static void init_sub_match_vector
|
||||
(
|
||||
sub_match_vector<BidiIterT> &subs_vect
|
||||
, sub_match_impl<BidiIterT> *subs_ptr
|
||||
, std::size_t size
|
||||
, sub_match_vector<BidiIterT> const &that
|
||||
)
|
||||
{
|
||||
subs_vect.init_(subs_ptr, size, that);
|
||||
}
|
||||
|
||||
static void init_match_results
|
||||
(
|
||||
match_results<BidiIterT> &what
|
||||
, regex_id_type regex_id
|
||||
, sub_match_impl<BidiIterT> *sub_matches
|
||||
, std::size_t size
|
||||
)
|
||||
{
|
||||
what.init_(regex_id, sub_matches, size);
|
||||
}
|
||||
|
||||
static sub_match_vector<BidiIterT> &get_sub_match_vector(match_results<BidiIterT> &what)
|
||||
{
|
||||
return what.sub_matches_;
|
||||
}
|
||||
|
||||
static sub_match_impl<BidiIterT> *get_sub_matches(sub_match_vector<BidiIterT> &subs)
|
||||
{
|
||||
return subs.sub_matches_;
|
||||
}
|
||||
|
||||
static results_extras<BidiIterT> &get_extras(match_results<BidiIterT> &what)
|
||||
{
|
||||
return what.get_extras_();
|
||||
}
|
||||
|
||||
static nested_results<BidiIterT> &get_nested_results(match_results<BidiIterT> &what)
|
||||
{
|
||||
return what.nested_results_;
|
||||
}
|
||||
|
||||
static action_state &get_action_state(match_results<BidiIterT> &what)
|
||||
{
|
||||
return what.action_state_;
|
||||
}
|
||||
|
||||
static void set_prefix_suffix(match_results<BidiIterT> &what, BidiIterT begin, BidiIterT end)
|
||||
{
|
||||
what.set_prefix_suffix_(begin, end);
|
||||
}
|
||||
|
||||
static void reset(match_results<BidiIterT> &what)
|
||||
{
|
||||
what.reset_();
|
||||
}
|
||||
|
||||
static void set_base(match_results<BidiIterT> &what, BidiIterT base)
|
||||
{
|
||||
what.set_base_(base);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
69
include/boost/xpressive/detail/core/action.hpp
Executable file
69
include/boost/xpressive/detail/core/action.hpp
Executable file
@@ -0,0 +1,69 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// action.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_ACTION_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_ACTION_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <typeinfo>
|
||||
#include <stdexcept>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/action_state.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
|
||||
|
||||
namespace boost { namespace xpressive
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// action
|
||||
//
|
||||
template<typename ActionT, typename SavedT>
|
||||
struct action
|
||||
: detail::action_matcher<ActionT>
|
||||
{
|
||||
typedef ActionT action_type;
|
||||
typedef SavedT saved_type;
|
||||
|
||||
SavedT &save()
|
||||
{
|
||||
return *static_cast<SavedT *>(this);
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
bool operator ()(match_results<BidiIterT> const &match, BidiIterT cur)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void restore(SavedT const &saved)
|
||||
{
|
||||
this->action_() = saved;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ActionT>
|
||||
struct action<ActionT, void>
|
||||
: action<ActionT, int>
|
||||
{
|
||||
int save()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void restore(int)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace boost::xpressive
|
||||
|
||||
#endif
|
||||
72
include/boost/xpressive/detail/core/action_state.hpp
Executable file
72
include/boost/xpressive/detail/core/action_state.hpp
Executable file
@@ -0,0 +1,72 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// action_state.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_ACTION_STATE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_ACTION_STATE_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <typeinfo>
|
||||
#include <stdexcept>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// type_info_ex
|
||||
//
|
||||
template<typename T>
|
||||
struct type_info_ex
|
||||
{
|
||||
static std::type_info const *const type_info_ptr_;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
std::type_info const *const type_info_ex<T>::type_info_ptr_ = &typeid(T);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// action_state
|
||||
//
|
||||
struct action_state
|
||||
{
|
||||
action_state()
|
||||
: type_ptr_(0)
|
||||
, ptr_(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename StateT>
|
||||
void set(StateT &state)
|
||||
{
|
||||
this->type_ptr_ = &type_info_ex<StateT>::type_info_ptr_;
|
||||
this->ptr_ = &state;
|
||||
}
|
||||
|
||||
template<typename StateT>
|
||||
StateT &get() const
|
||||
{
|
||||
if(&type_info_ex<StateT>::type_info_ptr_ != this->type_ptr_ &&
|
||||
(0 == this->type_ptr_ || **this->type_ptr_ != typeid(StateT)))
|
||||
{
|
||||
throw std::invalid_argument(std::string("bad action_state_cast"));
|
||||
}
|
||||
|
||||
BOOST_ASSERT(0 != this->ptr_);
|
||||
return *static_cast<StateT *>(this->ptr_);
|
||||
}
|
||||
|
||||
std::type_info const *const *type_ptr_;
|
||||
void *ptr_;
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
75
include/boost/xpressive/detail/core/adaptor.hpp
Executable file
75
include/boost/xpressive/detail/core/adaptor.hpp
Executable file
@@ -0,0 +1,75 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// adaptor.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_ADAPTOR_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_ADAPTOR_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/matchable.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// xpression_adaptor
|
||||
//
|
||||
// wrap a static xpression in a matchable interface so it can be stored
|
||||
// in and invoked from a basic_regex object.
|
||||
template<typename XprT, typename BidiIterT>
|
||||
struct xpression_adaptor
|
||||
: matchable<BidiIterT>
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
XprT xpr_;
|
||||
|
||||
xpression_adaptor(typename call_traits<XprT>::param_type xpr)
|
||||
: xpr_(xpr)
|
||||
{
|
||||
}
|
||||
|
||||
bool match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
return this->xpr_.match(state);
|
||||
}
|
||||
|
||||
std::size_t get_width(state_type<BidiIterT> *state) const
|
||||
{
|
||||
return this->xpr_.get_width(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);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_adaptor
|
||||
//
|
||||
template<typename BidiIterT, typename XprT>
|
||||
inline shared_ptr<matchable<BidiIterT> const> make_adaptor(XprT const &xpr)
|
||||
{
|
||||
return shared_ptr<matchable<BidiIterT> const>(new xpression_adaptor<XprT, BidiIterT>(xpr));
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
180
include/boost/xpressive/detail/core/finder.hpp
Executable file
180
include/boost/xpressive/detail/core/finder.hpp
Executable file
@@ -0,0 +1,180 @@
|
||||
/// Contains the definition of the basic_regex\<\> class template and its associated helper functions.
|
||||
//
|
||||
// Copyright 2004 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_CORE_FINDER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_FINDER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/regex_impl.hpp>
|
||||
#include <boost/xpressive/detail/utility/boyer_moore.hpp>
|
||||
//#include <boost/xpressive/detail/core/matchers.hpp>
|
||||
#include <boost/xpressive/detail/utility/hash_peek_bitset.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// boyer_moore_finder
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
struct boyer_moore_finder
|
||||
: finder<BidiIterT>
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
boyer_moore_finder(char_type const *begin, char_type const *end, TraitsT const &tr, bool icase)
|
||||
: bm_(begin, end, tr, icase)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator ()(state_type<BidiIterT> &state) const
|
||||
{
|
||||
TraitsT const &traits = traits_cast<TraitsT>(state);
|
||||
state.cur_ = this->bm_.find(state.cur_, state.end_, traits);
|
||||
return state.cur_ != state.end_;
|
||||
}
|
||||
|
||||
private:
|
||||
boyer_moore<BidiIterT, TraitsT> bm_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// hash_peek_finder
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
struct hash_peek_finder
|
||||
: finder<BidiIterT>
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
hash_peek_finder(hash_peek_bitset<char_type> const &bset)
|
||||
: bset_(bset)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator ()(state_type<BidiIterT> &state) const
|
||||
{
|
||||
TraitsT const &traits = traits_cast<TraitsT>(state);
|
||||
state.cur_ = (this->bset_.icase()
|
||||
? this->find_(state.cur_, state.end_, traits, mpl::true_())
|
||||
: this->find_(state.cur_, state.end_, traits, mpl::false_()));
|
||||
return state.cur_ != state.end_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename ICaseT>
|
||||
BidiIterT find_(BidiIterT begin, BidiIterT end, TraitsT const &traits, ICaseT) const
|
||||
{
|
||||
for(; begin != end && !this->bset_.test(*begin, traits, ICaseT()); ++begin)
|
||||
;
|
||||
return begin;
|
||||
}
|
||||
|
||||
hash_peek_bitset<char_type> bset_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// line_start_finder
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT, std::size_t SizeT = sizeof(typename iterator_value<BidiIterT>::type)>
|
||||
struct line_start_finder
|
||||
: finder<BidiIterT>
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef typename iterator_difference<BidiIterT>::type diff_type;
|
||||
typedef typename TraitsT::char_class_type char_class_type;
|
||||
|
||||
line_start_finder(TraitsT const &traits)
|
||||
: newline_(lookup_classname(traits, "newline"))
|
||||
{
|
||||
}
|
||||
|
||||
bool operator ()(state_type<BidiIterT> &state) const
|
||||
{
|
||||
if(state.bos() && state.flags_.match_bol_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TraitsT const &traits = traits_cast<TraitsT>(state);
|
||||
BidiIterT cur = state.cur_;
|
||||
BidiIterT const end = state.end_;
|
||||
std::advance(cur, static_cast<diff_type>(-!state.bos()));
|
||||
|
||||
for(; cur != end; ++cur)
|
||||
{
|
||||
if(traits.isctype(*cur, this->newline_))
|
||||
{
|
||||
state.cur_ = ++cur;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char_class_type newline_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// line_start_finder
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
struct line_start_finder<BidiIterT, TraitsT, 1u>
|
||||
: finder<BidiIterT>
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef typename iterator_difference<BidiIterT>::type diff_type;
|
||||
typedef typename TraitsT::char_class_type char_class_type;
|
||||
|
||||
line_start_finder(TraitsT const &traits)
|
||||
{
|
||||
char_class_type newline = lookup_classname(traits, "newline");
|
||||
for(int j = 0; j < 256; ++j)
|
||||
{
|
||||
this->bits_[j] = traits.isctype(static_cast<char_type>(static_cast<unsigned char>(j)), newline);
|
||||
}
|
||||
}
|
||||
|
||||
bool operator ()(state_type<BidiIterT> &state) const
|
||||
{
|
||||
if(state.bos() && state.flags_.match_bol_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BidiIterT cur = state.cur_;
|
||||
BidiIterT const end = state.end_;
|
||||
std::advance(cur, static_cast<diff_type>(-!state.bos()));
|
||||
|
||||
for(; cur != end; ++cur)
|
||||
{
|
||||
if(this->bits_[static_cast<unsigned char>(*cur)])
|
||||
{
|
||||
state.cur_ = ++cur;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool bits_[256];
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
67
include/boost/xpressive/detail/core/flow_control.hpp
Executable file
67
include/boost/xpressive/detail/core/flow_control.hpp
Executable file
@@ -0,0 +1,67 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// flow_control.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_FLOW_CONTROL_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_FLOW_CONTROL_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/regex_impl.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// push_context_match
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline bool push_context_match
|
||||
(
|
||||
regex_impl<BidiIterT> const &impl
|
||||
, state_type<BidiIterT> &state
|
||||
, matchable<BidiIterT> const &next
|
||||
)
|
||||
{
|
||||
// save state
|
||||
match_context<BidiIterT> context = state.push_context(impl, next, context);
|
||||
|
||||
// match the nested regex
|
||||
bool success = impl.xpr_->match(state);
|
||||
|
||||
// uninitialize the match context (reclaims the sub_match objects if necessary)
|
||||
state.pop_context(impl, success);
|
||||
return success;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// pop_context_match
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline bool pop_context_match(state_type<BidiIterT> &state)
|
||||
{
|
||||
// save state
|
||||
// BUGBUG nested regex could have changed state.traits_
|
||||
match_context<BidiIterT> &context(*state.context_.prev_context_);
|
||||
state.swap_context(context);
|
||||
|
||||
// Finished matching the nested regex; now match the rest of the enclosing regex
|
||||
bool success = context.next_ptr_->match(state);
|
||||
|
||||
// restore state
|
||||
state.swap_context(context);
|
||||
return success;
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
|
||||
30
include/boost/xpressive/detail/core/icase.hpp
Executable file
30
include/boost/xpressive/detail/core/icase.hpp
Executable file
@@ -0,0 +1,30 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// icase.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_ICASE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_ICASE_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
#include <boost/xpressive/detail/static/modifier.hpp>
|
||||
#include <boost/xpressive/detail/core/linker.hpp>
|
||||
|
||||
namespace boost { namespace xpressive
|
||||
{
|
||||
|
||||
namespace regex_constants { namespace
|
||||
{
|
||||
|
||||
detail::modifier_op<detail::icase_modifier> const icase = {{}, regex_constants::icase_};
|
||||
|
||||
}} // namespace regex_constants::anonymous-namespace
|
||||
|
||||
using regex_constants::icase;
|
||||
|
||||
}} // namespace boost::xpressive
|
||||
|
||||
#endif
|
||||
260
include/boost/xpressive/detail/core/linker.hpp
Executable file
260
include/boost/xpressive/detail/core/linker.hpp
Executable file
@@ -0,0 +1,260 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// linker.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_LINKER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_LINKER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <stack>
|
||||
#include <limits>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/spirit/fusion/algorithm/for_each.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/matchable.hpp>
|
||||
#include <boost/xpressive/detail/core/matchers.hpp>
|
||||
#include <boost/xpressive/detail/core/peeker.hpp>
|
||||
#include <boost/xpressive/detail/utility/never_true.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// icase_modifier
|
||||
//
|
||||
// wrapped by the modifier<> template and inserted into the xpression
|
||||
// template with the icase() helper function. icase_modifier morphs
|
||||
// a case-sensitive visitor into a case-insensitive visitor, which
|
||||
// causes all matchers visited to become case-insensitive.
|
||||
//
|
||||
struct icase_modifier
|
||||
{
|
||||
template<typename VisitorT>
|
||||
struct apply;
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct apply<xpression_visitor<BidiIterT, ICaseT, TraitsT> >
|
||||
{
|
||||
typedef xpression_visitor<BidiIterT, mpl::true_, TraitsT> type;
|
||||
};
|
||||
|
||||
template<typename VisitorT>
|
||||
static typename apply<VisitorT>::type
|
||||
call(VisitorT &visitor)
|
||||
{
|
||||
return typename apply<VisitorT>::type(visitor.traits(), visitor.self());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_traits_type : wrap a locale in the appropriate regex_traits
|
||||
//
|
||||
template<typename LocaleT, typename BidiIterT>
|
||||
struct regex_traits_type
|
||||
{
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
// if LocaleT is std::locale, wrap it in a cpp_regex_traits<CharT>
|
||||
typedef typename mpl::if_
|
||||
<
|
||||
is_same<LocaleT, std::locale>
|
||||
, cpp_regex_traits<char_type>
|
||||
, LocaleT
|
||||
>::type type;
|
||||
|
||||
#else
|
||||
|
||||
typedef LocaleT type;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// locale_modifier
|
||||
//
|
||||
// wrapped by the modifier<> template and inserted into the xpression
|
||||
// template with the imbue() helper function. Causes a sub-xpression to
|
||||
// use the specified LocaleT
|
||||
//
|
||||
template<typename LocaleT>
|
||||
struct locale_modifier
|
||||
{
|
||||
locale_modifier(LocaleT const &loc)
|
||||
: loc_(loc)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename VisitorT>
|
||||
struct apply;
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename OtherTraitsT>
|
||||
struct apply<xpression_visitor<BidiIterT, ICaseT, OtherTraitsT> >
|
||||
{
|
||||
typedef typename regex_traits_type<LocaleT, BidiIterT>::type traits_type;
|
||||
typedef xpression_visitor<BidiIterT, ICaseT, traits_type> type;
|
||||
};
|
||||
|
||||
template<typename VisitorT>
|
||||
typename apply<VisitorT>::type
|
||||
call(VisitorT &) const
|
||||
{
|
||||
return typename apply<VisitorT>::type(this->loc_);
|
||||
}
|
||||
|
||||
LocaleT getloc() const
|
||||
{
|
||||
return this->loc_;
|
||||
}
|
||||
|
||||
private:
|
||||
LocaleT loc_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// xpression_linker
|
||||
//
|
||||
template<typename CharT>
|
||||
struct xpression_linker
|
||||
{
|
||||
template<typename TraitsT>
|
||||
explicit xpression_linker(TraitsT const &traits)
|
||||
: back_stack_()
|
||||
, traits_(&traits)
|
||||
, traits_type_(&typeid(TraitsT))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename MatcherT>
|
||||
void link(MatcherT const &, xpression_base const *)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
void link(repeat_begin_matcher const &, xpression_base const *next)
|
||||
{
|
||||
this->back_stack_.push(next);
|
||||
}
|
||||
|
||||
template<bool GreedyT>
|
||||
void link(repeat_end_matcher<GreedyT> const &matcher, xpression_base const *)
|
||||
{
|
||||
matcher.back_ = this->back_stack_.top();
|
||||
this->back_stack_.pop();
|
||||
}
|
||||
|
||||
template<typename AlternatesT, typename TraitsT>
|
||||
void link(alternate_matcher<AlternatesT, TraitsT> const &matcher, xpression_base const *next)
|
||||
{
|
||||
xpression_peeker<CharT> peeker(&matcher.bset_, this->get_traits<TraitsT>());
|
||||
this->alt_link(matcher.alternates_, next, peeker);
|
||||
}
|
||||
|
||||
void link(alternate_end_matcher const &matcher, xpression_base const *)
|
||||
{
|
||||
matcher.back_ = this->back_stack_.top();
|
||||
this->back_stack_.pop();
|
||||
}
|
||||
|
||||
template<typename XprT>
|
||||
void link(keeper_matcher<XprT> const &matcher, xpression_base const *)
|
||||
{
|
||||
get_pointer(matcher.xpr_)->link(*this);
|
||||
}
|
||||
|
||||
template<typename XprT>
|
||||
void link(lookahead_matcher<XprT> const &matcher, xpression_base const *)
|
||||
{
|
||||
get_pointer(matcher.xpr_)->link(*this);
|
||||
}
|
||||
|
||||
template<typename XprT>
|
||||
void link(lookbehind_matcher<XprT> const &matcher, xpression_base const *)
|
||||
{
|
||||
get_pointer(matcher.xpr_)->link(*this);
|
||||
}
|
||||
|
||||
template<typename XprT, bool GreedyT>
|
||||
void link(simple_repeat_matcher<XprT, GreedyT> const &matcher, xpression_base const *)
|
||||
{
|
||||
matcher.xpr_.link(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_link_pred
|
||||
//
|
||||
struct alt_link_pred
|
||||
{
|
||||
xpression_linker<CharT> &linker_;
|
||||
xpression_peeker<CharT> &peeker_;
|
||||
xpression_base const *next_;
|
||||
|
||||
alt_link_pred
|
||||
(
|
||||
xpression_linker<CharT> &linker
|
||||
, xpression_peeker<CharT> &peeker
|
||||
, xpression_base const *next
|
||||
)
|
||||
: linker_(linker)
|
||||
, peeker_(peeker)
|
||||
, next_(next)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename XprT>
|
||||
void operator ()(XprT const &xpr) const
|
||||
{
|
||||
this->linker_.back_stack_.push(this->next_);
|
||||
get_pointer(xpr)->link(this->linker_);
|
||||
get_pointer(xpr)->peek(this->peeker_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
void alt_link
|
||||
(
|
||||
std::vector<shared_ptr<matchable<BidiIterT> const> > const &alternates
|
||||
, xpression_base const *next
|
||||
, xpression_peeker<CharT> &peeker
|
||||
)
|
||||
{
|
||||
std::for_each(alternates.begin(), alternates.end(), alt_link_pred(*this, peeker, next));
|
||||
}
|
||||
|
||||
template<typename AlternatesT>
|
||||
void alt_link
|
||||
(
|
||||
fusion::sequence_base<AlternatesT> const &alternates
|
||||
, xpression_base const *next
|
||||
, xpression_peeker<CharT> &peeker
|
||||
)
|
||||
{
|
||||
fusion::for_each(alternates.cast(), alt_link_pred(*this, peeker, next));
|
||||
}
|
||||
|
||||
template<typename TraitsT>
|
||||
TraitsT const &get_traits() const
|
||||
{
|
||||
BOOST_ASSERT(*this->traits_type_ == typeid(TraitsT));
|
||||
return *static_cast<TraitsT const *>(this->traits_);
|
||||
}
|
||||
|
||||
std::stack<xpression_base const *> back_stack_;
|
||||
void const *traits_;
|
||||
std::type_info const *traits_type_;
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
77
include/boost/xpressive/detail/core/matcher/action_matcher.hpp
Executable file
77
include/boost/xpressive/detail/core/matcher/action_matcher.hpp
Executable file
@@ -0,0 +1,77 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// action_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ACTION_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ACTION_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/access.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// action_matcher
|
||||
//
|
||||
template<typename ActionT>
|
||||
struct action_matcher
|
||||
: quant_style<quant_none, mpl::size_t<0>, mpl::false_>
|
||||
{
|
||||
ActionT *action_ptr_;
|
||||
|
||||
action_matcher()
|
||||
: action_ptr_(&action_())
|
||||
{
|
||||
}
|
||||
|
||||
action_matcher(action_matcher const &)
|
||||
: action_ptr_(&action_())
|
||||
{
|
||||
}
|
||||
|
||||
action_matcher &operator =(action_matcher const &)
|
||||
{
|
||||
return *this; // no-op
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
ActionT &action = *this->action_ptr_;
|
||||
typename ActionT::saved_type saved(action.save());
|
||||
|
||||
// set the action state pointer, so that action_state_cast works correctly
|
||||
core_access<BidiIterT>::get_action_state(*state.context_.results_ptr_) = state.action_state_;
|
||||
|
||||
match_results<BidiIterT> const &what = *state.context_.results_ptr_;
|
||||
if(!action(what, state.cur_) || !next.match(state))
|
||||
{
|
||||
action.restore(saved);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
ActionT &action_()
|
||||
{
|
||||
return *static_cast<ActionT *>(this);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
45
include/boost/xpressive/detail/core/matcher/alternate_end_matcher.hpp
Executable file
45
include/boost/xpressive/detail/core/matcher/alternate_end_matcher.hpp
Executable file
@@ -0,0 +1,45 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alternate_end_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ALTERNATE_END_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ALTERNATE_END_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alternate_end_matcher
|
||||
//
|
||||
struct alternate_end_matcher
|
||||
: quant_style_assertion
|
||||
{
|
||||
mutable xpression_base const *back_;
|
||||
|
||||
alternate_end_matcher()
|
||||
: back_(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
return next.pop_match(state, this->back_);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
196
include/boost/xpressive/detail/core/matcher/alternate_matcher.hpp
Executable file
196
include/boost/xpressive/detail/core/matcher/alternate_matcher.hpp
Executable file
@@ -0,0 +1,196 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alternate_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ALTERNATE_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ALTERNATE_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/spirit/fusion/sequence/range.hpp>
|
||||
#include <boost/spirit/fusion/algorithm/any.hpp>
|
||||
#include <boost/spirit/fusion/algorithm/for_each.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/static/width_of.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
#include <boost/xpressive/detail/dynamic/matchable.hpp>
|
||||
#include <boost/xpressive/detail/utility/hash_peek_bitset.hpp>
|
||||
#include <boost/xpressive/detail/utility/algorithm.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_match_pred
|
||||
//
|
||||
template<typename BidiIterT, typename NextT>
|
||||
struct alt_match_pred
|
||||
{
|
||||
state_type<BidiIterT> &state_;
|
||||
|
||||
alt_match_pred(state_type<BidiIterT> &state)
|
||||
: state_(state)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename XprT>
|
||||
bool operator ()(XprT const &xpr) const
|
||||
{
|
||||
return get_pointer(xpr)->BOOST_NESTED_TEMPLATE push_match<NextT>(this->state_);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_match
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline bool alt_match
|
||||
(
|
||||
std::vector<shared_ptr<matchable<BidiIterT> const> > const &alternates
|
||||
, state_type<BidiIterT> &state
|
||||
, matchable<BidiIterT> const &
|
||||
)
|
||||
{
|
||||
typedef alt_match_pred<BidiIterT, matchable<BidiIterT> > alt_match_pred;
|
||||
return detail::any(alternates.begin(), alternates.end(), alt_match_pred(state));
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT, typename AlternatesT>
|
||||
inline bool alt_match
|
||||
(
|
||||
fusion::sequence_base<AlternatesT> const &alternates
|
||||
, state_type<BidiIterT> &state
|
||||
, NextT const &
|
||||
)
|
||||
{
|
||||
typedef alt_match_pred<BidiIterT, NextT> alt_match_pred;
|
||||
return fusion::any(alternates.cast(), alt_match_pred(state));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_range
|
||||
template<typename BeginT, typename EndT>
|
||||
inline fusion::range<BeginT, EndT> make_range(BeginT const &begin, EndT const &end)
|
||||
{
|
||||
return fusion::range<BeginT, EndT>(begin, end);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_get_width_pred
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct alt_get_width_pred
|
||||
{
|
||||
state_type<BidiIterT> *state_;
|
||||
std::size_t *width_;
|
||||
|
||||
alt_get_width_pred(state_type<BidiIterT> *state, std::size_t *width)
|
||||
: state_(state)
|
||||
, width_(width)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename XprT>
|
||||
void operator ()(XprT const &xpr) const
|
||||
{
|
||||
if(*this->width_ != unknown_width())
|
||||
{
|
||||
std::size_t that_width = get_pointer(xpr)->get_width(this->state_);
|
||||
if(*this->width_ != that_width)
|
||||
{
|
||||
*this->width_ = unknown_width();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_get_width
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline std::size_t alt_get_width
|
||||
(
|
||||
std::vector<shared_ptr<matchable<BidiIterT> const> > const &alternates
|
||||
, state_type<BidiIterT> *state
|
||||
)
|
||||
{
|
||||
typedef alt_get_width_pred<BidiIterT> alt_get_width_pred;
|
||||
std::size_t width = alternates.front()->get_width(state);
|
||||
std::for_each(alternates.begin() + 1, alternates.end(), alt_get_width_pred(state, &width));
|
||||
return width;
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename AlternatesT>
|
||||
inline std::size_t alt_get_width
|
||||
(
|
||||
fusion::sequence_base<AlternatesT> const &alternates
|
||||
, state_type<BidiIterT> *state
|
||||
)
|
||||
{
|
||||
typedef alt_get_width_pred<BidiIterT> alt_get_width_pred;
|
||||
std::size_t width = (*fusion::begin(alternates.cast())).get_width(state);
|
||||
fusion::for_each
|
||||
(
|
||||
make_range(fusion::next(fusion::begin(alternates.cast())), fusion::end(alternates.cast()))
|
||||
, alt_get_width_pred(state, &width)
|
||||
);
|
||||
return width;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alternate_matcher
|
||||
//
|
||||
template<typename AlternatesT, typename TraitsT>
|
||||
struct alternate_matcher
|
||||
: quant_style_auto<width_of<AlternatesT>, is_pure<AlternatesT> >
|
||||
{
|
||||
typedef AlternatesT alternates_type;
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
|
||||
AlternatesT alternates_;
|
||||
mutable hash_peek_bitset<char_type> bset_;
|
||||
|
||||
explicit alternate_matcher(AlternatesT const &alternates = AlternatesT())
|
||||
: alternates_(alternates)
|
||||
, bset_()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(!this->can_match_(*state.cur_, traits_cast<TraitsT>(state)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return detail::alt_match(this->alternates_, state, next);
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
std::size_t get_width(state_type<BidiIterT> *state) const
|
||||
{
|
||||
return detail::alt_get_width(this->alternates_, state);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool can_match_(char_type ch, TraitsT const &traits) const
|
||||
{
|
||||
return this->bset_.test(ch, traits);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
50
include/boost/xpressive/detail/core/matcher/any_matcher.hpp
Executable file
50
include/boost/xpressive/detail/core/matcher/any_matcher.hpp
Executable file
@@ -0,0 +1,50 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// any_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ANY_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ANY_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// any_matcher
|
||||
//
|
||||
struct any_matcher
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
template<typename BidiIterT, typename NextT>
|
||||
static bool match(state_type<BidiIterT> &state, NextT const &next)
|
||||
{
|
||||
if(state.eos())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++state.cur_;
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
--state.cur_;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
57
include/boost/xpressive/detail/core/matcher/assert_bol_matcher.hpp
Executable file
57
include/boost/xpressive/detail/core/matcher/assert_bol_matcher.hpp
Executable file
@@ -0,0 +1,57 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_bol_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ASSERT_BOL_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ASSERT_BOL_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/assert_line_base.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_bol_matcher
|
||||
//
|
||||
template<typename TraitsT>
|
||||
struct assert_bol_matcher
|
||||
: assert_line_base<TraitsT>
|
||||
{
|
||||
assert_bol_matcher(TraitsT const &traits)
|
||||
: assert_line_base<TraitsT>(traits)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(state.bos())
|
||||
{
|
||||
if(!state.flags_.match_bol_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(!this->is_line_break(state))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return next.match(state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
38
include/boost/xpressive/detail/core/matcher/assert_bos_matcher.hpp
Executable file
38
include/boost/xpressive/detail/core/matcher/assert_bos_matcher.hpp
Executable file
@@ -0,0 +1,38 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_bos_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ASSERT_BOS_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ASSERT_BOS_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_bos_matcher
|
||||
// match the beginning of the sequence (\A)
|
||||
struct assert_bos_matcher
|
||||
: quant_style_assertion
|
||||
{
|
||||
template<typename BidiIterT, typename NextT>
|
||||
static bool match(state_type<BidiIterT> &state, NextT const &next)
|
||||
{
|
||||
return state.bos() && next.match(state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
57
include/boost/xpressive/detail/core/matcher/assert_eol_matcher.hpp
Executable file
57
include/boost/xpressive/detail/core/matcher/assert_eol_matcher.hpp
Executable file
@@ -0,0 +1,57 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_eol_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ASSERT_EOL_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ASSERT_EOL_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/assert_line_base.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_eol_matcher
|
||||
//
|
||||
template<typename TraitsT>
|
||||
struct assert_eol_matcher
|
||||
: assert_line_base<TraitsT>
|
||||
{
|
||||
assert_eol_matcher(TraitsT const &traits)
|
||||
: assert_line_base<TraitsT>(traits)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(state.eos())
|
||||
{
|
||||
if(!state.flags_.match_eol_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if((state.bos() && !state.flags_.match_prev_avail_) || !this->is_line_break(state))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return next.match(state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
38
include/boost/xpressive/detail/core/matcher/assert_eos_matcher.hpp
Executable file
38
include/boost/xpressive/detail/core/matcher/assert_eos_matcher.hpp
Executable file
@@ -0,0 +1,38 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_eos_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ASSERT_EOS_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ASSERT_EOS_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_eos_matcher
|
||||
// match the end of the sequence (\Z)
|
||||
struct assert_eos_matcher
|
||||
: quant_style_assertion
|
||||
{
|
||||
template<typename BidiIterT, typename NextT>
|
||||
static bool match(state_type<BidiIterT> &state, NextT const &next)
|
||||
{
|
||||
return state.eos() && next.match(state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
67
include/boost/xpressive/detail/core/matcher/assert_line_base.hpp
Executable file
67
include/boost/xpressive/detail/core/matcher/assert_line_base.hpp
Executable file
@@ -0,0 +1,67 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_line_base.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_DETAIL_ASSERT_LINE_BASE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_DETAIL_ASSERT_LINE_BASE_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_line_base
|
||||
//
|
||||
template<typename TraitsT>
|
||||
struct assert_line_base
|
||||
: quant_style_assertion
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
typedef typename TraitsT::char_class_type char_class_type;
|
||||
|
||||
protected:
|
||||
assert_line_base(TraitsT const &traits)
|
||||
: newline_(lookup_classname(traits, "newline"))
|
||||
, nl_(traits.widen('\n'))
|
||||
, cr_(traits.widen('\r'))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
bool is_line_break(state_type<BidiIterT> &state) const
|
||||
{
|
||||
BOOST_ASSERT(!state.bos() || state.flags_.match_prev_avail_);
|
||||
BidiIterT tmp = state.cur_;
|
||||
char_type ch = *--tmp;
|
||||
|
||||
if(traits_cast<TraitsT>(state).isctype(ch, this->newline_))
|
||||
{
|
||||
// there is no line-break between \r and \n
|
||||
if(this->cr_ != ch || state.eos() || this->nl_ != *state.cur_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
char_class_type newline_;
|
||||
char_type nl_, cr_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
112
include/boost/xpressive/detail/core/matcher/assert_word_matcher.hpp
Executable file
112
include/boost/xpressive/detail/core/matcher/assert_word_matcher.hpp
Executable file
@@ -0,0 +1,112 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_word_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_ASSERT_WORD_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_ASSERT_WORD_MATCHER_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/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// word_boundary
|
||||
//
|
||||
template<bool IsBoundaryT>
|
||||
struct word_boundary
|
||||
{
|
||||
template<typename BidiIterT>
|
||||
static bool eval(bool prevword, bool thisword, state_type<BidiIterT> &state)
|
||||
{
|
||||
if((state.flags_.match_not_bow_ && state.bos()) || (state.flags_.match_not_eow_ && state.eos()))
|
||||
{
|
||||
return !IsBoundaryT;
|
||||
}
|
||||
|
||||
return IsBoundaryT == (prevword != thisword);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// word_begin
|
||||
//
|
||||
struct word_begin
|
||||
{
|
||||
template<typename BidiIterT>
|
||||
static bool eval(bool prevword, bool thisword, state_type<BidiIterT> &state)
|
||||
{
|
||||
if(state.flags_.match_not_bow_ && state.bos())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !prevword && thisword;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// word_end
|
||||
//
|
||||
struct word_end
|
||||
{
|
||||
template<typename BidiIterT>
|
||||
static bool eval(bool prevword, bool thisword, state_type<BidiIterT> &state)
|
||||
{
|
||||
if(state.flags_.match_not_eow_ && state.eos())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return prevword && !thisword;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_word_matcher
|
||||
//
|
||||
template<typename CondT, typename TraitsT>
|
||||
struct assert_word_matcher
|
||||
: quant_style_assertion
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
|
||||
assert_word_matcher(TraitsT const &traits)
|
||||
: word_(lookup_classname(traits, "w"))
|
||||
{
|
||||
BOOST_ASSERT(0 != this->word_);
|
||||
}
|
||||
|
||||
bool is_word(TraitsT const &traits, char_type ch) const
|
||||
{
|
||||
return traits.isctype(traits.translate(ch), this->word_);
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
BidiIterT cur = state.cur_;
|
||||
bool const thisword = !state.eos() && this->is_word(traits_cast<TraitsT>(state), *cur);
|
||||
bool const prevword = (!state.bos() || state.flags_.match_prev_avail_)
|
||||
&& this->is_word(traits_cast<TraitsT>(state), *--cur);
|
||||
|
||||
return CondT::eval(prevword, thisword, state) && next.match(state);
|
||||
}
|
||||
|
||||
typename TraitsT::char_class_type word_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
62
include/boost/xpressive/detail/core/matcher/charset_matcher.hpp
Executable file
62
include/boost/xpressive/detail/core/matcher/charset_matcher.hpp
Executable file
@@ -0,0 +1,62 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// charset_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_CHARSET_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_CHARSET_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// charset_matcher
|
||||
//
|
||||
template<typename TraitsT, bool ICaseT, typename CharSetT>
|
||||
struct charset_matcher
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
typedef TraitsT traits_type;
|
||||
typedef mpl::bool_<ICaseT> icase_type;
|
||||
|
||||
charset_matcher(CharSetT const &charset = CharSetT())
|
||||
: charset_(charset)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(state.eos() || !this->charset_.test(*state.cur_, traits_cast<TraitsT>(state), icase_type()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++state.cur_;
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
--state.cur_;
|
||||
return false;
|
||||
}
|
||||
|
||||
CharSetT charset_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
66
include/boost/xpressive/detail/core/matcher/end_matcher.hpp
Executable file
66
include/boost/xpressive/detail/core/matcher/end_matcher.hpp
Executable file
@@ -0,0 +1,66 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// end_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_END_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_END_MATCHER_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/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/core/sub_match_impl.hpp>
|
||||
#include <boost/xpressive/detail/core/flow_control.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// end_matcher
|
||||
//
|
||||
struct end_matcher
|
||||
: quant_style_assertion
|
||||
{
|
||||
template<typename BidiIterT, typename NextT>
|
||||
static bool match(state_type<BidiIterT> &state, NextT const &)
|
||||
{
|
||||
BidiIterT const tmp = state.cur_;
|
||||
sub_match_impl<BidiIterT> &s0 = state.sub_match(0);
|
||||
BOOST_ASSERT(!s0.matched);
|
||||
|
||||
// SPECIAL: if there is a match context on the context stack, then
|
||||
// this pattern has been nested within another. pop that context and
|
||||
// continue executing.
|
||||
if(state.context_.prev_context_)
|
||||
{
|
||||
if(!pop_context_match(state))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(state.flags_.match_all_ && !state.eos() ||
|
||||
state.flags_.match_not_null_ && state.cur_ == s0.begin_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// record the end of sub-match zero
|
||||
s0.first = s0.begin_;
|
||||
s0.second = tmp;
|
||||
s0.matched = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
38
include/boost/xpressive/detail/core/matcher/epsilon_matcher.hpp
Executable file
38
include/boost/xpressive/detail/core/matcher/epsilon_matcher.hpp
Executable file
@@ -0,0 +1,38 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// epsilon_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_EPSILON_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_EPSILON_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// epsilon_matcher
|
||||
//
|
||||
struct epsilon_matcher
|
||||
: quant_style_assertion
|
||||
{
|
||||
template<typename BidiIterT, typename NextT>
|
||||
static bool match(state_type<BidiIterT> &state, NextT const &next)
|
||||
{
|
||||
return next.match(state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
97
include/boost/xpressive/detail/core/matcher/keeper_matcher.hpp
Executable file
97
include/boost/xpressive/detail/core/matcher/keeper_matcher.hpp
Executable file
@@ -0,0 +1,97 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// keeper_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_KEEPER_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_KEEPER_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// keeper_matcher
|
||||
// XprT can be either a static_xpression, or a shared_ptr<matchable>
|
||||
template<typename XprT>
|
||||
struct keeper_matcher
|
||||
: quant_style_auto<width_of<XprT>, is_pure<XprT> >
|
||||
{
|
||||
keeper_matcher(XprT const &xpr, bool do_save = !is_pure<XprT>::value)
|
||||
: xpr_(xpr)
|
||||
, do_save_(do_save)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
// Note that if is_pure<XprT>::value is true, the compiler can tell which
|
||||
// branch to take.
|
||||
return is_pure<XprT>::value || !this->do_save_
|
||||
? this->match_(state, next, mpl::true_())
|
||||
: this->match_(state, next, mpl::false_());
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, mpl::true_) const
|
||||
{
|
||||
BidiIterT const tmp = state.cur_;
|
||||
|
||||
// matching xpr is guaranteed to not produce side-effects, don't bother saving state
|
||||
if(!get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, mpl::false_) const
|
||||
{
|
||||
BidiIterT const tmp = state.cur_;
|
||||
|
||||
// matching xpr could produce side-effects, save state
|
||||
memento<BidiIterT> mem = save_sub_matches(state);
|
||||
|
||||
if(!get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
reclaim_sub_matches(mem, state);
|
||||
return false;
|
||||
}
|
||||
else if(next.match(state))
|
||||
{
|
||||
reclaim_sub_matches(mem, state);
|
||||
return true;
|
||||
}
|
||||
|
||||
restore_sub_matches(mem, state);
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
|
||||
XprT xpr_;
|
||||
bool do_save_; // true if matching xpr_ could modify the sub-matches
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
63
include/boost/xpressive/detail/core/matcher/literal_matcher.hpp
Executable file
63
include/boost/xpressive/detail/core/matcher/literal_matcher.hpp
Executable file
@@ -0,0 +1,63 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// literal_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_LITERAL_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_LITERAL_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/utility/traits_utils.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// literal_matcher
|
||||
//
|
||||
template<typename TraitsT, bool ICaseT, bool NotT>
|
||||
struct literal_matcher
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
typedef mpl::bool_<NotT> not_type;
|
||||
typedef mpl::bool_<ICaseT> icase_type;
|
||||
char_type ch_;
|
||||
|
||||
literal_matcher(char_type ch, TraitsT const &traits)
|
||||
: ch_(detail::translate(ch, traits, icase_type()))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(state.eos() || NotT ==
|
||||
(detail::translate(*state.cur_, traits_cast<TraitsT>(state), icase_type()) == this->ch_))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++state.cur_;
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
--state.cur_;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
78
include/boost/xpressive/detail/core/matcher/logical_newline_matcher.hpp
Executable file
78
include/boost/xpressive/detail/core/matcher/logical_newline_matcher.hpp
Executable file
@@ -0,0 +1,78 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// logical_newline_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_LOGICAL_NEWLINE_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_LOGICAL_NEWLINE_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// logical_newline_matcher
|
||||
//
|
||||
template<typename TraitsT>
|
||||
struct logical_newline_matcher
|
||||
: quant_style_variable_width
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
typedef typename TraitsT::char_class_type char_class_type;
|
||||
|
||||
logical_newline_matcher(TraitsT const &traits)
|
||||
: newline_(lookup_classname(traits, "newline"))
|
||||
, nl_(traits.widen('\n'))
|
||||
, cr_(traits.widen('\r'))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(state.eos())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char_type ch = *state.cur_;
|
||||
if(traits_cast<TraitsT>(state).isctype(ch, this->newline_))
|
||||
{
|
||||
++state.cur_;
|
||||
if(this->cr_ == ch && !state.eos() && this->nl_ == *state.cur_)
|
||||
{
|
||||
++state.cur_;
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
--state.cur_;
|
||||
}
|
||||
else if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
--state.cur_;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
char_class_type newline_;
|
||||
char_type nl_, cr_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
144
include/boost/xpressive/detail/core/matcher/lookahead_matcher.hpp
Executable file
144
include/boost/xpressive/detail/core/matcher/lookahead_matcher.hpp
Executable file
@@ -0,0 +1,144 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lookahead_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_LOOKAHEAD_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_LOOKAHEAD_MATCHER_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/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
#include <boost/xpressive/detail/utility/save_restore.hpp>
|
||||
#include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lookahead_matcher
|
||||
// XprT can be either a static_xpression, or a shared_ptr<matchable>
|
||||
//
|
||||
template<typename XprT>
|
||||
struct lookahead_matcher
|
||||
: quant_style<quant_none, mpl::size_t<0>, is_pure<XprT> >
|
||||
{
|
||||
lookahead_matcher(XprT const &xpr, bool no = false, bool do_save = !is_pure<XprT>::value)
|
||||
: xpr_(xpr)
|
||||
, not_(no)
|
||||
, do_save_(do_save)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
// Note that if is_pure<XprT>::value is true, the compiler can optimize this.
|
||||
return is_pure<XprT>::value || !this->do_save_
|
||||
? this->match_(state, next, mpl::true_())
|
||||
: this->match_(state, next, mpl::false_());
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, mpl::true_) const
|
||||
{
|
||||
BidiIterT const tmp = state.cur_;
|
||||
|
||||
if(this->not_)
|
||||
{
|
||||
// negative look-ahead assertions do not trigger partial matches.
|
||||
restore partial_match = save(state.found_partial_match_);
|
||||
ignore_unused(&partial_match);
|
||||
|
||||
if(get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
else if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
state.cur_ = tmp;
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_ASSERT(state.cur_ == tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, mpl::false_) const
|
||||
{
|
||||
BidiIterT const tmp = state.cur_;
|
||||
|
||||
// matching xpr could produce side-effects, save state
|
||||
memento<BidiIterT> mem = save_sub_matches(state);
|
||||
|
||||
if(this->not_)
|
||||
{
|
||||
// negative look-ahead assertions do not trigger partial matches.
|
||||
restore partial_match = save(state.found_partial_match_);
|
||||
ignore_unused(&partial_match);
|
||||
|
||||
if(get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
restore_sub_matches(mem, state);
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
else if(next.match(state))
|
||||
{
|
||||
reclaim_sub_matches(mem, state);
|
||||
return true;
|
||||
}
|
||||
reclaim_sub_matches(mem, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
reclaim_sub_matches(mem, state);
|
||||
return false;
|
||||
}
|
||||
state.cur_ = tmp;
|
||||
if(next.match(state))
|
||||
{
|
||||
reclaim_sub_matches(mem, state);
|
||||
return true;
|
||||
}
|
||||
restore_sub_matches(mem, state);
|
||||
}
|
||||
|
||||
BOOST_ASSERT(state.cur_ == tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
XprT xpr_;
|
||||
bool not_;
|
||||
bool do_save_; // true if matching xpr_ could modify the sub-matches
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
175
include/boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp
Executable file
175
include/boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp
Executable file
@@ -0,0 +1,175 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lookbehind_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_LOOKBEHIND_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_LOOKBEHIND_MATCHER_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/xpressive/regex_error.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/utility/algorithm.hpp>
|
||||
#include <boost/xpressive/detail/utility/save_restore.hpp>
|
||||
#include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get_width
|
||||
//
|
||||
template<typename XprT>
|
||||
inline std::size_t get_width(XprT const &xpr)
|
||||
{
|
||||
return xpr.get_width(static_cast<state_type<char const *>*>(0));
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
inline std::size_t get_width(shared_ptr<matchable<BidiIterT> const> const &xpr)
|
||||
{
|
||||
return xpr->get_width(0);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lookbehind_matcher
|
||||
// XprT can be either a static_xpression, or a shared_ptr<matchable>
|
||||
template<typename XprT>
|
||||
struct lookbehind_matcher
|
||||
: quant_style<quant_none, mpl::size_t<0>, is_pure<XprT> >
|
||||
{
|
||||
lookbehind_matcher(XprT const &xpr, bool no = false, bool do_save = !is_pure<XprT>::value)
|
||||
: xpr_(xpr)
|
||||
, not_(no)
|
||||
, do_save_(do_save)
|
||||
, width_(detail::get_width(xpr))
|
||||
{
|
||||
detail::ensure(this->width_ != unknown_width(), regex_constants::error_badlookbehind,
|
||||
"Variable-width look-behind assertions are not supported");
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
// Note that if is_pure<XprT>::value is true, the compiler can optimize this.
|
||||
return is_pure<XprT>::value || !this->do_save_
|
||||
? this->match_(state, next, mpl::true_())
|
||||
: this->match_(state, next, mpl::false_());
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, mpl::true_) const
|
||||
{
|
||||
typedef typename iterator_difference<BidiIterT>::type difference_type;
|
||||
BidiIterT const tmp = state.cur_;
|
||||
if(!detail::advance_to(state.cur_, -static_cast<difference_type>(this->width_), state.begin_))
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return this->not_ ? next.match(state) : false;
|
||||
}
|
||||
|
||||
if(this->not_)
|
||||
{
|
||||
if(get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
BOOST_ASSERT(state.cur_ == tmp);
|
||||
return false;
|
||||
}
|
||||
state.cur_ = tmp;
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(state.cur_ == tmp);
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_ASSERT(state.cur_ == tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, mpl::false_) const
|
||||
{
|
||||
typedef typename iterator_difference<BidiIterT>::type difference_type;
|
||||
BidiIterT const tmp = state.cur_;
|
||||
if(!detail::advance_to(state.cur_, -static_cast<difference_type>(this->width_), state.begin_))
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return this->not_ ? next.match(state) : false;
|
||||
}
|
||||
|
||||
// matching xpr could produce side-effects, save state
|
||||
memento<BidiIterT> mem = save_sub_matches(state);
|
||||
|
||||
if(this->not_)
|
||||
{
|
||||
// negative look-ahead assertions do not trigger partial matches.
|
||||
restore partial_match = save(state.found_partial_match_);
|
||||
ignore_unused(&partial_match);
|
||||
|
||||
if(get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
restore_sub_matches(mem, state);
|
||||
BOOST_ASSERT(state.cur_ == tmp);
|
||||
return false;
|
||||
}
|
||||
state.cur_ = tmp;
|
||||
if(next.match(state))
|
||||
{
|
||||
reclaim_sub_matches(mem, state);
|
||||
return true;
|
||||
}
|
||||
reclaim_sub_matches(mem, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!get_pointer(this->xpr_)->match(state))
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
reclaim_sub_matches(mem, state);
|
||||
return false;
|
||||
}
|
||||
BOOST_ASSERT(state.cur_ == tmp);
|
||||
if(next.match(state))
|
||||
{
|
||||
reclaim_sub_matches(mem, state);
|
||||
return true;
|
||||
}
|
||||
restore_sub_matches(mem, state);
|
||||
}
|
||||
|
||||
BOOST_ASSERT(state.cur_ == tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
XprT xpr_;
|
||||
bool not_;
|
||||
bool do_save_; // true if matching xpr_ could modify the sub-matches
|
||||
std::size_t width_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
56
include/boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp
Executable file
56
include/boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp
Executable file
@@ -0,0 +1,56 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_begin_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_MARK_BEGIN_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_MARK_BEGIN_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_begin_matcher
|
||||
//
|
||||
struct mark_begin_matcher
|
||||
: quant_style<quant_fixed_width, mpl::size_t<0>, mpl::false_>
|
||||
{
|
||||
int mark_number_; // signed because it could be negative
|
||||
|
||||
mark_begin_matcher(int mark_number)
|
||||
: mark_number_(mark_number)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
sub_match_impl<BidiIterT> &br = state.sub_match(this->mark_number_);
|
||||
|
||||
BidiIterT old_begin = br.begin_;
|
||||
br.begin_ = state.cur_;
|
||||
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
br.begin_ = old_begin;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
64
include/boost/xpressive/detail/core/matcher/mark_end_matcher.hpp
Executable file
64
include/boost/xpressive/detail/core/matcher/mark_end_matcher.hpp
Executable file
@@ -0,0 +1,64 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_end_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_MARK_END_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_MARK_END_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_end_matcher
|
||||
//
|
||||
struct mark_end_matcher
|
||||
: quant_style<quant_none, mpl::size_t<0>, mpl::false_>
|
||||
{
|
||||
int mark_number_;
|
||||
|
||||
mark_end_matcher(int mark_number)
|
||||
: mark_number_(mark_number)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
sub_match_impl<BidiIterT> &br = state.sub_match(this->mark_number_);
|
||||
|
||||
BidiIterT old_first = br.first;
|
||||
BidiIterT old_second = br.second;
|
||||
bool old_matched = br.matched;
|
||||
|
||||
br.first = br.begin_;
|
||||
br.second = state.cur_;
|
||||
br.matched = true;
|
||||
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
br.first = old_first;
|
||||
br.second = old_second;
|
||||
br.matched = old_matched;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
86
include/boost/xpressive/detail/core/matcher/mark_matcher.hpp
Executable file
86
include/boost/xpressive/detail/core/matcher/mark_matcher.hpp
Executable file
@@ -0,0 +1,86 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_MARK_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_MARK_MATCHER_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/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/utility/traits_utils.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_matcher
|
||||
//
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
struct mark_matcher
|
||||
: quant_style_fixed_unknown_width
|
||||
{
|
||||
typedef mpl::bool_<ICaseT> icase_type;
|
||||
int mark_number_;
|
||||
|
||||
mark_matcher(int mark_number, TraitsT const &)
|
||||
: mark_number_(mark_number)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
BOOST_ASSERT(this->mark_number_ < static_cast<int>(state.mark_count_));
|
||||
sub_match_impl<BidiIterT> const &br = state.sub_match(this->mark_number_);
|
||||
|
||||
if(!br.matched)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BidiIterT const tmp = state.cur_;
|
||||
for(BidiIterT begin = br.first, end = br.second; begin != end; ++begin, ++state.cur_)
|
||||
{
|
||||
if(state.eos()
|
||||
|| detail::translate(*state.cur_, traits_cast<TraitsT>(state), icase_type())
|
||||
!= detail::translate(*begin, traits_cast<TraitsT>(state), icase_type()))
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
std::size_t get_width(state_type<BidiIterT> *state) const
|
||||
{
|
||||
if(0 == state)
|
||||
{
|
||||
return unknown_width();
|
||||
}
|
||||
sub_match_impl<BidiIterT> &br = state->sub_match(this->mark_number_);
|
||||
return br.matched ? static_cast<std::size_t>(std::distance(br.first, br.second)) : 1U;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
69
include/boost/xpressive/detail/core/matcher/posix_charset_matcher.hpp
Executable file
69
include/boost/xpressive/detail/core/matcher/posix_charset_matcher.hpp
Executable file
@@ -0,0 +1,69 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// posix_charset_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_POSIX_CHARSET_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_POSIX_CHARSET_MATCHER_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/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/utility/traits_utils.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// posix_charset_matcher
|
||||
//
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
struct posix_charset_matcher
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
typedef TraitsT traits_type;
|
||||
typedef mpl::bool_<ICaseT> icase_type;
|
||||
typedef typename TraitsT::char_class_type char_class_type;
|
||||
|
||||
posix_charset_matcher(char_class_type m, bool no)
|
||||
: not_(no)
|
||||
, mask_(m)
|
||||
{
|
||||
BOOST_ASSERT(0 != this->mask_);
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(state.eos() || this->not_ == traits_cast<TraitsT>(state).isctype(
|
||||
detail::translate(*state.cur_, traits_cast<TraitsT>(state), icase_type()), this->mask_))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++state.cur_;
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
--state.cur_;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool not_;
|
||||
char_class_type mask_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
76
include/boost/xpressive/detail/core/matcher/range_matcher.hpp
Executable file
76
include/boost/xpressive/detail/core/matcher/range_matcher.hpp
Executable file
@@ -0,0 +1,76 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// range_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_RANGE_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_RANGE_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// range_matcher
|
||||
//
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
struct range_matcher
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
typedef mpl::bool_<ICaseT> icase_type;
|
||||
char_type ch_min_;
|
||||
char_type ch_max_;
|
||||
bool not_;
|
||||
|
||||
range_matcher(char_type ch_min, char_type ch_max, bool no, TraitsT const &)
|
||||
: ch_min_(ch_min)
|
||||
, ch_max_(ch_max)
|
||||
, not_(no)
|
||||
{
|
||||
}
|
||||
|
||||
bool in_range(TraitsT const &traits, char_type ch, mpl::false_) const // case-sensitive
|
||||
{
|
||||
return traits.in_range(this->ch_min_, this->ch_max_, ch);
|
||||
}
|
||||
|
||||
bool in_range(TraitsT const &traits, char_type ch, mpl::true_) const // case-insensitive
|
||||
{
|
||||
return traits.in_range_nocase(this->ch_min_, this->ch_max_, ch);
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(state.eos() || this->not_ ==
|
||||
this->in_range(traits_cast<TraitsT>(state), *state.cur_, icase_type()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
++state.cur_;
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
--state.cur_;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
69
include/boost/xpressive/detail/core/matcher/regex_byref_matcher.hpp
Executable file
69
include/boost/xpressive/detail/core/matcher/regex_byref_matcher.hpp
Executable file
@@ -0,0 +1,69 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_byref_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_REGEX_BYREF_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_REGEX_BYREF_MATCHER_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/shared_ptr.hpp>
|
||||
#include <boost/xpressive/regex_error.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/core/regex_impl.hpp>
|
||||
#include <boost/xpressive/detail/core/adaptor.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_byref_matcher
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct regex_byref_matcher
|
||||
: quant_style<quant_variable_width, unknown_width, mpl::false_>
|
||||
{
|
||||
// avoid cyclic references by holding a weak_ptr to the
|
||||
// regex_impl struct
|
||||
weak_ptr<regex_impl<BidiIterT> > wimpl_;
|
||||
|
||||
// the basic_regex object holds a ref-count to this regex_impl, so
|
||||
// we don't have to worry about it going away.
|
||||
regex_impl<BidiIterT> const *pimpl_;
|
||||
|
||||
regex_byref_matcher(shared_ptr<regex_impl<BidiIterT> > const &impl)
|
||||
: wimpl_(impl)
|
||||
, pimpl_(impl.get())
|
||||
{
|
||||
BOOST_ASSERT(this->pimpl_);
|
||||
}
|
||||
|
||||
template<typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
// regex_matcher is used for embeding a dynamic regex in a static regex. As such,
|
||||
// NextT will always point to a static regex.
|
||||
BOOST_MPL_ASSERT((is_static_xpression<NextT>));
|
||||
BOOST_ASSERT(this->pimpl_ == this->wimpl_.lock().get());
|
||||
ensure(this->pimpl_->xpr_, regex_constants::error_badref, "bad regex reference");
|
||||
|
||||
// wrap the static xpression in a matchable interface
|
||||
xpression_adaptor<NextT const &, BidiIterT> adaptor(next);
|
||||
return push_context_match(*this->pimpl_, state, adaptor);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
63
include/boost/xpressive/detail/core/matcher/regex_matcher.hpp
Executable file
63
include/boost/xpressive/detail/core/matcher/regex_matcher.hpp
Executable file
@@ -0,0 +1,63 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_REGEX_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_REGEX_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/regex_error.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
#include <boost/xpressive/detail/core/regex_impl.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/core/adaptor.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_matcher
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct regex_matcher
|
||||
: quant_style<quant_variable_width, unknown_width, mpl::false_>
|
||||
{
|
||||
regex_impl<BidiIterT> impl_;
|
||||
|
||||
regex_matcher(shared_ptr<regex_impl<BidiIterT> > const &impl)
|
||||
: impl_()
|
||||
{
|
||||
this->impl_.xpr_ = impl->xpr_;
|
||||
this->impl_.traits_ = impl->traits_;
|
||||
this->impl_.mark_count_ = impl->mark_count_;
|
||||
this->impl_.hidden_mark_count_ = impl->hidden_mark_count_;
|
||||
|
||||
ensure(this->impl_.xpr_, regex_constants::error_badref, "bad regex reference");
|
||||
}
|
||||
|
||||
template<typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
// regex_matcher is used for embeding a dynamic regex in a static regex. As such,
|
||||
// NextT will always point to a static regex.
|
||||
BOOST_MPL_ASSERT((is_static_xpression<NextT>));
|
||||
|
||||
// wrap the static xpression in a matchable interface
|
||||
xpression_adaptor<NextT const &, BidiIterT> adaptor(next);
|
||||
return push_context_match(this->impl_, state, adaptor);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
69
include/boost/xpressive/detail/core/matcher/repeat_begin_matcher.hpp
Executable file
69
include/boost/xpressive/detail/core/matcher/repeat_begin_matcher.hpp
Executable file
@@ -0,0 +1,69 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// repeat_end_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_REPEAT_BEGIN_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_REPEAT_BEGIN_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
//
|
||||
// Note: here is the variable-width xpression quantifier. It always
|
||||
// matches at least once, so if the min is 0, it is the responsibility
|
||||
// of the parser to make it alternate with an epsilon matcher.
|
||||
//
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// repeat_begin_matcher
|
||||
//
|
||||
struct repeat_begin_matcher
|
||||
: quant_style<quant_variable_width, unknown_width, mpl::false_>
|
||||
{
|
||||
int mark_number_;
|
||||
|
||||
repeat_begin_matcher(int mark_number)
|
||||
: mark_number_(mark_number)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
sub_match_impl<BidiIterT> &br = state.sub_match(this->mark_number_);
|
||||
|
||||
unsigned int old_repeat_count = br.repeat_count_;
|
||||
bool old_zero_width = br.zero_width_;
|
||||
|
||||
br.repeat_count_ = 1;
|
||||
br.zero_width_ = false;
|
||||
|
||||
// "push" next onto the stack, so it can be "popped" in
|
||||
// repeat_end_matcher and used to loop back.
|
||||
if(next.BOOST_NESTED_TEMPLATE push_match<NextT>(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
br.repeat_count_ = old_repeat_count;
|
||||
br.zero_width_ = old_zero_width;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
121
include/boost/xpressive/detail/core/matcher/repeat_end_matcher.hpp
Executable file
121
include/boost/xpressive/detail/core/matcher/repeat_end_matcher.hpp
Executable file
@@ -0,0 +1,121 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// repeat_end_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_REPEAT_END_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_REPEAT_END_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// repeat_end_matcher
|
||||
//
|
||||
template<bool GreedyT>
|
||||
struct repeat_end_matcher
|
||||
: quant_style<quant_none, mpl::size_t<0>, mpl::false_>
|
||||
{
|
||||
typedef mpl::bool_<GreedyT> greedy_type;
|
||||
int mark_number_;
|
||||
unsigned int min_, max_;
|
||||
mutable xpression_base const *back_;
|
||||
|
||||
repeat_end_matcher(int mark_number, unsigned int min, unsigned int max)
|
||||
: mark_number_(mark_number)
|
||||
, min_(min)
|
||||
, max_(max)
|
||||
, back_(0)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
// prevent repeated zero-width sub-matches from causing infinite recursion
|
||||
sub_match_impl<BidiIterT> &br = state.sub_match(this->mark_number_);
|
||||
|
||||
if(br.zero_width_ && br.begin_ == state.cur_)
|
||||
{
|
||||
return next.skip_match(state);
|
||||
}
|
||||
|
||||
bool old_zero_width = br.zero_width_;
|
||||
br.zero_width_ = (br.begin_ == state.cur_);
|
||||
|
||||
if(this->match_(state, next, greedy_type()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
br.zero_width_ = old_zero_width;
|
||||
return false;
|
||||
}
|
||||
|
||||
// greedy, variable-width quantifier
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, mpl::true_) const
|
||||
{
|
||||
sub_match_impl<BidiIterT> &br = state.sub_match(this->mark_number_);
|
||||
|
||||
if(this->max_ > br.repeat_count_)
|
||||
{
|
||||
++br.repeat_count_;
|
||||
// loop back to the expression "pushed" in repeat_begin_matcher::match
|
||||
if(next.top_match(state, this->back_))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if(--br.repeat_count_ < this->min_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// looping finished, continue matching the rest of the pattern
|
||||
return next.skip_match(state);
|
||||
}
|
||||
|
||||
// non-greedy, variable-width quantifier
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, mpl::false_) const
|
||||
{
|
||||
sub_match_impl<BidiIterT> &br = state.sub_match(this->mark_number_);
|
||||
|
||||
if(this->min_ <= br.repeat_count_)
|
||||
{
|
||||
if(next.skip_match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(this->max_ > br.repeat_count_)
|
||||
{
|
||||
++br.repeat_count_;
|
||||
if(next.top_match(state, this->back_))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
--br.repeat_count_;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
138
include/boost/xpressive/detail/core/matcher/set_matcher.hpp
Executable file
138
include/boost/xpressive/detail/core/matcher/set_matcher.hpp
Executable file
@@ -0,0 +1,138 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// set.hpp
|
||||
//
|
||||
// Copyright 2004 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_SET_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_SET_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// set_matcher
|
||||
//
|
||||
template<typename TraitsT, int SizeT>
|
||||
struct set_matcher
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
char_type set_[ SizeT ? SizeT : 1 ];
|
||||
bool not_;
|
||||
bool icase_;
|
||||
|
||||
typedef set_matcher<TraitsT, SizeT + 1> next_type;
|
||||
friend struct set_matcher<TraitsT, SizeT - 1>;
|
||||
|
||||
set_matcher(TraitsT const &)
|
||||
: set_()
|
||||
, not_(false)
|
||||
, icase_(false)
|
||||
{
|
||||
}
|
||||
|
||||
set_matcher(char_type ch, TraitsT const &traits)
|
||||
: set_()
|
||||
, not_(false)
|
||||
, icase_(false)
|
||||
{
|
||||
BOOST_MPL_ASSERT_RELATION(1, ==, SizeT);
|
||||
this->set_[0] = traits.translate(ch);
|
||||
}
|
||||
|
||||
void complement()
|
||||
{
|
||||
this->not_ = !this->not_;
|
||||
}
|
||||
|
||||
void nocase(TraitsT const &traits)
|
||||
{
|
||||
this->icase_ = true;
|
||||
|
||||
for(int i = 0; i < SizeT; ++i)
|
||||
{
|
||||
this->set_[i] = traits.translate_nocase(this->set_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
next_type push_back(char_type ch, TraitsT const &traits) const
|
||||
{
|
||||
return next_type(*this, ch, traits);
|
||||
}
|
||||
|
||||
char_type const *begin() const
|
||||
{
|
||||
return this->set_;
|
||||
}
|
||||
|
||||
char_type const *end() const
|
||||
{
|
||||
return this->set_ + SizeT;
|
||||
}
|
||||
|
||||
bool in_set(TraitsT const &traits, char_type ch) const
|
||||
{
|
||||
ch = this->icase_ ? traits.translate_nocase(ch) : traits.translate(ch);
|
||||
|
||||
if(1 == SizeT)
|
||||
{
|
||||
return this->set_[0] == ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->end() != std::find(this->begin(), this->end(), ch);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
if(state.eos() || this->not_ == this->in_set(traits_cast<TraitsT>(state), *state.cur_))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(++state.cur_, next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return --state.cur_, false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
set_matcher(set_matcher<TraitsT, SizeT - 1> const &that, char_type ch, TraitsT const &traits)
|
||||
: set_()
|
||||
, not_(false)
|
||||
, icase_(that.icase_)
|
||||
{
|
||||
std::copy(that.begin(), that.end(), this->set_);
|
||||
this->set_[ SizeT - 1 ] = traits.translate(ch);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// set_initializer
|
||||
struct set_initializer
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
214
include/boost/xpressive/detail/core/matcher/simple_repeat_matcher.hpp
Executable file
214
include/boost/xpressive/detail/core/matcher/simple_repeat_matcher.hpp
Executable file
@@ -0,0 +1,214 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// simple_repeat_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_SIMPLE_REPEAT_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_SIMPLE_REPEAT_MATCHER_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/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/static/type_traits.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// simple_repeat_traits
|
||||
//
|
||||
struct greedy_slow_tag {};
|
||||
struct greedy_fast_tag {};
|
||||
struct non_greedy_tag {};
|
||||
|
||||
typedef static_xpression<any_matcher, true_xpression> any_sxpr;
|
||||
typedef matcher_wrapper<any_matcher> any_dxpr;
|
||||
|
||||
template<typename XprT, typename GreedyT, typename RandomT>
|
||||
struct simple_repeat_traits
|
||||
{
|
||||
typedef typename mpl::if_<GreedyT, greedy_slow_tag, non_greedy_tag>::type tag_type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct simple_repeat_traits<any_sxpr, mpl::true_, mpl::true_>
|
||||
{
|
||||
typedef greedy_fast_tag tag_type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct simple_repeat_traits<any_dxpr, mpl::true_, mpl::true_>
|
||||
{
|
||||
typedef greedy_fast_tag tag_type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// simple_repeat_matcher
|
||||
//
|
||||
template<typename XprT, bool GreedyT>
|
||||
struct simple_repeat_matcher
|
||||
: quant_style_variable_width
|
||||
{
|
||||
typedef XprT xpr_type;
|
||||
typedef mpl::bool_<GreedyT> greedy_type;
|
||||
|
||||
XprT xpr_;
|
||||
unsigned int min_, max_;
|
||||
|
||||
simple_repeat_matcher(XprT const &xpr, unsigned int min, unsigned int max)
|
||||
: xpr_(xpr)
|
||||
, min_(min)
|
||||
, max_(max)
|
||||
{
|
||||
// it is the job of the parser to make sure this never happens
|
||||
BOOST_ASSERT(min <= max);
|
||||
BOOST_ASSERT(0 != max);
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
typedef mpl::bool_<is_random<BidiIterT>::value> is_rand;
|
||||
typedef typename simple_repeat_traits<XprT, greedy_type, is_rand>::tag_type tag_type;
|
||||
return this->match_(state, next, tag_type());
|
||||
}
|
||||
|
||||
// greedy, fixed-width quantifier
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, greedy_slow_tag) const
|
||||
{
|
||||
int const diff = -static_cast<int>(this->xpr_.get_width(&state));
|
||||
BOOST_ASSERT(diff != -static_cast<int>(unknown_width()));
|
||||
unsigned int matches = 0;
|
||||
BidiIterT const tmp = state.cur_;
|
||||
|
||||
if(0 == diff)
|
||||
{
|
||||
return this->xpr_.match(state) && next.match(state);
|
||||
}
|
||||
|
||||
// greedily match as much as we can
|
||||
while(matches < this->max_ && this->xpr_.match(state))
|
||||
{
|
||||
++matches;
|
||||
}
|
||||
|
||||
if(this->min_ > matches)
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
|
||||
// try matching the rest of the pattern, and back off if necessary
|
||||
for(; ; --matches, std::advance(state.cur_, diff))
|
||||
{
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if(this->min_ == matches)
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// non-greedy fixed-width quantification
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, non_greedy_tag) const
|
||||
{
|
||||
BidiIterT const tmp = state.cur_;
|
||||
unsigned int matches = 0;
|
||||
|
||||
if(0 == this->xpr_.get_width(&state))
|
||||
{
|
||||
return this->xpr_.match(state) && next.match(state);
|
||||
}
|
||||
|
||||
for(; matches < this->min_; ++matches)
|
||||
{
|
||||
if(!this->xpr_.match(state))
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
while(matches++ < this->max_ && this->xpr_.match(state));
|
||||
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
|
||||
// when greedily matching any character, skip to the end instead of iterating there.
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match_(state_type<BidiIterT> &state, NextT const &next, greedy_fast_tag) const
|
||||
{
|
||||
BidiIterT const tmp = state.cur_;
|
||||
std::size_t const diff_to_end = static_cast<std::size_t>(state.end_ - tmp);
|
||||
|
||||
// is there enough room?
|
||||
if(this->min_ > diff_to_end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BidiIterT const min_iter = tmp + this->min_;
|
||||
state.cur_ += (std::min)((std::size_t)this->max_, diff_to_end);
|
||||
|
||||
for(;; --state.cur_)
|
||||
{
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if(min_iter == state.cur_)
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
std::size_t get_width(state_type<BidiIterT> *state) const
|
||||
{
|
||||
if(this->min_ != this->max_)
|
||||
{
|
||||
return unknown_width();
|
||||
}
|
||||
return this->min_ * this->xpr_.get_width(state);
|
||||
}
|
||||
};
|
||||
|
||||
// BUGBUG can all non-greedy quantification be done with the fixed width quantifier?
|
||||
|
||||
// BUGBUG matchers are chained together using static_xpression so that matchers to
|
||||
// the left can invoke matchers to the right. This is so that if the left matcher
|
||||
// succeeds but the right matcher fails, the left matcher is given the opportunity
|
||||
// to try something else. This is how backtracking works. However, if the left matcher
|
||||
// can succeed only one way (as with any_matcher, for example), it does not need
|
||||
// backtracking. In this case, leaving its stack frame active is a waste of stack
|
||||
// space. Can something be done?
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
87
include/boost/xpressive/detail/core/matcher/string_matcher.hpp
Executable file
87
include/boost/xpressive/detail/core/matcher/string_matcher.hpp
Executable file
@@ -0,0 +1,87 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// string_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_STRING_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_STRING_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/utility/traits_utils.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// string_matcher
|
||||
//
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
struct string_matcher
|
||||
: quant_style_fixed_unknown_width
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
typedef mpl::bool_<ICaseT> icase_type;
|
||||
std::basic_string<char_type> str_;
|
||||
char_type const *end_;
|
||||
|
||||
string_matcher(std::basic_string<char_type> const &str, TraitsT const &traits)
|
||||
: str_(str)
|
||||
, end_(str_.data() + str_.size())
|
||||
{
|
||||
for(typename std::basic_string<char_type>::size_type i = 0; i < this->str_.size(); ++i)
|
||||
{
|
||||
this->str_[i] = detail::translate(this->str_[i], traits, icase_type());
|
||||
}
|
||||
}
|
||||
|
||||
string_matcher(string_matcher<TraitsT, ICaseT> const &that)
|
||||
: str_(that.str_)
|
||||
, end_(str_.data() + str_.size())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT, typename NextT>
|
||||
bool match(state_type<BidiIterT> &state, NextT const &next) const
|
||||
{
|
||||
BidiIterT const tmp = state.cur_;
|
||||
char_type const *begin = this->str_.data();
|
||||
for(; begin != this->end_; ++begin, ++state.cur_)
|
||||
{
|
||||
if(state.eos() ||
|
||||
(detail::translate(*state.cur_, traits_cast<TraitsT>(state), icase_type()) != *begin))
|
||||
{
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(next.match(state))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
state.cur_ = tmp;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
std::size_t get_width(state_type<BidiIterT> *) const
|
||||
{
|
||||
return this->str_.size();
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
38
include/boost/xpressive/detail/core/matcher/true_matcher.hpp
Executable file
38
include/boost/xpressive/detail/core/matcher/true_matcher.hpp
Executable file
@@ -0,0 +1,38 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// true_matcher.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHER_TRUE_MATCHER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHER_TRUE_MATCHER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// true_matcher
|
||||
//
|
||||
struct true_matcher
|
||||
: quant_style_assertion
|
||||
{
|
||||
template<typename BidiIterT, typename NextT>
|
||||
static bool match(state_type<BidiIterT> &, NextT const &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
47
include/boost/xpressive/detail/core/matchers.hpp
Executable file
47
include/boost/xpressive/detail/core/matchers.hpp
Executable file
@@ -0,0 +1,47 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matchers.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_MATCHERS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_MATCHERS_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/alternate_end_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/alternate_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/any_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/assert_bol_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/assert_bos_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/assert_eol_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/assert_eos_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/assert_word_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/charset_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/end_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/epsilon_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/keeper_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/literal_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/logical_newline_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/lookahead_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/mark_end_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/mark_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/posix_charset_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/range_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/regex_byref_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/regex_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/repeat_begin_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/repeat_end_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/set_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/simple_repeat_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/string_matcher.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/true_matcher.hpp>
|
||||
|
||||
#endif
|
||||
197
include/boost/xpressive/detail/core/peeker.hpp
Executable file
197
include/boost/xpressive/detail/core/peeker.hpp
Executable file
@@ -0,0 +1,197 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// peeker.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_PEEKER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_PEEKER_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/matchers.hpp>
|
||||
#include <boost/xpressive/detail/utility/hash_peek_bitset.hpp>
|
||||
#include <boost/xpressive/detail/utility/never_true.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// peek_next
|
||||
// tell whether or not to keep looking for a peek optimization
|
||||
template<typename MatcherT>
|
||||
struct peek_next
|
||||
: mpl::equal_to<typename MatcherT::width, mpl::size_t<0> >
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct peek_next<mark_begin_matcher>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct peek_next<repeat_begin_matcher>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// xpression_peeker
|
||||
//
|
||||
template<typename CharT>
|
||||
struct xpression_peeker
|
||||
{
|
||||
template<typename TraitsT>
|
||||
explicit xpression_peeker(hash_peek_bitset<CharT> *bset, TraitsT const &traits)
|
||||
: bset_(bset)
|
||||
, str_(0)
|
||||
, str_icase_(false)
|
||||
, line_start_(false)
|
||||
, traits_(0)
|
||||
, traits_type_(0)
|
||||
{
|
||||
this->set_traits(traits);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// accessors
|
||||
std::pair<std::basic_string<CharT> const *, bool> get_string() const
|
||||
{
|
||||
return std::make_pair(this->str_, this->str_icase_);
|
||||
}
|
||||
|
||||
bool line_start() const
|
||||
{
|
||||
return this->line_start_;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// modifiers
|
||||
void fail()
|
||||
{
|
||||
this->bset_->set_all();
|
||||
}
|
||||
|
||||
template<typename XprT>
|
||||
peek_next<XprT> peek(XprT const &xpr)
|
||||
{
|
||||
if(!peek_next<XprT>::value)
|
||||
{
|
||||
this->fail(); // fail, we're done
|
||||
}
|
||||
return peek_next<XprT>();
|
||||
}
|
||||
|
||||
template<typename TraitsT>
|
||||
mpl::true_ peek(assert_bol_matcher<TraitsT> const &xpr)
|
||||
{
|
||||
this->line_start_ = true;
|
||||
return mpl::true_();
|
||||
}
|
||||
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
mpl::false_ peek(literal_matcher<TraitsT, ICaseT, false> const &xpr)
|
||||
{
|
||||
this->bset_->set_char(xpr.ch_, ICaseT, this->get_traits_<TraitsT>());
|
||||
return mpl::false_();
|
||||
}
|
||||
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
mpl::false_ peek(string_matcher<TraitsT, ICaseT> const &xpr)
|
||||
{
|
||||
this->bset_->set_char(xpr.str_[0], ICaseT, this->get_traits_<TraitsT>());
|
||||
this->str_ = &xpr.str_;
|
||||
this->str_icase_ = ICaseT;
|
||||
return mpl::false_();
|
||||
}
|
||||
|
||||
template<typename AlternatesT, typename TraitsT>
|
||||
mpl::false_ peek(alternate_matcher<AlternatesT, TraitsT> const &xpr)
|
||||
{
|
||||
BOOST_ASSERT(0 != xpr.bset_.count());
|
||||
this->bset_->set_bitset(xpr.bset_);
|
||||
return mpl::false_();
|
||||
}
|
||||
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
mpl::false_ peek(posix_charset_matcher<TraitsT, ICaseT> const &xpr)
|
||||
{
|
||||
this->bset_->set_class(xpr.mask_, xpr.not_, ICaseT, this->get_traits_<TraitsT>());
|
||||
return mpl::false_();
|
||||
}
|
||||
|
||||
template<typename DummyT = void>
|
||||
struct is_char_8bit : mpl::bool_<1 == sizeof(CharT)> {};
|
||||
|
||||
template<bool ICaseT, typename TraitsT>
|
||||
typename enable_if<is_char_8bit<TraitsT>, mpl::false_>::type
|
||||
peek(charset_matcher<TraitsT, ICaseT, basic_chset<CharT> > const &xpr)
|
||||
{
|
||||
BOOST_ASSERT(0 != xpr.charset_.base().count());
|
||||
this->bset_->set_charset(xpr.charset_, ICaseT);
|
||||
return mpl::false_();
|
||||
}
|
||||
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
mpl::false_ peek(range_matcher<TraitsT, ICaseT> const &xpr)
|
||||
{
|
||||
this->bset_->set_range(xpr.ch_min_, xpr.ch_max_, xpr.not_, ICaseT, this->get_traits_<TraitsT>());
|
||||
return mpl::false_();
|
||||
}
|
||||
|
||||
template<typename XprT, bool GreedyT>
|
||||
mpl::false_ peek(simple_repeat_matcher<XprT, GreedyT> const &xpr)
|
||||
{
|
||||
0 != xpr.min_ ? xpr.xpr_.peek(*this) : this->fail(); // could be a union of xpr and next
|
||||
return mpl::false_();
|
||||
}
|
||||
|
||||
template<typename TraitsT>
|
||||
void set_traits(TraitsT const &traits)
|
||||
{
|
||||
if(0 == this->traits_)
|
||||
{
|
||||
this->traits_ = &traits;
|
||||
this->traits_type_ = &typeid(TraitsT);
|
||||
}
|
||||
else if(*this->traits_type_ != typeid(TraitsT) || this->get_traits_<TraitsT>() != traits)
|
||||
{
|
||||
this->fail(); // traits mis-match! set all and bail
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename TraitsT>
|
||||
TraitsT const &get_traits_() const
|
||||
{
|
||||
BOOST_ASSERT(!!(*this->traits_type_ == typeid(TraitsT)));
|
||||
return *static_cast<TraitsT const *>(this->traits_);
|
||||
}
|
||||
|
||||
hash_peek_bitset<CharT> *bset_;
|
||||
std::basic_string<CharT> const *str_;
|
||||
bool str_icase_;
|
||||
bool line_start_;
|
||||
void const *traits_;
|
||||
std::type_info const *traits_type_;
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
157
include/boost/xpressive/detail/core/quant_style.hpp
Executable file
157
include/boost/xpressive/detail/core/quant_style.hpp
Executable file
@@ -0,0 +1,157 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_style.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_QUANT_STYLE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_QUANT_STYLE_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not_equal_to.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
|
||||
#if defined(NDEBUG) & defined(BOOST_XPR_DEBUG_STACK)
|
||||
# undef BOOST_XPR_DEBUG_STACK
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_XPR_DEBUG_STACK
|
||||
# define BOOST_XPR_DEBUG_STACK_ASSERT BOOST_ASSERT
|
||||
#else
|
||||
# define BOOST_XPR_DEBUG_STACK_ASSERT(x) static_cast<void>(0)
|
||||
#endif
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// xpression_base
|
||||
//
|
||||
struct xpression_base
|
||||
{
|
||||
#ifdef BOOST_XPR_DEBUG_STACK
|
||||
virtual ~xpression_base()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_xpr
|
||||
//
|
||||
template<typename T>
|
||||
struct is_xpr
|
||||
: is_base_and_derived<xpression_base, T>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_enum
|
||||
//
|
||||
enum quant_enum
|
||||
{
|
||||
quant_none,
|
||||
quant_auto,
|
||||
quant_fixed_width,
|
||||
quant_variable_width
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_style
|
||||
//
|
||||
template<quant_enum QuantStyleT, typename WidthT = unknown_width, typename PureT = mpl::true_>
|
||||
struct quant_style
|
||||
: xpression_base
|
||||
{
|
||||
typedef mpl::int_<QuantStyleT> quant; // Which quantification strategy to use?
|
||||
typedef WidthT width; // how many characters this matcher consumes
|
||||
typedef PureT pure; // whether this matcher has observable side-effects
|
||||
|
||||
template<typename BidiIterT>
|
||||
static std::size_t get_width(state_type<BidiIterT> *)
|
||||
{
|
||||
return WidthT::value;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_style_none
|
||||
// this sub-expression cannot be quantified
|
||||
typedef quant_style<quant_none> quant_style_none;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_style_fixed_unknown_width
|
||||
// this sub-expression is fixed width for the purpose of quantification, but
|
||||
// the width cannot be determined at compile time. An example would be the
|
||||
// string_matcher or the mark_matcher.
|
||||
typedef quant_style<quant_fixed_width> quant_style_fixed_unknown_width;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_style_variable_width
|
||||
// this sub-expression can match a variable number of characters
|
||||
typedef quant_style<quant_variable_width> quant_style_variable_width;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_style_fixed_width
|
||||
// for when the sub-expression has a fixed width that is known at compile time
|
||||
template<std::size_t WidthT>
|
||||
struct quant_style_fixed_width
|
||||
: quant_style<quant_fixed_width, mpl::size_t<WidthT> >
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_style_assertion
|
||||
// a zero-width assertion.
|
||||
struct quant_style_assertion
|
||||
: quant_style<quant_none, mpl::size_t<0> >
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_style_auto
|
||||
// automatically pick the quantification style based on width and purity
|
||||
template<typename WidthT, typename PureT>
|
||||
struct quant_style_auto
|
||||
: quant_style<quant_auto, WidthT, PureT>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_type
|
||||
//
|
||||
template<typename MatcherT, typename QuantStyleT = typename MatcherT::quant>
|
||||
struct quant_type
|
||||
: QuantStyleT
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// when the quant_type is auto, determine the quant type from the width and purity
|
||||
template<typename MatcherT>
|
||||
struct quant_type<MatcherT, mpl::int_<quant_auto> >
|
||||
: mpl::if_
|
||||
<
|
||||
mpl::and_
|
||||
<
|
||||
mpl::not_equal_to<typename MatcherT::width, unknown_width>
|
||||
, typename MatcherT::pure
|
||||
>
|
||||
, mpl::int_<quant_fixed_width>
|
||||
, mpl::int_<quant_variable_width>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
89
include/boost/xpressive/detail/core/regex_impl.hpp
Executable file
89
include/boost/xpressive/detail/core/regex_impl.hpp
Executable file
@@ -0,0 +1,89 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_impl.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_REGEX_IMPL_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_REGEX_IMPL_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/utility/tracking_ptr.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// finder
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct finder
|
||||
{
|
||||
virtual ~finder() {}
|
||||
virtual bool operator ()(state_type<BidiIterT> &state) const = 0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_impl
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct regex_impl
|
||||
: enable_reference_tracking<regex_impl<BidiIterT> >
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
regex_impl()
|
||||
: xpr_()
|
||||
, traits_()
|
||||
, finder_()
|
||||
, mark_count_(0)
|
||||
, hidden_mark_count_(0)
|
||||
{
|
||||
#ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
|
||||
++instances;
|
||||
#endif
|
||||
}
|
||||
|
||||
~regex_impl()
|
||||
{
|
||||
#ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
|
||||
--instances;
|
||||
#endif
|
||||
}
|
||||
|
||||
void swap(regex_impl<BidiIterT> &that)
|
||||
{
|
||||
enable_reference_tracking<regex_impl<BidiIterT> >::swap(that);
|
||||
this->xpr_.swap(that.xpr_);
|
||||
this->traits_.swap(that.traits_);
|
||||
this->finder_.swap(that.finder_);
|
||||
std::swap(this->mark_count_, that.mark_count_);
|
||||
std::swap(this->hidden_mark_count_, that.hidden_mark_count_);
|
||||
}
|
||||
|
||||
shared_ptr<matchable<BidiIterT> const> xpr_;
|
||||
shared_ptr<void const> traits_;
|
||||
shared_ptr<finder<BidiIterT> > finder_;
|
||||
std::size_t mark_count_;
|
||||
std::size_t hidden_mark_count_;
|
||||
|
||||
#ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
|
||||
static int instances;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef BOOST_XPRESSIVE_DEBUG_CYCLE_TEST
|
||||
template<typename BidiIterT>
|
||||
int regex_impl<BidiIterT>::instances = 0;
|
||||
#endif
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
131
include/boost/xpressive/detail/core/results_cache.hpp
Executable file
131
include/boost/xpressive/detail/core/results_cache.hpp
Executable file
@@ -0,0 +1,131 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// results_cache.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_RESULTS_CACHE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_RESULTS_CACHE_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/access.hpp>
|
||||
#include <boost/xpressive/match_results.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nested_results
|
||||
// BUGBUG by using std::list, it makes construction of of an empty nested_results
|
||||
// incur a dynamic allocation. As a result, construction an empty match_results is
|
||||
// likewise not free. FIXME.
|
||||
template<typename BidiIterT>
|
||||
struct nested_results
|
||||
: private std::list<match_results<BidiIterT> >
|
||||
{
|
||||
friend struct results_cache<BidiIterT>;
|
||||
friend struct match_results<BidiIterT>;
|
||||
typedef std::list<match_results<BidiIterT> > base_type;
|
||||
|
||||
using base_type::iterator;
|
||||
using base_type::const_iterator;
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB , == 1)
|
||||
// old Dinkumware doesn't expose pointer typedefs
|
||||
typedef base_type::value_type *pointer;
|
||||
typedef base_type::value_type const *const_pointer;
|
||||
#else
|
||||
using base_type::pointer;
|
||||
using base_type::const_pointer;
|
||||
#endif
|
||||
using base_type::reference;
|
||||
using base_type::const_reference;
|
||||
using base_type::size_type;
|
||||
using base_type::begin;
|
||||
using base_type::end;
|
||||
using base_type::size;
|
||||
using base_type::empty;
|
||||
using base_type::front;
|
||||
using base_type::back;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// results_cache
|
||||
//
|
||||
// cache storage for reclaimed match_results structs
|
||||
template<typename BidiIterT>
|
||||
struct results_cache
|
||||
{
|
||||
typedef core_access<BidiIterT> access;
|
||||
|
||||
match_results<BidiIterT> &append_new(nested_results<BidiIterT> &out)
|
||||
{
|
||||
if(this->cache_.empty())
|
||||
{
|
||||
out.push_back(match_results<BidiIterT>());
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(access::get_nested_results(this->cache_.back()).empty());
|
||||
out.splice(out.end(), this->cache_, --this->cache_.end());
|
||||
}
|
||||
return out.back();
|
||||
}
|
||||
|
||||
// move the last match_results struct into the cache
|
||||
void reclaim_last(nested_results<BidiIterT> &out)
|
||||
{
|
||||
BOOST_ASSERT(!out.empty());
|
||||
// first, reclaim any nested results
|
||||
nested_results<BidiIterT> &nested = access::get_nested_results(out.back());
|
||||
if(!nested.empty())
|
||||
{
|
||||
this->reclaim_all(nested);
|
||||
}
|
||||
// then, reclaim the last match_results
|
||||
this->cache_.splice(this->cache_.end(), out, --out.end());
|
||||
}
|
||||
|
||||
// move the last n match_results structs into the cache
|
||||
void reclaim_last_n(nested_results<BidiIterT> &out, std::size_t count)
|
||||
{
|
||||
for(; 0 != count; --count)
|
||||
{
|
||||
this->reclaim_last(out);
|
||||
}
|
||||
}
|
||||
|
||||
void reclaim_all(nested_results<BidiIterT> &out)
|
||||
{
|
||||
typedef typename nested_results<BidiIterT>::iterator iter_type;
|
||||
|
||||
// first, recursively reclaim all the nested results
|
||||
for(iter_type begin = out.begin(); begin != out.end(); ++begin)
|
||||
{
|
||||
nested_results<BidiIterT> &nested = access::get_nested_results(*begin);
|
||||
|
||||
if(!nested.empty())
|
||||
{
|
||||
this->reclaim_all(nested);
|
||||
}
|
||||
}
|
||||
|
||||
// next, reclaim the results themselves
|
||||
this->cache_.splice(this->cache_.end(), out);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
nested_results<BidiIterT> cache_;
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
334
include/boost/xpressive/detail/core/state.hpp
Executable file
334
include/boost/xpressive/detail/core/state.hpp
Executable file
@@ -0,0 +1,334 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// state.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_STATE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_STATE_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/access.hpp>
|
||||
#include <boost/xpressive/detail/core/action_state.hpp>
|
||||
#include <boost/xpressive/detail/core/sub_match_vector.hpp>
|
||||
#include <boost/xpressive/detail/utility/sequence_stack.hpp>
|
||||
#include <boost/xpressive/basic_regex.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// match_context
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct match_context
|
||||
{
|
||||
// pointer to the current match results, passed to actions as a parameter.
|
||||
match_results<BidiIterT> *results_ptr_;
|
||||
|
||||
// The previous match context, if this match_context corresponds to a nested regex invocation
|
||||
match_context<BidiIterT> *prev_context_;
|
||||
|
||||
// If this is a nested match, the "next" sub-expression to execute after the nested match
|
||||
matchable<BidiIterT> const *next_ptr_;
|
||||
|
||||
// A pointer to the current traits object
|
||||
void const *traits_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// match_flags
|
||||
//
|
||||
struct match_flags
|
||||
{
|
||||
bool match_all_;
|
||||
bool match_prev_avail_;
|
||||
bool match_bol_;
|
||||
bool match_eol_;
|
||||
bool match_not_bow_;
|
||||
bool match_not_eow_;
|
||||
bool match_not_null_;
|
||||
bool match_continuous_;
|
||||
bool match_partial_;
|
||||
|
||||
explicit match_flags(regex_constants::match_flag_type flags)
|
||||
: match_all_(false)
|
||||
, match_prev_avail_(0 != (flags & regex_constants::match_prev_avail))
|
||||
, match_bol_(match_prev_avail_ || 0 == (flags & regex_constants::match_not_bol))
|
||||
, match_eol_(0 == (flags & regex_constants::match_not_eol))
|
||||
, match_not_bow_(!match_prev_avail_ && 0 != (flags & regex_constants::match_not_bow))
|
||||
, match_not_eow_(0 != (flags & regex_constants::match_not_eow))
|
||||
, match_not_null_(0 != (flags & regex_constants::match_not_null))
|
||||
, match_continuous_(0 != (flags & regex_constants::match_continuous))
|
||||
, match_partial_(0 != (flags & regex_constants::match_partial))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// state_type
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct state_type
|
||||
{
|
||||
typedef core_access<BidiIterT> access;
|
||||
typedef match_context<BidiIterT> match_context;
|
||||
typedef results_extras<BidiIterT> results_extras;
|
||||
typedef regex_impl<BidiIterT> regex_impl;
|
||||
typedef matchable<BidiIterT> matchable;
|
||||
typedef basic_regex<BidiIterT> basic_regex;
|
||||
typedef match_results<BidiIterT> match_results;
|
||||
typedef sub_match_impl<BidiIterT> sub_match_impl;
|
||||
|
||||
BidiIterT cur_;
|
||||
sub_match_impl *sub_matches_;
|
||||
std::size_t mark_count_;
|
||||
BidiIterT begin_;
|
||||
BidiIterT end_;
|
||||
|
||||
match_flags flags_;
|
||||
bool found_partial_match_;
|
||||
|
||||
match_context context_;
|
||||
results_extras &extras_;
|
||||
action_state action_state_;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
state_type
|
||||
(
|
||||
BidiIterT begin
|
||||
, BidiIterT end
|
||||
, match_results &what
|
||||
, basic_regex const &rex
|
||||
, regex_constants::match_flag_type flags
|
||||
)
|
||||
: cur_(begin)
|
||||
, sub_matches_(0)
|
||||
, mark_count_(0)
|
||||
, begin_(begin)
|
||||
, end_(end)
|
||||
, flags_(flags)
|
||||
, found_partial_match_(false)
|
||||
, context_() // zero-initializes the fields of context_
|
||||
, extras_(core_access<BidiIterT>::get_extras(what))
|
||||
, action_state_(core_access<BidiIterT>::get_action_state(what))
|
||||
{
|
||||
// reclaim any cached memory in the match_results struct
|
||||
this->extras_.sub_match_stack_.unwind();
|
||||
|
||||
// initialize the context_ struct
|
||||
this->init_(*access::get_regex_impl(rex), what);
|
||||
|
||||
// move all the nested match_results structs into the match_results cache
|
||||
this->extras_.results_cache_.reclaim_all(access::get_nested_results(what));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// reset
|
||||
void reset(match_results &what, basic_regex const &rex)
|
||||
{
|
||||
this->context_.prev_context_ = 0;
|
||||
this->found_partial_match_ = false;
|
||||
this->extras_.sub_match_stack_.unwind();
|
||||
this->init_(*access::get_regex_impl(rex), what);
|
||||
this->extras_.results_cache_.reclaim_all(access::get_nested_results(what));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// push_context
|
||||
// called to prepare the state object for a regex match
|
||||
match_context push_context(regex_impl const &impl, matchable const &next, match_context &prev)
|
||||
{
|
||||
// save state
|
||||
match_context context = this->context_;
|
||||
|
||||
// create a new nested match_results for this regex
|
||||
nested_results<BidiIterT> &nested = access::get_nested_results(*context.results_ptr_);
|
||||
match_results &what = this->extras_.results_cache_.append_new(nested);
|
||||
|
||||
// (re)initialize the match context
|
||||
this->init_(impl, what);
|
||||
|
||||
// create a linked list of match_context structs
|
||||
this->context_.prev_context_ = &prev;
|
||||
this->context_.next_ptr_ = &next;
|
||||
|
||||
// record the start of the zero-th sub-match
|
||||
this->sub_matches_[0].begin_ = this->cur_;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// pop_context
|
||||
// called after a nested match failed to restore the context
|
||||
void pop_context(regex_impl const &impl, bool success)
|
||||
{
|
||||
match_context &context = *this->context_.prev_context_;
|
||||
if(!success)
|
||||
{
|
||||
match_results &what = *context.results_ptr_;
|
||||
this->uninit_(impl, what);
|
||||
|
||||
// send the match_results struct back to the cache
|
||||
nested_results<BidiIterT> &nested = access::get_nested_results(what);
|
||||
this->extras_.results_cache_.reclaim_last(nested);
|
||||
}
|
||||
|
||||
// restore the state
|
||||
this->context_ = context;
|
||||
match_results &results = *this->context_.results_ptr_;
|
||||
this->sub_matches_ = access::get_sub_matches(access::get_sub_match_vector(results));
|
||||
this->mark_count_ = results.size();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// swap_context
|
||||
void swap_context(match_context &context)
|
||||
{
|
||||
std::swap(this->context_, context);
|
||||
match_results &results = *this->context_.results_ptr_;
|
||||
this->sub_matches_ = access::get_sub_matches(access::get_sub_match_vector(results));
|
||||
this->mark_count_ = results.size();
|
||||
}
|
||||
|
||||
// beginning of buffer
|
||||
bool bos() const
|
||||
{
|
||||
return this->cur_ == this->begin_;
|
||||
}
|
||||
|
||||
// end of buffer
|
||||
bool eos()
|
||||
{
|
||||
return this->cur_ == this->end_ && this->found_partial_match();
|
||||
}
|
||||
|
||||
// fetch the n-th sub_match
|
||||
sub_match_impl &sub_match(int n)
|
||||
{
|
||||
return this->sub_matches_[n];
|
||||
}
|
||||
|
||||
// called when a partial match has succeeded
|
||||
void set_partial_match()
|
||||
{
|
||||
sub_match_impl &sub0 = this->sub_match(0);
|
||||
sub0.first = sub0.begin_;
|
||||
sub0.second = this->end_;
|
||||
sub0.matched = false;
|
||||
}
|
||||
|
||||
template<typename TraitsT>
|
||||
TraitsT const &get_traits() const
|
||||
{
|
||||
return *static_cast<TraitsT const *>(this->context_.traits_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init_(regex_impl const &impl, match_results &what)
|
||||
{
|
||||
regex_id_type const id = impl.xpr_.get();
|
||||
std::size_t const total_mark_count = impl.mark_count_ + impl.hidden_mark_count_ + 1;
|
||||
|
||||
// initialize the context and the sub_match vector
|
||||
this->context_.results_ptr_ = &what;
|
||||
this->context_.traits_ = impl.traits_.get();
|
||||
this->mark_count_ = impl.mark_count_ + 1;
|
||||
this->sub_matches_ = this->extras_.sub_match_stack_.push_sequence(total_mark_count);
|
||||
this->sub_matches_ += impl.hidden_mark_count_;
|
||||
|
||||
// initialize the match_results struct
|
||||
access::init_match_results(what, id, this->sub_matches_, this->mark_count_);
|
||||
}
|
||||
|
||||
void uninit_(regex_impl const &impl, match_results &what)
|
||||
{
|
||||
extras_.sub_match_stack_.unwind_to(
|
||||
access::get_sub_matches(access::get_sub_match_vector(what)) + impl.hidden_mark_count_
|
||||
);
|
||||
}
|
||||
|
||||
bool found_partial_match()
|
||||
{
|
||||
this->found_partial_match_ = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// memento
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct memento
|
||||
{
|
||||
sub_match_impl<BidiIterT> *old_sub_matches_;
|
||||
std::size_t nested_results_count_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// save_sub_matches
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline memento<BidiIterT> save_sub_matches(state_type<BidiIterT> &state)
|
||||
{
|
||||
memento<BidiIterT> mem =
|
||||
{
|
||||
state.extras_.sub_match_stack_.push_sequence(state.mark_count_, no_fill)
|
||||
, state.context_.results_ptr_->nested_results().size()
|
||||
};
|
||||
std::copy(state.sub_matches_, state.sub_matches_ + state.mark_count_, mem.old_sub_matches_);
|
||||
return mem;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// restore_sub_matches
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline void restore_sub_matches(memento<BidiIterT> const &mem, state_type<BidiIterT> &state)
|
||||
{
|
||||
typedef core_access<BidiIterT> access;
|
||||
nested_results<BidiIterT> &nested = access::get_nested_results(*state.context_.results_ptr_);
|
||||
std::size_t count = state.context_.results_ptr_->nested_results().size() - mem.nested_results_count_;
|
||||
state.extras_.results_cache_.reclaim_last_n(nested, count);
|
||||
std::copy(mem.old_sub_matches_, mem.old_sub_matches_ + state.mark_count_, state.sub_matches_);
|
||||
state.extras_.sub_match_stack_.unwind_to(mem.old_sub_matches_);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// reclaim_sub_matches
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline void reclaim_sub_matches(memento<BidiIterT> const &mem, state_type<BidiIterT> &state)
|
||||
{
|
||||
std::size_t count = state.context_.results_ptr_->nested_results().size() - mem.nested_results_count_;
|
||||
if(count == 0)
|
||||
{
|
||||
state.extras_.sub_match_stack_.unwind_to(mem.old_sub_matches_);
|
||||
}
|
||||
// else we have we must orphan this block of backrefs because we are using the stack
|
||||
// space above it.
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// traits_cast
|
||||
//
|
||||
template<typename TraitsT, typename BidiIterT>
|
||||
inline TraitsT const &traits_cast(state_type<BidiIterT> const &state)
|
||||
{
|
||||
return state.template get_traits<TraitsT>();
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
43
include/boost/xpressive/detail/core/sub_match_impl.hpp
Executable file
43
include/boost/xpressive/detail/core/sub_match_impl.hpp
Executable file
@@ -0,0 +1,43 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// sub_match_impl.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_SUB_MATCH_IMPL_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_SUB_MATCH_IMPL_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/xpressive/sub_match.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// sub_match_impl
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct sub_match_impl
|
||||
: sub_match<BidiIterT>
|
||||
{
|
||||
unsigned int repeat_count_;
|
||||
BidiIterT begin_;
|
||||
bool zero_width_;
|
||||
|
||||
sub_match_impl()
|
||||
: sub_match<BidiIterT>()
|
||||
, repeat_count_(0)
|
||||
, begin_()
|
||||
, zero_width_(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
171
include/boost/xpressive/detail/core/sub_match_vector.hpp
Executable file
171
include/boost/xpressive/detail/core/sub_match_vector.hpp
Executable file
@@ -0,0 +1,171 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// sub_match_vector.hpp
|
||||
//
|
||||
// Copyright 2004 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_CORE_SUB_MATCH_VECTOR_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_CORE_SUB_MATCH_VECTOR_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/sub_match_impl.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
#if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// sub_match_iterator
|
||||
//
|
||||
template<typename ValueT, typename MainIterT>
|
||||
struct sub_match_iterator
|
||||
: iterator_adaptor
|
||||
<
|
||||
sub_match_iterator<ValueT, MainIterT>
|
||||
, MainIterT
|
||||
, ValueT
|
||||
, std::random_access_iterator_tag
|
||||
>
|
||||
{
|
||||
typedef iterator_adaptor
|
||||
<
|
||||
sub_match_iterator<ValueT, MainIterT>
|
||||
, MainIterT
|
||||
, ValueT
|
||||
, std::random_access_iterator_tag
|
||||
> base_t;
|
||||
|
||||
sub_match_iterator(MainIterT baseiter)
|
||||
: base_t(baseiter)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// sub_match_vector
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct sub_match_vector
|
||||
: private noncopyable
|
||||
{
|
||||
private:
|
||||
struct dummy { int i_; };
|
||||
typedef int dummy::*bool_type;
|
||||
|
||||
public:
|
||||
typedef sub_match<BidiIterT> value_type;
|
||||
typedef std::size_t size_type;
|
||||
typedef value_type const &const_reference;
|
||||
typedef const_reference reference;
|
||||
typedef typename iterator_difference<BidiIterT>::type difference_type;
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
|
||||
#if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
|
||||
|
||||
typedef sub_match_iterator
|
||||
<
|
||||
value_type const
|
||||
, sub_match_impl<BidiIterT> const *
|
||||
> const_iterator;
|
||||
|
||||
#else
|
||||
|
||||
typedef iterator_adaptor
|
||||
<
|
||||
sub_match_impl<BidiIterT> const *
|
||||
, default_iterator_policies
|
||||
, value_type
|
||||
, value_type const &
|
||||
, value_type const *
|
||||
> const_iterator;
|
||||
|
||||
#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
|
||||
|
||||
typedef const_iterator iterator;
|
||||
|
||||
sub_match_vector()
|
||||
: size_(0)
|
||||
, sub_matches_(0)
|
||||
{
|
||||
}
|
||||
|
||||
const_reference operator [](size_type index) const
|
||||
{
|
||||
static value_type const s_null;
|
||||
return (index >= this->size_)
|
||||
? s_null
|
||||
: *static_cast<value_type const *>(&this->sub_matches_[ index ]);
|
||||
}
|
||||
|
||||
size_type size() const
|
||||
{
|
||||
return this->size_;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return 0 == this->size();
|
||||
}
|
||||
|
||||
const_iterator begin() const
|
||||
{
|
||||
return const_iterator(this->sub_matches_);
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return const_iterator(this->sub_matches_ + this->size_);
|
||||
}
|
||||
|
||||
operator bool_type() const
|
||||
{
|
||||
return (!this->empty() && (*this)[0].matched) ? &dummy::i_ : 0;
|
||||
}
|
||||
|
||||
bool operator !() const
|
||||
{
|
||||
return this->empty() || !(*this)[0].matched;
|
||||
}
|
||||
|
||||
void swap(sub_match_vector<BidiIterT> &that)
|
||||
{
|
||||
std::swap(this->size_, that.size_);
|
||||
std::swap(this->sub_matches_, that.sub_matches_);
|
||||
}
|
||||
|
||||
private:
|
||||
friend struct detail::core_access<BidiIterT>;
|
||||
|
||||
void init_(sub_match_impl<BidiIterT> *sub_matches, size_type size)
|
||||
{
|
||||
this->size_ = size;
|
||||
this->sub_matches_ = sub_matches;
|
||||
}
|
||||
|
||||
void init_(sub_match_impl<BidiIterT> *sub_matches, size_type size, sub_match_vector<BidiIterT> const &that)
|
||||
{
|
||||
BOOST_ASSERT(size == that.size_);
|
||||
this->size_ = size;
|
||||
this->sub_matches_ = sub_matches;
|
||||
std::copy(that.sub_matches_, that.sub_matches_ + that.size_, this->sub_matches_);
|
||||
}
|
||||
|
||||
size_type size_;
|
||||
sub_match_impl<BidiIterT> *sub_matches_;
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
324
include/boost/xpressive/detail/detail_fwd.hpp
Executable file
324
include/boost/xpressive/detail/detail_fwd.hpp
Executable file
@@ -0,0 +1,324 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// detail_fwd.hpp
|
||||
//
|
||||
// Copyright 2004 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_DETAIL_FWD_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_DETAIL_FWD_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <climits> // for INT_MAX
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/xpressive/xpressive_fwd.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
typedef unsigned int uint_t;
|
||||
|
||||
template<uint_t MinT, uint_t MaxT>
|
||||
struct generic_quant_tag;
|
||||
|
||||
struct modifier_tag;
|
||||
|
||||
typedef mpl::size_t<INT_MAX / 2 - 1> unknown_width;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// placeholders
|
||||
//
|
||||
template<typename CharT, bool NotT = false>
|
||||
struct literal_placeholder;
|
||||
|
||||
template<typename CharT>
|
||||
struct string_placeholder;
|
||||
|
||||
struct mark_placeholder;
|
||||
|
||||
template<typename BidiIterT, bool ByRefT>
|
||||
struct regex_placeholder;
|
||||
|
||||
struct posix_charset_placeholder;
|
||||
|
||||
template<typename CondT>
|
||||
struct assert_word_placeholder;
|
||||
|
||||
template<typename CharT>
|
||||
struct range_placeholder;
|
||||
|
||||
struct assert_bol_placeholder;
|
||||
|
||||
struct assert_eol_placeholder;
|
||||
|
||||
struct logical_newline_placeholder;
|
||||
|
||||
struct self_placeholder;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matchers
|
||||
//
|
||||
struct end_matcher;
|
||||
|
||||
struct assert_bos_matcher;
|
||||
|
||||
struct assert_eos_matcher;
|
||||
|
||||
template<typename TraitsT>
|
||||
struct assert_bol_matcher;
|
||||
|
||||
template<typename TraitsT>
|
||||
struct assert_eol_matcher;
|
||||
|
||||
template<typename CondT, typename TraitsT>
|
||||
struct assert_word_matcher;
|
||||
|
||||
struct true_matcher;
|
||||
|
||||
template<typename AlternatesT, typename TraitsT>
|
||||
struct alternate_matcher;
|
||||
|
||||
struct alternate_end_matcher;
|
||||
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
struct posix_charset_matcher;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct alternates_factory;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct sequence;
|
||||
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
struct mark_matcher;
|
||||
|
||||
struct mark_begin_matcher;
|
||||
|
||||
struct mark_end_matcher;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct regex_matcher;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct regex_byref_matcher;
|
||||
|
||||
template<typename TraitsT>
|
||||
struct compound_charset;
|
||||
|
||||
template<typename TraitsT, bool ICaseT, typename CharSetT = compound_charset<TraitsT> >
|
||||
struct charset_matcher;
|
||||
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
struct range_matcher;
|
||||
|
||||
template<typename TraitsT, int SizeT>
|
||||
struct set_matcher;
|
||||
|
||||
template<typename XprT, bool GreedyT>
|
||||
struct simple_repeat_matcher;
|
||||
|
||||
struct repeat_begin_matcher;
|
||||
|
||||
template<bool GreedyT>
|
||||
struct repeat_end_matcher;
|
||||
|
||||
template<typename TraitsT, bool ICaseT, bool NotT>
|
||||
struct literal_matcher;
|
||||
|
||||
template<typename TraitsT, bool ICaseT>
|
||||
struct string_matcher;
|
||||
|
||||
template<typename ActionT>
|
||||
struct action_matcher;
|
||||
|
||||
template<typename XprT>
|
||||
struct as_xpr_type;
|
||||
|
||||
template<typename XprT>
|
||||
struct is_modifiable;
|
||||
|
||||
template<typename AlternatesT>
|
||||
struct alternates_list;
|
||||
|
||||
template<typename ModifierT>
|
||||
struct modifier_op;
|
||||
|
||||
template<typename LeftT, typename RightT>
|
||||
struct modifier_sequencer;
|
||||
|
||||
struct icase_modifier;
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct xpression_visitor;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct regex_impl;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct regex_matcher;
|
||||
|
||||
struct epsilon_matcher;
|
||||
|
||||
typedef proto::unary_op<epsilon_matcher, proto::noop_tag> epsilon_type;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct nested_results;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct regex_id_filter_predicate;
|
||||
|
||||
template<typename XprT>
|
||||
struct keeper_matcher;
|
||||
|
||||
template<typename XprT>
|
||||
struct lookahead_matcher;
|
||||
|
||||
template<typename XprT>
|
||||
struct lookbehind_matcher;
|
||||
|
||||
template<typename CondT>
|
||||
struct assert_word_placeholder;
|
||||
|
||||
template<bool IsBoundaryT>
|
||||
struct word_boundary;
|
||||
|
||||
template<typename BidiIterT, typename MatcherT>
|
||||
sequence<BidiIterT> make_dynamic_xpression(MatcherT const &matcher);
|
||||
|
||||
template<typename CharT>
|
||||
struct xpression_linker;
|
||||
|
||||
template<typename CharT>
|
||||
struct xpression_peeker;
|
||||
|
||||
typedef proto::unary_op<mark_placeholder, proto::noop_tag> mark_tag;
|
||||
|
||||
struct any_matcher;
|
||||
|
||||
template<typename TraitsT>
|
||||
struct logical_newline_matcher;
|
||||
|
||||
typedef proto::unary_op<logical_newline_placeholder, proto::noop_tag> logical_newline_xpression;
|
||||
|
||||
struct set_initializer;
|
||||
|
||||
typedef proto::unary_op<set_initializer, proto::noop_tag> set_initializer_type;
|
||||
|
||||
struct seq_tag;
|
||||
|
||||
template<bool PositiveT>
|
||||
struct lookahead_tag;
|
||||
|
||||
template<bool PositiveT>
|
||||
struct lookbehind_tag;
|
||||
|
||||
struct keeper_tag;
|
||||
|
||||
template<typename LocaleT>
|
||||
struct locale_modifier;
|
||||
|
||||
template<typename MatcherT>
|
||||
struct matcher_wrapper;
|
||||
|
||||
template<typename LocaleT, typename BidiIterT>
|
||||
struct regex_traits_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Misc.
|
||||
struct no_next;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct core_access;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct state_type;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct matchable;
|
||||
|
||||
template<typename MatcherT, typename BidiIterT>
|
||||
struct dynamic_xpression;
|
||||
|
||||
template<typename MatcherT, typename NextT>
|
||||
struct static_xpression;
|
||||
|
||||
typedef static_xpression<end_matcher, no_next> end_xpression;
|
||||
|
||||
typedef static_xpression<alternate_end_matcher, no_next> alternate_end_xpression;
|
||||
|
||||
typedef static_xpression<true_matcher, no_next> true_xpression;
|
||||
|
||||
template<typename MatcherT, typename NextT = end_xpression>
|
||||
struct static_xpression;
|
||||
|
||||
template<typename TopT, typename NextT>
|
||||
struct stacked_xpression;
|
||||
|
||||
template<typename XprT>
|
||||
struct is_static_xpression;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct sub_match_impl;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct results_cache;
|
||||
|
||||
template<typename T>
|
||||
struct sequence_stack;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct results_extras;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct match_context;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct sub_match_vector;
|
||||
|
||||
struct action_state;
|
||||
|
||||
template<typename TraitsT, typename BidiIterT>
|
||||
TraitsT const &traits_cast(state_type<BidiIterT> const &state);
|
||||
|
||||
template<typename CharT>
|
||||
struct basic_chset;
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct memento;
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
void set_char(compound_charset<TraitsT> &chset, CharT ch, TraitsT const &traits, bool icase);
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
void set_range(compound_charset<TraitsT> &chset, CharT from, CharT to, TraitsT const &traits, bool icase);
|
||||
|
||||
template<typename TraitsT>
|
||||
void set_class(compound_charset<TraitsT> &chset, typename TraitsT::char_class_type char_class, bool no, TraitsT const &traits, bool icase);
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
void set_char(basic_chset<CharT> &chset, CharT ch, TraitsT const &traits, bool icase);
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
void set_range(basic_chset<CharT> &chset, CharT from, CharT to, TraitsT const &traits, bool icase);
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
void set_class(basic_chset<CharT> &chset, typename TraitsT::char_class_type char_class, bool no, TraitsT const &traits, bool icase);
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
/// INTERNAL ONLY
|
||||
namespace boost { namespace xpressive
|
||||
{
|
||||
|
||||
/// INTERNAL ONLY
|
||||
template<typename TraitsT, std::size_t N>
|
||||
typename TraitsT::char_class_type
|
||||
lookup_classname(TraitsT const &traits, char const (&cname)[N], bool icase = false);
|
||||
|
||||
}} // namespace boost::xpressive
|
||||
|
||||
#endif
|
||||
429
include/boost/xpressive/detail/dynamic/dynamic.hpp
Executable file
429
include/boost/xpressive/detail/dynamic/dynamic.hpp
Executable file
@@ -0,0 +1,429 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// dynamic.hpp
|
||||
//
|
||||
// Copyright 2004 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 <list>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/assert.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/core/icase.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// invalid_xpression
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct invalid_xpression
|
||||
: matchable<BidiIterT>
|
||||
{
|
||||
bool match(state_type<BidiIterT> &) const
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::size_t get_width(state_type<BidiIterT> *) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void noop(matchable<BidiIterT> const *)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get_invalid_xpression
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline shared_ptr<matchable<BidiIterT> const> const &get_invalid_xpression()
|
||||
{
|
||||
static invalid_xpression<BidiIterT> const invalid_xpr;
|
||||
|
||||
static shared_ptr<matchable<BidiIterT> const> const invalid_ptr
|
||||
(
|
||||
static_cast<matchable<BidiIterT> const *>(&invalid_xpr)
|
||||
, &invalid_xpression<BidiIterT>::noop
|
||||
);
|
||||
|
||||
return invalid_ptr;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// dynamic_xpression
|
||||
//
|
||||
template<typename MatcherT, typename BidiIterT>
|
||||
struct dynamic_xpression
|
||||
: MatcherT
|
||||
, matchable<BidiIterT>
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
shared_ptr<matchable<BidiIterT> const> next_;
|
||||
|
||||
dynamic_xpression(MatcherT const &matcher = MatcherT())
|
||||
: MatcherT(matcher)
|
||||
, next_(get_invalid_xpression<BidiIterT>())
|
||||
{
|
||||
}
|
||||
|
||||
bool match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
return this->MatcherT::match(state, *this->next_);
|
||||
}
|
||||
|
||||
std::size_t get_width(state_type<BidiIterT> *state) const
|
||||
{
|
||||
std::size_t this_width = this->MatcherT::get_width(state);
|
||||
if(this_width == unknown_width())
|
||||
return unknown_width();
|
||||
std::size_t that_width = this->next_->get_width(state);
|
||||
if(that_width == unknown_width())
|
||||
return unknown_width();
|
||||
return this_width + that_width;
|
||||
}
|
||||
|
||||
void link(xpression_linker<char_type> &linker) const
|
||||
{
|
||||
linker.link(*static_cast<MatcherT const *>(this), this->next_.get());
|
||||
this->next_->link(linker);
|
||||
}
|
||||
|
||||
void peek(xpression_peeker<char_type> &peeker) const
|
||||
{
|
||||
this->peek_next_(peeker.peek(*static_cast<MatcherT const *>(this)), peeker);
|
||||
}
|
||||
|
||||
sequence<BidiIterT> quantify
|
||||
(
|
||||
quant_spec const &spec
|
||||
, std::size_t &hidden_mark_count
|
||||
, sequence<BidiIterT> seq
|
||||
, alternates_factory<BidiIterT> const &factory
|
||||
) const
|
||||
{
|
||||
return this->quantify_(spec, hidden_mark_count, seq, quant_type<MatcherT>(), factory, this);
|
||||
}
|
||||
|
||||
bool is_quantifiable() const
|
||||
{
|
||||
return quant_type<MatcherT>::value != (int)quant_none;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
sequence<BidiIterT> quantify_
|
||||
(
|
||||
quant_spec const &
|
||||
, std::size_t &
|
||||
, sequence<BidiIterT>
|
||||
, mpl::int_<quant_none>
|
||||
, alternates_factory<BidiIterT> const &
|
||||
, void const *
|
||||
) const;
|
||||
|
||||
sequence<BidiIterT> quantify_
|
||||
(
|
||||
quant_spec const &
|
||||
, std::size_t &
|
||||
, sequence<BidiIterT>
|
||||
, mpl::int_<quant_fixed_width>
|
||||
, alternates_factory<BidiIterT> const &
|
||||
, void const *
|
||||
) const;
|
||||
|
||||
sequence<BidiIterT> quantify_
|
||||
(
|
||||
quant_spec const &
|
||||
, std::size_t &
|
||||
, sequence<BidiIterT>
|
||||
, mpl::int_<quant_variable_width>
|
||||
, alternates_factory<BidiIterT> const &
|
||||
, void const *
|
||||
) const;
|
||||
|
||||
sequence<BidiIterT> quantify_
|
||||
(
|
||||
quant_spec const &
|
||||
, std::size_t &
|
||||
, sequence<BidiIterT>
|
||||
, mpl::int_<quant_fixed_width>
|
||||
, alternates_factory<BidiIterT> const &
|
||||
, mark_begin_matcher const *
|
||||
) const;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_dynamic_xpression
|
||||
//
|
||||
template<typename BidiIterT, typename MatcherT>
|
||||
inline sequence<BidiIterT> make_dynamic_xpression(MatcherT const &matcher)
|
||||
{
|
||||
typedef dynamic_xpression<MatcherT, BidiIterT> xpression_type;
|
||||
std::auto_ptr<xpression_type> xpr(new xpression_type(matcher));
|
||||
|
||||
sequence<BidiIterT> seq;
|
||||
seq.second = &xpr->next_;
|
||||
seq.first = xpr;
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alternates_factory
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct alternates_factory
|
||||
{
|
||||
typedef std::vector<shared_ptr<matchable<BidiIterT> const> > alternates_vector;
|
||||
|
||||
virtual ~alternates_factory() {}
|
||||
|
||||
virtual std::pair<sequence<BidiIterT>, alternates_vector *>
|
||||
operator ()() const = 0;
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
struct alternates_factory_impl
|
||||
: alternates_factory<BidiIterT>
|
||||
{
|
||||
typedef typename alternates_factory<BidiIterT>::alternates_vector alternates_vector;
|
||||
|
||||
std::pair<sequence<BidiIterT>, alternates_vector *>
|
||||
operator ()() const
|
||||
{
|
||||
typedef alternate_matcher<alternates_vector, TraitsT> alternate_matcher;
|
||||
typedef dynamic_xpression<alternate_matcher, BidiIterT> alternate_xpression;
|
||||
shared_ptr<alternate_xpression> alt_xpr(new alternate_xpression);
|
||||
sequence<BidiIterT> seq(alt_xpr, &alt_xpr->next_);
|
||||
return std::make_pair(seq, &alt_xpr->alternates_);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alternates_to_matchable
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
inline sequence<BidiIterT> alternates_to_matchable
|
||||
(
|
||||
std::list<sequence<BidiIterT> > const &alternates
|
||||
, alternates_factory<BidiIterT> const &factory
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT(0 != alternates.size());
|
||||
|
||||
// If there is only 1 alternate, just return it.
|
||||
if(1 == alternates.size())
|
||||
{
|
||||
return alternates.front();
|
||||
}
|
||||
|
||||
typedef std::vector<shared_ptr<matchable<BidiIterT> const> > alternates_vector;
|
||||
std::pair<sequence<BidiIterT>, alternates_vector *> result = factory();
|
||||
|
||||
// through the wonders of reference counting, all alternates can share an end_alternate
|
||||
typedef dynamic_xpression<alternate_end_matcher, BidiIterT> alternate_end_xpression;
|
||||
shared_ptr<alternate_end_xpression> end_alt_xpr(new alternate_end_xpression);
|
||||
|
||||
// terminate each alternate with an alternate_end_matcher
|
||||
result.second->reserve(alternates.size());
|
||||
typedef std::list<sequence<BidiIterT> > alternates_list;
|
||||
typename alternates_list::const_iterator begin = alternates.begin(), end = alternates.end();
|
||||
for(; begin != end; ++begin)
|
||||
{
|
||||
if(!begin->is_empty())
|
||||
{
|
||||
result.second->push_back(begin->first);
|
||||
*begin->second = end_alt_xpr;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.second->push_back(end_alt_xpr);
|
||||
}
|
||||
}
|
||||
|
||||
return result.first;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matcher_wrapper
|
||||
//
|
||||
template<typename MatcherT>
|
||||
struct matcher_wrapper
|
||||
: MatcherT
|
||||
{
|
||||
matcher_wrapper(MatcherT const &matcher = MatcherT())
|
||||
: MatcherT(matcher)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
bool match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
return this->MatcherT::match(state, matcher_wrapper<true_matcher>());
|
||||
}
|
||||
|
||||
template<typename CharT>
|
||||
void link(xpression_linker<CharT> &linker) const
|
||||
{
|
||||
linker.link(*static_cast<MatcherT const *>(this), 0);
|
||||
}
|
||||
|
||||
template<typename CharT>
|
||||
void peek(xpression_peeker<CharT> &peeker) const
|
||||
{
|
||||
peeker.peek(*static_cast<MatcherT const *>(this));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// dynamic_xpression::quantify_
|
||||
//
|
||||
// unquantifiable
|
||||
template<typename MatcherT, typename BidiIterT>
|
||||
inline sequence<BidiIterT> dynamic_xpression<MatcherT, BidiIterT>::quantify_
|
||||
(
|
||||
quant_spec const &
|
||||
, std::size_t &
|
||||
, sequence<BidiIterT>
|
||||
, mpl::int_<quant_none>
|
||||
, alternates_factory<BidiIterT> const &
|
||||
, void const *
|
||||
) const
|
||||
{
|
||||
BOOST_ASSERT(false); // should never get here
|
||||
throw regex_error(regex_constants::error_badrepeat, "expression cannot be quantified");
|
||||
}
|
||||
|
||||
// fixed-width matchers
|
||||
template<typename MatcherT, typename BidiIterT>
|
||||
inline sequence<BidiIterT> dynamic_xpression<MatcherT, BidiIterT>::quantify_
|
||||
(
|
||||
quant_spec const &spec
|
||||
, std::size_t &hidden_mark_count
|
||||
, sequence<BidiIterT> seq
|
||||
, mpl::int_<quant_fixed_width>
|
||||
, alternates_factory<BidiIterT> const &factory
|
||||
, void const *
|
||||
) const
|
||||
{
|
||||
if(this->next_ != get_invalid_xpression<BidiIterT>())
|
||||
{
|
||||
return this->quantify_(spec, hidden_mark_count, seq, mpl::int_<quant_variable_width>(), factory, this);
|
||||
}
|
||||
|
||||
typedef matcher_wrapper<MatcherT> xpr_type;
|
||||
|
||||
if(spec.greedy_)
|
||||
{
|
||||
simple_repeat_matcher<xpr_type, true> quant(*this, spec.min_, spec.max_);
|
||||
return make_dynamic_xpression<BidiIterT>(quant);
|
||||
}
|
||||
else
|
||||
{
|
||||
simple_repeat_matcher<xpr_type, false> quant(*this, spec.min_, spec.max_);
|
||||
return make_dynamic_xpression<BidiIterT>(quant);
|
||||
}
|
||||
}
|
||||
|
||||
// variable-width, no mark
|
||||
template<typename MatcherT, typename BidiIterT>
|
||||
inline sequence<BidiIterT> dynamic_xpression<MatcherT, BidiIterT>::quantify_
|
||||
(
|
||||
quant_spec const &spec
|
||||
, std::size_t &hidden_mark_count
|
||||
, sequence<BidiIterT> seq
|
||||
, mpl::int_<quant_variable_width>
|
||||
, alternates_factory<BidiIterT> const &factory
|
||||
, void const *
|
||||
) const
|
||||
{
|
||||
// create a hidden mark so this expression can be quantified
|
||||
int mark_nbr = -static_cast<int>(++hidden_mark_count);
|
||||
mark_begin_matcher mark_begin(mark_nbr);
|
||||
mark_end_matcher mark_end(mark_nbr);
|
||||
sequence<BidiIterT> new_seq = make_dynamic_xpression<BidiIterT>(mark_begin);
|
||||
new_seq += seq;
|
||||
new_seq += make_dynamic_xpression<BidiIterT>(mark_end);
|
||||
return new_seq.first->quantify(spec, hidden_mark_count, new_seq, factory);
|
||||
}
|
||||
|
||||
// variable-width with mark
|
||||
template<typename MatcherT, typename BidiIterT>
|
||||
inline sequence<BidiIterT> dynamic_xpression<MatcherT, BidiIterT>::quantify_
|
||||
(
|
||||
quant_spec const &spec
|
||||
, std::size_t &
|
||||
, sequence<BidiIterT> seq
|
||||
, mpl::int_<quant_fixed_width>
|
||||
, alternates_factory<BidiIterT> const &factory
|
||||
, mark_begin_matcher const *
|
||||
) const
|
||||
{
|
||||
BOOST_ASSERT(spec.max_); // we should never get here if max is 0
|
||||
|
||||
// only bother creating a quantifier if max is greater than one
|
||||
if(1 < spec.max_)
|
||||
{
|
||||
int mark_number = this->mark_number_;
|
||||
unsigned int min = spec.min_ ? spec.min_ : 1U;
|
||||
detail::sequence<BidiIterT> seq_quant;
|
||||
// TODO: statically bind the repeat_begin_matcher to the mark_begin for better perf
|
||||
seq_quant += make_dynamic_xpression<BidiIterT>(repeat_begin_matcher(mark_number));
|
||||
// TODO: statically bind the mark_end to the quantifier_end for better perf
|
||||
if(spec.greedy_)
|
||||
{
|
||||
repeat_end_matcher<true> end_quant(mark_number, min, spec.max_);
|
||||
seq += make_dynamic_xpression<BidiIterT>(end_quant);
|
||||
}
|
||||
else
|
||||
{
|
||||
repeat_end_matcher<false> end_quant(mark_number, min, spec.max_);
|
||||
seq += make_dynamic_xpression<BidiIterT>(end_quant);
|
||||
}
|
||||
seq_quant += seq;
|
||||
seq = seq_quant;
|
||||
}
|
||||
|
||||
// if min is 0, the quant must be made alternate with an empty matcher.
|
||||
if(0 == spec.min_)
|
||||
{
|
||||
std::list<sequence<BidiIterT> > alts(2);
|
||||
(spec.greedy_ ? alts.front() : alts.back()) = seq;
|
||||
seq = alternates_to_matchable(alts, factory);
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
155
include/boost/xpressive/detail/dynamic/matchable.hpp
Executable file
155
include/boost/xpressive/detail/dynamic/matchable.hpp
Executable file
@@ -0,0 +1,155 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matchable.hpp
|
||||
//
|
||||
// Copyright 2004 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 <utility>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/regex_error.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct matchable;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// sequence
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct sequence
|
||||
: std::pair
|
||||
<
|
||||
shared_ptr<matchable<BidiIterT> const>
|
||||
, shared_ptr<matchable<BidiIterT> const> *
|
||||
>
|
||||
{
|
||||
typedef shared_ptr<matchable<BidiIterT> const> matchable_ptr_t;
|
||||
typedef std::pair<matchable_ptr_t, matchable_ptr_t *> base_t;
|
||||
|
||||
explicit sequence(matchable_ptr_t head = matchable_ptr_t(), matchable_ptr_t *tail_ptr = 0)
|
||||
: base_t(head, tail_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
bool is_empty() const
|
||||
{
|
||||
return !this->first;
|
||||
}
|
||||
|
||||
sequence &operator +=(sequence that)
|
||||
{
|
||||
if(is_empty())
|
||||
{
|
||||
*this = that;
|
||||
}
|
||||
else if(!that.is_empty())
|
||||
{
|
||||
*this->second = that.first;
|
||||
this->second = that.second;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// quant_spec
|
||||
//
|
||||
struct quant_spec
|
||||
{
|
||||
unsigned int min_;
|
||||
unsigned int max_;
|
||||
bool greedy_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matchable
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct matchable
|
||||
: xpression_base
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
virtual ~matchable() {}
|
||||
|
||||
virtual bool match(state_type<BidiIterT> &state) const = 0;
|
||||
|
||||
virtual std::size_t get_width(state_type<BidiIterT> *state) const = 0;
|
||||
|
||||
virtual void link(xpression_linker<char_type> &linker) const {}
|
||||
|
||||
virtual void peek(xpression_peeker<char_type> &peeker) const
|
||||
{
|
||||
peeker.fail();
|
||||
}
|
||||
|
||||
virtual sequence<BidiIterT> quantify
|
||||
(
|
||||
quant_spec const &spec
|
||||
, std::size_t &hidden_mark_count
|
||||
, sequence<BidiIterT> seq
|
||||
, alternates_factory<BidiIterT> const &factory
|
||||
) const
|
||||
{
|
||||
throw regex_error(regex_constants::error_badrepeat, "expression cannot be quantified");
|
||||
}
|
||||
|
||||
virtual bool is_quantifiable() const
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
throw regex_error(regex_constants::error_internal, "internal error, sorry!");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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 TopT>
|
||||
bool push_match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
BOOST_MPL_ASSERT((is_same<TopT, matchable<BidiIterT> >));
|
||||
return this->match(state);
|
||||
}
|
||||
|
||||
static bool top_match(state_type<BidiIterT> &state, xpression_base const *top)
|
||||
{
|
||||
return static_cast<matchable<BidiIterT> const *>(top)->match(state);
|
||||
}
|
||||
|
||||
static bool pop_match(state_type<BidiIterT> &state, xpression_base const *top)
|
||||
{
|
||||
return static_cast<matchable<BidiIterT> const *>(top)->match(state);
|
||||
}
|
||||
|
||||
bool skip_match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
return this->match(state);
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
360
include/boost/xpressive/detail/dynamic/parse_charset.hpp
Executable file
360
include/boost/xpressive/detail/dynamic/parse_charset.hpp
Executable file
@@ -0,0 +1,360 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// parse_charset.hpp
|
||||
//
|
||||
// Copyright 2004 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/mpl/bool.hpp>
|
||||
#include <boost/integer.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 CharT, typename ClassT>
|
||||
struct escape_value
|
||||
{
|
||||
CharT ch_;
|
||||
int mark_nbr_;
|
||||
ClassT 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)
|
||||
{
|
||||
throw regex_error(regex_constants::error_escape,
|
||||
"character escape too large to fit in target character type");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// parse_escape
|
||||
//
|
||||
template<typename FwdIterT, typename CompilerTraitsT>
|
||||
escape_value<typename iterator_value<FwdIterT>::type, typename CompilerTraitsT::regex_traits::char_class_type>
|
||||
parse_escape(FwdIterT &begin, FwdIterT end, CompilerTraitsT &traits)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
typedef typename iterator_value<FwdIterT>::type char_type;
|
||||
typedef typename CompilerTraitsT::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;
|
||||
|
||||
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_ & traits.flags()));
|
||||
regex_traits const &rxtraits = traits.traits();
|
||||
FwdIterT 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'):
|
||||
ensure(++begin != end, error_escape, "unexpected end of pattern found");
|
||||
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'):
|
||||
ensure(++begin != end, error_escape, "unexpected end of pattern found");
|
||||
tmp = begin;
|
||||
esc.ch_ = converter(toi(begin, end, rxtraits, 16, 0xff));
|
||||
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'):
|
||||
ensure(++begin != end, error_escape, "unexpected end of pattern found");
|
||||
tmp = begin;
|
||||
esc.ch_ = converter(toi(begin, end, rxtraits, 16, 0xffff));
|
||||
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 FwdIterT, typename RegexTraitsT, typename CompilerTraitsT>
|
||||
inline void parse_charset
|
||||
(
|
||||
FwdIterT &begin
|
||||
, FwdIterT end
|
||||
, compound_charset<RegexTraitsT> &chset
|
||||
, CompilerTraitsT &traits
|
||||
)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
typedef typename RegexTraitsT::char_type char_type;
|
||||
typedef typename RegexTraitsT::char_class_type char_class_type;
|
||||
BOOST_ASSERT(begin != end);
|
||||
RegexTraitsT const &rxtraits = traits.traits();
|
||||
bool const icase = (0 != (regex_constants::icase_ & traits.flags()));
|
||||
FwdIterT iprev = FwdIterT();
|
||||
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 == traits.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 == traits.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;
|
||||
|
||||
ensure(begin != end, error_brack, "unexpected end of pattern found");
|
||||
|
||||
// remember the current position and grab the next token
|
||||
iprev = begin;
|
||||
tok = traits.get_charset_token(begin, end);
|
||||
do
|
||||
{
|
||||
ensure(begin != end, error_brack, "unexpected end of pattern found");
|
||||
|
||||
if(token_charset_hyphen == tok && have_prev)
|
||||
{
|
||||
// remember the current position
|
||||
FwdIterT iprev2 = begin;
|
||||
have_prev = false;
|
||||
|
||||
// ch_prev is lower bound of a range
|
||||
switch(traits.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++;
|
||||
detail::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
|
||||
detail::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, traits);
|
||||
if(escape_char == esc.type_)
|
||||
{
|
||||
detail::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:
|
||||
{
|
||||
FwdIterT tmp = begin, start = begin;
|
||||
bool invert = (token_charset_invert == traits.get_charset_token(tmp, end));
|
||||
if(invert)
|
||||
{
|
||||
begin = start = tmp;
|
||||
}
|
||||
while(token_literal == (tok = traits.get_charset_token(begin, end)))
|
||||
{
|
||||
tmp = ++begin;
|
||||
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);
|
||||
ensure(0 != chclass, error_ctype, "unknown class name");
|
||||
chset.set_class(chclass, invert, icase);
|
||||
continue;
|
||||
}
|
||||
begin = iprev; // un-get this token
|
||||
ch_prev = *begin++;
|
||||
have_prev = true;
|
||||
}
|
||||
continue;
|
||||
|
||||
case token_escape:
|
||||
esc = parse_escape(begin, end, traits);
|
||||
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_), icase);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
}
|
||||
continue;
|
||||
|
||||
default:
|
||||
ch_prev = *begin++;
|
||||
have_prev = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
while(ensure((iprev = begin) != end, error_brack, "unexpected end of pattern found"),
|
||||
token_charset_end != (tok = traits.get_charset_token(begin, end)));
|
||||
|
||||
if(have_prev)
|
||||
{
|
||||
chset.set_char(ch_prev, rxtraits, icase);
|
||||
}
|
||||
|
||||
if(invert)
|
||||
{
|
||||
chset.inverse();
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
358
include/boost/xpressive/detail/dynamic/parser.hpp
Executable file
358
include/boost/xpressive/detail/dynamic/parser.hpp
Executable file
@@ -0,0 +1,358 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file parser.hpp
|
||||
/// Contains the definition of regex_compiler, a factory for building regex objects
|
||||
/// from strings.
|
||||
//
|
||||
// Copyright 2004 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
|
||||
#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/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 BidiIterT, typename CharT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_char_xpression
|
||||
(
|
||||
CharT ch
|
||||
, regex_constants::syntax_option_type flags
|
||||
, TraitsT const &traits
|
||||
)
|
||||
{
|
||||
if(0 != (regex_constants::icase_ & flags))
|
||||
{
|
||||
literal_matcher<TraitsT, true, false> matcher(ch, traits);
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
literal_matcher<TraitsT, false, false> matcher(ch, traits);
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_any_xpression
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_any_xpression
|
||||
(
|
||||
regex_constants::syntax_option_type flags
|
||||
, TraitsT const &traits
|
||||
)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef set_matcher<TraitsT, 2> set_matcher;
|
||||
typedef literal_matcher<TraitsT, false, true> literal_matcher;
|
||||
|
||||
char_type const newline = traits.widen('\n');
|
||||
set_matcher s(traits);
|
||||
s.set_[0] = newline;
|
||||
s.set_[1] = 0;
|
||||
s.complement();
|
||||
|
||||
switch(((int)not_dot_newline | not_dot_null) & flags)
|
||||
{
|
||||
case not_dot_null:
|
||||
return make_dynamic_xpression<BidiIterT>(literal_matcher(char_type(0), traits));
|
||||
|
||||
case not_dot_newline:
|
||||
return make_dynamic_xpression<BidiIterT>(literal_matcher(newline, traits));
|
||||
|
||||
case (int)not_dot_newline | not_dot_null:
|
||||
return make_dynamic_xpression<BidiIterT>(s);
|
||||
|
||||
default:
|
||||
return make_dynamic_xpression<BidiIterT>(any_matcher());
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_literal_xpression
|
||||
//
|
||||
template<typename BidiIterT, typename CharT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_literal_xpression
|
||||
(
|
||||
std::basic_string<CharT> const &literal
|
||||
, regex_constants::syntax_option_type flags
|
||||
, TraitsT const &traits
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT(0 != literal.size());
|
||||
if(1 == literal.size())
|
||||
{
|
||||
return make_char_xpression<BidiIterT>(literal[0], flags, traits);
|
||||
}
|
||||
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
BOOST_MPL_ASSERT((is_same<char_type, CharT>));
|
||||
|
||||
if(0 != (regex_constants::icase_ & flags))
|
||||
{
|
||||
string_matcher<TraitsT, true> matcher(literal, traits);
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
string_matcher<TraitsT, false> matcher(literal, traits);
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_backref_xpression
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_backref_xpression
|
||||
(
|
||||
int mark_nbr
|
||||
, regex_constants::syntax_option_type flags
|
||||
, TraitsT const &traits
|
||||
)
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
if(0 != (regex_constants::icase_ & flags))
|
||||
{
|
||||
return make_dynamic_xpression<BidiIterT>
|
||||
(
|
||||
mark_matcher<TraitsT, true>(mark_nbr, traits)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return make_dynamic_xpression<BidiIterT>
|
||||
(
|
||||
mark_matcher<TraitsT, false>(mark_nbr, traits)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// merge_charset
|
||||
//
|
||||
template<typename CharT, typename TraitsT>
|
||||
inline void merge_charset
|
||||
(
|
||||
basic_chset<CharT> &basic
|
||||
, compound_charset<TraitsT> const &compound
|
||||
, TraitsT const &traits
|
||||
)
|
||||
{
|
||||
if(0 != compound.posix_yes())
|
||||
{
|
||||
typename TraitsT::char_class_type mask = compound.posix_yes();
|
||||
for(int i = 0; i <= UCHAR_MAX; ++i)
|
||||
{
|
||||
if(traits.isctype((CharT)i, mask))
|
||||
{
|
||||
basic.set((CharT)i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!compound.posix_no().empty())
|
||||
{
|
||||
for(std::size_t j = 0; j < compound.posix_no().size(); ++j)
|
||||
{
|
||||
typename TraitsT::char_class_type mask = compound.posix_no()[j];
|
||||
for(int i = 0; i <= UCHAR_MAX; ++i)
|
||||
{
|
||||
if(!traits.isctype((CharT)i, mask))
|
||||
{
|
||||
basic.set((CharT)i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(compound.is_inverted())
|
||||
{
|
||||
basic.inverse();
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_charset_xpression
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_charset_xpression
|
||||
(
|
||||
compound_charset<TraitsT> &chset
|
||||
, TraitsT const &traits
|
||||
, regex_constants::syntax_option_type flags
|
||||
)
|
||||
{
|
||||
typedef typename TraitsT::char_type char_type;
|
||||
bool const icase = (0 != (regex_constants::icase_ & flags));
|
||||
|
||||
// don't care about compile speed -- fold eveything into a bitset<256>
|
||||
if(1 == sizeof(char_type) && 0 != (regex_constants::optimize & flags))
|
||||
{
|
||||
typedef basic_chset<char_type> charset_type;
|
||||
charset_type charset(chset.basic_chset());
|
||||
if(icase)
|
||||
{
|
||||
charset_matcher<TraitsT, true, charset_type> matcher(charset);
|
||||
merge_charset(matcher.charset_, chset, traits);
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
charset_matcher<TraitsT, false, charset_type> matcher(charset);
|
||||
merge_charset(matcher.charset_, chset, traits);
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
// special case to make [[:digit:]] fast
|
||||
else if(chset.basic_chset().empty() && chset.posix_no().empty())
|
||||
{
|
||||
BOOST_ASSERT(0 != chset.posix_yes());
|
||||
if(icase)
|
||||
{
|
||||
posix_charset_matcher<TraitsT, true> matcher(chset.posix_yes(), chset.is_inverted());
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
posix_charset_matcher<TraitsT, false> matcher(chset.posix_yes(), chset.is_inverted());
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
// default, slow
|
||||
else
|
||||
{
|
||||
if(icase)
|
||||
{
|
||||
charset_matcher<TraitsT, true> matcher(chset);
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
else
|
||||
{
|
||||
charset_matcher<TraitsT, false> matcher(chset);
|
||||
return make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_posix_charset_xpression
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_posix_charset_xpression
|
||||
(
|
||||
typename TraitsT::char_class_type m
|
||||
, bool no
|
||||
, regex_constants::syntax_option_type flags
|
||||
, TraitsT const &traits
|
||||
)
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
bool const icase = (0 != (regex_constants::icase_ & flags));
|
||||
|
||||
if(icase)
|
||||
{
|
||||
posix_charset_matcher<TraitsT, true> charset(m, no);
|
||||
return make_dynamic_xpression<BidiIterT>(charset);
|
||||
}
|
||||
else
|
||||
{
|
||||
posix_charset_matcher<TraitsT, false> charset(m, no);
|
||||
return make_dynamic_xpression<BidiIterT>(charset);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_assert_begin_line
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_assert_begin_line
|
||||
(
|
||||
regex_constants::syntax_option_type flags
|
||||
, TraitsT const &traits
|
||||
)
|
||||
{
|
||||
if(0 != (regex_constants::single_line & flags))
|
||||
{
|
||||
return detail::make_dynamic_xpression<BidiIterT>(detail::assert_bos_matcher());
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::assert_bol_matcher<TraitsT> matcher(traits);
|
||||
return detail::make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_assert_end_line
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_assert_end_line
|
||||
(
|
||||
regex_constants::syntax_option_type flags
|
||||
, TraitsT const &traits
|
||||
)
|
||||
{
|
||||
if(0 != (regex_constants::single_line & flags))
|
||||
{
|
||||
return detail::make_dynamic_xpression<BidiIterT>(detail::assert_eos_matcher());
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::assert_eol_matcher<TraitsT> matcher(traits);
|
||||
return detail::make_dynamic_xpression<BidiIterT>(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_assert_word
|
||||
//
|
||||
template<typename BidiIterT, typename CondT, typename TraitsT>
|
||||
inline sequence<BidiIterT> make_assert_word(CondT, TraitsT const &traits)
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
return detail::make_dynamic_xpression<BidiIterT>
|
||||
(
|
||||
detail::assert_word_matcher<CondT, TraitsT>(traits)
|
||||
);
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
72
include/boost/xpressive/detail/dynamic/parser_enum.hpp
Executable file
72
include/boost/xpressive/detail/dynamic/parser_enum.hpp
Executable file
@@ -0,0 +1,72 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// parser_enum.hpp
|
||||
//
|
||||
// Copyright 2004 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_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_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
|
||||
400
include/boost/xpressive/detail/dynamic/parser_traits.hpp
Executable file
400
include/boost/xpressive/detail/dynamic/parser_traits.hpp
Executable file
@@ -0,0 +1,400 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// detail/dynamic/parser_traits.hpp
|
||||
//
|
||||
// Copyright 2004 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/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 RegexTraitsT>
|
||||
struct compiler_traits
|
||||
{
|
||||
typedef typename RegexTraitsT::char_type char_type;
|
||||
typedef std::basic_string<char_type> string_type;
|
||||
typedef typename string_type::const_iterator iterator_type;
|
||||
typedef RegexTraitsT regex_traits;
|
||||
typedef typename RegexTraitsT::locale_type locale_type;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
explicit compiler_traits(RegexTraitsT const &traits = RegexTraitsT())
|
||||
: traits_(traits)
|
||||
, flags_(regex_constants::ECMAScript)
|
||||
, space_(lookup_classname(traits_, "space"))
|
||||
{
|
||||
BOOST_ASSERT(0 != this->space_);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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");
|
||||
BOOST_ASSERT(0 != this->space_);
|
||||
return oldloc;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// getloc
|
||||
locale_type getloc() const
|
||||
{
|
||||
return this->traits().getloc();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get_token
|
||||
// get a token and advance the iterator
|
||||
regex_constants::compiler_token_type get_token(iterator_type &begin, iterator_type 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, ']'): ++begin; return token_charset_end;
|
||||
|
||||
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, '{'):
|
||||
default:
|
||||
return token_literal;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// get_quant_spec
|
||||
bool get_quant_spec(iterator_type &begin, iterator_type end, detail::quant_spec &spec)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
iterator_type 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());
|
||||
detail::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());
|
||||
detail::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
|
||||
{
|
||||
detail::ensure
|
||||
(
|
||||
spec.min_ <= spec.max_, error_badbrace, "invalid quantification range"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::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
|
||||
regex_constants::compiler_token_type get_group_type(iterator_type &begin, iterator_type end)
|
||||
{
|
||||
using namespace regex_constants;
|
||||
if(this->eat_ws_(begin, end) != end && BOOST_XPR_CHAR_(char_type, '?') == *begin)
|
||||
{
|
||||
this->eat_ws_(++begin, end);
|
||||
detail::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, '<'):
|
||||
this->eat_ws_(++begin, end);
|
||||
detail::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:
|
||||
throw 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:
|
||||
throw regex_error(error_badbrace, "unrecognized extension");
|
||||
}
|
||||
}
|
||||
|
||||
return token_literal;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// get_charset_token
|
||||
// NOTE: white-space is *never* ignored in a charset.
|
||||
regex_constants::compiler_token_type get_charset_token(iterator_type &begin, iterator_type 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, '['):
|
||||
{
|
||||
iterator_type next = begin; ++next;
|
||||
if(next != end && *next == BOOST_XPR_CHAR_(char_type, ':'))
|
||||
{
|
||||
begin = ++next;
|
||||
return token_posix_charset_begin;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BOOST_XPR_CHAR_(char_type, ':'):
|
||||
{
|
||||
iterator_type 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
|
||||
regex_constants::compiler_token_type get_escape_token(iterator_type &begin, iterator_type 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_
|
||||
regex_constants::compiler_token_type parse_mods_(iterator_type &begin, iterator_type 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(!(set = !set)) break; // else fall-through
|
||||
default: throw regex_error(error_paren, "unknown pattern modifier");
|
||||
}
|
||||
while(detail::ensure(++begin != end, error_paren, "incomplete extension"), true);
|
||||
BOOST_UNREACHABLE_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 this->traits().isctype(ch, this->space_);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// eat_ws_
|
||||
iterator_type &eat_ws_(iterator_type &begin, iterator_type 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_;
|
||||
};
|
||||
|
||||
}} // namespace boost::xpressive
|
||||
|
||||
#endif
|
||||
185
include/boost/xpressive/detail/static/as_xpr.hpp
Executable file
185
include/boost/xpressive/detail/static/as_xpr.hpp
Executable file
@@ -0,0 +1,185 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// as_xpr.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_AS_XPR_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_AS_XPR_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/apply.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/logical.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/type_traits/remove_bounds.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/static/placeholders.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
struct wrap { wrap(T); };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_string_literal
|
||||
//
|
||||
template<typename T>
|
||||
struct is_string_literal
|
||||
: mpl::or_
|
||||
<
|
||||
is_convertible<T, wrap<char const *> >
|
||||
, is_convertible<T, wrap<wchar_t const *> >
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// string_generator
|
||||
//
|
||||
template<typename StringT>
|
||||
struct string_placeholder_generator
|
||||
{
|
||||
typedef typename remove_cv
|
||||
<
|
||||
typename mpl::eval_if
|
||||
<
|
||||
is_array<StringT>
|
||||
, remove_bounds<StringT>
|
||||
, remove_pointer<StringT>
|
||||
>::type
|
||||
>::type char_type;
|
||||
|
||||
typedef string_placeholder<char_type> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// as_matcher
|
||||
template<typename MatcherT, bool IsXprT = is_xpr<MatcherT>::value>
|
||||
struct as_matcher_type
|
||||
{
|
||||
typedef MatcherT type;
|
||||
|
||||
static type const &call(MatcherT const &matcher)
|
||||
{
|
||||
return matcher;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename LiteralT>
|
||||
struct as_matcher_type<LiteralT, false>
|
||||
{
|
||||
typedef typename mpl::eval_if
|
||||
<
|
||||
is_string_literal<LiteralT>
|
||||
, string_placeholder_generator<LiteralT>
|
||||
, mpl::identity<literal_placeholder<LiteralT, false> >
|
||||
>::type type;
|
||||
|
||||
static type call(LiteralT const &literal)
|
||||
{
|
||||
return type(literal);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct as_matcher_type<basic_regex<BidiIterT>, false>
|
||||
{
|
||||
typedef regex_placeholder<BidiIterT, false> type;
|
||||
|
||||
static type call(basic_regex<BidiIterT> const &rex)
|
||||
{
|
||||
typedef core_access<BidiIterT> access;
|
||||
shared_ptr<regex_impl<BidiIterT> > impl = access::get_regex_impl(rex);
|
||||
return type(impl);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct as_matcher_type<reference_wrapper<basic_regex<BidiIterT> const>, false>
|
||||
{
|
||||
typedef regex_placeholder<BidiIterT, false> type;
|
||||
|
||||
static type call(reference_wrapper<basic_regex<BidiIterT> const> const &rex)
|
||||
{
|
||||
typedef core_access<BidiIterT> access;
|
||||
shared_ptr<regex_impl<BidiIterT> > impl = access::get_regex_impl(rex.get());
|
||||
return type(impl);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// matcher_generator
|
||||
//
|
||||
template<typename MatcherT>
|
||||
struct matcher_generator
|
||||
{
|
||||
typedef proto::unary_op
|
||||
<
|
||||
typename as_matcher_type<MatcherT>::type
|
||||
, proto::noop_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// as_xpr_type
|
||||
//
|
||||
template<typename XprT>
|
||||
struct as_xpr_type
|
||||
{
|
||||
typedef typename mpl::eval_if
|
||||
<
|
||||
proto::is_op<XprT>
|
||||
, mpl::identity<XprT>
|
||||
, matcher_generator<XprT>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
|
||||
namespace boost { namespace xpressive
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// as_xpr (from a literal to an xpression)
|
||||
//
|
||||
template<typename XprT>
|
||||
inline typename enable_if
|
||||
<
|
||||
proto::is_op<XprT>
|
||||
, XprT const &
|
||||
>::type
|
||||
as_xpr(XprT const &xpr)
|
||||
{
|
||||
return xpr;
|
||||
}
|
||||
|
||||
template<typename XprT>
|
||||
inline typename lazy_disable_if
|
||||
<
|
||||
proto::is_op<XprT>
|
||||
, detail::as_xpr_type<XprT>
|
||||
>::type
|
||||
as_xpr(XprT const &xpr)
|
||||
{
|
||||
return proto::noop(detail::as_matcher_type<XprT>::call(xpr));
|
||||
}
|
||||
|
||||
}} // namespace boost::xpressive
|
||||
|
||||
#endif
|
||||
249
include/boost/xpressive/detail/static/is_pure.hpp
Executable file
249
include/boost/xpressive/detail/static/is_pure.hpp
Executable file
@@ -0,0 +1,249 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_pure.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_IS_PURE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_IS_PURE_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/lambda.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/not_equal_to.hpp>
|
||||
#include <boost/mpl/transform_view.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/as_xpr.hpp>
|
||||
#include <boost/xpressive/detail/static/width_of.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// use_simple_repeat
|
||||
//
|
||||
template<typename XprT>
|
||||
struct use_simple_repeat;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_pure
|
||||
//
|
||||
template<typename XprT>
|
||||
struct is_pure;
|
||||
|
||||
template<>
|
||||
struct is_pure<no_next>
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename MatcherT>
|
||||
struct is_pure<proto::unary_op<MatcherT, proto::noop_tag> >
|
||||
: as_matcher_type<MatcherT>::type::pure
|
||||
{
|
||||
};
|
||||
|
||||
template<typename LeftT, typename RightT>
|
||||
struct is_pure<proto::binary_op<LeftT, RightT, proto::right_shift_tag> >
|
||||
: mpl::and_<is_pure<LeftT>, is_pure<RightT> >
|
||||
{
|
||||
};
|
||||
|
||||
template<typename LeftT, typename RightT>
|
||||
struct is_pure<proto::binary_op<LeftT, RightT, proto::bitor_tag> >
|
||||
: mpl::and_<is_pure<LeftT>, is_pure<RightT> >
|
||||
{
|
||||
};
|
||||
|
||||
template<typename RightT>
|
||||
struct is_pure<proto::binary_op<mark_tag, RightT, proto::assign_tag> >
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename RightT>
|
||||
struct is_pure<proto::binary_op<set_initializer_type, RightT, proto::assign_tag> >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename ModifierT, typename XprT>
|
||||
struct is_pure<proto::binary_op<ModifierT, XprT, modifier_tag> >
|
||||
: is_pure<XprT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename XprT, bool PositiveT>
|
||||
struct is_pure<proto::unary_op<XprT, lookahead_tag<PositiveT> > >
|
||||
: is_pure<XprT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename XprT, bool PositiveT>
|
||||
struct is_pure<proto::unary_op<XprT, lookbehind_tag<PositiveT> > >
|
||||
: is_pure<XprT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename XprT>
|
||||
struct is_pure<proto::unary_op<XprT, keeper_tag> >
|
||||
: is_pure<XprT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename MatcherT, typename NextT>
|
||||
struct is_pure<static_xpression<MatcherT, NextT> >
|
||||
: mpl::and_<typename MatcherT::pure, is_pure<NextT> >::type
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct is_pure<shared_ptr<matchable<BidiIterT> const> >
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct is_pure<std::vector<shared_ptr<matchable<BidiIterT> const> > >
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
//template<typename BidiIterT>
|
||||
//struct is_pure<basic_regex<BidiIterT> >
|
||||
// : mpl::false_
|
||||
//{
|
||||
//};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct is_pure<proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag> >
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct is_pure<proto::unary_op<reference_wrapper<basic_regex<BidiIterT> const>, proto::noop_tag> >
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
// when complementing a set or an assertion, the purity is that of the set (true) or the assertion
|
||||
template<typename OpT>
|
||||
struct is_pure<proto::unary_op<OpT, proto::complement_tag> >
|
||||
: is_pure<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
// The comma is used in list-initialized sets, which are pure
|
||||
template<typename LeftT, typename RightT>
|
||||
struct is_pure<proto::binary_op<LeftT, RightT, proto::comma_tag> >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
// The subscript operator[] is used for sets, as in set['a' | range('b','h')]
|
||||
// It is also used for actions, which by definition have side-effects and thus are impure
|
||||
template<typename LeftT, typename RightT>
|
||||
struct is_pure<proto::binary_op<LeftT, RightT, proto::subscript_tag> >
|
||||
: is_same<LeftT, set_initializer_type>
|
||||
{
|
||||
// If LeftT is "set" then make sure that RightT is pure
|
||||
BOOST_MPL_ASSERT
|
||||
((
|
||||
mpl::or_
|
||||
<
|
||||
mpl::not_<is_same<LeftT, set_initializer_type> >
|
||||
, is_pure<RightT>
|
||||
>
|
||||
));
|
||||
};
|
||||
|
||||
// Quantified expressions are pure IFF they use the simple_repeat_matcher
|
||||
|
||||
template<typename OpT>
|
||||
struct is_pure<proto::unary_op<OpT, proto::unary_plus_tag> >
|
||||
: use_simple_repeat<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT>
|
||||
struct is_pure<proto::unary_op<OpT, proto::unary_star_tag> >
|
||||
: use_simple_repeat<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT>
|
||||
struct is_pure<proto::unary_op<OpT, proto::logical_not_tag> >
|
||||
: use_simple_repeat<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT, uint_t MinT, uint_t MaxT>
|
||||
struct is_pure<proto::unary_op<OpT, generic_quant_tag<MinT, MaxT> > >
|
||||
: use_simple_repeat<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT>
|
||||
struct is_pure<proto::unary_op<OpT, proto::unary_minus_tag> >
|
||||
: is_pure<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename AlternatesT>
|
||||
struct is_pure<alternates_list<AlternatesT> >
|
||||
: mpl::fold
|
||||
<
|
||||
mpl::transform_view<AlternatesT, is_pure<mpl::_1> >
|
||||
, mpl::true_
|
||||
, mpl::and_<mpl::_1, mpl::_2>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// use_simple_repeat
|
||||
// BUGBUG this doesn't handle +(_ >> s1) correctly, right?
|
||||
template<typename XprT>
|
||||
struct use_simple_repeat
|
||||
: mpl::and_<mpl::not_equal_to<width_of<XprT>, unknown_width>, is_pure<XprT> >
|
||||
{
|
||||
// should never try to quantify something of 0-width
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<width_of<XprT>, mpl::size_t<0> >));
|
||||
};
|
||||
|
||||
template<typename MatcherT>
|
||||
struct use_simple_repeat<proto::unary_op<MatcherT, proto::noop_tag> >
|
||||
: mpl::and_
|
||||
<
|
||||
mpl::equal_to
|
||||
<
|
||||
quant_type<typename as_matcher_type<MatcherT>::type>
|
||||
, mpl::int_<quant_fixed_width>
|
||||
>
|
||||
, typename as_matcher_type<MatcherT>::type::pure
|
||||
>
|
||||
{
|
||||
BOOST_MPL_ASSERT_RELATION(0, !=, as_matcher_type<MatcherT>::type::width::value);
|
||||
};
|
||||
|
||||
template<typename OpT, typename ArgT>
|
||||
struct is_pure<proto::op_proxy<OpT, ArgT> >
|
||||
: is_pure<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
48
include/boost/xpressive/detail/static/modifier.hpp
Executable file
48
include/boost/xpressive/detail/static/modifier.hpp
Executable file
@@ -0,0 +1,48 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// modifier.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_MODIFIER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_MODIFIER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/regex_constants.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// modifier
|
||||
template<typename ModifierT>
|
||||
struct modifier_op
|
||||
{
|
||||
typedef regex_constants::syntax_option_type opt_type;
|
||||
|
||||
template<typename XprT>
|
||||
struct apply
|
||||
{
|
||||
typedef proto::binary_op<ModifierT, typename as_xpr_type<XprT>::type, modifier_tag> type;
|
||||
};
|
||||
|
||||
template<typename XprT>
|
||||
typename apply<XprT>::type
|
||||
operator ()(XprT const &xpr) const
|
||||
{
|
||||
return proto::make_op<modifier_tag>(this->mod_, as_xpr(xpr));
|
||||
}
|
||||
|
||||
operator opt_type() const
|
||||
{
|
||||
return this->opt_;
|
||||
}
|
||||
|
||||
ModifierT mod_;
|
||||
opt_type opt_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
162
include/boost/xpressive/detail/static/placeholders.hpp
Executable file
162
include/boost/xpressive/detail/static/placeholders.hpp
Executable file
@@ -0,0 +1,162 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// placeholders.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PLACEHOLDERS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PLACEHOLDERS_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/xpressive/detail/core/quant_style.hpp>
|
||||
#include <boost/xpressive/detail/core/regex_impl.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// literal_placeholder
|
||||
//
|
||||
template<typename CharT, bool NotT>
|
||||
struct literal_placeholder
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
typedef mpl::bool_<NotT> not_type;
|
||||
CharT ch_;
|
||||
|
||||
literal_placeholder(CharT ch)
|
||||
: ch_(ch)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// string_placeholder
|
||||
//
|
||||
template<typename CharT>
|
||||
struct string_placeholder
|
||||
: quant_style_fixed_unknown_width
|
||||
{
|
||||
std::basic_string<CharT> str_;
|
||||
|
||||
string_placeholder(std::basic_string<CharT> const &str)
|
||||
: str_(str)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_placeholder
|
||||
//
|
||||
struct mark_placeholder
|
||||
: quant_style_fixed_unknown_width
|
||||
{
|
||||
int mark_number_;
|
||||
|
||||
mark_placeholder(int mark_number)
|
||||
: mark_number_(mark_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_placeholder
|
||||
//
|
||||
template<typename BidiIterT, bool ByRefT>
|
||||
struct regex_placeholder
|
||||
: quant_style<quant_variable_width, unknown_width, mpl::false_>
|
||||
{
|
||||
shared_ptr<regex_impl<BidiIterT> > impl_;
|
||||
|
||||
regex_placeholder(shared_ptr<regex_impl<BidiIterT> > const &impl)
|
||||
: impl_(impl)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// posix_charset_placeholder
|
||||
//
|
||||
struct posix_charset_placeholder
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
char const *name_;
|
||||
bool not_;
|
||||
|
||||
posix_charset_placeholder(char const *name)
|
||||
: name_(name)
|
||||
, not_(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_word_placeholder
|
||||
//
|
||||
template<typename CondT>
|
||||
struct assert_word_placeholder
|
||||
: quant_style_assertion
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// range_placeholder
|
||||
//
|
||||
template<typename CharT>
|
||||
struct range_placeholder
|
||||
: quant_style_fixed_width<1>
|
||||
{
|
||||
CharT ch_min_;
|
||||
CharT ch_max_;
|
||||
bool not_;
|
||||
|
||||
range_placeholder(CharT ch_min, CharT ch_max)
|
||||
: ch_min_(ch_min)
|
||||
, ch_max_(ch_max)
|
||||
, not_(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_bol_placeholder
|
||||
//
|
||||
struct assert_bol_placeholder
|
||||
: quant_style_assertion
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assert_eol_placeholder
|
||||
//
|
||||
struct assert_eol_placeholder
|
||||
: quant_style_assertion
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// logical_newline_placeholder
|
||||
//
|
||||
struct logical_newline_placeholder
|
||||
: quant_style_variable_width
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// self_placeholder
|
||||
//
|
||||
struct self_placeholder
|
||||
: quant_style<quant_variable_width, unknown_width, mpl::false_>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
95
include/boost/xpressive/detail/static/productions/Attic/alt_compilers.hpp
Executable file
95
include/boost/xpressive/detail/static/productions/Attic/alt_compilers.hpp
Executable file
@@ -0,0 +1,95 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_compilers.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_ALT_COMPILERS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_ALT_COMPILERS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/spirit/fusion/sequence/cons.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/fold.hpp>
|
||||
#include <boost/xpressive/proto/compiler/branch.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_branch
|
||||
// Describes how to construct an alternate xpression
|
||||
struct alt_branch
|
||||
{
|
||||
typedef boost::fusion::nil state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression
|
||||
<
|
||||
alternate_matcher<alternates_list<OpT>, typename VisitorT::traits_type>
|
||||
, StateT
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef alternate_matcher<alternates_list<OpT>, typename VisitorT::traits_type> alt_matcher;
|
||||
return make_static_xpression(alt_matcher(op), state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_list_branch
|
||||
struct alt_list_branch
|
||||
{
|
||||
typedef alternate_end_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef boost::fusion::cons<OpT, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT>
|
||||
static boost::fusion::cons<OpT, StateT>
|
||||
call(OpT const &op, StateT const &state, dont_care)
|
||||
{
|
||||
return boost::fusion::make_cons(op, state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
// production for alternates in sequence
|
||||
template<>
|
||||
struct compiler<bitor_tag, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::alt_branch, xpressive::detail::alt_tag>
|
||||
{
|
||||
};
|
||||
|
||||
// handle alternates with the alt branch compiler
|
||||
template<typename OpTagT>
|
||||
struct compiler<OpTagT, xpressive::detail::alt_tag>
|
||||
: branch_compiler<xpressive::detail::alt_list_branch, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
// production for alternates in alternate
|
||||
template<>
|
||||
struct compiler<bitor_tag, xpressive::detail::alt_tag>
|
||||
: fold_compiler<bitor_tag, xpressive::detail::alt_tag>
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
137
include/boost/xpressive/detail/static/productions/Attic/charset_transforms.hpp
Executable file
137
include/boost/xpressive/detail/static/productions/Attic/charset_transforms.hpp
Executable file
@@ -0,0 +1,137 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// charset_transforms.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_CHARSET_TRANSFORMS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_CHARSET_TRANSFORMS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/sizeof.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/utility/never_true.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// charset_state
|
||||
//
|
||||
template<typename CharSetT, typename TraitsT>
|
||||
struct charset_state
|
||||
{
|
||||
typedef TraitsT traits_type;
|
||||
typedef typename CharSetT::char_type char_type;
|
||||
typedef typename CharSetT::icase_type icase_type;
|
||||
|
||||
explicit charset_state(CharSetT &charset, traits_type const &traits)
|
||||
: charset_(charset)
|
||||
, traits_(traits)
|
||||
{
|
||||
}
|
||||
|
||||
template<bool NotT>
|
||||
void set(literal_matcher<traits_type, icase_type::value, NotT> const &ch) const
|
||||
{
|
||||
// BUGBUG fixme!
|
||||
BOOST_MPL_ASSERT_NOT((mpl::bool_<NotT>));
|
||||
set_char(this->charset_.charset_, ch.ch_, this->traits_, icase_type());
|
||||
}
|
||||
|
||||
void set(range_matcher<traits_type, icase_type::value> const &rg) const
|
||||
{
|
||||
// BUGBUG fixme!
|
||||
BOOST_ASSERT(!rg.not_);
|
||||
set_range(this->charset_.charset_, rg.ch_min_, rg.ch_max_, this->traits_, icase_type());
|
||||
}
|
||||
|
||||
template<int SizeT>
|
||||
void set(set_matcher<traits_type, SizeT> const &set_) const
|
||||
{
|
||||
// BUGBUG fixme!
|
||||
BOOST_ASSERT(!set_.not_);
|
||||
for(int i=0; i<SizeT; ++i)
|
||||
{
|
||||
set_char(this->charset_.charset_, set_.set_[i], this->traits_, icase_type::value);
|
||||
}
|
||||
}
|
||||
|
||||
void set(posix_charset_matcher<traits_type, icase_type::value> const &posix) const
|
||||
{
|
||||
set_class(this->charset_.charset_, posix.mask_, posix.not_, this->traits_, icase_type::value);
|
||||
}
|
||||
|
||||
template<typename UnknownT>
|
||||
void set(UnknownT const &) const
|
||||
{
|
||||
// If this assert fires, it means that you have put something in a set[] that doesn't
|
||||
// belong there. For instance, set["hello"]. Legal members of sets are characters,
|
||||
// character ranges, list-initialized sets such as (set='a','b','c') and posix-style
|
||||
// character sets such as digit and ~alpha.
|
||||
BOOST_MPL_ASSERT((never_true<UnknownT>));
|
||||
}
|
||||
|
||||
private:
|
||||
CharSetT &charset_;
|
||||
traits_type const &traits_;
|
||||
};
|
||||
|
||||
template<typename CharSetT, typename TraitsT>
|
||||
charset_state<CharSetT, TraitsT> make_charset_state(CharSetT &charset, TraitsT const &traits)
|
||||
{
|
||||
return charset_state<CharSetT, TraitsT>(charset, traits);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct charset_transform
|
||||
{
|
||||
template<typename, typename, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename VisitorT::char_type char_type;
|
||||
|
||||
// if sizeof(char_type)==1, merge everything into a basic_chset
|
||||
// BUGBUG this is not optimal.
|
||||
typedef typename mpl::if_
|
||||
<
|
||||
mpl::equal_to<mpl::sizeof_<char_type>, mpl::size_t<1> >
|
||||
, basic_chset<char_type>
|
||||
, compound_charset<typename VisitorT::traits_type>
|
||||
>::type charset_type;
|
||||
|
||||
typedef charset_matcher
|
||||
<
|
||||
typename VisitorT::traits_type
|
||||
, VisitorT::icase_type::value
|
||||
, charset_type
|
||||
> matcher_type;
|
||||
|
||||
typedef proto::unary_op<matcher_type, proto::noop_tag> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor, bool complement = false)
|
||||
{
|
||||
typedef typename apply<OpT, StateT, VisitorT>::matcher_type matcher_type;
|
||||
matcher_type matcher;
|
||||
// Walks the tree and fills in the charset
|
||||
proto::compile(proto::right(op), make_charset_state(matcher, visitor.traits()), visitor, set_tag());
|
||||
if(complement)
|
||||
{
|
||||
matcher.charset_.inverse();
|
||||
}
|
||||
return proto::noop(matcher);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
251
include/boost/xpressive/detail/static/productions/Attic/complement_compiler.hpp
Executable file
251
include/boost/xpressive/detail/static/productions/Attic/complement_compiler.hpp
Executable file
@@ -0,0 +1,251 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// complement_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_COMPLEMENT_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_COMPLEMENT_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/transform.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/utility/never_true.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/set_compilers.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/charset_transforms.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// complement
|
||||
// the result of applying operator~ to various expressions
|
||||
template<typename OpT, typename VisitorT>
|
||||
struct complement
|
||||
{
|
||||
// If your compile breaks here, then you are applying the complement operator ~
|
||||
// to something that does not support it. For instance, ~(_ >> 'a') will trigger this
|
||||
// assertion because the sub-expression (_ >> 'a') has no complement.
|
||||
BOOST_MPL_ASSERT((never_true<OpT>));
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename CharT, bool NotT, typename VisitorT>
|
||||
struct complement<proto::unary_op<literal_placeholder<CharT, NotT>, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<literal_placeholder<CharT, !NotT>, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<literal_placeholder<CharT, NotT>, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
literal_placeholder<CharT, !NotT> literal = proto::arg(op).ch_;
|
||||
return proto::noop(literal);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename CharT, typename VisitorT>
|
||||
struct complement<proto::unary_op<CharT, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<literal_placeholder<CharT, true>, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<CharT, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
literal_placeholder<CharT, true> literal = proto::arg(op);
|
||||
return proto::noop(literal);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename TraitsT, int SizeT, typename VisitorT>
|
||||
struct complement<proto::unary_op<set_matcher<TraitsT, SizeT>, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<set_matcher<TraitsT, SizeT>, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<set_matcher<TraitsT, SizeT>, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
set_matcher<TraitsT, SizeT> set = proto::arg(op);
|
||||
set.complement();
|
||||
return proto::noop(set);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename VisitorT>
|
||||
struct complement<proto::unary_op<posix_charset_placeholder, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<posix_charset_placeholder, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<posix_charset_placeholder, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
posix_charset_placeholder posix = proto::arg(op);
|
||||
posix.not_ = !posix.not_;
|
||||
return proto::noop(posix);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename OpT, typename VisitorT>
|
||||
struct complement<proto::binary_op<set_initializer_type, OpT, proto::subscript_tag>, VisitorT>
|
||||
{
|
||||
typedef typename charset_transform::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
proto::binary_op<set_initializer_type, OpT, proto::subscript_tag>
|
||||
, dont_care
|
||||
, VisitorT
|
||||
>::type type;
|
||||
|
||||
static type call(proto::binary_op<set_initializer_type, OpT, proto::subscript_tag> const &op, VisitorT &visitor)
|
||||
{
|
||||
return charset_transform::call(op, dont_care(), visitor, true);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// for complementing a list-initialized set, as in ~(set= 'a','b','c')
|
||||
template<typename LeftT, typename RightT, typename VisitorT>
|
||||
struct complement<proto::binary_op<LeftT, RightT, proto::comma_tag>, VisitorT>
|
||||
{
|
||||
// First, convert the parse tree into a set_matcher
|
||||
typedef typename proto::compiler<proto::comma_tag, lst_tag>::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
proto::binary_op<LeftT, RightT, proto::comma_tag>
|
||||
, dont_care
|
||||
, VisitorT
|
||||
>::type set_matcher;
|
||||
|
||||
typedef proto::unary_op<set_matcher, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::binary_op<LeftT, RightT, proto::comma_tag> const &op, VisitorT &visitor)
|
||||
{
|
||||
set_matcher set(proto::compile(op, dont_care(), visitor, lst_tag()));
|
||||
set.complement();
|
||||
return proto::noop(set);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename OpT, typename VisitorT>
|
||||
struct complement<proto::unary_op<OpT, lookahead_tag<true> >, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<OpT, lookahead_tag<false> > type;
|
||||
|
||||
static type call(proto::unary_op<OpT, lookahead_tag<true> > const &op, VisitorT &)
|
||||
{
|
||||
return proto::make_op<lookahead_tag<false> >(proto::arg(op));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename OpT, typename VisitorT>
|
||||
struct complement<proto::unary_op<OpT, lookbehind_tag<true> >, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<OpT, lookbehind_tag<false> > type;
|
||||
|
||||
static type call(proto::unary_op<OpT, lookbehind_tag<true> > const &op, VisitorT &)
|
||||
{
|
||||
return proto::make_op<lookbehind_tag<false> >(proto::arg(op));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename VisitorT>
|
||||
struct complement<proto::unary_op<assert_word_placeholder<word_boundary<true> >, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<assert_word_placeholder<word_boundary<false> >, proto::noop_tag> type;
|
||||
|
||||
static type call(proto::unary_op<assert_word_placeholder<word_boundary<true> >, proto::noop_tag> const &, VisitorT &)
|
||||
{
|
||||
return proto::noop(assert_word_placeholder<word_boundary<false> >());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename VisitorT>
|
||||
struct complement<logical_newline_xpression, VisitorT>
|
||||
{
|
||||
typedef proto::binary_op
|
||||
<
|
||||
proto::unary_op<logical_newline_xpression, lookahead_tag<false> >
|
||||
, proto::unary_op<any_matcher, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
> type;
|
||||
|
||||
static type call(logical_newline_xpression const &op, VisitorT &)
|
||||
{
|
||||
return proto::make_op<lookahead_tag<false> >(op) >> proto::noop(any_matcher());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// complementing a complement is a no-op
|
||||
template<typename ArgT, typename VisitorT>
|
||||
struct complement<proto::unary_op<ArgT, proto::complement_tag>, VisitorT>
|
||||
{
|
||||
typedef ArgT type;
|
||||
|
||||
static ArgT const &call(proto::unary_op<ArgT, proto::complement_tag> const &op, VisitorT &)
|
||||
{
|
||||
return proto::arg(op);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename CharT, typename VisitorT>
|
||||
struct complement<proto::unary_op<range_placeholder<CharT>, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<range_placeholder<CharT>, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<range_placeholder<CharT>, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
range_placeholder<CharT> rng = proto::arg(op);
|
||||
rng.not_ = !rng.not_;
|
||||
return proto::noop(rng);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// complement_transform
|
||||
struct complement_transform
|
||||
{
|
||||
template<typename OpT, typename, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename complement<typename proto::arg_type<OpT>::type, VisitorT>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename complement<typename proto::arg_type<OpT>::type, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &visitor)
|
||||
{
|
||||
return complement<typename proto::arg_type<OpT>::type, VisitorT>::call(proto::arg(op), visitor);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
template<>
|
||||
struct compiler<complement_tag, xpressive::detail::seq_tag>
|
||||
: transform_compiler<xpressive::detail::complement_transform, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
24
include/boost/xpressive/detail/static/productions/Attic/domain_tags.hpp
Executable file
24
include/boost/xpressive/detail/static/productions/Attic/domain_tags.hpp
Executable file
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// domain_tags.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_DOMAIN_TAGS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_DOMAIN_TAGS_HPP_EAN_10_04_2005
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex domain tags
|
||||
struct seq_tag {};
|
||||
struct alt_tag {};
|
||||
struct lst_tag {};
|
||||
struct set_tag {};
|
||||
struct ind_tag {};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
121
include/boost/xpressive/detail/static/productions/Attic/independent_compiler.hpp
Executable file
121
include/boost/xpressive/detail/static/productions/Attic/independent_compiler.hpp
Executable file
@@ -0,0 +1,121 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// independent_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_INDEPENDENT_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_INDEPENDENT_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
template<bool PositiveT>
|
||||
struct lookahead_tag : proto::unary_tag {};
|
||||
|
||||
template<bool PositiveT>
|
||||
struct lookbehind_tag : proto::unary_tag {};
|
||||
|
||||
struct keeper_tag : proto::unary_tag {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lookahead_branch
|
||||
template<bool PositiveT>
|
||||
struct lookahead_branch
|
||||
{
|
||||
typedef true_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression<lookahead_matcher<OpT>, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static static_xpression<lookahead_matcher<OpT>, StateT>
|
||||
call(OpT const &op, StateT const &state, VisitorT &)
|
||||
{
|
||||
return make_static_xpression(lookahead_matcher<OpT>(op, !PositiveT), state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lookbehind_branch
|
||||
template<bool PositiveT>
|
||||
struct lookbehind_branch
|
||||
{
|
||||
typedef true_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression<lookbehind_matcher<OpT>, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static static_xpression<lookbehind_matcher<OpT>, StateT>
|
||||
call(OpT const &op, StateT const &state, VisitorT &)
|
||||
{
|
||||
return make_static_xpression(lookbehind_matcher<OpT>(op, !PositiveT), state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// keeper_branch
|
||||
struct keeper_branch
|
||||
{
|
||||
typedef true_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression<keeper_matcher<OpT>, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static static_xpression<keeper_matcher<OpT>, StateT>
|
||||
call(OpT const &op, StateT const &state, VisitorT &)
|
||||
{
|
||||
return make_static_xpression(keeper_matcher<OpT>(op), state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
namespace boost { namespace proto {
|
||||
|
||||
template<bool PositiveT>
|
||||
struct compiler<xpressive::detail::lookahead_tag<PositiveT>, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::lookahead_branch<PositiveT>, xpressive::detail::ind_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool PositiveT>
|
||||
struct compiler<xpressive::detail::lookbehind_tag<PositiveT>, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::lookbehind_branch<PositiveT>, xpressive::detail::ind_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<xpressive::detail::keeper_tag, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::keeper_branch, xpressive::detail::ind_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpTagT>
|
||||
struct compiler<OpTagT, xpressive::detail::ind_tag>
|
||||
: transform_compiler<arg_transform, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
73
include/boost/xpressive/detail/static/productions/Attic/marker_compiler.hpp
Executable file
73
include/boost/xpressive/detail/static/productions/Attic/marker_compiler.hpp
Executable file
@@ -0,0 +1,73 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// marker_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_MARKER_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_MARKER_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/branch.hpp>
|
||||
#include <boost/xpressive/proto/compiler/conditional.hpp>
|
||||
#include <boost/xpressive/proto/compiler/transform.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/marker_transform.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/set_compilers.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// marker_assign_transform
|
||||
struct marker_assign_transform
|
||||
: proto::compose_transforms<proto::right_transform, marker_transform>
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
return marker_transform::call(proto::right(op), state, visitor, proto::arg(proto::left(op)).mark_number_);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_marker_predicate
|
||||
struct is_marker_predicate
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
: is_same<typename proto::left_type<OpT>::type, mark_tag>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assign_compiler
|
||||
// could be (s1= 'a') or (set= 'a')
|
||||
struct assign_compiler
|
||||
: proto::conditional_compiler
|
||||
<
|
||||
is_marker_predicate
|
||||
, proto::transform_compiler<marker_assign_transform, seq_tag>
|
||||
, proto::branch_compiler<list_branch, lst_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto {
|
||||
|
||||
template<>
|
||||
struct compiler<assign_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::assign_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
93
include/boost/xpressive/detail/static/productions/Attic/marker_transform.hpp
Executable file
93
include/boost/xpressive/detail/static/productions/Attic/marker_transform.hpp
Executable file
@@ -0,0 +1,93 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// marker_transform.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_MARKER_TRANSFORM_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_MARKER_TRANSFORM_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_marker
|
||||
template<typename OpT>
|
||||
struct is_marker
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename OpT>
|
||||
struct is_marker
|
||||
<
|
||||
proto::binary_op
|
||||
<
|
||||
proto::unary_op<mark_begin_matcher, proto::noop_tag>
|
||||
, OpT
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_number
|
||||
template<typename OpT, typename VisitorT>
|
||||
int mark_number
|
||||
(
|
||||
proto::binary_op
|
||||
<
|
||||
proto::unary_op<mark_begin_matcher, proto::noop_tag>
|
||||
, OpT
|
||||
, proto::right_shift_tag
|
||||
> const &op
|
||||
, VisitorT &
|
||||
)
|
||||
{
|
||||
return proto::arg(proto::left(op)).mark_number_;
|
||||
}
|
||||
|
||||
template<typename ArgT, typename VisitorT>
|
||||
int mark_number(ArgT const &, VisitorT &visitor)
|
||||
{
|
||||
return visitor.get_hidden_mark();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// marker_transform
|
||||
// Insert mark tags before and after the expression
|
||||
struct marker_transform
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef proto::binary_op
|
||||
<
|
||||
proto::unary_op<mark_begin_matcher, proto::noop_tag>
|
||||
, proto::binary_op
|
||||
<
|
||||
OpT
|
||||
, proto::unary_op<mark_end_matcher, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
, proto::right_shift_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &visitor, int mark_nbr = -1)
|
||||
{
|
||||
return proto::noop(mark_begin_matcher(mark_nbr))
|
||||
>> (op >> proto::noop(mark_end_matcher(mark_nbr)));
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
74
include/boost/xpressive/detail/static/productions/Attic/modify_compiler.hpp
Executable file
74
include/boost/xpressive/detail/static/productions/Attic/modify_compiler.hpp
Executable file
@@ -0,0 +1,74 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// modify_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_MODIFY_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_MODIFY_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex operator tags
|
||||
struct modifier_tag
|
||||
: proto::binary_tag
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// modify_compiler
|
||||
struct modify_compiler
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename proto::left_type<OpT>::type modifier_type;
|
||||
typedef typename modifier_type::BOOST_NESTED_TEMPLATE apply<VisitorT>::type visitor_type;
|
||||
typedef typename proto::right_type<OpT>::type op_type;
|
||||
|
||||
typedef typename proto::compiler<typename proto::tag_type<op_type>::type, seq_tag>::
|
||||
BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
op_type
|
||||
, StateT
|
||||
, visitor_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef typename apply<OpT, StateT, VisitorT>::visitor_type new_visitor_type;
|
||||
new_visitor_type new_visitor(proto::left(op).call(visitor));
|
||||
new_visitor.swap(visitor);
|
||||
struct local // for swapping state back after proto::compile returns
|
||||
{ ~local() { v->swap(*nv); }
|
||||
VisitorT *const v; new_visitor_type *const nv;
|
||||
} const undo = { &visitor, &new_visitor };
|
||||
ignore_unused(&undo);
|
||||
return proto::compile(proto::right(op), state, new_visitor, seq_tag());
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
// production for modifiers
|
||||
template<>
|
||||
struct compiler<xpressive::detail::modifier_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::modify_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
55
include/boost/xpressive/detail/static/productions/Attic/noop_compiler.hpp
Executable file
55
include/boost/xpressive/detail/static/productions/Attic/noop_compiler.hpp
Executable file
@@ -0,0 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// noop_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_NOOP_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_NOOP_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/independent_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex compiler productions
|
||||
struct noop_compiler
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transformation that happens to leaf nodes in the parse tree
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename as_matcher_type<typename proto::arg_type<OpT>::type>::type matcher1;
|
||||
typedef typename VisitorT::BOOST_NESTED_TEMPLATE apply<matcher1>::type matcher2;
|
||||
typedef static_xpression<matcher2, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef typename proto::arg_type<OpT>::type arg_type;
|
||||
return make_static_xpression(visitor.call(as_matcher_type<arg_type>::call(proto::arg(op))), state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
// production for terminals in sequence
|
||||
template<>
|
||||
struct compiler<noop_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::noop_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
108
include/boost/xpressive/detail/static/productions/Attic/productions.hpp
Executable file
108
include/boost/xpressive/detail/static/productions/Attic/productions.hpp
Executable file
@@ -0,0 +1,108 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// productions.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_PRODUCTIONS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_PRODUCTIONS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/fold.hpp>
|
||||
#include <boost/xpressive/proto/compiler/transform.hpp>
|
||||
#include <boost/xpressive/proto/compiler/conditional.hpp>
|
||||
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/visitor.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/quant_compilers.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/alt_compilers.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/independent_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/noop_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/modify_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/complement_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/set_compilers.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/marker_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/charset_transforms.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct is_set_initializer_predicate
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef typename is_same<typename proto::left_type<OpT>::type, set_initializer_type>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct action_transform
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef proto::binary_op
|
||||
<
|
||||
typename proto::left_type<OpT>::type
|
||||
, typename proto::right_type<OpT>::type
|
||||
, proto::right_shift_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &)
|
||||
{
|
||||
return proto::left(op) >> proto::right(op);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// subscript_compiler
|
||||
struct subscript_compiler
|
||||
: proto::conditional_compiler
|
||||
<
|
||||
is_set_initializer_predicate
|
||||
, proto::transform_compiler<charset_transform, seq_tag>
|
||||
, proto::transform_compiler<action_transform, seq_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// misc regex compiler productions
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
template<typename BidiIterT>
|
||||
struct value_type<xpressive::basic_regex<BidiIterT> >
|
||||
{
|
||||
// store regex objects in the parse tree by reference
|
||||
typedef reference_wrapper<xpressive::basic_regex<BidiIterT> const> type;
|
||||
};
|
||||
|
||||
// production for sequences in sequence
|
||||
template<>
|
||||
struct compiler<right_shift_tag, xpressive::detail::seq_tag>
|
||||
: fold_compiler<right_shift_tag, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<subscript_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::subscript_compiler
|
||||
{
|
||||
};
|
||||
}}
|
||||
|
||||
#endif
|
||||
169
include/boost/xpressive/detail/static/productions/Attic/quant_compilers.hpp
Executable file
169
include/boost/xpressive/detail/static/productions/Attic/quant_compilers.hpp
Executable file
@@ -0,0 +1,169 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_compilers.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_QUANT_COMPILERS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_QUANT_COMPILERS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <limits.h>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/branch.hpp>
|
||||
#include <boost/xpressive/proto/compiler/transform.hpp>
|
||||
#include <boost/xpressive/proto/compiler/conditional.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/quant_traits.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/quant_transforms.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/independent_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
template<bool GreedyT = true, uint_t MinT = 1, uint_t MaxT = UINT_MAX-1>
|
||||
struct plus_compiler
|
||||
: proto::conditional_compiler
|
||||
<
|
||||
use_simple_repeat_predicate
|
||||
, proto::branch_compiler<simple_repeat_branch<GreedyT, MinT, MaxT>, ind_tag>
|
||||
, proto::transform_compiler<plus_transform<GreedyT, MinT, MaxT>, seq_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT = true, uint_t MaxT = UINT_MAX-1>
|
||||
struct star_compiler
|
||||
: proto::conditional_compiler
|
||||
<
|
||||
use_simple_repeat_predicate
|
||||
, proto::branch_compiler<simple_repeat_branch<GreedyT, 0, MaxT>, ind_tag>
|
||||
, proto::transform_compiler<star_transform<GreedyT, MaxT>, seq_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT = true>
|
||||
struct optional_compiler
|
||||
: proto::transform_compiler<optional_transform<GreedyT>, seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// generic_quant_compiler
|
||||
template<bool GreedyT, uint_t MinT, uint_t MaxT>
|
||||
struct generic_quant_compiler
|
||||
: plus_compiler<GreedyT, MinT, MaxT>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT, uint_t MaxT>
|
||||
struct generic_quant_compiler<GreedyT, 0, MaxT>
|
||||
: star_compiler<GreedyT, MaxT>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT>
|
||||
struct generic_quant_compiler<GreedyT, 0, 1>
|
||||
: optional_compiler<GreedyT>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT>
|
||||
struct generic_quant_compiler<GreedyT, 1, 1>
|
||||
: proto::transform_compiler<proto::arg_transform, seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT>
|
||||
struct generic_quant_compiler<GreedyT, 0, 0>
|
||||
: proto::transform_compiler<epsilon_transform, seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// non_greedy_compiler
|
||||
//
|
||||
struct non_greedy_compiler
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
// Did you apply operator- to something that wasn't a quantifier?
|
||||
BOOST_MPL_ASSERT((is_greedy_quant<typename proto::arg_type<OpT>::type>));
|
||||
|
||||
typedef typename proto::tag_type<typename proto::arg_type<OpT>::type>::type tag_type;
|
||||
typedef typename min_type<tag_type>::type min_type;
|
||||
typedef typename max_type<tag_type>::type max_type;
|
||||
|
||||
typedef generic_quant_compiler
|
||||
<
|
||||
false
|
||||
, min_type::value
|
||||
, max_type::value
|
||||
> compiler_type;
|
||||
|
||||
typedef typename compiler_type::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
typename proto::arg_type<OpT>::type
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef typename apply<OpT, StateT, VisitorT>::compiler_type compiler_type;
|
||||
return compiler_type::call(proto::arg(op), state, visitor);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
// production for one or more quant
|
||||
template<>
|
||||
struct compiler<unary_plus_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::plus_compiler<>
|
||||
{
|
||||
};
|
||||
|
||||
// production for zero or more quant
|
||||
template<>
|
||||
struct compiler<unary_star_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::star_compiler<>
|
||||
{
|
||||
};
|
||||
|
||||
// production for optional
|
||||
template<>
|
||||
struct compiler<logical_not_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::optional_compiler<>
|
||||
{
|
||||
};
|
||||
|
||||
// production for generic quantifiers
|
||||
template<unsigned int MinT, unsigned int MaxT>
|
||||
struct compiler<xpressive::detail::generic_quant_tag<MinT, MaxT>, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::generic_quant_compiler<true, MinT, MaxT>
|
||||
{
|
||||
};
|
||||
|
||||
// production for non-greedy quantifiers
|
||||
template<>
|
||||
struct compiler<unary_minus_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::non_greedy_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
106
include/boost/xpressive/detail/static/productions/Attic/quant_traits.hpp
Executable file
106
include/boost/xpressive/detail/static/productions/Attic/quant_traits.hpp
Executable file
@@ -0,0 +1,106 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_traits.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_QUANT_TRAITS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_QUANT_TRAITS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/mpl/integral_c.hpp>
|
||||
#include <boost/mpl/not_equal_to.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/width_of.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4307) // '+' : integral constant overflow
|
||||
#endif
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// generic_quant_tag
|
||||
template<uint_t MinT, uint_t MaxT>
|
||||
struct generic_quant_tag
|
||||
: proto::unary_tag
|
||||
{
|
||||
typedef mpl::integral_c<uint_t, MinT> min_type;
|
||||
typedef mpl::integral_c<uint_t, MaxT> max_type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// min_type / max_type
|
||||
template<typename TagT>
|
||||
struct min_type : TagT::min_type {};
|
||||
|
||||
template<>
|
||||
struct min_type<proto::unary_plus_tag> : mpl::integral_c<uint_t, 1> {};
|
||||
|
||||
template<>
|
||||
struct min_type<proto::unary_star_tag> : mpl::integral_c<uint_t, 0> {};
|
||||
|
||||
template<>
|
||||
struct min_type<proto::logical_not_tag> : mpl::integral_c<uint_t, 0> {};
|
||||
|
||||
template<typename TagT>
|
||||
struct max_type : TagT::max_type {};
|
||||
|
||||
template<>
|
||||
struct max_type<proto::unary_plus_tag> : mpl::integral_c<uint_t, UINT_MAX-1> {};
|
||||
|
||||
template<>
|
||||
struct max_type<proto::unary_star_tag> : mpl::integral_c<uint_t, UINT_MAX-1> {};
|
||||
|
||||
template<>
|
||||
struct max_type<proto::logical_not_tag> : mpl::integral_c<uint_t, 1> {};
|
||||
|
||||
struct use_simple_repeat_predicate
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef typename use_simple_repeat<typename proto::arg_type<OpT>::type>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_greedy_quant
|
||||
template<typename XprT>
|
||||
struct is_greedy_quant
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT, typename TagT>
|
||||
struct is_greedy_quant<proto::unary_op<OpT, TagT> >
|
||||
: mpl::or_
|
||||
<
|
||||
is_same<TagT, proto::unary_plus_tag>
|
||||
, is_same<TagT, proto::unary_star_tag>
|
||||
, is_same<TagT, proto::logical_not_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT, uint_t MinT, uint_t MaxT>
|
||||
struct is_greedy_quant<proto::unary_op<OpT, generic_quant_tag<MinT, MaxT> > >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
263
include/boost/xpressive/detail/static/productions/Attic/quant_transforms.hpp
Executable file
263
include/boost/xpressive/detail/static/productions/Attic/quant_transforms.hpp
Executable file
@@ -0,0 +1,263 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_transforms.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_QUANT_TRANSFORMS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_QUANT_TRANSFORMS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <limits.h>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/not_equal_to.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/width_of.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/quant_traits.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/marker_transform.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// plus_no_mark_transform
|
||||
// Unary plus becomes a quantifier by wrapping arg in begin/end quantifiers
|
||||
template<bool GreedyT = true, uint_t MinT = 1, uint_t MaxT = UINT_MAX-1>
|
||||
struct plus_no_mark_transform
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<typename proto::arg_type<OpT>::type> >));
|
||||
|
||||
typedef proto::binary_op
|
||||
<
|
||||
proto::binary_op
|
||||
<
|
||||
proto::unary_op<repeat_begin_matcher, proto::noop_tag>
|
||||
, typename proto::arg_type<OpT>::type // skip the "plus" node
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
, proto::unary_op<repeat_end_matcher<GreedyT>, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &, int mark_number = -1, uint_t min = MinT, uint_t max = MaxT)
|
||||
{
|
||||
return proto::noop(repeat_begin_matcher(mark_number))
|
||||
>> proto::arg(op)
|
||||
>> proto::noop(repeat_end_matcher<GreedyT>(mark_number, min, max));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// plus_mark_transform
|
||||
// compose the quant and mark transforms
|
||||
template<bool GreedyT = true, uint_t MinT = 1, uint_t MaxT = UINT_MAX-1>
|
||||
struct plus_mark_transform
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<typename proto::arg_type<OpT>::type> >));
|
||||
|
||||
typedef typename marker_transform::apply
|
||||
<
|
||||
typename proto::arg_type<OpT>::type
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type marker_type;
|
||||
|
||||
typedef typename plus_no_mark_transform<GreedyT, MinT, MaxT>::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
proto::unary_op<marker_type, typename proto::tag_type<OpT>::type>
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor, int mark_number = -1, uint_t min = MinT, uint_t max = MaxT)
|
||||
{
|
||||
return plus_no_mark_transform<GreedyT, MinT, MaxT>::call
|
||||
(
|
||||
proto::make_op<typename proto::tag_type<OpT>::type>
|
||||
(
|
||||
marker_transform::call(proto::arg(op), state, visitor, mark_number)
|
||||
)
|
||||
, state
|
||||
, visitor
|
||||
, mark_number
|
||||
, min
|
||||
, max
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// optional_transform
|
||||
// An optional expression gets the following transformation:
|
||||
template<bool GreedyT>
|
||||
struct optional_transform
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<typename proto::arg_type<OpT>::type> >));
|
||||
|
||||
typedef proto::binary_op
|
||||
<
|
||||
typename proto::arg_type<OpT>::type
|
||||
, proto::unary_op<epsilon_matcher, proto::noop_tag>
|
||||
, proto::bitor_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &)
|
||||
{
|
||||
return proto::arg(op) | proto::noop(epsilon_matcher());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// non-greedy optional transform
|
||||
template<>
|
||||
struct optional_transform<false>
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<typename proto::arg_type<OpT>::type> >));
|
||||
|
||||
typedef proto::binary_op
|
||||
<
|
||||
proto::unary_op<epsilon_matcher, proto::noop_tag>
|
||||
, typename proto::arg_type<OpT>::type
|
||||
, proto::bitor_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &)
|
||||
{
|
||||
return proto::noop(epsilon_matcher()) | proto::arg(op);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// simple_repeat_branch
|
||||
template<bool GreedyT = true, uint_t MinT = 0, uint_t MaxT = UINT_MAX-1>
|
||||
struct simple_repeat_branch
|
||||
{
|
||||
typedef true_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<OpT> >));
|
||||
typedef static_xpression<simple_repeat_matcher<OpT, GreedyT>, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &, uint_t min = MinT, uint_t max = MaxT)
|
||||
{
|
||||
return make_static_xpression(simple_repeat_matcher<OpT, GreedyT>(op, min, max), state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// plus_transform
|
||||
// Optimization: don't insert a hidden mark if we already have a visible one
|
||||
template<bool GreedyT = true, uint_t MinT = 1, uint_t MaxT = UINT_MAX-1>
|
||||
struct plus_transform
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::if_
|
||||
<
|
||||
is_marker<typename proto::arg_type<OpT>::type>
|
||||
, plus_no_mark_transform<GreedyT, MinT, MaxT>
|
||||
, plus_mark_transform<GreedyT, MinT, MaxT>
|
||||
>::type transform;
|
||||
|
||||
typedef typename transform::BOOST_NESTED_TEMPLATE apply<OpT, StateT, VisitorT>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor, uint_t min = MinT, uint_t max = MaxT)
|
||||
{
|
||||
return apply<OpT, StateT, VisitorT>::transform::call(op, state, visitor, mark_number(proto::arg(op), visitor), min, max);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// star_transform
|
||||
template<bool GreedyT = true, uint_t MaxT = UINT_MAX-1>
|
||||
struct star_transform
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename plus_transform<GreedyT, 1, MaxT>::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
OpT
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type plus_type;
|
||||
|
||||
typedef typename optional_transform<GreedyT>::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
proto::unary_op<plus_type, proto::unary_plus_tag>
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor, uint_t max = MaxT)
|
||||
{
|
||||
return optional_transform<GreedyT>::call
|
||||
(
|
||||
+plus_transform<GreedyT, 1, MaxT>::call(op, state, visitor, 1, max)
|
||||
, state
|
||||
, visitor
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// epsilon_transform
|
||||
struct epsilon_transform
|
||||
{
|
||||
template<typename, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef proto::unary_op<epsilon_matcher, proto::noop_tag> type;
|
||||
};
|
||||
|
||||
static proto::unary_op<epsilon_matcher, proto::noop_tag>
|
||||
call(dont_care, dont_care, dont_care)
|
||||
{
|
||||
return proto::noop(epsilon_matcher());
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
171
include/boost/xpressive/detail/static/productions/Attic/set_compilers.hpp
Executable file
171
include/boost/xpressive/detail/static/productions/Attic/set_compilers.hpp
Executable file
@@ -0,0 +1,171 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// set_compilers.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_SET_COMPILERS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_SET_COMPILERS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/fold.hpp>
|
||||
#include <boost/xpressive/proto/compiler/branch.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/utility/traits_utils.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// set_branch
|
||||
//
|
||||
struct set_branch
|
||||
{
|
||||
typedef no_next state_type;
|
||||
|
||||
template<typename, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef StateT type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static StateT const &call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
return state.set(set_branch::get_matcher(op)), state;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename MatcherT>
|
||||
static MatcherT const &get_matcher(static_xpression<MatcherT, no_next> const &xpr)
|
||||
{
|
||||
return xpr;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// list_branch
|
||||
struct list_branch
|
||||
{
|
||||
typedef int state_type; // not used
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression<OpT, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT>
|
||||
static static_xpression<OpT, StateT>
|
||||
call(OpT const &op, StateT const &state, dont_care)
|
||||
{
|
||||
return make_static_xpression(op, state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// list_noop_compiler
|
||||
struct list_noop_compiler
|
||||
{
|
||||
template<typename, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef typename StateT::next_type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename StateT::next_type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef typename VisitorT::char_type char_type;
|
||||
char_type ch = char_cast<char_type>(proto::arg(op), visitor.traits());
|
||||
return state.push_back(ch, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// list_assign_compiler
|
||||
struct list_assign_compiler
|
||||
{
|
||||
template<typename OpT, typename, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename VisitorT::traits_type traits_type;
|
||||
typedef set_matcher<traits_type, 1> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &visitor)
|
||||
{
|
||||
typedef typename VisitorT::char_type char_type;
|
||||
char_type ch = char_cast<char_type>(proto::arg(proto::right(op)), visitor.traits());
|
||||
return typename apply<OpT, StateT, VisitorT>::type(ch, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compilers for sets such as set['a' | range('a','z')]
|
||||
template<>
|
||||
struct compiler<bitor_tag, xpressive::detail::set_tag>
|
||||
: fold_compiler<bitor_tag, xpressive::detail::set_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<noop_tag, xpressive::detail::set_tag>
|
||||
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<complement_tag, xpressive::detail::set_tag>
|
||||
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<comma_tag, xpressive::detail::set_tag>
|
||||
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compilers for list-initialized sets such as (set='a','b','c')
|
||||
template<>
|
||||
struct compiler<comma_tag, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::list_branch, xpressive::detail::lst_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<comma_tag, xpressive::detail::lst_tag>
|
||||
: fold_compiler<comma_tag, xpressive::detail::lst_tag, false>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<noop_tag, xpressive::detail::lst_tag>
|
||||
: xpressive::detail::list_noop_compiler
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<assign_tag, xpressive::detail::lst_tag>
|
||||
: xpressive::detail::list_assign_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
199
include/boost/xpressive/detail/static/productions/Attic/transmogrify.hpp
Executable file
199
include/boost/xpressive/detail/static/productions/Attic/transmogrify.hpp
Executable file
@@ -0,0 +1,199 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transmogrify.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_TRANSMOGRIFY_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_TRANSMOGRIFY_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/matchers.hpp>
|
||||
#include <boost/xpressive/detail/static/placeholders.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/utility/traits_utils.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transmogrify
|
||||
//
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename MatcherT>
|
||||
struct transmogrify
|
||||
{
|
||||
typedef MatcherT type;
|
||||
|
||||
static type const &call(MatcherT const &m, dont_care)
|
||||
{
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, assert_bol_placeholder>
|
||||
{
|
||||
typedef assert_bol_matcher<TraitsT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(assert_bol_placeholder, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, assert_eol_placeholder>
|
||||
{
|
||||
typedef assert_eol_matcher<TraitsT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(assert_eol_placeholder, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, logical_newline_placeholder>
|
||||
{
|
||||
typedef logical_newline_matcher<TraitsT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(logical_newline_placeholder, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename CharT, bool NotT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, literal_placeholder<CharT, NotT> >
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef literal_matcher<TraitsT, ICaseT::value, NotT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(literal_placeholder<CharT, NotT> const &m, VisitorT &visitor)
|
||||
{
|
||||
char_type ch = char_cast<char_type>(m.ch_, visitor.traits());
|
||||
return type(ch, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename CharT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, range_placeholder<CharT> >
|
||||
{
|
||||
// By design, we don't widen character ranges.
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
BOOST_MPL_ASSERT((is_same<CharT, char_type>));
|
||||
typedef range_matcher<TraitsT, ICaseT::value> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(range_placeholder<CharT> const &m, VisitorT &visitor)
|
||||
{
|
||||
return type(m.ch_min_, m.ch_max_, m.not_, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename CharT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, string_placeholder<CharT> >
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef string_matcher<TraitsT, ICaseT::value> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(string_placeholder<CharT> const &m, VisitorT &visitor)
|
||||
{
|
||||
return type(string_cast<char_type>(m.str_, visitor.traits()), visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, mark_placeholder>
|
||||
{
|
||||
typedef mark_matcher<TraitsT, ICaseT::value> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(mark_placeholder const &m, VisitorT &visitor)
|
||||
{
|
||||
return type(m.mark_number_, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, posix_charset_placeholder>
|
||||
{
|
||||
typedef posix_charset_matcher<TraitsT, ICaseT::value> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(posix_charset_placeholder const &m, VisitorT &visitor)
|
||||
{
|
||||
char const *name_end = m.name_ + std::strlen(m.name_);
|
||||
return type(visitor.traits().lookup_classname(m.name_, name_end, ICaseT::value), m.not_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename TraitsT, int SizeT>
|
||||
struct transmogrify<BidiIterT, mpl::true_, TraitsT, set_matcher<TraitsT, SizeT> >
|
||||
{
|
||||
typedef set_matcher<TraitsT, SizeT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(set_matcher<TraitsT, SizeT> m, VisitorT &visitor)
|
||||
{
|
||||
m.nocase(visitor.traits());
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename CondT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, assert_word_placeholder<CondT> >
|
||||
{
|
||||
typedef assert_word_matcher<CondT, TraitsT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(dont_care, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, bool ByRefT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, regex_placeholder<BidiIterT, ByRefT> >
|
||||
{
|
||||
typedef typename mpl::if_c
|
||||
<
|
||||
ByRefT
|
||||
, regex_byref_matcher<BidiIterT>
|
||||
, regex_matcher<BidiIterT>
|
||||
>::type type;
|
||||
|
||||
static type call(regex_placeholder<BidiIterT, ByRefT> const &m, dont_care)
|
||||
{
|
||||
return type(m.impl_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, self_placeholder>
|
||||
{
|
||||
typedef regex_byref_matcher<BidiIterT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(self_placeholder, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.self());
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
142
include/boost/xpressive/detail/static/productions/Attic/visitor.hpp
Executable file
142
include/boost/xpressive/detail/static/productions/Attic/visitor.hpp
Executable file
@@ -0,0 +1,142 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// visitor.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_VISITOR_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_VISITOR_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bind.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/regex_impl.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/transmogrify.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct xpression_visitor_base
|
||||
{
|
||||
explicit xpression_visitor_base(shared_ptr<regex_impl<BidiIterT> > const &self)
|
||||
: impl_()
|
||||
, self_(self)
|
||||
{
|
||||
}
|
||||
|
||||
void swap(xpression_visitor_base &that)
|
||||
{
|
||||
this->impl_.swap(that.impl_);
|
||||
this->self_.swap(that.self_);
|
||||
}
|
||||
|
||||
int get_hidden_mark()
|
||||
{
|
||||
return -(int)(++this->impl_.hidden_mark_count_);
|
||||
}
|
||||
|
||||
void mark_number(int mark_number)
|
||||
{
|
||||
if(0 < mark_number)
|
||||
{
|
||||
this->impl_.mark_count_ =
|
||||
(std::max)(this->impl_.mark_count_, (std::size_t)mark_number);
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<regex_impl<BidiIterT> > &self()
|
||||
{
|
||||
return this->self_;
|
||||
}
|
||||
|
||||
regex_impl<BidiIterT> &impl()
|
||||
{
|
||||
return this->impl_;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template<typename MatcherT>
|
||||
void visit_(MatcherT const &)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
template<bool ByRefT>
|
||||
void visit_(regex_placeholder<BidiIterT, ByRefT> const &rex)
|
||||
{
|
||||
// when visiting an embeded regex, track the references
|
||||
this->impl_.track_reference(rex.impl_);
|
||||
}
|
||||
|
||||
void visit_(mark_placeholder const &backref)
|
||||
{
|
||||
// keep track of the largest mark number found
|
||||
this->mark_number(backref.mark_number_);
|
||||
}
|
||||
|
||||
void visit_(mark_begin_matcher const &mark_begin)
|
||||
{
|
||||
// keep track of the largest mark number found
|
||||
this->mark_number(mark_begin.mark_number_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
regex_impl<BidiIterT> impl_;
|
||||
shared_ptr<regex_impl<BidiIterT> > self_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct xpression_visitor
|
||||
: xpression_visitor_base<BidiIterT>
|
||||
{
|
||||
typedef BidiIterT iterator_type;
|
||||
typedef ICaseT icase_type;
|
||||
typedef TraitsT traits_type;
|
||||
typedef typename boost::iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
explicit xpression_visitor(TraitsT const &tr, shared_ptr<regex_impl<BidiIterT> > const &self)
|
||||
: xpression_visitor_base<BidiIterT>(self)
|
||||
, traits_(tr)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename MatcherT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename transmogrify<BidiIterT, ICaseT, TraitsT, MatcherT>::type type;
|
||||
};
|
||||
|
||||
template<typename MatcherT>
|
||||
typename apply<MatcherT>::type
|
||||
call(MatcherT const &matcher)
|
||||
{
|
||||
this->visit_(matcher);
|
||||
return transmogrify<BidiIterT, ICaseT, TraitsT, MatcherT>::call(matcher, *this);
|
||||
}
|
||||
|
||||
TraitsT const &traits() const
|
||||
{
|
||||
return this->traits_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
TraitsT traits_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
95
include/boost/xpressive/detail/static/productions/alt_compilers.hpp
Executable file
95
include/boost/xpressive/detail/static/productions/alt_compilers.hpp
Executable file
@@ -0,0 +1,95 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_compilers.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_ALT_COMPILERS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_ALT_COMPILERS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/spirit/fusion/sequence/cons.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/fold.hpp>
|
||||
#include <boost/xpressive/proto/compiler/branch.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_branch
|
||||
// Describes how to construct an alternate xpression
|
||||
struct alt_branch
|
||||
{
|
||||
typedef boost::fusion::nil state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression
|
||||
<
|
||||
alternate_matcher<alternates_list<OpT>, typename VisitorT::traits_type>
|
||||
, StateT
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef alternate_matcher<alternates_list<OpT>, typename VisitorT::traits_type> alt_matcher;
|
||||
return make_static_xpression(alt_matcher(op), state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alt_list_branch
|
||||
struct alt_list_branch
|
||||
{
|
||||
typedef alternate_end_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef boost::fusion::cons<OpT, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT>
|
||||
static boost::fusion::cons<OpT, StateT>
|
||||
call(OpT const &op, StateT const &state, dont_care)
|
||||
{
|
||||
return boost::fusion::make_cons(op, state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
// production for alternates in sequence
|
||||
template<>
|
||||
struct compiler<bitor_tag, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::alt_branch, xpressive::detail::alt_tag>
|
||||
{
|
||||
};
|
||||
|
||||
// handle alternates with the alt branch compiler
|
||||
template<typename OpTagT>
|
||||
struct compiler<OpTagT, xpressive::detail::alt_tag>
|
||||
: branch_compiler<xpressive::detail::alt_list_branch, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
// production for alternates in alternate
|
||||
template<>
|
||||
struct compiler<bitor_tag, xpressive::detail::alt_tag>
|
||||
: fold_compiler<bitor_tag, xpressive::detail::alt_tag>
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
137
include/boost/xpressive/detail/static/productions/charset_transforms.hpp
Executable file
137
include/boost/xpressive/detail/static/productions/charset_transforms.hpp
Executable file
@@ -0,0 +1,137 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// charset_transforms.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_CHARSET_TRANSFORMS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_CHARSET_TRANSFORMS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/sizeof.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/utility/never_true.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// charset_state
|
||||
//
|
||||
template<typename CharSetT, typename TraitsT>
|
||||
struct charset_state
|
||||
{
|
||||
typedef TraitsT traits_type;
|
||||
typedef typename CharSetT::char_type char_type;
|
||||
typedef typename CharSetT::icase_type icase_type;
|
||||
|
||||
explicit charset_state(CharSetT &charset, traits_type const &traits)
|
||||
: charset_(charset)
|
||||
, traits_(traits)
|
||||
{
|
||||
}
|
||||
|
||||
template<bool NotT>
|
||||
void set(literal_matcher<traits_type, icase_type::value, NotT> const &ch) const
|
||||
{
|
||||
// BUGBUG fixme!
|
||||
BOOST_MPL_ASSERT_NOT((mpl::bool_<NotT>));
|
||||
set_char(this->charset_.charset_, ch.ch_, this->traits_, icase_type());
|
||||
}
|
||||
|
||||
void set(range_matcher<traits_type, icase_type::value> const &rg) const
|
||||
{
|
||||
// BUGBUG fixme!
|
||||
BOOST_ASSERT(!rg.not_);
|
||||
set_range(this->charset_.charset_, rg.ch_min_, rg.ch_max_, this->traits_, icase_type());
|
||||
}
|
||||
|
||||
template<int SizeT>
|
||||
void set(set_matcher<traits_type, SizeT> const &set_) const
|
||||
{
|
||||
// BUGBUG fixme!
|
||||
BOOST_ASSERT(!set_.not_);
|
||||
for(int i=0; i<SizeT; ++i)
|
||||
{
|
||||
set_char(this->charset_.charset_, set_.set_[i], this->traits_, icase_type::value);
|
||||
}
|
||||
}
|
||||
|
||||
void set(posix_charset_matcher<traits_type, icase_type::value> const &posix) const
|
||||
{
|
||||
set_class(this->charset_.charset_, posix.mask_, posix.not_, this->traits_, icase_type::value);
|
||||
}
|
||||
|
||||
template<typename UnknownT>
|
||||
void set(UnknownT const &) const
|
||||
{
|
||||
// If this assert fires, it means that you have put something in a set[] that doesn't
|
||||
// belong there. For instance, set["hello"]. Legal members of sets are characters,
|
||||
// character ranges, list-initialized sets such as (set='a','b','c') and posix-style
|
||||
// character sets such as digit and ~alpha.
|
||||
BOOST_MPL_ASSERT((never_true<UnknownT>));
|
||||
}
|
||||
|
||||
private:
|
||||
CharSetT &charset_;
|
||||
traits_type const &traits_;
|
||||
};
|
||||
|
||||
template<typename CharSetT, typename TraitsT>
|
||||
charset_state<CharSetT, TraitsT> make_charset_state(CharSetT &charset, TraitsT const &traits)
|
||||
{
|
||||
return charset_state<CharSetT, TraitsT>(charset, traits);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct charset_transform
|
||||
{
|
||||
template<typename, typename, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename VisitorT::char_type char_type;
|
||||
|
||||
// if sizeof(char_type)==1, merge everything into a basic_chset
|
||||
// BUGBUG this is not optimal.
|
||||
typedef typename mpl::if_
|
||||
<
|
||||
mpl::equal_to<mpl::sizeof_<char_type>, mpl::size_t<1> >
|
||||
, basic_chset<char_type>
|
||||
, compound_charset<typename VisitorT::traits_type>
|
||||
>::type charset_type;
|
||||
|
||||
typedef charset_matcher
|
||||
<
|
||||
typename VisitorT::traits_type
|
||||
, VisitorT::icase_type::value
|
||||
, charset_type
|
||||
> matcher_type;
|
||||
|
||||
typedef proto::unary_op<matcher_type, proto::noop_tag> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor, bool complement = false)
|
||||
{
|
||||
typedef typename apply<OpT, StateT, VisitorT>::matcher_type matcher_type;
|
||||
matcher_type matcher;
|
||||
// Walks the tree and fills in the charset
|
||||
proto::compile(proto::right(op), make_charset_state(matcher, visitor.traits()), visitor, set_tag());
|
||||
if(complement)
|
||||
{
|
||||
matcher.charset_.inverse();
|
||||
}
|
||||
return proto::noop(matcher);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
251
include/boost/xpressive/detail/static/productions/complement_compiler.hpp
Executable file
251
include/boost/xpressive/detail/static/productions/complement_compiler.hpp
Executable file
@@ -0,0 +1,251 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// complement_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_COMPLEMENT_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_COMPLEMENT_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/transform.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/utility/never_true.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/set_compilers.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/charset_transforms.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// complement
|
||||
// the result of applying operator~ to various expressions
|
||||
template<typename OpT, typename VisitorT>
|
||||
struct complement
|
||||
{
|
||||
// If your compile breaks here, then you are applying the complement operator ~
|
||||
// to something that does not support it. For instance, ~(_ >> 'a') will trigger this
|
||||
// assertion because the sub-expression (_ >> 'a') has no complement.
|
||||
BOOST_MPL_ASSERT((never_true<OpT>));
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename CharT, bool NotT, typename VisitorT>
|
||||
struct complement<proto::unary_op<literal_placeholder<CharT, NotT>, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<literal_placeholder<CharT, !NotT>, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<literal_placeholder<CharT, NotT>, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
literal_placeholder<CharT, !NotT> literal = proto::arg(op).ch_;
|
||||
return proto::noop(literal);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename CharT, typename VisitorT>
|
||||
struct complement<proto::unary_op<CharT, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<literal_placeholder<CharT, true>, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<CharT, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
literal_placeholder<CharT, true> literal = proto::arg(op);
|
||||
return proto::noop(literal);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename TraitsT, int SizeT, typename VisitorT>
|
||||
struct complement<proto::unary_op<set_matcher<TraitsT, SizeT>, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<set_matcher<TraitsT, SizeT>, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<set_matcher<TraitsT, SizeT>, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
set_matcher<TraitsT, SizeT> set = proto::arg(op);
|
||||
set.complement();
|
||||
return proto::noop(set);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename VisitorT>
|
||||
struct complement<proto::unary_op<posix_charset_placeholder, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<posix_charset_placeholder, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<posix_charset_placeholder, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
posix_charset_placeholder posix = proto::arg(op);
|
||||
posix.not_ = !posix.not_;
|
||||
return proto::noop(posix);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename OpT, typename VisitorT>
|
||||
struct complement<proto::binary_op<set_initializer_type, OpT, proto::subscript_tag>, VisitorT>
|
||||
{
|
||||
typedef typename charset_transform::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
proto::binary_op<set_initializer_type, OpT, proto::subscript_tag>
|
||||
, dont_care
|
||||
, VisitorT
|
||||
>::type type;
|
||||
|
||||
static type call(proto::binary_op<set_initializer_type, OpT, proto::subscript_tag> const &op, VisitorT &visitor)
|
||||
{
|
||||
return charset_transform::call(op, dont_care(), visitor, true);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// for complementing a list-initialized set, as in ~(set= 'a','b','c')
|
||||
template<typename LeftT, typename RightT, typename VisitorT>
|
||||
struct complement<proto::binary_op<LeftT, RightT, proto::comma_tag>, VisitorT>
|
||||
{
|
||||
// First, convert the parse tree into a set_matcher
|
||||
typedef typename proto::compiler<proto::comma_tag, lst_tag>::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
proto::binary_op<LeftT, RightT, proto::comma_tag>
|
||||
, dont_care
|
||||
, VisitorT
|
||||
>::type set_matcher;
|
||||
|
||||
typedef proto::unary_op<set_matcher, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::binary_op<LeftT, RightT, proto::comma_tag> const &op, VisitorT &visitor)
|
||||
{
|
||||
set_matcher set(proto::compile(op, dont_care(), visitor, lst_tag()));
|
||||
set.complement();
|
||||
return proto::noop(set);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename OpT, typename VisitorT>
|
||||
struct complement<proto::unary_op<OpT, lookahead_tag<true> >, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<OpT, lookahead_tag<false> > type;
|
||||
|
||||
static type call(proto::unary_op<OpT, lookahead_tag<true> > const &op, VisitorT &)
|
||||
{
|
||||
return proto::make_op<lookahead_tag<false> >(proto::arg(op));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename OpT, typename VisitorT>
|
||||
struct complement<proto::unary_op<OpT, lookbehind_tag<true> >, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<OpT, lookbehind_tag<false> > type;
|
||||
|
||||
static type call(proto::unary_op<OpT, lookbehind_tag<true> > const &op, VisitorT &)
|
||||
{
|
||||
return proto::make_op<lookbehind_tag<false> >(proto::arg(op));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename VisitorT>
|
||||
struct complement<proto::unary_op<assert_word_placeholder<word_boundary<true> >, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<assert_word_placeholder<word_boundary<false> >, proto::noop_tag> type;
|
||||
|
||||
static type call(proto::unary_op<assert_word_placeholder<word_boundary<true> >, proto::noop_tag> const &, VisitorT &)
|
||||
{
|
||||
return proto::noop(assert_word_placeholder<word_boundary<false> >());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename VisitorT>
|
||||
struct complement<logical_newline_xpression, VisitorT>
|
||||
{
|
||||
typedef proto::binary_op
|
||||
<
|
||||
proto::unary_op<logical_newline_xpression, lookahead_tag<false> >
|
||||
, proto::unary_op<any_matcher, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
> type;
|
||||
|
||||
static type call(logical_newline_xpression const &op, VisitorT &)
|
||||
{
|
||||
return proto::make_op<lookahead_tag<false> >(op) >> proto::noop(any_matcher());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// complementing a complement is a no-op
|
||||
template<typename ArgT, typename VisitorT>
|
||||
struct complement<proto::unary_op<ArgT, proto::complement_tag>, VisitorT>
|
||||
{
|
||||
typedef ArgT type;
|
||||
|
||||
static ArgT const &call(proto::unary_op<ArgT, proto::complement_tag> const &op, VisitorT &)
|
||||
{
|
||||
return proto::arg(op);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename CharT, typename VisitorT>
|
||||
struct complement<proto::unary_op<range_placeholder<CharT>, proto::noop_tag>, VisitorT>
|
||||
{
|
||||
typedef proto::unary_op<range_placeholder<CharT>, proto::noop_tag> type;
|
||||
|
||||
static type const call(proto::unary_op<range_placeholder<CharT>, proto::noop_tag> const &op, VisitorT &)
|
||||
{
|
||||
range_placeholder<CharT> rng = proto::arg(op);
|
||||
rng.not_ = !rng.not_;
|
||||
return proto::noop(rng);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// complement_transform
|
||||
struct complement_transform
|
||||
{
|
||||
template<typename OpT, typename, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename complement<typename proto::arg_type<OpT>::type, VisitorT>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename complement<typename proto::arg_type<OpT>::type, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &visitor)
|
||||
{
|
||||
return complement<typename proto::arg_type<OpT>::type, VisitorT>::call(proto::arg(op), visitor);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
template<>
|
||||
struct compiler<complement_tag, xpressive::detail::seq_tag>
|
||||
: transform_compiler<xpressive::detail::complement_transform, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
24
include/boost/xpressive/detail/static/productions/domain_tags.hpp
Executable file
24
include/boost/xpressive/detail/static/productions/domain_tags.hpp
Executable file
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// domain_tags.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_DOMAIN_TAGS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_DOMAIN_TAGS_HPP_EAN_10_04_2005
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex domain tags
|
||||
struct seq_tag {};
|
||||
struct alt_tag {};
|
||||
struct lst_tag {};
|
||||
struct set_tag {};
|
||||
struct ind_tag {};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
121
include/boost/xpressive/detail/static/productions/independent_compiler.hpp
Executable file
121
include/boost/xpressive/detail/static/productions/independent_compiler.hpp
Executable file
@@ -0,0 +1,121 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// independent_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_INDEPENDENT_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_INDEPENDENT_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
template<bool PositiveT>
|
||||
struct lookahead_tag : proto::unary_tag {};
|
||||
|
||||
template<bool PositiveT>
|
||||
struct lookbehind_tag : proto::unary_tag {};
|
||||
|
||||
struct keeper_tag : proto::unary_tag {};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lookahead_branch
|
||||
template<bool PositiveT>
|
||||
struct lookahead_branch
|
||||
{
|
||||
typedef true_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression<lookahead_matcher<OpT>, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static static_xpression<lookahead_matcher<OpT>, StateT>
|
||||
call(OpT const &op, StateT const &state, VisitorT &)
|
||||
{
|
||||
return make_static_xpression(lookahead_matcher<OpT>(op, !PositiveT), state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// lookbehind_branch
|
||||
template<bool PositiveT>
|
||||
struct lookbehind_branch
|
||||
{
|
||||
typedef true_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression<lookbehind_matcher<OpT>, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static static_xpression<lookbehind_matcher<OpT>, StateT>
|
||||
call(OpT const &op, StateT const &state, VisitorT &)
|
||||
{
|
||||
return make_static_xpression(lookbehind_matcher<OpT>(op, !PositiveT), state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// keeper_branch
|
||||
struct keeper_branch
|
||||
{
|
||||
typedef true_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression<keeper_matcher<OpT>, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static static_xpression<keeper_matcher<OpT>, StateT>
|
||||
call(OpT const &op, StateT const &state, VisitorT &)
|
||||
{
|
||||
return make_static_xpression(keeper_matcher<OpT>(op), state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
namespace boost { namespace proto {
|
||||
|
||||
template<bool PositiveT>
|
||||
struct compiler<xpressive::detail::lookahead_tag<PositiveT>, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::lookahead_branch<PositiveT>, xpressive::detail::ind_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool PositiveT>
|
||||
struct compiler<xpressive::detail::lookbehind_tag<PositiveT>, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::lookbehind_branch<PositiveT>, xpressive::detail::ind_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<xpressive::detail::keeper_tag, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::keeper_branch, xpressive::detail::ind_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpTagT>
|
||||
struct compiler<OpTagT, xpressive::detail::ind_tag>
|
||||
: transform_compiler<arg_transform, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
73
include/boost/xpressive/detail/static/productions/marker_compiler.hpp
Executable file
73
include/boost/xpressive/detail/static/productions/marker_compiler.hpp
Executable file
@@ -0,0 +1,73 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// marker_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_MARKER_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_MARKER_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/branch.hpp>
|
||||
#include <boost/xpressive/proto/compiler/conditional.hpp>
|
||||
#include <boost/xpressive/proto/compiler/transform.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/marker_transform.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/set_compilers.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// marker_assign_transform
|
||||
struct marker_assign_transform
|
||||
: proto::compose_transforms<proto::right_transform, marker_transform>
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
return marker_transform::call(proto::right(op), state, visitor, proto::arg(proto::left(op)).mark_number_);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_marker_predicate
|
||||
struct is_marker_predicate
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
: is_same<typename proto::left_type<OpT>::type, mark_tag>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// assign_compiler
|
||||
// could be (s1= 'a') or (set= 'a')
|
||||
struct assign_compiler
|
||||
: proto::conditional_compiler
|
||||
<
|
||||
is_marker_predicate
|
||||
, proto::transform_compiler<marker_assign_transform, seq_tag>
|
||||
, proto::branch_compiler<list_branch, lst_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto {
|
||||
|
||||
template<>
|
||||
struct compiler<assign_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::assign_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
93
include/boost/xpressive/detail/static/productions/marker_transform.hpp
Executable file
93
include/boost/xpressive/detail/static/productions/marker_transform.hpp
Executable file
@@ -0,0 +1,93 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// marker_transform.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_MARKER_TRANSFORM_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_MARKER_TRANSFORM_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_marker
|
||||
template<typename OpT>
|
||||
struct is_marker
|
||||
: mpl::false_
|
||||
{};
|
||||
|
||||
template<typename OpT>
|
||||
struct is_marker
|
||||
<
|
||||
proto::binary_op
|
||||
<
|
||||
proto::unary_op<mark_begin_matcher, proto::noop_tag>
|
||||
, OpT
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
>
|
||||
: mpl::true_
|
||||
{};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mark_number
|
||||
template<typename OpT, typename VisitorT>
|
||||
int mark_number
|
||||
(
|
||||
proto::binary_op
|
||||
<
|
||||
proto::unary_op<mark_begin_matcher, proto::noop_tag>
|
||||
, OpT
|
||||
, proto::right_shift_tag
|
||||
> const &op
|
||||
, VisitorT &
|
||||
)
|
||||
{
|
||||
return proto::arg(proto::left(op)).mark_number_;
|
||||
}
|
||||
|
||||
template<typename ArgT, typename VisitorT>
|
||||
int mark_number(ArgT const &, VisitorT &visitor)
|
||||
{
|
||||
return visitor.get_hidden_mark();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// marker_transform
|
||||
// Insert mark tags before and after the expression
|
||||
struct marker_transform
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef proto::binary_op
|
||||
<
|
||||
proto::unary_op<mark_begin_matcher, proto::noop_tag>
|
||||
, proto::binary_op
|
||||
<
|
||||
OpT
|
||||
, proto::unary_op<mark_end_matcher, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
, proto::right_shift_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &visitor, int mark_nbr = -1)
|
||||
{
|
||||
return proto::noop(mark_begin_matcher(mark_nbr))
|
||||
>> (op >> proto::noop(mark_end_matcher(mark_nbr)));
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
74
include/boost/xpressive/detail/static/productions/modify_compiler.hpp
Executable file
74
include/boost/xpressive/detail/static/productions/modify_compiler.hpp
Executable file
@@ -0,0 +1,74 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// modify_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_MODIFY_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_MODIFY_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/utility/ignore_unused.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex operator tags
|
||||
struct modifier_tag
|
||||
: proto::binary_tag
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// modify_compiler
|
||||
struct modify_compiler
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename proto::left_type<OpT>::type modifier_type;
|
||||
typedef typename modifier_type::BOOST_NESTED_TEMPLATE apply<VisitorT>::type visitor_type;
|
||||
typedef typename proto::right_type<OpT>::type op_type;
|
||||
|
||||
typedef typename proto::compiler<typename proto::tag_type<op_type>::type, seq_tag>::
|
||||
BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
op_type
|
||||
, StateT
|
||||
, visitor_type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef typename apply<OpT, StateT, VisitorT>::visitor_type new_visitor_type;
|
||||
new_visitor_type new_visitor(proto::left(op).call(visitor));
|
||||
new_visitor.swap(visitor);
|
||||
struct local // for swapping state back after proto::compile returns
|
||||
{ ~local() { v->swap(*nv); }
|
||||
VisitorT *const v; new_visitor_type *const nv;
|
||||
} const undo = { &visitor, &new_visitor };
|
||||
ignore_unused(&undo);
|
||||
return proto::compile(proto::right(op), state, new_visitor, seq_tag());
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
// production for modifiers
|
||||
template<>
|
||||
struct compiler<xpressive::detail::modifier_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::modify_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
55
include/boost/xpressive/detail/static/productions/noop_compiler.hpp
Executable file
55
include/boost/xpressive/detail/static/productions/noop_compiler.hpp
Executable file
@@ -0,0 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// noop_compiler.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_NOOP_COMPILER_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_NOOP_COMPILER_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/independent_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex compiler productions
|
||||
struct noop_compiler
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transformation that happens to leaf nodes in the parse tree
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename as_matcher_type<typename proto::arg_type<OpT>::type>::type matcher1;
|
||||
typedef typename VisitorT::BOOST_NESTED_TEMPLATE apply<matcher1>::type matcher2;
|
||||
typedef static_xpression<matcher2, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef typename proto::arg_type<OpT>::type arg_type;
|
||||
return make_static_xpression(visitor.call(as_matcher_type<arg_type>::call(proto::arg(op))), state);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
// production for terminals in sequence
|
||||
template<>
|
||||
struct compiler<noop_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::noop_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
108
include/boost/xpressive/detail/static/productions/productions.hpp
Executable file
108
include/boost/xpressive/detail/static/productions/productions.hpp
Executable file
@@ -0,0 +1,108 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// productions.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_PRODUCTIONS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_PRODUCTIONS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/fold.hpp>
|
||||
#include <boost/xpressive/proto/compiler/transform.hpp>
|
||||
#include <boost/xpressive/proto/compiler/conditional.hpp>
|
||||
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/visitor.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/quant_compilers.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/alt_compilers.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/independent_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/noop_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/modify_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/complement_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/set_compilers.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/marker_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/charset_transforms.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct is_set_initializer_predicate
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef typename is_same<typename proto::left_type<OpT>::type, set_initializer_type>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct action_transform
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef proto::binary_op
|
||||
<
|
||||
typename proto::left_type<OpT>::type
|
||||
, typename proto::right_type<OpT>::type
|
||||
, proto::right_shift_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &)
|
||||
{
|
||||
return proto::left(op) >> proto::right(op);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// subscript_compiler
|
||||
struct subscript_compiler
|
||||
: proto::conditional_compiler
|
||||
<
|
||||
is_set_initializer_predicate
|
||||
, proto::transform_compiler<charset_transform, seq_tag>
|
||||
, proto::transform_compiler<action_transform, seq_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// misc regex compiler productions
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
template<typename BidiIterT>
|
||||
struct value_type<xpressive::basic_regex<BidiIterT> >
|
||||
{
|
||||
// store regex objects in the parse tree by reference
|
||||
typedef reference_wrapper<xpressive::basic_regex<BidiIterT> const> type;
|
||||
};
|
||||
|
||||
// production for sequences in sequence
|
||||
template<>
|
||||
struct compiler<right_shift_tag, xpressive::detail::seq_tag>
|
||||
: fold_compiler<right_shift_tag, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<subscript_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::subscript_compiler
|
||||
{
|
||||
};
|
||||
}}
|
||||
|
||||
#endif
|
||||
169
include/boost/xpressive/detail/static/productions/quant_compilers.hpp
Executable file
169
include/boost/xpressive/detail/static/productions/quant_compilers.hpp
Executable file
@@ -0,0 +1,169 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_compilers.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_QUANT_COMPILERS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_QUANT_COMPILERS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <limits.h>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/branch.hpp>
|
||||
#include <boost/xpressive/proto/compiler/transform.hpp>
|
||||
#include <boost/xpressive/proto/compiler/conditional.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/quant_traits.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/quant_transforms.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/independent_compiler.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
template<bool GreedyT = true, uint_t MinT = 1, uint_t MaxT = UINT_MAX-1>
|
||||
struct plus_compiler
|
||||
: proto::conditional_compiler
|
||||
<
|
||||
use_simple_repeat_predicate
|
||||
, proto::branch_compiler<simple_repeat_branch<GreedyT, MinT, MaxT>, ind_tag>
|
||||
, proto::transform_compiler<plus_transform<GreedyT, MinT, MaxT>, seq_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT = true, uint_t MaxT = UINT_MAX-1>
|
||||
struct star_compiler
|
||||
: proto::conditional_compiler
|
||||
<
|
||||
use_simple_repeat_predicate
|
||||
, proto::branch_compiler<simple_repeat_branch<GreedyT, 0, MaxT>, ind_tag>
|
||||
, proto::transform_compiler<star_transform<GreedyT, MaxT>, seq_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT = true>
|
||||
struct optional_compiler
|
||||
: proto::transform_compiler<optional_transform<GreedyT>, seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// generic_quant_compiler
|
||||
template<bool GreedyT, uint_t MinT, uint_t MaxT>
|
||||
struct generic_quant_compiler
|
||||
: plus_compiler<GreedyT, MinT, MaxT>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT, uint_t MaxT>
|
||||
struct generic_quant_compiler<GreedyT, 0, MaxT>
|
||||
: star_compiler<GreedyT, MaxT>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT>
|
||||
struct generic_quant_compiler<GreedyT, 0, 1>
|
||||
: optional_compiler<GreedyT>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT>
|
||||
struct generic_quant_compiler<GreedyT, 1, 1>
|
||||
: proto::transform_compiler<proto::arg_transform, seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool GreedyT>
|
||||
struct generic_quant_compiler<GreedyT, 0, 0>
|
||||
: proto::transform_compiler<epsilon_transform, seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// non_greedy_compiler
|
||||
//
|
||||
struct non_greedy_compiler
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
// Did you apply operator- to something that wasn't a quantifier?
|
||||
BOOST_MPL_ASSERT((is_greedy_quant<typename proto::arg_type<OpT>::type>));
|
||||
|
||||
typedef typename proto::tag_type<typename proto::arg_type<OpT>::type>::type tag_type;
|
||||
typedef typename min_type<tag_type>::type min_type;
|
||||
typedef typename max_type<tag_type>::type max_type;
|
||||
|
||||
typedef generic_quant_compiler
|
||||
<
|
||||
false
|
||||
, min_type::value
|
||||
, max_type::value
|
||||
> compiler_type;
|
||||
|
||||
typedef typename compiler_type::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
typename proto::arg_type<OpT>::type
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef typename apply<OpT, StateT, VisitorT>::compiler_type compiler_type;
|
||||
return compiler_type::call(proto::arg(op), state, visitor);
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
// production for one or more quant
|
||||
template<>
|
||||
struct compiler<unary_plus_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::plus_compiler<>
|
||||
{
|
||||
};
|
||||
|
||||
// production for zero or more quant
|
||||
template<>
|
||||
struct compiler<unary_star_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::star_compiler<>
|
||||
{
|
||||
};
|
||||
|
||||
// production for optional
|
||||
template<>
|
||||
struct compiler<logical_not_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::optional_compiler<>
|
||||
{
|
||||
};
|
||||
|
||||
// production for generic quantifiers
|
||||
template<unsigned int MinT, unsigned int MaxT>
|
||||
struct compiler<xpressive::detail::generic_quant_tag<MinT, MaxT>, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::generic_quant_compiler<true, MinT, MaxT>
|
||||
{
|
||||
};
|
||||
|
||||
// production for non-greedy quantifiers
|
||||
template<>
|
||||
struct compiler<unary_minus_tag, xpressive::detail::seq_tag>
|
||||
: xpressive::detail::non_greedy_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif
|
||||
106
include/boost/xpressive/detail/static/productions/quant_traits.hpp
Executable file
106
include/boost/xpressive/detail/static/productions/quant_traits.hpp
Executable file
@@ -0,0 +1,106 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_traits.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_QUANT_TRAITS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_QUANT_TRAITS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/mpl/integral_c.hpp>
|
||||
#include <boost/mpl/not_equal_to.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/width_of.hpp>
|
||||
#include <boost/xpressive/detail/static/is_pure.hpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4307) // '+' : integral constant overflow
|
||||
#endif
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// generic_quant_tag
|
||||
template<uint_t MinT, uint_t MaxT>
|
||||
struct generic_quant_tag
|
||||
: proto::unary_tag
|
||||
{
|
||||
typedef mpl::integral_c<uint_t, MinT> min_type;
|
||||
typedef mpl::integral_c<uint_t, MaxT> max_type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// min_type / max_type
|
||||
template<typename TagT>
|
||||
struct min_type : TagT::min_type {};
|
||||
|
||||
template<>
|
||||
struct min_type<proto::unary_plus_tag> : mpl::integral_c<uint_t, 1> {};
|
||||
|
||||
template<>
|
||||
struct min_type<proto::unary_star_tag> : mpl::integral_c<uint_t, 0> {};
|
||||
|
||||
template<>
|
||||
struct min_type<proto::logical_not_tag> : mpl::integral_c<uint_t, 0> {};
|
||||
|
||||
template<typename TagT>
|
||||
struct max_type : TagT::max_type {};
|
||||
|
||||
template<>
|
||||
struct max_type<proto::unary_plus_tag> : mpl::integral_c<uint_t, UINT_MAX-1> {};
|
||||
|
||||
template<>
|
||||
struct max_type<proto::unary_star_tag> : mpl::integral_c<uint_t, UINT_MAX-1> {};
|
||||
|
||||
template<>
|
||||
struct max_type<proto::logical_not_tag> : mpl::integral_c<uint_t, 1> {};
|
||||
|
||||
struct use_simple_repeat_predicate
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef typename use_simple_repeat<typename proto::arg_type<OpT>::type>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_greedy_quant
|
||||
template<typename XprT>
|
||||
struct is_greedy_quant
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT, typename TagT>
|
||||
struct is_greedy_quant<proto::unary_op<OpT, TagT> >
|
||||
: mpl::or_
|
||||
<
|
||||
is_same<TagT, proto::unary_plus_tag>
|
||||
, is_same<TagT, proto::unary_star_tag>
|
||||
, is_same<TagT, proto::logical_not_tag>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT, uint_t MinT, uint_t MaxT>
|
||||
struct is_greedy_quant<proto::unary_op<OpT, generic_quant_tag<MinT, MaxT> > >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
263
include/boost/xpressive/detail/static/productions/quant_transforms.hpp
Executable file
263
include/boost/xpressive/detail/static/productions/quant_transforms.hpp
Executable file
@@ -0,0 +1,263 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// quant_transforms.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_QUANT_TRANSFORMS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_QUANT_TRANSFORMS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <limits.h>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/not_equal_to.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/width_of.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/quant_traits.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/marker_transform.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// plus_no_mark_transform
|
||||
// Unary plus becomes a quantifier by wrapping arg in begin/end quantifiers
|
||||
template<bool GreedyT = true, uint_t MinT = 1, uint_t MaxT = UINT_MAX-1>
|
||||
struct plus_no_mark_transform
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<typename proto::arg_type<OpT>::type> >));
|
||||
|
||||
typedef proto::binary_op
|
||||
<
|
||||
proto::binary_op
|
||||
<
|
||||
proto::unary_op<repeat_begin_matcher, proto::noop_tag>
|
||||
, typename proto::arg_type<OpT>::type // skip the "plus" node
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
, proto::unary_op<repeat_end_matcher<GreedyT>, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &, int mark_number = -1, uint_t min = MinT, uint_t max = MaxT)
|
||||
{
|
||||
return proto::noop(repeat_begin_matcher(mark_number))
|
||||
>> proto::arg(op)
|
||||
>> proto::noop(repeat_end_matcher<GreedyT>(mark_number, min, max));
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// plus_mark_transform
|
||||
// compose the quant and mark transforms
|
||||
template<bool GreedyT = true, uint_t MinT = 1, uint_t MaxT = UINT_MAX-1>
|
||||
struct plus_mark_transform
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<typename proto::arg_type<OpT>::type> >));
|
||||
|
||||
typedef typename marker_transform::apply
|
||||
<
|
||||
typename proto::arg_type<OpT>::type
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type marker_type;
|
||||
|
||||
typedef typename plus_no_mark_transform<GreedyT, MinT, MaxT>::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
proto::unary_op<marker_type, typename proto::tag_type<OpT>::type>
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor, int mark_number = -1, uint_t min = MinT, uint_t max = MaxT)
|
||||
{
|
||||
return plus_no_mark_transform<GreedyT, MinT, MaxT>::call
|
||||
(
|
||||
proto::make_op<typename proto::tag_type<OpT>::type>
|
||||
(
|
||||
marker_transform::call(proto::arg(op), state, visitor, mark_number)
|
||||
)
|
||||
, state
|
||||
, visitor
|
||||
, mark_number
|
||||
, min
|
||||
, max
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// optional_transform
|
||||
// An optional expression gets the following transformation:
|
||||
template<bool GreedyT>
|
||||
struct optional_transform
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<typename proto::arg_type<OpT>::type> >));
|
||||
|
||||
typedef proto::binary_op
|
||||
<
|
||||
typename proto::arg_type<OpT>::type
|
||||
, proto::unary_op<epsilon_matcher, proto::noop_tag>
|
||||
, proto::bitor_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &)
|
||||
{
|
||||
return proto::arg(op) | proto::noop(epsilon_matcher());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// non-greedy optional transform
|
||||
template<>
|
||||
struct optional_transform<false>
|
||||
{
|
||||
template<typename OpT, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<typename proto::arg_type<OpT>::type> >));
|
||||
|
||||
typedef proto::binary_op
|
||||
<
|
||||
proto::unary_op<epsilon_matcher, proto::noop_tag>
|
||||
, typename proto::arg_type<OpT>::type
|
||||
, proto::bitor_tag
|
||||
> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &)
|
||||
{
|
||||
return proto::noop(epsilon_matcher()) | proto::arg(op);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// simple_repeat_branch
|
||||
template<bool GreedyT = true, uint_t MinT = 0, uint_t MaxT = UINT_MAX-1>
|
||||
struct simple_repeat_branch
|
||||
{
|
||||
typedef true_xpression state_type;
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
BOOST_MPL_ASSERT((mpl::not_equal_to<mpl::size_t<0>, width_of<OpT> >));
|
||||
typedef static_xpression<simple_repeat_matcher<OpT, GreedyT>, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &, uint_t min = MinT, uint_t max = MaxT)
|
||||
{
|
||||
return make_static_xpression(simple_repeat_matcher<OpT, GreedyT>(op, min, max), state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// plus_transform
|
||||
// Optimization: don't insert a hidden mark if we already have a visible one
|
||||
template<bool GreedyT = true, uint_t MinT = 1, uint_t MaxT = UINT_MAX-1>
|
||||
struct plus_transform
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::if_
|
||||
<
|
||||
is_marker<typename proto::arg_type<OpT>::type>
|
||||
, plus_no_mark_transform<GreedyT, MinT, MaxT>
|
||||
, plus_mark_transform<GreedyT, MinT, MaxT>
|
||||
>::type transform;
|
||||
|
||||
typedef typename transform::BOOST_NESTED_TEMPLATE apply<OpT, StateT, VisitorT>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor, uint_t min = MinT, uint_t max = MaxT)
|
||||
{
|
||||
return apply<OpT, StateT, VisitorT>::transform::call(op, state, visitor, mark_number(proto::arg(op), visitor), min, max);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// star_transform
|
||||
template<bool GreedyT = true, uint_t MaxT = UINT_MAX-1>
|
||||
struct star_transform
|
||||
{
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename plus_transform<GreedyT, 1, MaxT>::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
OpT
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type plus_type;
|
||||
|
||||
typedef typename optional_transform<GreedyT>::BOOST_NESTED_TEMPLATE apply
|
||||
<
|
||||
proto::unary_op<plus_type, proto::unary_plus_tag>
|
||||
, StateT
|
||||
, VisitorT
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor, uint_t max = MaxT)
|
||||
{
|
||||
return optional_transform<GreedyT>::call
|
||||
(
|
||||
+plus_transform<GreedyT, 1, MaxT>::call(op, state, visitor, 1, max)
|
||||
, state
|
||||
, visitor
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// epsilon_transform
|
||||
struct epsilon_transform
|
||||
{
|
||||
template<typename, typename, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef proto::unary_op<epsilon_matcher, proto::noop_tag> type;
|
||||
};
|
||||
|
||||
static proto::unary_op<epsilon_matcher, proto::noop_tag>
|
||||
call(dont_care, dont_care, dont_care)
|
||||
{
|
||||
return proto::noop(epsilon_matcher());
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
171
include/boost/xpressive/detail/static/productions/set_compilers.hpp
Executable file
171
include/boost/xpressive/detail/static/productions/set_compilers.hpp
Executable file
@@ -0,0 +1,171 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// set_compilers.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_SET_COMPILERS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_SET_COMPILERS_HPP_EAN_10_04_2005
|
||||
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/proto/compiler/fold.hpp>
|
||||
#include <boost/xpressive/proto/compiler/branch.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/utility/traits_utils.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/domain_tags.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// set_branch
|
||||
//
|
||||
struct set_branch
|
||||
{
|
||||
typedef no_next state_type;
|
||||
|
||||
template<typename, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef StateT type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static StateT const &call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
return state.set(set_branch::get_matcher(op)), state;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename MatcherT>
|
||||
static MatcherT const &get_matcher(static_xpression<MatcherT, no_next> const &xpr)
|
||||
{
|
||||
return xpr;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// list_branch
|
||||
struct list_branch
|
||||
{
|
||||
typedef int state_type; // not used
|
||||
|
||||
template<typename OpT, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef static_xpression<OpT, StateT> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT>
|
||||
static static_xpression<OpT, StateT>
|
||||
call(OpT const &op, StateT const &state, dont_care)
|
||||
{
|
||||
return make_static_xpression(op, state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// list_noop_compiler
|
||||
struct list_noop_compiler
|
||||
{
|
||||
template<typename, typename StateT, typename>
|
||||
struct apply
|
||||
{
|
||||
typedef typename StateT::next_type type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename StateT::next_type
|
||||
call(OpT const &op, StateT const &state, VisitorT &visitor)
|
||||
{
|
||||
typedef typename VisitorT::char_type char_type;
|
||||
char_type ch = char_cast<char_type>(proto::arg(op), visitor.traits());
|
||||
return state.push_back(ch, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// list_assign_compiler
|
||||
struct list_assign_compiler
|
||||
{
|
||||
template<typename OpT, typename, typename VisitorT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename VisitorT::traits_type traits_type;
|
||||
typedef set_matcher<traits_type, 1> type;
|
||||
};
|
||||
|
||||
template<typename OpT, typename StateT, typename VisitorT>
|
||||
static typename apply<OpT, StateT, VisitorT>::type
|
||||
call(OpT const &op, StateT const &, VisitorT &visitor)
|
||||
{
|
||||
typedef typename VisitorT::char_type char_type;
|
||||
char_type ch = char_cast<char_type>(proto::arg(proto::right(op)), visitor.traits());
|
||||
return typename apply<OpT, StateT, VisitorT>::type(ch, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
namespace boost { namespace proto
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compilers for sets such as set['a' | range('a','z')]
|
||||
template<>
|
||||
struct compiler<bitor_tag, xpressive::detail::set_tag>
|
||||
: fold_compiler<bitor_tag, xpressive::detail::set_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<noop_tag, xpressive::detail::set_tag>
|
||||
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<complement_tag, xpressive::detail::set_tag>
|
||||
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<comma_tag, xpressive::detail::set_tag>
|
||||
: branch_compiler<xpressive::detail::set_branch, xpressive::detail::seq_tag>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// compilers for list-initialized sets such as (set='a','b','c')
|
||||
template<>
|
||||
struct compiler<comma_tag, xpressive::detail::seq_tag>
|
||||
: branch_compiler<xpressive::detail::list_branch, xpressive::detail::lst_tag>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<comma_tag, xpressive::detail::lst_tag>
|
||||
: fold_compiler<comma_tag, xpressive::detail::lst_tag, false>
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<noop_tag, xpressive::detail::lst_tag>
|
||||
: xpressive::detail::list_noop_compiler
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct compiler<assign_tag, xpressive::detail::lst_tag>
|
||||
: xpressive::detail::list_assign_compiler
|
||||
{
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
199
include/boost/xpressive/detail/static/productions/transmogrify.hpp
Executable file
199
include/boost/xpressive/detail/static/productions/transmogrify.hpp
Executable file
@@ -0,0 +1,199 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transmogrify.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_TRANSMOGRIFY_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_TRANSMOGRIFY_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/matchers.hpp>
|
||||
#include <boost/xpressive/detail/static/placeholders.hpp>
|
||||
#include <boost/xpressive/detail/utility/dont_care.hpp>
|
||||
#include <boost/xpressive/detail/utility/traits_utils.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// transmogrify
|
||||
//
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename MatcherT>
|
||||
struct transmogrify
|
||||
{
|
||||
typedef MatcherT type;
|
||||
|
||||
static type const &call(MatcherT const &m, dont_care)
|
||||
{
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, assert_bol_placeholder>
|
||||
{
|
||||
typedef assert_bol_matcher<TraitsT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(assert_bol_placeholder, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, assert_eol_placeholder>
|
||||
{
|
||||
typedef assert_eol_matcher<TraitsT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(assert_eol_placeholder, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, logical_newline_placeholder>
|
||||
{
|
||||
typedef logical_newline_matcher<TraitsT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(logical_newline_placeholder, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename CharT, bool NotT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, literal_placeholder<CharT, NotT> >
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef literal_matcher<TraitsT, ICaseT::value, NotT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(literal_placeholder<CharT, NotT> const &m, VisitorT &visitor)
|
||||
{
|
||||
char_type ch = char_cast<char_type>(m.ch_, visitor.traits());
|
||||
return type(ch, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename CharT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, range_placeholder<CharT> >
|
||||
{
|
||||
// By design, we don't widen character ranges.
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
BOOST_MPL_ASSERT((is_same<CharT, char_type>));
|
||||
typedef range_matcher<TraitsT, ICaseT::value> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(range_placeholder<CharT> const &m, VisitorT &visitor)
|
||||
{
|
||||
return type(m.ch_min_, m.ch_max_, m.not_, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename CharT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, string_placeholder<CharT> >
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef string_matcher<TraitsT, ICaseT::value> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(string_placeholder<CharT> const &m, VisitorT &visitor)
|
||||
{
|
||||
return type(string_cast<char_type>(m.str_, visitor.traits()), visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, mark_placeholder>
|
||||
{
|
||||
typedef mark_matcher<TraitsT, ICaseT::value> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(mark_placeholder const &m, VisitorT &visitor)
|
||||
{
|
||||
return type(m.mark_number_, visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, posix_charset_placeholder>
|
||||
{
|
||||
typedef posix_charset_matcher<TraitsT, ICaseT::value> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(posix_charset_placeholder const &m, VisitorT &visitor)
|
||||
{
|
||||
char const *name_end = m.name_ + std::strlen(m.name_);
|
||||
return type(visitor.traits().lookup_classname(m.name_, name_end, ICaseT::value), m.not_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename TraitsT, int SizeT>
|
||||
struct transmogrify<BidiIterT, mpl::true_, TraitsT, set_matcher<TraitsT, SizeT> >
|
||||
{
|
||||
typedef set_matcher<TraitsT, SizeT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(set_matcher<TraitsT, SizeT> m, VisitorT &visitor)
|
||||
{
|
||||
m.nocase(visitor.traits());
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, typename CondT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, assert_word_placeholder<CondT> >
|
||||
{
|
||||
typedef assert_word_matcher<CondT, TraitsT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(dont_care, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.traits());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT, bool ByRefT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, regex_placeholder<BidiIterT, ByRefT> >
|
||||
{
|
||||
typedef typename mpl::if_c
|
||||
<
|
||||
ByRefT
|
||||
, regex_byref_matcher<BidiIterT>
|
||||
, regex_matcher<BidiIterT>
|
||||
>::type type;
|
||||
|
||||
static type call(regex_placeholder<BidiIterT, ByRefT> const &m, dont_care)
|
||||
{
|
||||
return type(m.impl_);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct transmogrify<BidiIterT, ICaseT, TraitsT, self_placeholder>
|
||||
{
|
||||
typedef regex_byref_matcher<BidiIterT> type;
|
||||
|
||||
template<typename VisitorT>
|
||||
static type call(self_placeholder, VisitorT &visitor)
|
||||
{
|
||||
return type(visitor.self());
|
||||
}
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
142
include/boost/xpressive/detail/static/productions/visitor.hpp
Executable file
142
include/boost/xpressive/detail/static/productions/visitor.hpp
Executable file
@@ -0,0 +1,142 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// visitor.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_PRODUCTIONS_VISITOR_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_PRODUCTIONS_VISITOR_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/bind.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/regex_impl.hpp>
|
||||
#include <boost/xpressive/detail/static/productions/transmogrify.hpp>
|
||||
#include <boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct xpression_visitor_base
|
||||
{
|
||||
explicit xpression_visitor_base(shared_ptr<regex_impl<BidiIterT> > const &self)
|
||||
: impl_()
|
||||
, self_(self)
|
||||
{
|
||||
}
|
||||
|
||||
void swap(xpression_visitor_base &that)
|
||||
{
|
||||
this->impl_.swap(that.impl_);
|
||||
this->self_.swap(that.self_);
|
||||
}
|
||||
|
||||
int get_hidden_mark()
|
||||
{
|
||||
return -(int)(++this->impl_.hidden_mark_count_);
|
||||
}
|
||||
|
||||
void mark_number(int mark_number)
|
||||
{
|
||||
if(0 < mark_number)
|
||||
{
|
||||
this->impl_.mark_count_ =
|
||||
(std::max)(this->impl_.mark_count_, (std::size_t)mark_number);
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<regex_impl<BidiIterT> > &self()
|
||||
{
|
||||
return this->self_;
|
||||
}
|
||||
|
||||
regex_impl<BidiIterT> &impl()
|
||||
{
|
||||
return this->impl_;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
template<typename MatcherT>
|
||||
void visit_(MatcherT const &)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
template<bool ByRefT>
|
||||
void visit_(regex_placeholder<BidiIterT, ByRefT> const &rex)
|
||||
{
|
||||
// when visiting an embeded regex, track the references
|
||||
this->impl_.track_reference(rex.impl_);
|
||||
}
|
||||
|
||||
void visit_(mark_placeholder const &backref)
|
||||
{
|
||||
// keep track of the largest mark number found
|
||||
this->mark_number(backref.mark_number_);
|
||||
}
|
||||
|
||||
void visit_(mark_begin_matcher const &mark_begin)
|
||||
{
|
||||
// keep track of the largest mark number found
|
||||
this->mark_number(mark_begin.mark_number_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
regex_impl<BidiIterT> impl_;
|
||||
shared_ptr<regex_impl<BidiIterT> > self_;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<typename BidiIterT, typename ICaseT, typename TraitsT>
|
||||
struct xpression_visitor
|
||||
: xpression_visitor_base<BidiIterT>
|
||||
{
|
||||
typedef BidiIterT iterator_type;
|
||||
typedef ICaseT icase_type;
|
||||
typedef TraitsT traits_type;
|
||||
typedef typename boost::iterator_value<BidiIterT>::type char_type;
|
||||
|
||||
explicit xpression_visitor(TraitsT const &tr, shared_ptr<regex_impl<BidiIterT> > const &self)
|
||||
: xpression_visitor_base<BidiIterT>(self)
|
||||
, traits_(tr)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename MatcherT>
|
||||
struct apply
|
||||
{
|
||||
typedef typename transmogrify<BidiIterT, ICaseT, TraitsT, MatcherT>::type type;
|
||||
};
|
||||
|
||||
template<typename MatcherT>
|
||||
typename apply<MatcherT>::type
|
||||
call(MatcherT const &matcher)
|
||||
{
|
||||
this->visit_(matcher);
|
||||
return transmogrify<BidiIterT, ICaseT, TraitsT, MatcherT>::call(matcher, *this);
|
||||
}
|
||||
|
||||
TraitsT const &traits() const
|
||||
{
|
||||
return this->traits_;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
TraitsT traits_;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
164
include/boost/xpressive/detail/static/regex_operators.hpp
Executable file
164
include/boost/xpressive/detail/static/regex_operators.hpp
Executable file
@@ -0,0 +1,164 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// regex_operators.hpp
|
||||
//
|
||||
// Copyright 2005 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_STATIC_REGEX_OPERATORS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_REGEX_OPERATORS_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/xpressive/proto/proto.hpp>
|
||||
#include <boost/xpressive/basic_regex.hpp>
|
||||
|
||||
namespace boost { namespace xpressive
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator +
|
||||
template<typename BidiIterT>
|
||||
inline proto::unary_op
|
||||
<
|
||||
proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::unary_plus_tag
|
||||
>
|
||||
operator +(basic_regex<BidiIterT> const ®ex)
|
||||
{
|
||||
return +proto::noop(regex);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator *
|
||||
template<typename BidiIterT>
|
||||
inline proto::unary_op
|
||||
<
|
||||
proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::unary_star_tag
|
||||
>
|
||||
operator *(basic_regex<BidiIterT> const ®ex)
|
||||
{
|
||||
return *proto::noop(regex);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator !
|
||||
template<typename BidiIterT>
|
||||
inline proto::unary_op
|
||||
<
|
||||
proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::logical_not_tag
|
||||
>
|
||||
operator !(basic_regex<BidiIterT> const ®ex)
|
||||
{
|
||||
return !proto::noop(regex);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator >>
|
||||
template<typename RightT, typename BidiIterT>
|
||||
inline typename disable_if
|
||||
<
|
||||
proto::is_op<RightT>
|
||||
, proto::binary_op
|
||||
<
|
||||
proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::unary_op<RightT, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
>::type
|
||||
operator >>(basic_regex<BidiIterT> const ®ex, RightT const &right)
|
||||
{
|
||||
return proto::noop(regex) >> proto::noop(right);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator >>
|
||||
template<typename BidiIterT, typename LeftT>
|
||||
inline typename disable_if
|
||||
<
|
||||
proto::is_op<LeftT>
|
||||
, proto::binary_op
|
||||
<
|
||||
proto::unary_op<LeftT, proto::noop_tag>
|
||||
, proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
>::type
|
||||
operator >>(LeftT const &left, basic_regex<BidiIterT> const ®ex)
|
||||
{
|
||||
return proto::noop(left) >> proto::noop(regex);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator >>
|
||||
template<typename BidiIterT>
|
||||
inline proto::binary_op
|
||||
<
|
||||
proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::right_shift_tag
|
||||
>
|
||||
operator >>(basic_regex<BidiIterT> const &left, basic_regex<BidiIterT> const &right)
|
||||
{
|
||||
return proto::noop(left) >> proto::noop(right);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator |
|
||||
template<typename RightT, typename BidiIterT>
|
||||
inline typename disable_if
|
||||
<
|
||||
proto::is_op<RightT>
|
||||
, proto::binary_op
|
||||
<
|
||||
proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::unary_op<RightT, proto::noop_tag>
|
||||
, proto::bitor_tag
|
||||
>
|
||||
>::type
|
||||
operator |(basic_regex<BidiIterT> const ®ex, RightT const &right)
|
||||
{
|
||||
return proto::noop(regex) | proto::noop(right);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator |
|
||||
template<typename BidiIterT, typename LeftT>
|
||||
inline typename disable_if
|
||||
<
|
||||
proto::is_op<LeftT>
|
||||
, proto::binary_op
|
||||
<
|
||||
proto::unary_op<LeftT, proto::noop_tag>
|
||||
, proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::bitor_tag
|
||||
>
|
||||
>::type
|
||||
operator |(LeftT const &left, basic_regex<BidiIterT> const ®ex)
|
||||
{
|
||||
return proto::noop(left) | proto::noop(regex);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// operator |
|
||||
template<typename BidiIterT>
|
||||
inline proto::binary_op
|
||||
<
|
||||
proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag>
|
||||
, proto::bitor_tag
|
||||
>
|
||||
operator |(basic_regex<BidiIterT> const &left, basic_regex<BidiIterT> const &right)
|
||||
{
|
||||
return proto::noop(left) | proto::noop(right);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
289
include/boost/xpressive/detail/static/static.hpp
Executable file
289
include/boost/xpressive/detail/static/static.hpp
Executable file
@@ -0,0 +1,289 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// static.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_STATIC_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_STATIC_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/core/state.hpp>
|
||||
#include <boost/xpressive/detail/core/linker.hpp>
|
||||
#include <boost/xpressive/detail/core/peeker.hpp>
|
||||
|
||||
// Random thoughts:
|
||||
// set[ a + b - c ]
|
||||
// set[ a ] + set[ b ] - set[ c ]
|
||||
// -set[ a + b + c ] (set negation)
|
||||
// must support indirect repeat counts {$n,$m}
|
||||
// must support logical newline and intelligent negation of logical newline
|
||||
// add ws to eat whitespace (make *_ws illegal)
|
||||
// a{n} -> a[n]
|
||||
// a{n,m} -> a[n][m]
|
||||
// a{n,m}? -> -a[n][m] // yuk, breaks quantifier up.
|
||||
// a{n,m} -> repeat<n,m>(a)
|
||||
// a{$n,$m} -> repeat(n,m)(a)
|
||||
// add nil to match nothing
|
||||
|
||||
//
|
||||
// instead of s1, s2, etc., how about s[1], s[2], etc.? Needlessly verbose?
|
||||
//
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
#ifdef BOOST_XPR_DEBUG_STACK
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// top_type
|
||||
//
|
||||
template<typename TopT>
|
||||
struct top_type
|
||||
{
|
||||
typedef TopT type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// top_type
|
||||
//
|
||||
template<typename TopT, typename NextT>
|
||||
struct top_type<stacked_xpression<TopT, NextT> >
|
||||
{
|
||||
typedef NextT type;
|
||||
};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// stacked_xpression
|
||||
//
|
||||
template<typename TopT, typename NextT>
|
||||
struct stacked_xpression
|
||||
: NextT
|
||||
{
|
||||
// match
|
||||
// delegates to NextT
|
||||
template<typename BidiIterT>
|
||||
bool match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
return this->NextT::BOOST_NESTED_TEMPLATE push_match<TopT>(state);
|
||||
}
|
||||
|
||||
// top_match
|
||||
// jump back to the xpression on top of the xpression stack,
|
||||
// and keep the xpression on the stack.
|
||||
template<typename BidiIterT>
|
||||
static bool top_match(state_type<BidiIterT> &state, xpression_base const *top)
|
||||
{
|
||||
BOOST_XPR_DEBUG_STACK_ASSERT(typeid(*top) == typeid(typename top_type<TopT>::type));
|
||||
return static_cast<TopT const *>(top)->
|
||||
BOOST_NESTED_TEMPLATE push_match<TopT>(state);
|
||||
}
|
||||
|
||||
// pop_match
|
||||
// jump back to the xpression on top of the xpression stack,
|
||||
// pop the xpression off the stack.
|
||||
template<typename BidiIterT>
|
||||
static bool pop_match(state_type<BidiIterT> &state, xpression_base const *top)
|
||||
{
|
||||
BOOST_XPR_DEBUG_STACK_ASSERT(typeid(*top) == typeid(typename top_type<TopT>::type));
|
||||
return static_cast<TopT const *>(top)->match(state);
|
||||
}
|
||||
|
||||
// skip_match
|
||||
// pop the xpression off the top of the stack and ignore it; call
|
||||
// match on next.
|
||||
template<typename BidiIterT>
|
||||
bool skip_match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
// could be static_xpression::skip_impl or stacked_xpression::skip_impl
|
||||
// depending on if there is 1 or more than 1 xpression on the
|
||||
// xpression stack
|
||||
return TopT::skip_impl(*static_cast<NextT const *>(this), state);
|
||||
}
|
||||
|
||||
//protected:
|
||||
|
||||
// skip_impl
|
||||
// implementation of skip_match.
|
||||
template<typename ThatT, typename BidiIterT>
|
||||
static bool skip_impl(ThatT const &that, state_type<BidiIterT> &state)
|
||||
{
|
||||
return that.BOOST_NESTED_TEMPLATE push_match<TopT>(state);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// stacked_xpression_cast
|
||||
//
|
||||
template<typename TopT, typename NextT>
|
||||
inline stacked_xpression<TopT, NextT> const &stacked_xpression_cast(NextT const &next)
|
||||
{
|
||||
// NOTE: this is a little white lie. The "next" object doesn't really have
|
||||
// the type to which we're casting it. It is harmless, though. We are only using
|
||||
// the cast to decorate the next object with type information. It is done
|
||||
// this way to save stack space.
|
||||
BOOST_MPL_ASSERT_RELATION(sizeof(stacked_xpression<TopT, NextT>), ==, sizeof(NextT));
|
||||
return *static_cast<stacked_xpression<TopT, NextT> const *>(&next);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// static_xpression
|
||||
//
|
||||
template<typename MatcherT, typename NextT>
|
||||
struct static_xpression
|
||||
: MatcherT
|
||||
{
|
||||
NextT next_;
|
||||
|
||||
static_xpression(MatcherT const &matcher = MatcherT(), NextT const &next = NextT())
|
||||
: MatcherT(matcher)
|
||||
, next_(next)
|
||||
{
|
||||
}
|
||||
|
||||
// match
|
||||
// delegates to the MatcherT
|
||||
template<typename BidiIterT>
|
||||
bool match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
return this->MatcherT::match(state, this->next_);
|
||||
}
|
||||
|
||||
// push_match
|
||||
// call match on this, but also push "TopT" onto the xpression
|
||||
// stack so we know what we are jumping back to later.
|
||||
template<typename TopT, typename BidiIterT>
|
||||
bool push_match(state_type<BidiIterT> &state) const
|
||||
{
|
||||
return this->MatcherT::match(state, stacked_xpression_cast<TopT>(this->next_));
|
||||
}
|
||||
|
||||
// skip_impl
|
||||
// implementation of skip_match, called from stacked_xpression::skip_match
|
||||
template<typename ThatT, typename BidiIterT>
|
||||
static bool skip_impl(ThatT const &that, state_type<BidiIterT> &state)
|
||||
{
|
||||
return that.match(state);
|
||||
}
|
||||
|
||||
// for linking a compiled regular xpression
|
||||
template<typename CharT>
|
||||
void link(xpression_linker<CharT> &linker) const
|
||||
{
|
||||
linker.link(*static_cast<MatcherT const *>(this), &this->next_);
|
||||
this->next_.link(linker);
|
||||
}
|
||||
|
||||
// for building a lead-follow
|
||||
template<typename CharT>
|
||||
void peek(xpression_peeker<CharT> &peeker) const
|
||||
{
|
||||
this->peek_next_(peeker.peek(*static_cast<MatcherT const *>(this)), peeker);
|
||||
}
|
||||
|
||||
// for getting xpression width
|
||||
template<typename BidiIterT>
|
||||
std::size_t get_width(state_type<BidiIterT> *state) const
|
||||
{
|
||||
// BUGBUG this gets called from the simple_repeat_matcher::match(), so this is slow.
|
||||
// or will the compiler be able to optimize this all away?
|
||||
std::size_t this_width = this->MatcherT::get_width(state);
|
||||
if(this_width == unknown_width())
|
||||
return unknown_width();
|
||||
std::size_t that_width = this->next_.get_width(state);
|
||||
if(that_width == unknown_width())
|
||||
return unknown_width();
|
||||
return this_width + that_width;
|
||||
}
|
||||
|
||||
private: // hide this
|
||||
|
||||
template<typename CharT>
|
||||
void peek_next_(mpl::true_, xpression_peeker<CharT> &peeker) const
|
||||
{
|
||||
this->next_.peek(peeker);
|
||||
}
|
||||
|
||||
template<typename CharT>
|
||||
static void peek_next_(mpl::false_, xpression_peeker<CharT> &)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
using MatcherT::width;
|
||||
using MatcherT::pure;
|
||||
};
|
||||
|
||||
// syntactic sugar so this xpression can be treated the same as
|
||||
// (a smart pointer to) a dynamic xpression from templates
|
||||
template<typename MatcherT, typename NextT>
|
||||
inline static_xpression<MatcherT, NextT> const *
|
||||
get_pointer(static_xpression<MatcherT, NextT> const &xpr)
|
||||
{
|
||||
return &xpr;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// make_static_xpression
|
||||
//
|
||||
template<typename MatcherT>
|
||||
inline static_xpression<MatcherT> const
|
||||
make_static_xpression(MatcherT const &matcher)
|
||||
{
|
||||
return static_xpression<MatcherT>(matcher);
|
||||
}
|
||||
|
||||
template<typename MatcherT, typename NextT>
|
||||
inline static_xpression<MatcherT, NextT> const
|
||||
make_static_xpression(MatcherT const &matcher, NextT const &next)
|
||||
{
|
||||
return static_xpression<MatcherT, NextT>(matcher, next);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// no_next
|
||||
//
|
||||
struct no_next
|
||||
: xpression_base
|
||||
{
|
||||
template<typename CharT>
|
||||
void link(xpression_linker<CharT> &linker) const
|
||||
{
|
||||
}
|
||||
|
||||
template<typename CharT>
|
||||
void peek(xpression_peeker<CharT> &peeker) const
|
||||
{
|
||||
peeker.fail();
|
||||
}
|
||||
|
||||
template<typename BidiIterT>
|
||||
static std::size_t get_width(state_type<BidiIterT> *)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// alternates_list
|
||||
//
|
||||
template<typename AlternatesT>
|
||||
struct alternates_list
|
||||
: AlternatesT
|
||||
{
|
||||
alternates_list(AlternatesT const &alternates)
|
||||
: AlternatesT(alternates)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
91
include/boost/xpressive/detail/static/type_traits.hpp
Executable file
91
include/boost/xpressive/detail/static/type_traits.hpp
Executable file
@@ -0,0 +1,91 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// type_traits.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_TYPE_TRAITS_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_TYPE_TRAITS_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_static_xpression
|
||||
//
|
||||
template<typename T>
|
||||
struct is_static_xpression
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename MatcherT, typename NextT>
|
||||
struct is_static_xpression<static_xpression<MatcherT, NextT> >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename TopT, typename NextT>
|
||||
struct is_static_xpression<stacked_xpression<TopT, NextT> >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_regex
|
||||
//
|
||||
template<typename XprT>
|
||||
struct is_regex
|
||||
: mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct is_regex<basic_regex<BidiIterT> >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct is_regex<reference_wrapper<basic_regex<BidiIterT> > >
|
||||
: mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// is_modifiable
|
||||
//
|
||||
template<typename XprT>
|
||||
struct is_modifiable
|
||||
: mpl::not_<is_regex<XprT> >
|
||||
{
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// is_random
|
||||
//
|
||||
template<typename BidiIterT>
|
||||
struct is_random
|
||||
: is_convertible
|
||||
<
|
||||
typename iterator_category<BidiIterT>::type
|
||||
, std::random_access_iterator_tag
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
267
include/boost/xpressive/detail/static/width_of.hpp
Executable file
267
include/boost/xpressive/detail/static/width_of.hpp
Executable file
@@ -0,0 +1,267 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// width_of.hpp
|
||||
//
|
||||
// Copyright 2004 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_STATIC_WIDTH_OF_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_STATIC_WIDTH_OF_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/plus.hpp>
|
||||
#include <boost/mpl/front.hpp>
|
||||
#include <boost/mpl/times.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/lambda.hpp>
|
||||
#include <boost/mpl/size_t.hpp>
|
||||
#include <boost/mpl/logical.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/transform_view.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
#include <boost/xpressive/detail/static/as_xpr.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// add_width
|
||||
template<typename X, typename Y>
|
||||
struct add_width
|
||||
: mpl::eval_if
|
||||
<
|
||||
mpl::or_
|
||||
<
|
||||
mpl::equal_to<X, unknown_width>
|
||||
, mpl::equal_to<Y, unknown_width>
|
||||
>
|
||||
, mpl::identity<unknown_width>
|
||||
, mpl::plus<X, Y>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// mult_width
|
||||
template<typename X, typename Y>
|
||||
struct mult_width
|
||||
: mpl::eval_if
|
||||
<
|
||||
mpl::or_
|
||||
<
|
||||
mpl::equal_to<X, unknown_width>
|
||||
, mpl::equal_to<Y, unknown_width>
|
||||
>
|
||||
, mpl::identity<unknown_width>
|
||||
, mpl::times<X, Y>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// equal_width
|
||||
template<typename X, typename Y>
|
||||
struct equal_width
|
||||
: mpl::if_
|
||||
<
|
||||
mpl::equal_to<X, Y>
|
||||
, X
|
||||
, unknown_width
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// width_of
|
||||
//
|
||||
template<typename XprT>
|
||||
struct width_of;
|
||||
|
||||
template<>
|
||||
struct width_of<no_next>
|
||||
: mpl::size_t<0>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename MatcherT>
|
||||
struct width_of<proto::unary_op<MatcherT, proto::noop_tag> >
|
||||
: as_matcher_type<MatcherT>::type::width
|
||||
{
|
||||
};
|
||||
|
||||
template<typename LeftT, typename RightT>
|
||||
struct width_of<proto::binary_op<LeftT, RightT, proto::right_shift_tag> >
|
||||
: add_width<width_of<LeftT>, width_of<RightT> >
|
||||
{
|
||||
};
|
||||
|
||||
template<typename LeftT, typename RightT>
|
||||
struct width_of<proto::binary_op<LeftT, RightT, proto::bitor_tag> >
|
||||
: equal_width<width_of<LeftT>, width_of<RightT> >
|
||||
{
|
||||
};
|
||||
|
||||
template<typename RightT>
|
||||
struct width_of<proto::binary_op<mark_tag, RightT, proto::assign_tag> >
|
||||
: width_of<RightT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename RightT>
|
||||
struct width_of<proto::binary_op<set_initializer_type, RightT, proto::assign_tag> >
|
||||
: mpl::size_t<1>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename ModifierT, typename XprT>
|
||||
struct width_of<proto::binary_op<ModifierT, XprT, modifier_tag> >
|
||||
: width_of<XprT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename XprT, bool PositiveT>
|
||||
struct width_of<proto::unary_op<XprT, lookahead_tag<PositiveT> > >
|
||||
: mpl::size_t<0>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename XprT, bool PositiveT>
|
||||
struct width_of<proto::unary_op<XprT, lookbehind_tag<PositiveT> > >
|
||||
: mpl::size_t<0>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename XprT>
|
||||
struct width_of<proto::unary_op<XprT, keeper_tag> >
|
||||
: width_of<XprT>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename MatcherT, typename NextT>
|
||||
struct width_of<static_xpression<MatcherT, NextT> >
|
||||
: add_width<typename MatcherT::width, width_of<NextT> >
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct width_of<shared_ptr<matchable<BidiIterT> const> >
|
||||
: unknown_width
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct width_of<std::vector<shared_ptr<matchable<BidiIterT> const> > >
|
||||
: unknown_width
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct width_of<proto::unary_op<basic_regex<BidiIterT>, proto::noop_tag> >
|
||||
: unknown_width
|
||||
{
|
||||
};
|
||||
|
||||
template<typename BidiIterT>
|
||||
struct width_of<proto::unary_op<reference_wrapper<basic_regex<BidiIterT> const>, proto::noop_tag> >
|
||||
: unknown_width
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT>
|
||||
struct width_of<proto::unary_op<OpT, proto::unary_plus_tag> >
|
||||
: unknown_width
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT>
|
||||
struct width_of<proto::unary_op<OpT, proto::unary_star_tag> >
|
||||
: unknown_width
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT>
|
||||
struct width_of<proto::unary_op<OpT, proto::logical_not_tag> >
|
||||
: unknown_width
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT, uint_t MinT, uint_t MaxT>
|
||||
struct width_of<proto::unary_op<OpT, generic_quant_tag<MinT, MaxT> > >
|
||||
: mpl::if_c<MinT==MaxT, mult_width<width_of<OpT>, mpl::size_t<MinT> >, unknown_width>::type
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT>
|
||||
struct width_of<proto::unary_op<OpT, proto::unary_minus_tag> >
|
||||
: width_of<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
// when complementing a set or an assertion, the width is that of the set (1) or the assertion (0)
|
||||
template<typename OpT>
|
||||
struct width_of<proto::unary_op<OpT, proto::complement_tag> >
|
||||
: width_of<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
// The comma is used in list-initialized sets, and the width of sets are 1
|
||||
template<typename LeftT, typename RightT>
|
||||
struct width_of<proto::binary_op<LeftT, RightT, proto::comma_tag> >
|
||||
: mpl::size_t<1>
|
||||
{
|
||||
};
|
||||
|
||||
// The subscript operator[] is used for sets, as in set['a' | range('b','h')],
|
||||
// or for actions as in (any >> expr)[ action ]
|
||||
template<typename LeftT, typename RightT>
|
||||
struct width_of<proto::binary_op<LeftT, RightT, proto::subscript_tag> >
|
||||
: mpl::if_<is_same<LeftT, set_initializer_type>, mpl::size_t<1>, width_of<LeftT> >::type
|
||||
{
|
||||
// If LeftT is "set" then make sure that RightT has a width_of 1
|
||||
BOOST_MPL_ASSERT
|
||||
((
|
||||
mpl::or_
|
||||
<
|
||||
mpl::not_<is_same<LeftT, set_initializer_type> >
|
||||
, mpl::equal_to<width_of<RightT>, mpl::size_t<1> >
|
||||
>
|
||||
));
|
||||
};
|
||||
|
||||
// The width of a list of alternates is N if all the alternates have width N, otherwise unknown_width
|
||||
template<typename WidthsT>
|
||||
struct alt_width_of
|
||||
: mpl::fold
|
||||
<
|
||||
WidthsT
|
||||
, typename mpl::front<WidthsT>::type
|
||||
, equal_width<mpl::_1, mpl::_2>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template<typename AlternatesT>
|
||||
struct width_of<alternates_list<AlternatesT> >
|
||||
: alt_width_of<mpl::transform_view<AlternatesT, width_of<mpl::_1> > >
|
||||
{
|
||||
};
|
||||
|
||||
template<typename OpT, typename ArgT>
|
||||
struct width_of<proto::op_proxy<OpT, ArgT> >
|
||||
: width_of<OpT>
|
||||
{
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
102
include/boost/xpressive/detail/utility/algorithm.hpp
Executable file
102
include/boost/xpressive/detail/utility/algorithm.hpp
Executable file
@@ -0,0 +1,102 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// algorithm.hpp
|
||||
//
|
||||
// Copyright 2004 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_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_UTILITY_ALGORITHM_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <climits>
|
||||
#include <algorithm>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// any
|
||||
//
|
||||
template<typename InIterT, typename PredT>
|
||||
inline bool any(InIterT begin, InIterT end, PredT pred)
|
||||
{
|
||||
return end != std::find_if(begin, end, pred);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// find_nth_if
|
||||
//
|
||||
template<typename FwdIterT, typename DiffT, typename PredT>
|
||||
FwdIterT find_nth_if(FwdIterT begin, FwdIterT end, DiffT count, PredT pred)
|
||||
{
|
||||
for(; begin != end; ++begin)
|
||||
{
|
||||
if(pred(*begin) && 0 == count--)
|
||||
{
|
||||
return begin;
|
||||
}
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// toi
|
||||
//
|
||||
template<typename InIterT, typename TraitsT>
|
||||
int toi(InIterT &begin, InIterT end, TraitsT const &traits, int radix = 10, int max = INT_MAX)
|
||||
{
|
||||
int i = 0, c = 0;
|
||||
for(; begin != end && -1 != (c = traits.value(*begin, radix)); ++begin)
|
||||
{
|
||||
if(max < ((i *= radix) += c))
|
||||
return i / radix;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// advance_to
|
||||
//
|
||||
template<typename BidiIterT, typename DiffT>
|
||||
inline bool advance_to_impl(BidiIterT & iter, DiffT diff, BidiIterT end, std::bidirectional_iterator_tag)
|
||||
{
|
||||
for(; 0 < diff && iter != end; --diff)
|
||||
++iter;
|
||||
for(; 0 > diff && iter != end; ++diff)
|
||||
--iter;
|
||||
return 0 == diff;
|
||||
}
|
||||
|
||||
template<typename RandIterT, typename DiffT>
|
||||
inline bool advance_to_impl(RandIterT & iter, DiffT diff, RandIterT end, std::random_access_iterator_tag)
|
||||
{
|
||||
if(0 < diff)
|
||||
{
|
||||
if((end - iter) < diff)
|
||||
return false;
|
||||
}
|
||||
else if(0 > diff)
|
||||
{
|
||||
if((iter - end) < -diff)
|
||||
return false;
|
||||
}
|
||||
iter += diff;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IterT, typename DiffT>
|
||||
inline bool advance_to(IterT & iter, DiffT diff, IterT end)
|
||||
{
|
||||
return detail::advance_to_impl(iter, diff, end, typename iterator_category<IterT>::type());
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
204
include/boost/xpressive/detail/utility/boyer_moore.hpp
Executable file
204
include/boost/xpressive/detail/utility/boyer_moore.hpp
Executable file
@@ -0,0 +1,204 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// \file boyer_moore.hpp
|
||||
/// Contains the boyer-moore implementation. Note: this is *not* a general-
|
||||
/// purpose boyer-moore implementation. It truncates the search string at
|
||||
/// 256 characters, but it is sufficient for the needs of xpressive.
|
||||
//
|
||||
// Copyright 2004 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_BOYER_MOORE_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_DETAIL_BOYER_MOORE_HPP_EAN_10_04_2005
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <climits> // for UCHAR_MAX
|
||||
#include <cstddef> // for std::ptrdiff_t
|
||||
#include <utility> // for std::max
|
||||
#include <vector>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/xpressive/detail/detail_fwd.hpp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//// case_fold
|
||||
//template<typename TraitsT>
|
||||
//struct case_fold
|
||||
// : is_convertible<
|
||||
// typename TraitsT::version_tag *
|
||||
// , regex_traits_version_1_case_fold_tag *
|
||||
// >
|
||||
//{
|
||||
//};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// boyer_moore
|
||||
//
|
||||
template<typename BidiIterT, typename TraitsT> //, bool CaseFoldT = case_fold<TraitsT>::value>
|
||||
struct boyer_moore
|
||||
{
|
||||
typedef typename iterator_value<BidiIterT>::type char_type;
|
||||
typedef TraitsT traits_type;
|
||||
typedef is_convertible<
|
||||
typename TraitsT::version_tag *
|
||||
, regex_traits_version_1_case_fold_tag *
|
||||
> case_fold;
|
||||
typedef typename TraitsT::string_type string_type;
|
||||
|
||||
// initialize the Boyer-Moore search data structure, using the
|
||||
// search sub-sequence to prime the pump.
|
||||
boyer_moore(char_type const *begin, char_type const *end, TraitsT const &traits, bool icase)
|
||||
: begin_(begin)
|
||||
, last_(begin)
|
||||
, fold_()
|
||||
, find_fun_(
|
||||
icase
|
||||
? (case_fold() ? &boyer_moore::find_nocase_fold_ : &boyer_moore::find_nocase_)
|
||||
: &boyer_moore::find_
|
||||
)
|
||||
{
|
||||
std::ptrdiff_t const uchar_max = UCHAR_MAX;
|
||||
std::ptrdiff_t diff = std::distance(begin, end);
|
||||
this->length_ = static_cast<unsigned char>((std::min)(diff, uchar_max));
|
||||
std::fill_n(this->offsets_, uchar_max + 1, this->length_);
|
||||
--this->length_;
|
||||
|
||||
icase ? this->init_(traits, case_fold()) : this->init_(traits, mpl::false_());
|
||||
}
|
||||
|
||||
BidiIterT find(BidiIterT begin, BidiIterT end, TraitsT const &traits) const
|
||||
{
|
||||
return (this->*this->find_fun_)(begin, end, traits);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init_(TraitsT const &traits, mpl::false_)
|
||||
{
|
||||
for(unsigned char offset = this->length_; offset; --offset, ++this->last_)
|
||||
{
|
||||
this->offsets_[traits.hash(*this->last_)] = offset;
|
||||
}
|
||||
}
|
||||
|
||||
void init_(TraitsT const &traits, mpl::true_)
|
||||
{
|
||||
this->fold_.reserve(this->length_ + 1);
|
||||
for(unsigned char offset = this->length_; offset; --offset, ++this->last_)
|
||||
{
|
||||
this->fold_.push_back(traits.fold_case(*this->last_));
|
||||
for(typename string_type::const_iterator beg = this->fold_.back().begin(), end = this->fold_.back().end();
|
||||
beg != end; ++beg)
|
||||
{
|
||||
this->offsets_[traits.hash(*beg)] = offset;
|
||||
}
|
||||
}
|
||||
this->fold_.push_back(traits.fold_case(*this->last_));
|
||||
}
|
||||
|
||||
// case-sensitive Boyer-Moore search
|
||||
BidiIterT find_(BidiIterT begin, BidiIterT end, TraitsT const &traits) const
|
||||
{
|
||||
typedef typename boost::iterator_difference<BidiIterT>::type diff_type;
|
||||
diff_type const endpos = std::distance(begin, end);
|
||||
diff_type offset = static_cast<diff_type>(this->length_);
|
||||
|
||||
for(diff_type curpos = offset; curpos < endpos; curpos += offset)
|
||||
{
|
||||
std::advance(begin, offset);
|
||||
|
||||
char_type const *pat_tmp = this->last_;
|
||||
BidiIterT str_tmp = begin;
|
||||
|
||||
for(; traits.translate(*str_tmp) == *pat_tmp; --pat_tmp, --str_tmp)
|
||||
{
|
||||
if(pat_tmp == this->begin_)
|
||||
{
|
||||
return str_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
offset = this->offsets_[traits.hash(traits.translate(*begin))];
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
// case-insensitive Boyer-Moore search
|
||||
BidiIterT find_nocase_(BidiIterT begin, BidiIterT end, TraitsT const &traits) const
|
||||
{
|
||||
typedef typename boost::iterator_difference<BidiIterT>::type diff_type;
|
||||
diff_type const endpos = std::distance(begin, end);
|
||||
diff_type offset = static_cast<diff_type>(this->length_);
|
||||
|
||||
for(diff_type curpos = offset; curpos < endpos; curpos += offset)
|
||||
{
|
||||
std::advance(begin, offset);
|
||||
|
||||
char_type const *pat_tmp = this->last_;
|
||||
BidiIterT str_tmp = begin;
|
||||
|
||||
for(; traits.translate_nocase(*str_tmp) == *pat_tmp; --pat_tmp, --str_tmp)
|
||||
{
|
||||
if(pat_tmp == this->begin_)
|
||||
{
|
||||
return str_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
offset = this->offsets_[traits.hash(traits.translate_nocase(*begin))];
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
// case-insensitive Boyer-Moore search with case-folding
|
||||
BidiIterT find_nocase_fold_(BidiIterT begin, BidiIterT end, TraitsT const &traits) const
|
||||
{
|
||||
typedef typename boost::iterator_difference<BidiIterT>::type diff_type;
|
||||
diff_type const endpos = std::distance(begin, end);
|
||||
diff_type offset = static_cast<diff_type>(this->length_);
|
||||
|
||||
for(diff_type curpos = offset; curpos < endpos; curpos += offset)
|
||||
{
|
||||
std::advance(begin, offset);
|
||||
|
||||
string_type const *pat_tmp = &this->fold_.back();
|
||||
BidiIterT str_tmp = begin;
|
||||
|
||||
for(; pat_tmp->end() != std::find(pat_tmp->begin(), pat_tmp->end(), *str_tmp);
|
||||
--pat_tmp, --str_tmp)
|
||||
{
|
||||
if(pat_tmp == &this->fold_.front())
|
||||
{
|
||||
return str_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
offset = this->offsets_[traits.hash(*begin)];
|
||||
}
|
||||
|
||||
return end;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
char_type const *begin_;
|
||||
char_type const *last_;
|
||||
std::vector<string_type> fold_;
|
||||
BidiIterT (boyer_moore::*const find_fun_)(BidiIterT, BidiIterT, TraitsT const &) const;
|
||||
unsigned char length_;
|
||||
unsigned char offsets_[UCHAR_MAX + 1];
|
||||
};
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
150
include/boost/xpressive/detail/utility/chset/basic_chset.hpp
Executable file
150
include/boost/xpressive/detail/utility/chset/basic_chset.hpp
Executable file
@@ -0,0 +1,150 @@
|
||||
/*=============================================================================
|
||||
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_XPRESSIVE_SPIRIT_BASIC_CHSET_HPP_EAN_10_04_2005
|
||||
#define BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_HPP_EAN_10_04_2005
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <bitset>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/xpressive/detail/utility/chset/range_run.ipp>
|
||||
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: basic character set implementation using range_run
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename CharT>
|
||||
struct basic_chset
|
||||
{
|
||||
basic_chset();
|
||||
basic_chset(basic_chset const &arg);
|
||||
|
||||
bool empty() const;
|
||||
void set(CharT from, CharT to);
|
||||
template<typename TraitsT>
|
||||
void set(CharT from, CharT to, TraitsT const &traits);
|
||||
void set(CharT c);
|
||||
template<typename TraitsT>
|
||||
void set(CharT c, TraitsT const &traits);
|
||||
|
||||
void clear(CharT from, CharT to);
|
||||
template<typename TraitsT>
|
||||
void clear(CharT from, CharT to, TraitsT const &traits);
|
||||
void clear(CharT c);
|
||||
template<typename TraitsT>
|
||||
void clear(CharT c, TraitsT const &traits);
|
||||
void clear();
|
||||
|
||||
template<typename TraitsT>
|
||||
bool test(CharT v, TraitsT const &traits, mpl::false_) const; // case-sensitive
|
||||
template<typename TraitsT>
|
||||
bool test(CharT v, TraitsT const &traits, mpl::true_) const; // case-insensitive
|
||||
|
||||
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:
|
||||
range_run<CharT> rr_;
|
||||
};
|
||||
|
||||
#if(CHAR_BIT == 8)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// basic_chset: specializations for 8 bit chars using std::bitset
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
template<typename CharT>
|
||||
struct basic_chset_8bit
|
||||
{
|
||||
basic_chset_8bit();
|
||||
basic_chset_8bit(basic_chset_8bit const &arg);
|
||||
|
||||
bool empty() const;
|
||||
|
||||
void set(CharT from, CharT to);
|
||||
template<typename TraitsT>
|
||||
void set(CharT from, CharT to, TraitsT const &traits);
|
||||
void set(CharT c);
|
||||
template<typename TraitsT>
|
||||
void set(CharT c, TraitsT const &traits);
|
||||
|
||||
void clear(CharT from, CharT to);
|
||||
template<typename TraitsT>
|
||||
void clear(CharT from, CharT to, TraitsT const &traits);
|
||||
void clear(CharT c);
|
||||
template<typename TraitsT>
|
||||
void clear(CharT c, TraitsT const &traits);
|
||||
void clear();
|
||||
|
||||
template<typename TraitsT>
|
||||
bool test(CharT v, TraitsT const &traits, mpl::false_) const; // case-sensitive
|
||||
template<typename TraitsT>
|
||||
bool test(CharT v, TraitsT const &traits, mpl::true_) const; // case-insensitive
|
||||
|
||||
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);
|
||||
|
||||
std::bitset<256> const &base() const;
|
||||
|
||||
private:
|
||||
std::bitset<256> bset_; // BUGBUG range-checking slows this down
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
template<>
|
||||
struct basic_chset<char>
|
||||
: basic_chset_8bit<char>
|
||||
{
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
template<>
|
||||
struct basic_chset<signed char>
|
||||
: basic_chset_8bit<signed char>
|
||||
{
|
||||
};
|
||||
|
||||
/////////////////////////////////
|
||||
template<>
|
||||
struct basic_chset<unsigned char>
|
||||
: basic_chset_8bit<unsigned char>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// helpers
|
||||
template<typename CharT, typename TraitsT>
|
||||
void set_char(basic_chset<CharT> &chset, CharT ch, TraitsT const &traits, bool icase);
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
void set_range(basic_chset<CharT> &chset, CharT from, CharT to, TraitsT const &traits, bool icase);
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
void set_class(basic_chset<CharT> &chset, typename TraitsT::char_class_type char_class, bool no, TraitsT const &traits, bool icase);
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
409
include/boost/xpressive/detail/utility/chset/basic_chset.ipp
Executable file
409
include/boost/xpressive/detail/utility/chset/basic_chset.ipp
Executable file
@@ -0,0 +1,409 @@
|
||||
/*=============================================================================
|
||||
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_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
|
||||
#define BOOST_XPRESSIVE_SPIRIT_BASIC_CHSET_IPP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <bitset>
|
||||
#include <boost/xpressive/detail/utility/chset/basic_chset.hpp>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
namespace boost { namespace xpressive { namespace detail
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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>::empty() const
|
||||
{
|
||||
return this->rr_.empty();
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline bool basic_chset<CharT>::test(CharT v, TraitsT const &, mpl::false_) const // case-sensitive
|
||||
{
|
||||
return this->rr_.test(v);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline bool basic_chset<CharT>::test(CharT v, TraitsT const &traits, mpl::true_) const // case-insensitive
|
||||
{
|
||||
return this->rr_.test(v, traits);
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset<CharT>::set(CharT from, CharT to)
|
||||
{
|
||||
this->rr_.set(range<CharT>(from, to));
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline void basic_chset<CharT>::set(CharT from, CharT to, TraitsT const &)
|
||||
{
|
||||
this->rr_.set(range<CharT>(from, to));
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset<CharT>::set(CharT c)
|
||||
{
|
||||
this->rr_.set(range<CharT>(c, c));
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline void basic_chset<CharT>::set(CharT c, TraitsT const &)
|
||||
{
|
||||
this->rr_.set(range<CharT>(c, c));
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset<CharT>::clear(CharT c)
|
||||
{
|
||||
this->rr_.clear(range<CharT>(c, c));
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline void basic_chset<CharT>::clear(CharT c, TraitsT const &)
|
||||
{
|
||||
this->rr_.clear(range<CharT>(c, c));
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset<CharT>::clear(CharT from, CharT to)
|
||||
{
|
||||
this->rr_.clear(range<CharT>(from, to));
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline void basic_chset<CharT>::clear(CharT from, CharT to, TraitsT const &)
|
||||
{
|
||||
this->rr_.clear(range<CharT>(from, to));
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset<CharT>::clear()
|
||||
{
|
||||
this->rr_.clear();
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset<CharT>::inverse()
|
||||
{
|
||||
// BUGBUG is this right? Does this handle icase correctly?
|
||||
basic_chset<CharT> inv;
|
||||
inv.set((std::numeric_limits<CharT>::min)(), (std::numeric_limits<CharT>::max)());
|
||||
inv -= *this;
|
||||
this->swap(inv);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset<CharT>::swap(basic_chset<CharT> &that)
|
||||
{
|
||||
this->rr_.swap(that.rr_);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline basic_chset<CharT> &
|
||||
basic_chset<CharT>::operator |=(basic_chset<CharT> const &that)
|
||||
{
|
||||
typedef typename range_run<CharT>::const_iterator const_iterator;
|
||||
for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
|
||||
{
|
||||
this->rr_.set(*iter);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline basic_chset<CharT> &
|
||||
basic_chset<CharT>::operator &=(basic_chset<CharT> const &that)
|
||||
{
|
||||
basic_chset<CharT> inv;
|
||||
inv.set((std::numeric_limits<CharT>::min)(), (std::numeric_limits<CharT>::max)());
|
||||
inv -= that;
|
||||
*this -= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline basic_chset<CharT> &
|
||||
basic_chset<CharT>::operator -=(basic_chset<CharT> const &that)
|
||||
{
|
||||
typedef typename range_run<CharT>::const_iterator const_iterator;
|
||||
for(const_iterator iter = that.rr_.begin(); iter != that.rr_.end(); ++iter)
|
||||
{
|
||||
this->rr_.clear(*iter);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline basic_chset<CharT> &
|
||||
basic_chset<CharT>::operator ^=(basic_chset<CharT> const &that)
|
||||
{
|
||||
basic_chset bma = that;
|
||||
bma -= *this;
|
||||
*this -= that;
|
||||
*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<CharT> const &arg)
|
||||
: bset_(arg.bset_)
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline bool basic_chset_8bit<CharT>::empty() const
|
||||
{
|
||||
return !this->bset_.any();
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline bool basic_chset_8bit<CharT>::test(CharT v, TraitsT const &, mpl::false_) const // case-sensitive
|
||||
{
|
||||
return this->bset_.test((unsigned char)v);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline bool basic_chset_8bit<CharT>::test(CharT v, TraitsT const &traits, mpl::true_) const // case-insensitive
|
||||
{
|
||||
return this->bset_.test((unsigned char)traits.translate_nocase(v));
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset_8bit<CharT>::set(CharT from, CharT to)
|
||||
{
|
||||
for(int i = from; i <= to; ++i)
|
||||
{
|
||||
this->bset_.set((unsigned char)i);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline void basic_chset_8bit<CharT>::set(CharT from, CharT to, TraitsT const &traits)
|
||||
{
|
||||
for(int i = from; i <= to; ++i)
|
||||
{
|
||||
this->bset_.set((unsigned char)traits.translate_nocase((CharT)i));
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset_8bit<CharT>::set(CharT c)
|
||||
{
|
||||
this->bset_.set((unsigned char)c);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline void basic_chset_8bit<CharT>::set(CharT c, TraitsT const &traits)
|
||||
{
|
||||
this->bset_.set((unsigned char)traits.translate_nocase(c));
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset_8bit<CharT>::clear(CharT from, CharT to)
|
||||
{
|
||||
for(int i = from; i <= to; ++i)
|
||||
{
|
||||
this->bset_.reset((unsigned char)i);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline void basic_chset_8bit<CharT>::clear(CharT from, CharT to, TraitsT const &traits)
|
||||
{
|
||||
for(int i = from; i <= to; ++i)
|
||||
{
|
||||
this->bset_.reset((unsigned char)traits.translate_nocase((CharT)i));
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset_8bit<CharT>::clear(CharT c)
|
||||
{
|
||||
this->bset_.reset((unsigned char)c);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
template<typename TraitsT>
|
||||
inline void basic_chset_8bit<CharT>::clear(CharT c, TraitsT const &traits)
|
||||
{
|
||||
this->bset_.reset((unsigned char)traits.tranlsate_nocase(c));
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset_8bit<CharT>::clear()
|
||||
{
|
||||
this->bset_.reset();
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset_8bit<CharT>::inverse()
|
||||
{
|
||||
this->bset_.flip();
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline void basic_chset_8bit<CharT>::swap(basic_chset_8bit<CharT> &that)
|
||||
{
|
||||
std::swap(this->bset_, that.bset_);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline basic_chset_8bit<CharT> &
|
||||
basic_chset_8bit<CharT>::operator |=(basic_chset_8bit<CharT> const &that)
|
||||
{
|
||||
this->bset_ |= that.bset_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline basic_chset_8bit<CharT> &
|
||||
basic_chset_8bit<CharT>::operator &=(basic_chset_8bit<CharT> const &that)
|
||||
{
|
||||
this->bset_ &= that.bset_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline basic_chset_8bit<CharT> &
|
||||
basic_chset_8bit<CharT>::operator -=(basic_chset_8bit<CharT> const &that)
|
||||
{
|
||||
this->bset_ &= ~that.bset_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
template<typename CharT>
|
||||
inline basic_chset_8bit<CharT> &
|
||||
basic_chset_8bit<CharT>::operator ^=(basic_chset_8bit<CharT> const &that)
|
||||
{
|
||||
this->bset_ ^= that.bset_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename CharT>
|
||||
inline std::bitset<256> const &
|
||||
basic_chset_8bit<CharT>::base() const
|
||||
{
|
||||
return this->bset_;
|
||||
}
|
||||
|
||||
#endif // if(CHAR_BIT == 8)
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// helpers
|
||||
template<typename CharT, typename TraitsT>
|
||||
inline void set_char(basic_chset<CharT> &chset, CharT ch, TraitsT const &traits, bool icase)
|
||||
{
|
||||
icase ? chset.set(ch, traits) : chset.set(ch);
|
||||
}
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
inline void set_range(basic_chset<CharT> &chset, CharT from, CharT to, TraitsT const &traits, bool icase)
|
||||
{
|
||||
icase ? chset.set(from, to, traits) : chset.set(from, to);
|
||||
}
|
||||
|
||||
template<typename CharT, typename TraitsT>
|
||||
inline void set_class(basic_chset<CharT> &chset, typename TraitsT::char_class_type char_class, bool no, TraitsT const &traits, bool icase)
|
||||
{
|
||||
BOOST_MPL_ASSERT_RELATION(1, ==, sizeof(CharT));
|
||||
for(std::size_t i = 0; i <= UCHAR_MAX; ++i)
|
||||
{
|
||||
typedef typename std::char_traits<CharT>::int_type int_type;
|
||||
CharT ch = std::char_traits<CharT>::to_char_type(static_cast<int_type>(i));
|
||||
if(no != traits.isctype(ch, char_class))
|
||||
{
|
||||
chset.set(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace boost::xpressive::detail
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user