perl_matcher_non_recursive.hpp

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

HPP
1,303
字号
   // If we've had at least one repeat already, and the last one    // matched the NULL string then set the repeat count to   // maximum:   //   next_count->check_null_repeat(position, rep->max);   if(next_count->get_count() < rep->min)   {      // we must take the repeat:      if(take_first)      {         // increase the counter:         ++(*next_count);         pstate = rep->next.p;         return true;      }      return false;   }   if(rep->greedy)   {      // try and take the repeat if we can:      if((next_count->get_count() < rep->max) && take_first)      {         if(take_second)         {            // store position in case we fail:            push_alt(rep->alt.p);         }         // increase the counter:         ++(*next_count);         pstate = rep->next.p;         return true;      }      else if(take_second)      {         pstate = rep->alt.p;         return true;      }      return false; // can't take anything, fail...   }   else // non-greedy   {      // try and skip the repeat if we can:      if(take_second)      {         // store position in case we fail:         push_non_greedy_repeat(rep->next.p);         pstate = rep->alt.p;         return true;      }      if((next_count->get_count() < rep->max) && take_first)      {         // increase the counter:         ++(*next_count);         pstate = rep->next.p;         return true;      }   }   return false;#ifdef __BORLANDC__#pragma option pop#endif#ifdef BOOST_MSVC#pragma warning(pop)#endif}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_slow(){   unsigned count = 0;   const re_repeat* rep = static_cast<const re_repeat*>(pstate);   re_syntax_base* psingle = rep->next.p;   // match compulsary repeats first:   while(count < rep->min)   {      pstate = psingle;      if(!match_wild())         return false;      ++count;   }   if(rep->greedy)   {      // repeat for as long as we can:      while(count < rep->max)      {         pstate = psingle;         if(!match_wild())            break;         ++count;      }      // remember where we got to if this is a leading repeat:      if((rep->leading) && (count < rep->max))         restart = position;      // push backtrack info if available:      if(count - rep->min)         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);      // jump to next state:      pstate = rep->alt.p;      return true;   }   else   {      // non-greedy, push state and return true if we can skip:      if(count < rep->max)         push_single_repeat(count, rep, position, saved_state_rep_slow_dot);      pstate = rep->alt.p;      return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);   }}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_fast(){   if(m_match_flags & (match_not_dot_newline | match_not_dot_null))      return match_dot_repeat_slow();   const re_repeat* rep = static_cast<const re_repeat*>(pstate);   unsigned count = (std::min)(static_cast<unsigned>(re_detail::distance(position, last)), static_cast<unsigned>(rep->greedy ? rep->max : rep->min));   if(rep->min > count)      return false;  // not enough text left to match   std::advance(position, count);   if(rep->greedy)   {      if((rep->leading) && (count < rep->max))         restart = position;      // push backtrack info if available:      if(count - rep->min)         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);      // jump to next state:      pstate = rep->alt.p;      return true;   }   else   {      // non-greedy, push state and return true if we can skip:      if(count < rep->max)         push_single_repeat(count, rep, position, saved_state_rep_fast_dot);      pstate = rep->alt.p;      return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);   }}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repeat(){#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable:4127)#endif#ifdef __BORLANDC__#pragma option push -w-8008 -w-8066 -w-8004#endif   const re_repeat* rep = static_cast<const re_repeat*>(pstate);   assert(1 == static_cast<const re_literal*>(rep->next.p)->length);   const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);   unsigned count = 0;   //   // start by working out how much we can skip:   //   unsigned desired = rep->greedy ? rep->max : rep->min;   if(::boost::is_random_access_iterator<BidiIterator>::value)   {      BidiIterator end = position;      std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));      BidiIterator origin(position);      while((position != end) && (traits_inst.translate(*position, icase) == what))      {         ++position;      }      count = (unsigned)re_detail::distance(origin, position);   }   else   {      while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))      {         ++position;         ++count;      }   }   if(count < rep->min)      return false;   if(rep->greedy)   {      if((rep->leading) && (count < rep->max))         restart = position;      // push backtrack info if available:      if(count - rep->min)         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);      // jump to next state:      pstate = rep->alt.p;      return true;   }   else   {      // non-greedy, push state and return true if we can skip:      if(count < rep->max)         push_single_repeat(count, rep, position, saved_state_rep_char);      pstate = rep->alt.p;      return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);   }#ifdef __BORLANDC__#pragma option pop#endif#ifdef BOOST_MSVC#pragma warning(pop)#endif}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat(){#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable:4127)#endif#ifdef __BORLANDC__#pragma option push -w-8008 -w-8066 -w-8004#endif   const re_repeat* rep = static_cast<const re_repeat*>(pstate);   const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;   unsigned count = 0;   //   // start by working out how much we can skip:   //   unsigned desired = rep->greedy ? rep->max : rep->min;   if(::boost::is_random_access_iterator<BidiIterator>::value)   {      BidiIterator end = position;      std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));      BidiIterator origin(position);      while((position != end) && map[(traits_uchar_type)traits_inst.translate(*position, icase)])      {         ++position;      }      count = (unsigned)re_detail::distance(origin, position);   }   else   {      while((count < desired) && (position != last) && map[(traits_uchar_type)traits_inst.translate(*position, icase)])      {         ++position;         ++count;      }   }   if(count < rep->min)      return false;   if(rep->greedy)   {      if((rep->leading) && (count < rep->max))         restart = position;      // push backtrack info if available:      if(count - rep->min)         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);      // jump to next state:      pstate = rep->alt.p;      return true;   }   else   {      // non-greedy, push state and return true if we can skip:      if(count < rep->max)         push_single_repeat(count, rep, position, saved_state_rep_short_set);      pstate = rep->alt.p;      return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);   }#ifdef __BORLANDC__#pragma option pop#endif#ifdef BOOST_MSVC#pragma warning(pop)#endif}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_repeat(){#ifdef BOOST_MSVC#pragma warning(push)#pragma warning(disable:4127)#endif#ifdef __BORLANDC__#pragma option push -w-8008 -w-8066 -w-8004#endif   const re_repeat* rep = static_cast<const re_repeat*>(pstate);   const re_set_long* set = static_cast<const re_set_long*>(pstate->next.p);   unsigned count = 0;   //   // start by working out how much we can skip:   //   unsigned desired = rep->greedy ? rep->max : rep->min;   if(::boost::is_random_access_iterator<BidiIterator>::value)   {      BidiIterator end = position;      std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));      BidiIterator origin(position);      while((position != end) && (position != re_is_set_member(position, last, set, re)))      {         ++position;      }      count = (unsigned)re_detail::distance(origin, position);   }   else   {      while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re)))      {         ++position;         ++count;      }   }   if(count < rep->min)      return false;   if(rep->greedy)   {      if((rep->leading) && (count < rep->max))         restart = position;      // push backtrack info if available:      if(count - rep->min)         push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);      // jump to next state:      pstate = rep->alt.p;      return true;   }   else   {      // non-greedy, push state and return true if we can skip:      if(count < rep->max)         push_single_repeat(count, rep, position, saved_state_rep_long_set);      pstate = rep->alt.p;      return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);   }#ifdef __BORLANDC__#pragma option pop#endif#ifdef BOOST_MSVC#pragma warning(pop)#endif}/****************************************************************************Unwind and associated proceedures follow, these perform what normal stackunwinding does in the recursive implementation.****************************************************************************/template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind(bool have_match){   static unwind_proc_type const s_unwind_table[14] =    {      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_end,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_paren,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_recursion_stopper,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_assertion,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_alt,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_repeater_counter,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_extra_block,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_greedy_single_repeat,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_slow_dot_repeat,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_fast_dot_repeat,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_char_repeat,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_short_set_repeat,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_repeat,      &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_non_greedy_repeat,   };   m_recursive_result = have_match;   unwind_proc_type unwinder;   bool cont;   //   // keep unwinding our stack until we have something to do:   //   do   {      unwinder = s_unwind_table[m_backup_state->id];      cont = (this->*unwinder)(m_recursive_result);   }while(cont);   //   // return true if we have more states to try:   //   return pstate ? true : false;}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_end(bool){   pstate = 0;   // nothing left to search   return false; // end of stack nothing more to search}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_paren(bool have_match){   saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);   // restore previous values if no match was found:   if(have_match == false)   {      m_presult->set_first(pmp->sub.first, pmp->index);      m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched);   }#ifdef BOOST_REGEX_MATCH_EXTRA   //   // we have a match, push the capture information onto the stack:   //   else if(pmp->sub.matched && (match_extra & m_match_flags))      ((*m_presult)[pmp->index]).get_captures().push_back(pmp->sub);#endif   // unwind stack:   m_backup_state = pmp+1;   boost::re_detail::inplace_destroy(pmp);   return true; // keep looking}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_recursion_stopper(bool){   boost::re_detail::inplace_destroy(m_backup_state++);   pstate = 0;   // nothing left to search   return false; // end of stack nothing more to search}template <class BidiIterator, class Allocator, class traits, class Allocator2>bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_assertion(bool r){   saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);   pstate = pmp->pstate;

⌨️ 快捷键说明

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