📄 regex_compile.hpp
字号:
/*
*
* Copyright (c) 1998-2002
* Dr John Maddock
*
* Use, modification and distribution are 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)
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_compile.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares reg_expression<> member functions. This is
* an internal header file, do not include directly.
*/
#ifndef BOOST_REGEX_COMPILE_HPP
#define BOOST_REGEX_COMPILE_HPP
namespace boost{
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
#ifdef __BORLANDC__
#pragma option push -w-8004
#endif
namespace re_detail{
template <class traits>
struct kmp_translator
{
typedef typename traits::char_type char_type;
bool icase;
const traits* pt;
kmp_translator(bool c, traits* p) : icase(c), pt(p) {}
char_type operator()(char_type c)
{
return pt->translate(c, icase);
}
};
template <class charT, class traits_type, class Allocator>
bool BOOST_REGEX_CALL re_maybe_set_member(charT c,
const re_set_long* set_,
const reg_expression<charT, traits_type, Allocator>& e)
{
const charT* p = reinterpret_cast<const charT*>(set_+1);
bool icase = e.flags() & regex_constants::icase;
charT col = e.get_traits().translate(c, icase);
for(unsigned int i = 0; i < set_->csingles; ++i)
{
if(col == *p)
return set_->isnot ? false : true;
while(*p)++p;
++p; // skip null
}
return set_->isnot ? true : false;
}
} // namespace re_detail
template <class traits>
struct is_big_char
{
typedef typename traits::uchar_type traits_uchar_type;
typedef typename traits::size_type traits_size_type;
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
static bool test(char)
{ return false; }
static bool test(unsigned char)
{ return false; }
static bool test(signed char)
{ return false; }
#endif
template <class charT> static bool test(charT c)
{ return (traits_size_type)(traits_uchar_type)c >= 256; }
};
template <class charT, class traits, class Allocator>
inline bool BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::can_start(charT c, const unsigned char* _map, unsigned char mask, const re_detail::_wide_type&)
{
if(is_big_char<traits>::test(c))
return true;
return BOOST_REGEX_MAKE_BOOL(_map[(traits_uchar_type)c] & mask);
}
template <class charT, class traits, class Allocator>
inline bool BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::can_start(charT c, const unsigned char* _map, unsigned char mask, const re_detail::_narrow_type&)
{
return BOOST_REGEX_MAKE_BOOL(_map[(traits_uchar_type)c] & mask);
}
template <class charT, class traits, class Allocator>
reg_expression<charT, traits, Allocator>::reg_expression(const Allocator& a)
: regbase(), data(a), pkmp(0), error_code_(REG_EMPTY), _expression(0)
{
}
template <class charT, class traits, class Allocator>
reg_expression<charT, traits, Allocator>::reg_expression(const charT* p, flag_type f, const Allocator& a)
: data(a), pkmp(0), error_code_(REG_EMPTY), _expression(0)
{
set_expression(p, f | regex_constants::use_except);
}
template <class charT, class traits, class Allocator>
reg_expression<charT, traits, Allocator>::reg_expression(const charT* p1, const charT* p2, flag_type f, const Allocator& a)
: data(a), pkmp(0), error_code_(REG_EMPTY), _expression(0)
{
set_expression(p1, p2, f | regex_constants::use_except);
}
template <class charT, class traits, class Allocator>
reg_expression<charT, traits, Allocator>::reg_expression(const charT* p, size_type len, flag_type f, const Allocator& a)
: data(a), pkmp(0), error_code_(REG_EMPTY), _expression(0)
{
set_expression(p, p + len, f | regex_constants::use_except);
}
template <class charT, class traits, class Allocator>
reg_expression<charT, traits, Allocator>::reg_expression(const reg_expression<charT, traits, Allocator>& e)
: regbase(e), data(e.allocator()), pkmp(0), error_code_(REG_EMPTY), _expression(0)
{
//
// we do a deep copy only if e is a valid expression, otherwise fail.
//
if(e.error_code() == 0)
{
const charT* pe = e.expression();
set_expression(pe, pe + e._expression_len, e.flags() | regex_constants::use_except);
}
else
{
_flags = e.flags() & ~(regex_constants::use_except);
fail(e.error_code());
}
}
template <class charT, class traits, class Allocator>
reg_expression<charT, traits, Allocator>::~reg_expression()
{
if(pkmp)
re_detail::kmp_free(pkmp, data.allocator());
}
template <class charT, class traits, class Allocator>
reg_expression<charT, traits, Allocator>& BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::operator=(const reg_expression<charT, traits, Allocator>& e)
{
//
// we do a deep copy only if e is a valid expression, otherwise fail.
//
if(this == &e) return *this;
_flags = use_except;
fail(e.error_code());
if(error_code() == 0)
set_expression(e._expression, e._expression + e._expression_len, e.flags() | regex_constants::use_except);
return *this;
}
template <class charT, class traits, class Allocator>
int BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::compare(const reg_expression<charT, traits, Allocator>& e)const
{
if(_flags != e.flags())
return _flags - e.flags();
return str().compare(e.str());
}
template <class charT, class traits, class Allocator>
void BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::swap(reg_expression& that)throw()
{
traits_inst.swap(that.traits_inst);
data.swap(that.data);
static_cast<regbase&>(*this).swap(that);
std::swap(_restart_type, that._restart_type);
std::swap(marks, that.marks);
std::swap(repeats, that.repeats);
std::swap(startmap, that.startmap);
std::swap(_expression_len, that._expression_len);
std::swap(_leading_len, that._leading_len);
std::swap(_leading_string, that._leading_string);
std::swap(_leading_string_len, that._leading_string_len);
std::swap(pkmp, that.pkmp);
std::swap(error_code_, that.error_code_);
std::swap(_expression, that._expression);
}
template <class charT, class traits, class Allocator>
Allocator BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::allocator()const
{
return data.allocator();
}
template <class charT, class traits, class Allocator>
Allocator BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::get_allocator()const
{
return data.allocator();
}
template <class charT, class traits, class Allocator>
unsigned int BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::parse_inner_set(const charT*& arg_first, const charT* arg_last)
{
//
// we have an inner [...] construct
//
jm_assert(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*arg_first) == traits_type::syntax_open_set);
const charT* base = arg_first;
while( (arg_first != arg_last)
&& (traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*arg_first) != traits_type::syntax_close_set) )
++arg_first;
if(arg_first == arg_last)
return 0;
++arg_first;
if((arg_first-base) < 5)
return 0;
if(*(base+1) != *(arg_first-2))
return 0;
unsigned int result = traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*(base+1));
if((result == traits_type::syntax_colon) && ((arg_first-base) == 5))
{
unsigned type = traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*(base+2));
if((type == traits_type::syntax_left_word) || (type == traits_type::syntax_right_word))
return type;
}
return ((result == traits_type::syntax_colon) || (result == traits_type::syntax_dot) || (result == traits_type::syntax_equal)) ? result : 0;
}
template <class charT, class traits, class Allocator>
bool BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::skip_space(const charT*& arg_first, const charT* arg_last)
{
//
// returns true if we get to arg_last:
//
while((arg_first != arg_last) && (traits_inst.is_class(*arg_first, traits_type::char_class_space) == true))
{
++arg_first;
}
return arg_first == arg_last;
}
template <class charT, class traits, class Allocator>
void BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::parse_range(const charT*& ptr, const charT* arg_end, unsigned& min, unsigned& max)
{
//
// we have {x} or {x,} or {x,y} NB no spaces inside braces
// anything else is illegal
// On input ptr points to "{"
//
++ptr;
if(skip_space(ptr, arg_end))
{
fail(REG_EBRACE);
return;
}
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*ptr) != traits_type::syntax_digit)
{
fail(REG_BADBR);
return;
}
min = traits_inst.toi(ptr, arg_end, 10);
if(skip_space(ptr, arg_end))
{
fail(REG_EBRACE);
return;
}
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*ptr) == traits_type::syntax_comma)
{
//we have a second interval:
++ptr;
if(skip_space(ptr, arg_end))
{
fail(REG_EBRACE);
return;
}
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*ptr) == traits_type::syntax_digit)
max = traits_inst.toi(ptr, arg_end, 10);
else
max = (unsigned)-1;
}
else
max = min;
// validate input:
if(skip_space(ptr, arg_end))
{
fail(REG_EBRACE);
return;
}
if(max < min)
{
fail(REG_ERANGE);
return;
}
if(_flags & bk_braces)
{
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*ptr) != traits_type::syntax_slash)
{
fail(REG_BADBR);
return;
}
else
{
// back\ is OK now check the }
++ptr;
if((ptr == arg_end) || (traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*ptr) != traits_type::syntax_close_brace))
{
fail(REG_BADBR);
return;
}
}
}
else if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*ptr) != traits_type::syntax_close_brace)
{
fail(REG_BADBR);
return;
}
}
template <class charT, class traits, class Allocator>
charT BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::parse_escape(const charT*& arg_first, const charT* arg_last)
{
charT c(*arg_first);
traits_size_type c_unsigned = (traits_size_type)(traits_uchar_type)*arg_first;
// this is only used for the switch(), but cannot be folded in
// due to a bug in Comeau 4.2.44beta3
traits_size_type syntax = traits_inst.syntax_type(c_unsigned);
switch(syntax)
{
case traits_type::syntax_a:
c = '\a';
++arg_first;
break;
case traits_type::syntax_f:
c = '\f';
++arg_first;
break;
case traits_type::syntax_n:
c = '\n';
++arg_first;
break;
case traits_type::syntax_r:
c = '\r';
++arg_first;
break;
case traits_type::syntax_t:
c = '\t';
++arg_first;
break;
case traits_type::syntax_v:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -