regex_compile.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 1,861 行 · 第 1/5 页

HPP
1,861
字号
/* * * 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 __BORLANDC__   #pragma option push -a8 -b -Vx -Ve -pc  -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() & regbase::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 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((traits_size_type)(traits_uchar_type)c >= 256)      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 | regbase::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 | regbase::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 | regbase::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() | regbase::use_except);   }   else   {      _flags = e.flags() & ~(regbase::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() | regbase::use_except);   return *this;}template <class charT, class traits, class Allocator>inline bool BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::operator==(const reg_expression<charT, traits, Allocator>& e)const{   return (_flags == e.flags())           && (_expression_len == e._expression_len)           && (std::memcmp(_expression, e._expression, _expression_len * sizeof(charT)) == 0);}template <class charT, class traits, class Allocator>bool BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::operator<(const reg_expression<charT, traits, Allocator>& e)const{   //   // we can't offer a diffinitive ordering, but we can be consistant:   if(_flags != e.flags()) return _flags < e.flags();   if(_expression_len != e._expression_len) return _expression_len < e._expression_len;   return std::memcmp(expression(), e.expression(), _expression_len);}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*& first, const charT* last){   //   // we have an inner [...] construct   //   jm_assert(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*first) == traits_type::syntax_open_set);   const charT* base = first;   while( (first != last)      && (traits_inst.syntax_type((traits_size_type)(traits_uchar_type)*first) != traits_type::syntax_close_set) )         ++first;   if(first == last)      return 0;   ++first;   if((first-base) < 5)      return 0;   if(*(base+1) != *(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) && ((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*& first, const charT* last){   //   // returns true if we get to last:   //   while((first != last) && (traits_inst.is_class(*first, traits_type::char_class_space) == true))   {      ++first;   }   return first == last;}template <class charT, class traits, class Allocator>void BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::parse_range(const charT*& ptr, const charT* 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, 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, end, 10);   if(skip_space(ptr, 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, 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, end, 10);      else         max = (unsigned)-1;   }   else      max = min;   // validate input:   if(skip_space(ptr, 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 == 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*& first, const charT* last){   charT c(*first);   traits_size_type c_unsigned = (traits_size_type)(traits_uchar_type)*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';      ++first;      break;   case traits_type::syntax_f:      c = '\f';      ++first;      break;   case traits_type::syntax_n:      c = '\n';      ++first;      break;   case traits_type::syntax_r:      c = '\r';      ++first;      break;   case traits_type::syntax_t:      c = '\t';      ++first;      break;   case traits_type::syntax_v:      c = '\v';      ++first;      break;   case traits_type::syntax_x:      ++first;      if(first == last)      {         fail(REG_EESCAPE);         break;      }      // maybe have \x{ddd}      if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*first)) == traits_type::syntax_open_brace)      {         ++first;         if(first == last)         {            fail(REG_EESCAPE);            break;         }         if(traits_inst.is_class(*first, traits_type::char_class_xdigit) == false)         {            fail(REG_BADBR);            break;         }         c = (charT)traits_inst.toi(first, last, -16);         if((first == last) || (traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*first)) != traits_type::syntax_close_brace))         {            fail(REG_BADBR);         }         ++first;         break;      }      else      {         if(traits_inst.is_class(*first, traits_type::char_class_xdigit) == false)         {            fail(REG_BADBR);            break;         }         c = (charT)traits_inst.toi(first, last, -16);      }      break;   case traits_type::syntax_c:      ++first;      if(first == last)      {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?