regex_compile.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 1,825 行 · 第 1/5 页
HPP
1,825 行
/* * * 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_HPPnamespace boost{#ifdef BOOST_HAS_ABI_HEADERS# include BOOST_ABI_PREFIX#endif#ifdef __BORLANDC__#pragma option push -w-8004#endifnamespace 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_detailtemplate <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: c = '\v'; ++arg_first; break; case traits_type::syntax_x: ++arg_first; if(arg_first == arg_last) { fail(REG_EESCAPE);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?