mirror of
https://github.com/boostorg/regex.git
synced 2025-07-04 16:16:32 +02:00
Add recursive implementation of THEN.
This commit is contained in:
@ -509,6 +509,7 @@ private:
|
|||||||
// Set to false by a (*COMMIT):
|
// Set to false by a (*COMMIT):
|
||||||
bool m_can_backtrack;
|
bool m_can_backtrack;
|
||||||
bool m_have_accept;
|
bool m_have_accept;
|
||||||
|
bool m_have_then;
|
||||||
#endif
|
#endif
|
||||||
#ifdef BOOST_REGEX_NON_RECURSIVE
|
#ifdef BOOST_REGEX_NON_RECURSIVE
|
||||||
//
|
//
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
template <class BidiIterator, class Allocator, class traits>
|
template <class BidiIterator, class Allocator, class traits>
|
||||||
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
|
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_startmark),
|
||||||
&perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
|
&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_fail,
|
||||||
&perl_matcher<BidiIterator, Allocator, traits>::match_accept,
|
&perl_matcher<BidiIterator, Allocator, traits>::match_accept,
|
||||||
&perl_matcher<BidiIterator, Allocator, traits>::match_commit,
|
&perl_matcher<BidiIterator, Allocator, traits>::match_commit,
|
||||||
|
&perl_matcher<BidiIterator, Allocator, traits>::match_then,
|
||||||
};
|
};
|
||||||
|
|
||||||
if(state_count > max_state_count)
|
if(state_count > max_state_count)
|
||||||
@ -155,6 +156,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
|
|||||||
pstate = pstate->next.p->next.p;
|
pstate = pstate->next.p->next.p;
|
||||||
bool can_backtrack = m_can_backtrack;
|
bool can_backtrack = m_can_backtrack;
|
||||||
r = match_all_states();
|
r = match_all_states();
|
||||||
|
if(r)
|
||||||
m_can_backtrack = can_backtrack;
|
m_can_backtrack = can_backtrack;
|
||||||
pstate = next_pstate;
|
pstate = next_pstate;
|
||||||
m_independent = old_independent;
|
m_independent = old_independent;
|
||||||
@ -287,11 +289,19 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
|
|||||||
BidiIterator oldposition(position);
|
BidiIterator oldposition(position);
|
||||||
const re_syntax_base* old_pstate = jmp->alt.p;
|
const re_syntax_base* old_pstate = jmp->alt.p;
|
||||||
pstate = pstate->next.p;
|
pstate = pstate->next.p;
|
||||||
|
m_have_then = false;
|
||||||
if(!match_all_states())
|
if(!match_all_states())
|
||||||
{
|
{
|
||||||
pstate = old_pstate;
|
pstate = old_pstate;
|
||||||
position = oldposition;
|
position = oldposition;
|
||||||
|
if(m_have_then)
|
||||||
|
{
|
||||||
|
m_can_backtrack = true;
|
||||||
|
m_have_then = false;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
m_have_then = false;
|
||||||
return m_can_backtrack;
|
return m_can_backtrack;
|
||||||
}
|
}
|
||||||
pstate = pstate->next.p;
|
pstate = pstate->next.p;
|
||||||
@ -1015,6 +1025,17 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_commit()
|
|||||||
return true;
|
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>
|
template <class BidiIterator, class Allocator, class traits>
|
||||||
bool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool match)
|
bool perl_matcher<BidiIterator, Allocator, traits>::skip_until_paren(int index, bool match)
|
||||||
{
|
{
|
||||||
|
@ -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("(?: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));
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user