Add recursive implementation of THEN.

This commit is contained in:
jzmaddock
2015-10-05 18:27:37 +01:00
parent 7a4e883675
commit 201d3a424e
3 changed files with 24 additions and 61 deletions

View File

@ -509,6 +509,7 @@ private:
// Set to false by a (*COMMIT):
bool m_can_backtrack;
bool m_have_accept;
bool m_have_then;
#endif
#ifdef BOOST_REGEX_NON_RECURSIVE
//

View File

@ -60,7 +60,7 @@ public:
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
{
static matcher_proc_type const s_match_vtable[33] =
static matcher_proc_type const s_match_vtable[34] =
{
(&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
&perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
@ -99,6 +99,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
&perl_matcher<BidiIterator, Allocator, traits>::match_fail,
&perl_matcher<BidiIterator, Allocator, traits>::match_accept,
&perl_matcher<BidiIterator, Allocator, traits>::match_commit,
&perl_matcher<BidiIterator, Allocator, traits>::match_then,
};
if(state_count > max_state_count)
@ -155,7 +156,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
pstate = pstate->next.p->next.p;
bool can_backtrack = m_can_backtrack;
r = match_all_states();
m_can_backtrack = can_backtrack;
if(r)
m_can_backtrack = can_backtrack;
pstate = next_pstate;
m_independent = old_independent;
#ifdef BOOST_REGEX_MATCH_EXTRA
@ -287,11 +289,19 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
BidiIterator oldposition(position);
const re_syntax_base* old_pstate = jmp->alt.p;
pstate = pstate->next.p;
m_have_then = false;
if(!match_all_states())
{
pstate = old_pstate;
position = oldposition;
if(m_have_then)
{
m_can_backtrack = true;
m_have_then = false;
return false;
}
}
m_have_then = false;
return m_can_backtrack;
}
pstate = pstate->next.p;
@ -1015,6 +1025,17 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_commit()
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_then()
{
pstate = pstate->next.p;
if(match_all_states())
return true;
m_can_backtrack = false;
m_have_then = true;
return false;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool match)
{

View File

@ -1000,63 +1000,4 @@ void test_verbs()
TEST_REGEX_SEARCH("(?:a+(*THEN)\\w{6}|x\\w{3})", perl, "aaaxxxxx", match_default, make_array(3, 7, -2, -2));
TEST_REGEX_SEARCH("(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?", perl, "yes", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?>(*COMMIT)(yes|no)(*THEN)(*F))?", perl, "yes", match_default, make_array(-2, -2));
#if 0
# Check the use of names for failure
/^(A(*PRUNE:A)B|C(*PRUNE:B)D)/mark
** Failers
AC
CB
/(*MARK:A)(*SKIP:B)(C|X)/mark
C
D
/^(A(*THEN:A)B|C(*THEN:B)D)/mark
** Failers
CB
/^(?:A(*THEN:A)B|C(*THEN:B)D)/mark
CB
/^(?>A(*THEN:A)B|C(*THEN:B)D)/mark
CB
# This should succeed, as the skip causes bump to offset 1 (the mark). Note
# that we have to have something complicated such as (B|Z) at the end because,
# for Perl, a simple character somehow causes an unwanted optimization to mess
# with the handling of backtracking verbs.
/A(*MARK:A)A+(*SKIP:A)(B|Z) | AC/x,mark
AAAC
# Test skipping over a non-matching mark.
/A(*MARK:A)A+(*MARK:B)(*SKIP:A)(B|Z) | AC/x,mark
AAAC
# Check shorthand for MARK.
/A(*:A)A+(*SKIP:A)(B|Z) | AC/x,mark
AAAC
/(*:A)A+(*SKIP:A)(B|Z)/mark
AAAC
# This should succeed, as a non-existent skip name disables the skip.
/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC/x,mark
AAAC
/A(*MARK:A)A+(*SKIP:B)(B|Z) | AC(*:B)/x,mark
AAAC
#endif
}