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 + -
显示快捷键?