/** * Restart a match by restarting it one character further on * @param m the match to restart * @param v the new version * @param log the log to record errors in * @return 1 if it worked else 0 (ran out of text) */ int match_restart( match *m, int v, plugin_log *log ) { card *old = m->start.current; pair *sp = card_pair(m->start.current); if ( m->start.pos == pair_len(sp)-1 ) { card *c = card_next_nonempty(m->start.current,m->bs,v); pair *p = (c==NULL)?NULL:card_pair(c); if ( c != NULL && p!= NULL && bitset_next_set_bit(pair_versions(p),v)!=v ) { bitset *overlap = card_overlap(c,m->bs); if ( overlap != NULL ) { pos loc; location pos; memset( &pos, 0, sizeof(location) ); pos.current = c; pos.pos = 0; loc.loc = 0; loc.v = suffixtree_root(m->st); match_state *ms = match_state_create( &pos, &pos, &pos, m->text_off, m->len, overlap, NULL, &loc, 0, log ); if ( m->queue == NULL ) m->queue = ms; else match_state_push( m->queue, ms ); // restrict the current match to ANDed versions bitset_and( m->bs, pair_versions(card_pair(c)) ); } m->start.pos = 0; m->start.current = c; } else return 0; } else m->start.pos++; if ( old != m->start.current ) bitset_and( m->bs, pair_versions(card_pair(m->start.current)) ); m->end = m->start; m->prev = m->end; // push versions match_push_versions( m ); m->len = 0; m->maximal = 0; return 1; }
static int count_sr_conflicts (state *s) { int i; int src_count = 0; transitions *trans = s->transitions; reductions *reds = s->reductions; if (!trans) return 0; bitset_zero (lookahead_set); bitset_zero (shift_set); FOR_EACH_SHIFT (trans, i) bitset_set (shift_set, TRANSITION_SYMBOL (trans, i)); for (i = 0; i < reds->num; ++i) bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]); bitset_and (lookahead_set, lookahead_set, shift_set); src_count = bitset_count (lookahead_set); return src_count; }
/** * Advance the match position - we have already matched the character * @param m the match object * @param loc the location in the suffix tree matched to so far * @param v the version of the new text. Stop when you see this * @param log the log to record errors in * @return 1 if we could advance else 0 if we reached the end */ int match_advance( match *m, pos *loc, int v, plugin_log *log ) { int res = 0; if ( m->end.current != NULL ) { card *c = m->end.current; m->prev = m->end; match_push_versions( m );// surely only needed for a new pair if ( pair_len(card_pair(c))-1==m->end.pos ) { card *old_c = c; c = card_next_nonempty( c, m->bs, v ); if ( c != NULL ) { pair *p = card_pair(c); bitset *bs = pair_versions( p ); if ( bitset_next_set_bit(bs,v)==v ) { c = NULL; } else { bitset *overlap = card_overlap(c,m->bs); if ( overlap != NULL ) { location new_end; new_end.current = card_next_nonempty(old_c,overlap,v); // could return NULL if there was a clash with v if ( new_end.current != NULL ) { new_end.pos = 0; match_state *ms = match_state_create( &m->start, &new_end, &m->prev, m->text_off, m->len, overlap, m->prev_bs, loc, m->maximal, log ); if ( m->queue == NULL ) m->queue = ms; else match_state_push( m->queue, ms ); } } // restrict the current match to ANDed versions bitset_and( m->bs, pair_versions(card_pair(c)) ); m->end.pos = 0; m->end.current = c; res = 1; } } } else { m->end.pos++; res = 1; } } return res; }