Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Patch for new NFA engine for vim
diff -r a1cf4a444f9b src/regexp.h
--- a/src/regexp.h Tue May 28 22:52:17 2013 +0200
+++ b/src/regexp.h Wed May 29 09:21:16 2013 +0900
@@ -72,6 +72,8 @@
int id;
int lastlist;
int negated;
+ int op;
+ int val;
};
/*
diff -r a1cf4a444f9b src/regexp_nfa.c
--- a/src/regexp_nfa.c Tue May 28 22:52:17 2013 +0200
+++ b/src/regexp_nfa.c Wed May 29 09:21:16 2013 +0900
@@ -117,6 +117,12 @@
NFA_NLOWER, /* Match non-lowercase char */
NFA_UPPER, /* Match uppercase char */
NFA_NUPPER, /* Match non-uppercase char */
+
+ NFA_CURSOR, /* Match cursor pos */
+ NFA_COL, /* Match cursor column */
+ NFA_VCOL, /* Match cursor virtical column */
+ NFA_LNUM, /* Match line number */
+
NFA_FIRST_NL = NFA_ANY + ADD_NL,
NFA_LAST_NL = NFA_NUPPER + ADD_NL,
@@ -722,11 +728,13 @@
EMSGN(_(e_misplaced), no_Magic(c));
return FAIL;
+ case Magic('*'):
+ break;
+
case Magic('='):
case Magic('?'):
case Magic('+'):
case Magic('@'):
- case Magic('*'):
case Magic('{'):
/* these should follow an atom, not form an atom */
syntax_error = TRUE;
@@ -831,8 +839,7 @@
break;
case '#':
- /* TODO: not supported yet */
- return FAIL;
+ EMIT(NFA_CURSOR);
break;
case 'V':
@@ -861,6 +868,31 @@
return FAIL;
default:
+ {
+ long_u n = 0;
+ int cmp;
+
+ cmp = c;
+ if (cmp == '<' || cmp == '>')
+ c = getchr();
+ while (VIM_ISDIGIT(c))
+ {
+ n = n * 10 + (c - '0');
+ c = getchr();
+ }
+ if (c == 'l' || c == 'c' || c == 'v')
+ {
+ EMIT(cmp == '<' || cmp == '>' ? cmp : '=');
+ EMIT(n);
+ if (c == 'l')
+ EMIT(NFA_LNUM);
+ else if (c == 'c')
+ EMIT(NFA_COL);
+ else
+ EMIT(NFA_VCOL);
+ } else
+ return FAIL;
+ }
syntax_error = TRUE;
EMSGN(_("E867: (NFA) Unknown operator '\\%%%c'"),
no_Magic(c));
@@ -1332,6 +1364,8 @@
EMIT(NFA_PREV_ATOM_NO_WIDTH);
break;
case '!':
+ EMIT(NFA_PREV_ATOM_NO_WIDTH_NEG);
+ break;
case '<':
case '>':
/* Not supported yet */
@@ -1669,6 +1703,8 @@
case NFA_PREV_ATOM_NO_WIDTH:
STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH"); break;
+ case NFA_PREV_ATOM_NO_WIDTH_NEG:
+ STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH_NEG"); break;
case NFA_NOPEN: STRCPY(code, "NFA_MOPEN_INVISIBLE"); break;
case NFA_NCLOSE: STRCPY(code, "NFA_MCLOSE_INVISIBLE"); break;
case NFA_START_INVISIBLE: STRCPY(code, "NFA_START_INVISIBLE"); break;
@@ -2326,6 +2362,32 @@
PUSH(frag(s, list1(&s1->out)));
break;
+ case NFA_PREV_ATOM_NO_WIDTH_NEG:
+ /* The \@= operator: match the preceding atom with 0 width.
+ * Surrounds the preceding atom with START_INVISIBLE and
+ * END_INVISIBLE, similarly to MOPEN.
+ */
+ /* TODO: Maybe this drops the speed? */
+ goto theend;
+
+ if (nfa_calc_size == TRUE)
+ {
+ nstate += 2;
+ break;
+ }
+ e = POP();
+ e.start->negated = TRUE;
+ s1 = new_state(NFA_END_INVISIBLE, NULL, NULL);
+ if (s1 == NULL)
+ goto theend;
+ patch(e.out, s1);
+
+ s = new_state(NFA_START_INVISIBLE, e.start, s1);
+ if (s == NULL)
+ goto theend;
+ PUSH(frag(s, list1(&s1->out)));
+ break;
+
#ifdef FEAT_MBYTE
case NFA_COMPOSING: /* char with composing char */
#if 0
@@ -2434,6 +2496,24 @@
PUSH(frag(s, list1(&s1->out)));
break;
+ case NFA_LNUM:
+ case NFA_VCOL:
+ case NFA_COL:
+ if (nfa_calc_size == TRUE)
+ {
+ nstate += 1;
+ break;
+ }
+ e2 = POP();
+ e1 = POP();
+ s = new_state(*p, NULL, NULL);
+ if (s == NULL)
+ goto theend;
+ s->op = e1.start->c;
+ s->val = e2.start->c;
+ PUSH(frag(s, list1(&s->out)));
+ break;
+
case NFA_ZSTART:
case NFA_ZEND:
default:
@@ -3066,6 +3146,17 @@
}
}
+ static int
+nfa_re_num_cmp(val, op, pos)
+ long_u val;
+ char_u op;
+ char_u pos;
+{
+ if (op == '>') return pos > val;
+ else if (op == '<') return pos < val;
+ return val == pos;
+}
+
static int nfa_regmatch __ARGS((nfa_state_T *start, regsub_T *submatch, regsub_T *m));
/*
@@ -3781,6 +3872,31 @@
/* TODO: should not happen? */
break;
+ case NFA_LNUM:
+ result = (REG_MULTI &&
+ nfa_re_num_cmp(t->state->val, t->state->op,
+ (long_u)(reglnum + reg_firstlnum)));
+ ADD_POS_NEG_STATE(t->state);
+ break;
+ case NFA_VCOL:
+ result = nfa_re_num_cmp(t->state->val, t->state->op,
+ (long_u)win_linetabsize(
+ reg_win == NULL ? curwin : reg_win,
+ regline, (colnr_T)(reginput - regline)) + 1);
+ ADD_POS_NEG_STATE(t->state);
+ break;
+ case NFA_COL:
+ result = nfa_re_num_cmp(t->state->val, t->state->op,
+ (long_u)(reginput - regline) + 1);
+ ADD_POS_NEG_STATE(t->state);
+ break;
+ case NFA_CURSOR:
+ result = (reg_win != NULL
+ && (reglnum + reg_firstlnum == reg_win->w_cursor.lnum)
+ && ((colnr_T)(reginput - regline) == reg_win->w_cursor.col));
+ ADD_POS_NEG_STATE(t->state);
+ break;
+
default: /* regular character */
{
int c = t->state->c;
diff -r a1cf4a444f9b src/testdir/test96.in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/testdir/test96.in Wed May 29 09:21:16 2013 +0900
@@ -0,0 +1,24 @@
+Test for new regexp engine
+
+STARTTEST
+:so small.vim
+:so mbyte.vim
+:set nocp encoding=utf-8 viminfo+=nviminfo nomore
+:set re=2
+
+:%d
+:call setline(1, ['ffooooo', 'boboooo', 'zoooooo', 'koooooo', 'moooooo', "\t\t\tfoo", 'abababababababfoo', 'bababababababafoo', '********_'])
+:call setpos('.', [0, 1, 3, 0])
+:s/\%>3c//g
+:call setpos('.', [0, 2, 3, 0])
+:s/\%#\zs.*$//g
+:call setpos('.', [0, 3, 3, 0])
+:s/\%<3c/_/g
+:%s/\%4l\%>6c/_/g
+:%s/\%6l\%>2v/_/g
+:%s/\(ab\)\@=foo/bar/g
+:%s/^**//g
+:w! test.out
+:qa!
+ENDTEST
+
diff -r a1cf4a444f9b src/testdir/test96.ok
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/testdir/test96.ok Wed May 29 09:21:16 2013 +0900
@@ -0,0 +1,9 @@
+ffo
+bob
+__ooooo
+koooo_
+moooooo
+___
+barbarbarbarbarbarbarbfoo
+barbarbarbarbarbarbafoo
+_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.