Mercurial > vim
diff src/regexp_nfa.c @ 4657:93b7ed814bec v7.3.1076
updated for version 7.3.1076
Problem: New regexp engine: \@= and \& don't work.
Solution: Make these items work. Add column info to logging.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Thu, 30 May 2013 21:42:13 +0200 |
parents | 779ca415f8e1 |
children | 0dce3d812e7a |
line wrap: on
line diff
--- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -1740,8 +1740,8 @@ nfa_set_code(c) 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_NOPEN: STRCPY(code, "NFA_NOPEN"); break; + case NFA_NCLOSE: STRCPY(code, "NFA_NCLOSE"); break; case NFA_START_INVISIBLE: STRCPY(code, "NFA_START_INVISIBLE"); break; case NFA_END_INVISIBLE: STRCPY(code, "NFA_END_INVISIBLE"); break; @@ -2373,12 +2373,9 @@ post2nfa(postfix, end, nfa_calc_size) break; case NFA_PREV_ATOM_NO_WIDTH: - /* The \@= operator: match the preceding atom with 0 width. + /* The \@= operator: match the preceding atom with zero width. * Surrounds the preceding atom with START_INVISIBLE and - * END_INVISIBLE, similarly to MOPEN. - */ - /* TODO: Maybe this drops the speed? */ - goto theend; + * END_INVISIBLE, similarly to MOPEN. */ if (nfa_calc_size == TRUE) { @@ -2745,6 +2742,9 @@ addstate(l, state, sub, off) int save_in_use; char_u *save_ptr; int i; +#ifdef ENABLE_LOG + int did_print = FALSE; +#endif if (l == NULL || state == NULL) return; @@ -2782,7 +2782,7 @@ addstate(l, state, sub, off) /* These nodes do not need to be added, but we need to bail out * when it was tried to be added to this list before. */ if (state->lastlist == l->id) - return; + goto skip_add; state->lastlist = l->id; break; @@ -2792,7 +2792,15 @@ addstate(l, state, sub, off) /* This state is already in the list, don't add it again, * unless it is an MOPEN that is used for a backreference. */ if (!nfa_has_backref) + { +skip_add: +#ifdef ENABLE_LOG + nfa_set_code(state->c); + fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n", + abs(state->id), l->id, state->c, code); +#endif return; + } /* See if the same state is already in the list with the same * positions. */ @@ -2801,7 +2809,7 @@ addstate(l, state, sub, off) thread = &l->t[i]; if (thread->state->id == state->id && sub_equal(&thread->sub, sub)) - return; + goto skip_add; } } @@ -2832,12 +2840,39 @@ addstate(l, state, sub, off) &sub->list.line[0], sizeof(struct linepos) * sub->in_use); } +#ifdef ENABLE_LOG + { + int col; + + if (thread->sub.in_use <= 0) + col = -1; + else if (REG_MULTI) + col = thread->sub.list.multi[0].start.col; + else + col = (int)(thread->sub.list.line[0].start - regline); + nfa_set_code(state->c); + fprintf(log_fd, "> Adding state %d to list %d. char %d: %s (start col %d)\n", + abs(state->id), l->id, state->c, code, col); + did_print = TRUE; + } +#endif } #ifdef ENABLE_LOG - nfa_set_code(state->c); - fprintf(log_fd, "> Adding state %d to list. Character %d: %s\n", - abs(state->id), state->c, code); + if (!did_print) + { + int col; + + if (sub->in_use <= 0) + col = -1; + else if (REG_MULTI) + col = sub->list.multi[0].start.col; + else + col = (int)(sub->list.line[0].start - regline); + nfa_set_code(state->c); + fprintf(log_fd, "> Processing state %d for list %d. char %d: %s (start col %d)\n", + abs(state->id), l->id, state->c, code, col); + } #endif switch (state->c) { @@ -2873,14 +2908,6 @@ addstate(l, state, sub, off) addstate(l, state->out, sub, off); break; - /* If this state is reached, then a recursive call of nfa_regmatch() - * succeeded. the next call saves the found submatches in the - * first state after the "invisible" branch. */ -#if 0 - case NFA_END_INVISIBLE: - break; -#endif - case NFA_MOPEN + 0: case NFA_MOPEN + 1: case NFA_MOPEN + 2: @@ -3450,9 +3477,19 @@ nfa_regmatch(start, submatch, m) fprintf(debug, "%s, ", code); #endif #ifdef ENABLE_LOG - nfa_set_code(t->state->c); - fprintf(log_fd, "(%d) %s, code %d ... \n", abs(t->state->id), - code, (int)t->state->c); + { + int col; + + if (t->sub.in_use <= 0) + col = -1; + else if (REG_MULTI) + col = t->sub.list.multi[0].start.col; + else + col = (int)(t->sub.list.line[0].start - regline); + nfa_set_code(t->state->c); + fprintf(log_fd, "(%d) char %d %s (start col %d) ... \n", + abs(t->state->id), (int)t->state->c, code, col); + } #endif /* @@ -3504,6 +3541,7 @@ nfa_regmatch(start, submatch, m) addstate_here(thislist, t->state->out, &t->sub, &listidx); else { + /* TODO: only copy positions in use. */ *m = t->sub; nfa_match = TRUE; } @@ -3538,6 +3576,7 @@ nfa_regmatch(start, submatch, m) result = nfa_regmatch(t->state->out, submatch, m); nfa_set_neg_listids(start); nfa_restore_listids(start, listids); + nfa_match = FALSE; #ifdef ENABLE_LOG log_fd = fopen(NFA_REGEXP_RUN_LOG, "a"); @@ -3575,9 +3614,11 @@ nfa_regmatch(start, submatch, m) t->sub.list.line[j].start = m->list.line[j].start; t->sub.list.line[j].end = m->list.line[j].end; } - t->sub.in_use = m->in_use; - - /* t->state->out1 is the corresponding END_INVISIBLE node */ + if (m->in_use > t->sub.in_use) + t->sub.in_use = m->in_use; + + /* t->state->out1 is the corresponding END_INVISIBLE node; + * Add it to the current list (zero-width match). */ addstate_here(thislist, t->state->out1->out, &t->sub, &listidx); } @@ -4146,7 +4187,7 @@ nfa_regtry(start, col) fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr); #endif fprintf(f, "\tInput text is \"%s\" \n", reginput); - fprintf(f, " =======================================================\n\n\n\n\n\n\n"); + fprintf(f, " =======================================================\n\n"); nfa_print_state(f, start); fprintf(f, "\n\n"); fclose(f);