Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 37 additions & 46 deletions stl/inc/regex
Original file line number Diff line number Diff line change
Expand Up @@ -1677,6 +1677,8 @@ public:
enum class _Rx_unwind_ops {
_After_assert = _N_end + 1,
_After_neg_assert,
_Disjunction_eval_alt_on_failure,
_Disjunction_eval_alt_always,
};

template <class _BidIt>
Expand Down Expand Up @@ -1753,7 +1755,7 @@ public:

_Matched = false;

bool _Succeeded = _Match_pat(_Rep);
bool _Succeeded = _Match_pat(_Rep) || _Matched;
_STL_INTERNAL_CHECK(_Frames_count == 0);

if (!_Succeeded) {
Expand Down Expand Up @@ -1810,7 +1812,6 @@ private:
void _Increase_stack_usage_count();
void _Decrease_stack_usage_count();

bool _Do_if(_Node_if*);
bool _Do_rep0(_Node_rep*, bool);
bool _Do_rep(_Node_rep*, bool, int);
bool _Do_rep_first(_Node_rep*);
Expand Down Expand Up @@ -3402,44 +3403,6 @@ void _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Decrease_stack_usage_cou
}
}

template <class _BidIt, class _Elem, class _RxTraits, class _It, class _Alloc>
bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_if(_Node_if* _Node) { // apply if node
const size_t _Frame_idx = _Push_frame();

// look for the first match
for (; _Node; _Node = _Node->_Child) { // process one branch of if
_Tgt_state = _Frames[_Frame_idx]._Match_state; // rewind to where the alternation starts in input
if (_Match_pat(_Node->_Next)) { // try to match this branch
break;
}
}

// if none of the if branches matched, fail to match
if (!_Node) {
_Pop_frame(_Frame_idx);
return false;
}

// if we aren't looking for the longest match, that's it
if (!_Longest) {
_Pop_frame(_Frame_idx);
return true;
}

// see if there is a longer match
for (;;) { // process one branch of if
_Node = _Node->_Child;
if (!_Node) {
break;
}

_Tgt_state = _Frames[_Frame_idx]._Match_state;
(void) _Match_pat(_Node->_Next);
}
_Pop_frame(_Frame_idx);
return true;
}

template <class _BidIt, class _Elem, class _RxTraits, class _It, class _Alloc>
bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Do_rep0(_Node_rep* _Node, bool _Greedy) {
// apply repetition to loop with no nested if/do
Expand Down Expand Up @@ -4175,13 +4138,17 @@ bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
}

case _N_if:
if (!_Do_if(static_cast<_Node_if*>(_Nx))) {
_Failed = true;
{
auto _Node = static_cast<_Node_if*>(_Nx);
if (_Node->_Child) {
_Push_frame(_Longest ? _Rx_unwind_ops::_Disjunction_eval_alt_always
: _Rx_unwind_ops::_Disjunction_eval_alt_on_failure,
_Node->_Child);
_Increase_stack_usage_count();
}
break;
}

_Next = nullptr;
break;

case _N_endif:
break;

Expand Down Expand Up @@ -4236,7 +4203,7 @@ bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
} while (_Nx);

while (_Frames_count > _Initial_frames_count && !_Nx) {
const auto& _Frame = _Frames[--_Frames_count];
auto& _Frame = _Frames[--_Frames_count];

switch (_Frame._Code) {
case _Rx_unwind_ops::_After_assert:
Expand All @@ -4261,6 +4228,30 @@ bool _Matcher3<_BidIt, _Elem, _RxTraits, _It, _Alloc>::_Match_pat(_Node_base* _N
break;
}

case _Rx_unwind_ops::_Disjunction_eval_alt_on_failure:
// evaluate next alternative if matching prior alternatives failed
if (!_Failed) {
_Decrease_stack_usage_count();
break;
}
_FALLTHROUGH;

case _Rx_unwind_ops::_Disjunction_eval_alt_always:
// evaluate next alternative no matter if matching prior alternatives succeeded
{
auto _Node = static_cast<_Node_if*>(_Frame._Node);
_Nx = _Node->_Next;
_Tgt_state = _Frame._Match_state;
_Failed = false;
if (_Node->_Child) {
_Frame._Node = _Node->_Child;
++_Frames_count;
} else {
_Decrease_stack_usage_count();
}
break;
}

default:
#if _ITERATOR_DEBUG_LEVEL != 0
_STL_REPORT_ERROR("internal stack of regex matcher corrupted");
Expand Down