vim-patch:7.4.290 #753

Problem:    A non-greedy match followed by a branch is too greedy. (Ingo
            Karkat)
Solution:   Add NFA_MATCH when it is already in the state list if the position
            differs.

https://code.google.com/p/vim/source/detail?r=b871734bf54ea185dbd2cc759d86dbfbe21cde26
This commit is contained in:
oni-link
2014-05-22 12:41:41 +02:00
committed by Justin M. Keyes
parent 37fe5aa444
commit 057e36ea19
4 changed files with 27 additions and 9 deletions

View File

@@ -3877,8 +3877,10 @@ addstate (
if (state->lastlist[nfa_ll_index] == l->id && state->c != NFA_SKIP) { if (state->lastlist[nfa_ll_index] == l->id && state->c != NFA_SKIP) {
/* This state is already in the list, don't add it again, /* This state is already in the list, don't add it again,
* unless it is an MOPEN that is used for a backreference or * unless it is an MOPEN that is used for a backreference or
* when there is a PIM. */ * when there is a PIM. For NFA_MATCH check the position,
if (!nfa_has_backref && pim == NULL && !l->has_pim) { * lower position is preferred. */
if (!nfa_has_backref && pim == NULL && !l->has_pim
&& state->c != NFA_MATCH) {
skip_add: skip_add:
#ifdef REGEXP_DEBUG #ifdef REGEXP_DEBUG
nfa_set_code(state->c); nfa_set_code(state->c);

View File

@@ -238,7 +238,11 @@ STARTTEST
:call add(tl, [2, '\vx(.{-,8})yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz','ayxa','xayzxayz']) :call add(tl, [2, '\vx(.{-,8})yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz','ayxa','xayzxayz'])
:call add(tl, [2, '\vx(.*)yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz', 'ayxayzxayzxa','']) :call add(tl, [2, '\vx(.*)yz(.*)','xayxayzxayzxayz','xayxayzxayzxayz', 'ayxayzxayzxa',''])
:call add(tl, [2, '\v(a{1,2}){-2,3}','aaaaaaa','aaaa','aa']) :call add(tl, [2, '\v(a{1,2}){-2,3}','aaaaaaa','aaaa','aa'])
:call add(tl, [2, '\v(a{-1,3})+','aa','aa','a']) :call add(tl, [2, '\v(a{-1,3})+', 'aa', 'aa', 'a'])
:call add(tl, [2, '^\s\{-}\zs\( x\|x$\)', ' x', ' x', ' x'])
:call add(tl, [2, '^\s\{-}\zs\(x\| x$\)', ' x', ' x', ' x'])
:call add(tl, [2, '^\s\{-}\ze\(x\| x$\)', ' x', '', ' x'])
:call add(tl, [2, '^\(\s\{-}\)\(x\| x$\)', ' x', ' x', '', ' x'])
:" :"
:" Test Character classes :" Test Character classes
:call add(tl, [2, '\d\+e\d\d','test 10e23 fd','10e23']) :call add(tl, [2, '\d\+e\d\d','test 10e23 fd','10e23'])
@@ -462,15 +466,15 @@ STARTTEST
: try : try
: let l = matchlist(text, pat) : let l = matchlist(text, pat)
: catch : catch
: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", caused an exception: \"' . v:exception . '\"' : $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", caused an exception: \"' . v:exception . '\"'
: endtry : endtry
:" check the match itself :" check the match itself
: if len(l) == 0 && len(t) > matchidx : if len(l) == 0 && len(t) > matchidx
: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", did not match, expected: \"' . t[matchidx] . '\"' : $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", did not match, expected: \"' . t[matchidx] . '\"'
: elseif len(l) > 0 && len(t) == matchidx : elseif len(l) > 0 && len(t) == matchidx
: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected no match' : $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected no match'
: elseif len(t) > matchidx && l[0] != t[matchidx] : elseif len(t) > matchidx && l[0] != t[matchidx]
: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected: \"' . t[matchidx] . '\"' : $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", match: \"' . l[0] . '\", expected: \"' . t[matchidx] . '\"'
: else : else
: $put ='OK ' . engine . ' - ' . pat : $put ='OK ' . engine . ' - ' . pat
: endif : endif
@@ -483,7 +487,7 @@ STARTTEST
: let e = t[matchidx + i] : let e = t[matchidx + i]
: endif : endif
: if l[i] != e : if l[i] != e
: $put ='ERROR: pat: \"' . pat . '\", text: \"' . text . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"' : $put ='ERROR ' . engine . ': pat: \"' . pat . '\", text: \"' . text . '\", submatch ' . i . ': \"' . l[i] . '\", expected: \"' . e . '\"'
: endif : endif
: endfor : endfor
: unlet i : unlet i

View File

@@ -533,6 +533,18 @@ OK 2 - \v(a{1,2}){-2,3}
OK 0 - \v(a{-1,3})+ OK 0 - \v(a{-1,3})+
OK 1 - \v(a{-1,3})+ OK 1 - \v(a{-1,3})+
OK 2 - \v(a{-1,3})+ OK 2 - \v(a{-1,3})+
OK 0 - ^\s\{-}\zs\( x\|x$\)
OK 1 - ^\s\{-}\zs\( x\|x$\)
OK 2 - ^\s\{-}\zs\( x\|x$\)
OK 0 - ^\s\{-}\zs\(x\| x$\)
OK 1 - ^\s\{-}\zs\(x\| x$\)
OK 2 - ^\s\{-}\zs\(x\| x$\)
OK 0 - ^\s\{-}\ze\(x\| x$\)
OK 1 - ^\s\{-}\ze\(x\| x$\)
OK 2 - ^\s\{-}\ze\(x\| x$\)
OK 0 - ^\(\s\{-}\)\(x\| x$\)
OK 1 - ^\(\s\{-}\)\(x\| x$\)
OK 2 - ^\(\s\{-}\)\(x\| x$\)
OK 0 - \d\+e\d\d OK 0 - \d\+e\d\d
OK 1 - \d\+e\d\d OK 1 - \d\+e\d\d
OK 2 - \d\+e\d\d OK 2 - \d\+e\d\d

View File

@@ -228,7 +228,7 @@ static int included_patches[] = {
//293, //293,
292, 292,
//291, //291,
//290, 290,
289, 289,
288, 288,
//287, //287,