forked from boostorg/regex
Fix up recursive implementation of ACCEPT and COMMIT.
This commit is contained in:
@ -446,9 +446,7 @@ private:
|
|||||||
bool match_fail();
|
bool match_fail();
|
||||||
bool match_accept();
|
bool match_accept();
|
||||||
bool match_commit();
|
bool match_commit();
|
||||||
#ifdef BOOST_REGEX_NON_RECURSIVE
|
|
||||||
bool skip_until_paren(int index, bool match = true);
|
bool skip_until_paren(int index, bool match = true);
|
||||||
#endif
|
|
||||||
|
|
||||||
// find procs stored in s_find_vtable:
|
// find procs stored in s_find_vtable:
|
||||||
bool find_restart_any();
|
bool find_restart_any();
|
||||||
@ -509,6 +507,7 @@ private:
|
|||||||
#ifdef BOOST_REGEX_RECURSIVE
|
#ifdef BOOST_REGEX_RECURSIVE
|
||||||
// Set to false by a (*COMMIT):
|
// Set to false by a (*COMMIT):
|
||||||
bool m_can_backtrack;
|
bool m_can_backtrack;
|
||||||
|
bool m_have_accept;
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOOST_REGEX_NON_RECURSIVE
|
#ifdef BOOST_REGEX_NON_RECURSIVE
|
||||||
//
|
//
|
||||||
|
@ -82,6 +82,7 @@ void perl_matcher<BidiIterator, Allocator, traits>::construct_init(const basic_r
|
|||||||
m_backup_state = 0;
|
m_backup_state = 0;
|
||||||
#elif defined(BOOST_REGEX_RECURSIVE)
|
#elif defined(BOOST_REGEX_RECURSIVE)
|
||||||
m_can_backtrack = true;
|
m_can_backtrack = true;
|
||||||
|
m_have_accept = false;
|
||||||
#endif
|
#endif
|
||||||
// find the value to use for matching word boundaries:
|
// find the value to use for matching word boundaries:
|
||||||
m_word_mask = re.get_data().m_word_mask;
|
m_word_mask = re.get_data().m_word_mask;
|
||||||
@ -805,6 +806,18 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_fail()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class BidiIterator, class Allocator, class traits>
|
||||||
|
bool perl_matcher<BidiIterator, Allocator, traits>::match_accept()
|
||||||
|
{
|
||||||
|
if(!recursion_stack.empty())
|
||||||
|
{
|
||||||
|
return skip_until_paren(recursion_stack.back().idx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return skip_until_paren(INT_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class BidiIterator, class Allocator, class traits>
|
template <class BidiIterator, class Allocator, class traits>
|
||||||
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
|
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
|
||||||
|
@ -1070,20 +1070,6 @@ bool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class BidiIterator, class Allocator, class traits>
|
|
||||||
bool perl_matcher<BidiIterator, Allocator, traits>::match_accept()
|
|
||||||
{
|
|
||||||
if(!recursion_stack.empty())
|
|
||||||
{
|
|
||||||
skip_until_paren(recursion_stack.back().idx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
skip_until_paren(INT_MAX);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
||||||
Unwind and associated proceedures follow, these perform what normal stack
|
Unwind and associated proceedures follow, these perform what normal stack
|
||||||
|
@ -142,6 +142,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
|
|||||||
r = false;
|
r = false;
|
||||||
else
|
else
|
||||||
r = true;
|
r = true;
|
||||||
|
if(r && m_have_accept)
|
||||||
|
r = skip_until_paren(INT_MAX);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case -3:
|
case -3:
|
||||||
@ -183,6 +185,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if(r && m_have_accept)
|
||||||
|
r = skip_until_paren(INT_MAX);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case -4:
|
case -4:
|
||||||
@ -1003,11 +1007,45 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_commit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class BidiIterator, class Allocator, class traits>
|
template <class BidiIterator, class Allocator, class traits>
|
||||||
bool perl_matcher<BidiIterator, Allocator, traits>::match_accept()
|
bool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool match)
|
||||||
{
|
{
|
||||||
|
while(pstate)
|
||||||
|
{
|
||||||
|
if(pstate->type == syntax_element_endmark)
|
||||||
|
{
|
||||||
|
if(static_cast<const re_brace*>(pstate)->index == index)
|
||||||
|
{
|
||||||
|
if(match)
|
||||||
|
return this->match_endmark();
|
||||||
|
pstate = pstate->next.p;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unenclosed closing ), occurs when (*ACCEPT) is inside some other
|
||||||
|
// parenthesis which may or may not have other side effects associated with it.
|
||||||
|
bool r = match_endmark();
|
||||||
|
m_have_accept = true;
|
||||||
|
if(!pstate)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(pstate->type == syntax_element_match)
|
||||||
|
return true;
|
||||||
|
else if(pstate->type == syntax_element_startmark)
|
||||||
|
{
|
||||||
|
int idx = static_cast<const re_brace*>(pstate)->index;
|
||||||
|
pstate = pstate->next.p;
|
||||||
|
skip_until_paren(idx, false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pstate = pstate->next.p;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace BOOST_REGEX_DETAIL_NS
|
} // namespace BOOST_REGEX_DETAIL_NS
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
#ifdef BOOST_MSVC
|
#ifdef BOOST_MSVC
|
||||||
|
@ -49,7 +49,6 @@ int error_count = 0;
|
|||||||
|
|
||||||
void run_tests()
|
void run_tests()
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
RUN_TESTS(basic_tests);
|
RUN_TESTS(basic_tests);
|
||||||
RUN_TESTS(test_simple_repeats);
|
RUN_TESTS(test_simple_repeats);
|
||||||
RUN_TESTS(test_alt);
|
RUN_TESTS(test_alt);
|
||||||
@ -83,7 +82,6 @@ void run_tests()
|
|||||||
RUN_TESTS(test_pocessive_repeats);
|
RUN_TESTS(test_pocessive_repeats);
|
||||||
RUN_TESTS(test_mark_resets);
|
RUN_TESTS(test_mark_resets);
|
||||||
RUN_TESTS(test_recursion);
|
RUN_TESTS(test_recursion);
|
||||||
#endif
|
|
||||||
RUN_TESTS(test_verbs);
|
RUN_TESTS(test_verbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,13 +939,13 @@ void test_verbs()
|
|||||||
TEST_INVALID_REGEX("a+(*", perl);
|
TEST_INVALID_REGEX("a+(*", perl);
|
||||||
TEST_INVALID_REGEX("a+(*FX)", perl);
|
TEST_INVALID_REGEX("a+(*FX)", perl);
|
||||||
TEST_REGEX_SEARCH("a+(*FAIL)b", perl, "aaaab", match_default, make_array(-2, -2));
|
TEST_REGEX_SEARCH("a+(*FAIL)b", perl, "aaaab", match_default, make_array(-2, -2));
|
||||||
//TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AB", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2));
|
TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AB", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2));
|
||||||
//TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "ACDE", match_default, make_array(0, 4, 0, 3, 1, 2, 3, 4, -2, -2));
|
TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "ACDE", match_default, make_array(0, 4, 0, 3, 1, 2, 3, 4, -2, -2));
|
||||||
|
|
||||||
TEST_REGEX_SEARCH("^a+(*FAIL)", perl, "aaaaaa", match_default, make_array(-2, -2));
|
TEST_REGEX_SEARCH("^a+(*FAIL)", perl, "aaaaaa", match_default, make_array(-2, -2));
|
||||||
TEST_REGEX_SEARCH("a+b?c+(*FAIL)", perl, "aaabccc", match_default, make_array(-2, -2));
|
TEST_REGEX_SEARCH("a+b?c+(*FAIL)", perl, "aaabccc", match_default, make_array(-2, -2));
|
||||||
TEST_REGEX_SEARCH("a+b?(*COMMIT)c+(*FAIL)", perl, "aaabccc", match_default, make_array(-2, -2));
|
TEST_REGEX_SEARCH("a+b?(*COMMIT)c+(*FAIL)", perl, "aaabccc", match_default, make_array(-2, -2));
|
||||||
/*
|
|
||||||
TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AB", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2));
|
TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AB", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2));
|
||||||
TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "ABX", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2));
|
TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "ABX", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2));
|
||||||
TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AADE", match_default, make_array(0, 4, 0, 3, 1, 2, 3, 4, -2, -2));
|
TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AADE", match_default, make_array(0, 4, 0, 3, 1, 2, 3, 4, -2, -2));
|
||||||
@ -959,8 +959,8 @@ void test_verbs()
|
|||||||
TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "BAX", match_default, make_array(0, 2, 1, 2, -2, -2));
|
TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "BAX", match_default, make_array(0, 2, 1, 2, -2, -2));
|
||||||
TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "ACX", match_default, make_array(-2, -2));
|
TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "ACX", match_default, make_array(-2, -2));
|
||||||
TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "ABC", match_default, make_array(-2, -2));
|
TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "ABC", match_default, make_array(-2, -2));
|
||||||
*/
|
|
||||||
//TEST_REGEX_SEARCH("^(?=a(*ACCEPT)b)", perl, "ac", match_default, make_array(0, 0, -2, -2));
|
TEST_REGEX_SEARCH("^(?=a(*ACCEPT)b)", perl, "ac", match_default, make_array(0, 0, -2, -2));
|
||||||
TEST_REGEX_SEARCH("A(*COMMIT)(B|D)", perl, "ACABX", match_default, make_array(-2, -2));
|
TEST_REGEX_SEARCH("A(*COMMIT)(B|D)", perl, "ACABX", match_default, make_array(-2, -2));
|
||||||
|
|
||||||
TEST_REGEX_SEARCH("(*COMMIT)(A|P)(B|P)(C|P)", perl, "ABCDEFG", match_default, make_array(0, 3, 0, 1, 1, 2, 2, 3, -2, -2));
|
TEST_REGEX_SEARCH("(*COMMIT)(A|P)(B|P)(C|P)", perl, "ABCDEFG", match_default, make_array(0, 3, 0, 1, 1, 2, 2, 3, -2, -2));
|
||||||
|
Reference in New Issue
Block a user