mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
updated for version 7.3.1157
Problem: New regexp engine fails on "\(\<command\)\@<=.*" Solution: Fix rule for postponing match. Further tune estimating whether postponing works better. Add test.
This commit is contained in:
@@ -4587,6 +4587,7 @@ static long find_match_text __ARGS((colnr_T startcol, int regstart, char_u *matc
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Estimate the chance of a match with "state" failing.
|
* Estimate the chance of a match with "state" failing.
|
||||||
|
* empty match: 0
|
||||||
* NFA_ANY: 1
|
* NFA_ANY: 1
|
||||||
* specific character: 99
|
* specific character: 99
|
||||||
*/
|
*/
|
||||||
@@ -4616,7 +4617,9 @@ failure_chance(state, depth)
|
|||||||
case NFA_ANY:
|
case NFA_ANY:
|
||||||
/* matches anything, unlikely to fail */
|
/* matches anything, unlikely to fail */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case NFA_MATCH:
|
case NFA_MATCH:
|
||||||
|
case NFA_MCLOSE:
|
||||||
/* empty match works always */
|
/* empty match works always */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -4664,7 +4667,6 @@ failure_chance(state, depth)
|
|||||||
case NFA_ZCLOSE9:
|
case NFA_ZCLOSE9:
|
||||||
#endif
|
#endif
|
||||||
case NFA_NOPEN:
|
case NFA_NOPEN:
|
||||||
case NFA_MCLOSE:
|
|
||||||
case NFA_MCLOSE1:
|
case NFA_MCLOSE1:
|
||||||
case NFA_MCLOSE2:
|
case NFA_MCLOSE2:
|
||||||
case NFA_MCLOSE3:
|
case NFA_MCLOSE3:
|
||||||
@@ -5095,23 +5097,46 @@ nfa_regmatch(prog, start, submatch, m)
|
|||||||
case NFA_START_INVISIBLE_BEFORE:
|
case NFA_START_INVISIBLE_BEFORE:
|
||||||
case NFA_START_INVISIBLE_BEFORE_NEG:
|
case NFA_START_INVISIBLE_BEFORE_NEG:
|
||||||
{
|
{
|
||||||
int cout = t->state->out1->out->c;
|
int directly = FALSE;
|
||||||
|
|
||||||
/* Do it directly when what follows is possibly end of
|
#ifdef ENABLE_LOG
|
||||||
* match (closing paren).
|
fprintf(log_fd, "Failure chance invisible: %d, what follows: %d\n",
|
||||||
* Do it directly if there already is a PIM.
|
failure_chance(t->state->out, 0),
|
||||||
* Postpone when it is \@<= or \@<!, these are expensive.
|
failure_chance(t->state->out1->out, 0));
|
||||||
* Otherwise first do the one that has the highest chance
|
|
||||||
* of failing. */
|
|
||||||
if ((cout >= NFA_MCLOSE && cout <= NFA_MCLOSE9)
|
|
||||||
#ifdef FEAT_SYN_HL
|
|
||||||
|| (cout >= NFA_ZCLOSE && cout <= NFA_ZCLOSE9)
|
|
||||||
#endif
|
#endif
|
||||||
|| t->pim.result != NFA_PIM_UNUSED
|
/* Do it directly when what follows is possibly the end of
|
||||||
|| (t->state->c != NFA_START_INVISIBLE_BEFORE
|
* the match.
|
||||||
&& t->state->c != NFA_START_INVISIBLE_BEFORE_NEG
|
* Do it directly if there already is a PIM.
|
||||||
&& failure_chance(t->state->out1->out, 0)
|
* Postpone when the invisible match is expensive or has a
|
||||||
< failure_chance(t->state->out, 0)))
|
* lower chance of failing. */
|
||||||
|
if (match_follows(t->state->out1->out, 0)
|
||||||
|
|| t->pim.result != NFA_PIM_UNUSED)
|
||||||
|
directly = TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ch_invisible = failure_chance(t->state->out, 0);
|
||||||
|
int ch_follows = failure_chance(t->state->out1->out, 0);
|
||||||
|
|
||||||
|
if (t->state->c == NFA_START_INVISIBLE_BEFORE
|
||||||
|
|| t->state->c == NFA_START_INVISIBLE_BEFORE_NEG)
|
||||||
|
{
|
||||||
|
/* "before" matches are very expensive when
|
||||||
|
* unbounded, always prefer what follows then,
|
||||||
|
* unless what follows will always match.
|
||||||
|
* Otherwise strongly prefer what follows. */
|
||||||
|
if (t->state->val <= 0 && ch_follows > 0)
|
||||||
|
directly = FALSE;
|
||||||
|
else
|
||||||
|
directly = ch_follows * 10 < ch_invisible;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* normal invisible, first do the one with the
|
||||||
|
* highest failure chance */
|
||||||
|
directly = ch_follows < ch_invisible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (directly)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* First try matching the invisible match, then what
|
* First try matching the invisible match, then what
|
||||||
|
@@ -392,6 +392,7 @@ STARTTEST
|
|||||||
:call add(tl, [2, '\v\C%(<Last Changed:\s+)@<=.*$', '" Last Changed: 1970', '1970'])
|
:call add(tl, [2, '\v\C%(<Last Changed:\s+)@<=.*$', '" Last Changed: 1970', '1970'])
|
||||||
:call add(tl, [2, '\(foo\)\@<=\>', 'foobar'])
|
:call add(tl, [2, '\(foo\)\@<=\>', 'foobar'])
|
||||||
:call add(tl, [2, '\(foo\)\@<=\>', 'barfoo', '', 'foo'])
|
:call add(tl, [2, '\(foo\)\@<=\>', 'barfoo', '', 'foo'])
|
||||||
|
:call add(tl, [2, '\(foo\)\@<=.*', 'foobar', 'bar', 'foo'])
|
||||||
:"
|
:"
|
||||||
:""""" \@>
|
:""""" \@>
|
||||||
:call add(tl, [2, '\(a*\)\@>a', 'aaaa'])
|
:call add(tl, [2, '\(a*\)\@>a', 'aaaa'])
|
||||||
|
@@ -890,6 +890,9 @@ OK 2 - \(foo\)\@<=\>
|
|||||||
OK 0 - \(foo\)\@<=\>
|
OK 0 - \(foo\)\@<=\>
|
||||||
OK 1 - \(foo\)\@<=\>
|
OK 1 - \(foo\)\@<=\>
|
||||||
OK 2 - \(foo\)\@<=\>
|
OK 2 - \(foo\)\@<=\>
|
||||||
|
OK 0 - \(foo\)\@<=.*
|
||||||
|
OK 1 - \(foo\)\@<=.*
|
||||||
|
OK 2 - \(foo\)\@<=.*
|
||||||
OK 0 - \(a*\)\@>a
|
OK 0 - \(a*\)\@>a
|
||||||
OK 1 - \(a*\)\@>a
|
OK 1 - \(a*\)\@>a
|
||||||
OK 2 - \(a*\)\@>a
|
OK 2 - \(a*\)\@>a
|
||||||
|
@@ -728,6 +728,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1157,
|
||||||
/**/
|
/**/
|
||||||
1156,
|
1156,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user