145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <stdlib.h>
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <ctype.h>
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <string.h>
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "tools/re2c/globals.h"
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "tools/re2c/substr.h"
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "tools/re2c/dfa.h"
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define octCh(c) ('0' + c%8)
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid prtCh(FILE *o, unsigned char c){
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned char oc = talx[c];
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    switch(oc){
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\'': fputs("\\'", o); break;
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\n': fputs("\\n", o); break;
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\t': fputs("\\t", o); break;
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\v': fputs("\\v", o); break;
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\b': fputs("\\b", o); break;
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\r': fputs("\\r", o); break;
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\f': fputs("\\f", o); break;
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\a': fputs("\\a", o); break;
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    case '\\': fputs("\\\\", o); break;
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    default:
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	if(isprint(oc))
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    fputc(oc, o);
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	else
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    fprintf(o, "\\%c%c%c", octCh(c/64), octCh(c/8), octCh(c));
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid printSpan(FILE *o, unsigned int lb, unsigned int ub){
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if(lb > ub)
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	fputc('*', o);
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fputc('[', o);
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if((ub - lb) == 1){
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	prtCh(o, lb);
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } else {
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	prtCh(o, lb);
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	fputc('-', o);
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	prtCh(o, ub-1);
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fputc(']', o);
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgunsigned int
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgSpan_show(Span *s, FILE *o, unsigned int lb)
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if(s->to){
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	printSpan(o, lb, s->ub);
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	fprintf(o, " %u; ", s->to->label);
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return s->ub;
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgState_out(FILE *o, const State *s){
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned int lb, i;
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(o, "state %u", s->label);
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if(s->rule)
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	fprintf(o, " accepts %u", s->rule->d.RuleOp.accept);
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fputs("\n", o); oline++;
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lb = 0;
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for(i = 0; i < s->go.nSpans; ++i)
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	lb = Span_show(&s->go.span[i], o, lb);
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDFA_out(FILE *o, const DFA *dfa){
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    State *s;
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for(s = dfa->head; s; s = s->next) {
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	State_out(o, s);
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	fputs("\n\n", o); oline+=2;
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgState *
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgState_new(void)
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    State *s = malloc(sizeof(State));
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->label = 0;
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->rule = NULL;
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->next = NULL;
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->link = NULL;
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->depth = 0;
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->kCount = 0;
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->kernel = NULL;
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->isBase = 0;
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->action = NULL;
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->go.nSpans = 0;
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->go.span = NULL;
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return s;
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgState_delete(State *s)
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (s->kernel)
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	free(s->kernel);
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (s->go.span)
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	free(s->go.span);
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    free(s);
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic Ins **closure(Ins **cP, Ins *i){
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while(!isMarked(i)){
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	mark(i);
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	*(cP++) = i;
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	if(i->i.tag == FORK){
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    cP = closure(cP, i + 1);
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    i = (Ins*) i->i.link;
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	} else if(i->i.tag == GOTO){
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    i = (Ins*) i->i.link;
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	} else
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    break;
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return cP;
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct GoTo {
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Char	ch;
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    void	*to;
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} GoTo;
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDFA *
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDFA_new(Ins *ins, unsigned int ni, unsigned int lb, unsigned int ub, Char *rep)
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    DFA *d = malloc(sizeof(DFA));
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Ins **work = malloc(sizeof(Ins*)*(ni+1));
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    unsigned int nc = ub - lb;
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    GoTo *goTo = malloc(sizeof(GoTo)*nc);
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Span *span = malloc(sizeof(Span)*nc);
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    d->lbChar = lb;
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    d->ubChar = ub;
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    memset((char*) goTo, 0, nc*sizeof(GoTo));
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    d->tail = &d->head;
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    d->head = NULL;
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    d->nStates = 0;
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    d->toDo = NULL;
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    DFA_findState(d, work, closure(work, &ins[0]) - work);
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while(d->toDo){
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	State *s = d->toDo;
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	Ins **cP, **iP, *i;
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	unsigned int nGoTos = 0;
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	unsigned int j;
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	d->toDo = s->link;
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	s->rule = NULL;
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	for(iP = s->kernel; (i = *iP); ++iP){
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    if(i->i.tag == CHAR){
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		Ins *j2;
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		for(j2 = i + 1; j2 < (Ins*) i->i.link; ++j2){
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		    if(!(j2->c.link = goTo[j2->c.value - lb].to))
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org			goTo[nGoTos++].ch = j2->c.value;
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		    goTo[j2->c.value - lb].to = j2;
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		}
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    } else if(i->i.tag == TERM){
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		if(!s->rule || ((RegExp *)i->i.link)->d.RuleOp.accept < s->rule->d.RuleOp.accept)
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		    s->rule = (RegExp *)i->i.link;
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    }
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	}
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	for(j = 0; j < nGoTos; ++j){
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    GoTo *go = &goTo[goTo[j].ch - lb];
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    i = (Ins*) go->to;
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    for(cP = work; i; i = (Ins*) i->c.link)
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		cP = closure(cP, i + i->c.bump);
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    go->to = DFA_findState(d, work, cP - work);
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	}
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	s->go.nSpans = 0;
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	for(j = 0; j < nc;){
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    State *to = (State*) goTo[rep[j]].to;
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    while(++j < nc && goTo[rep[j]].to == to);
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    span[s->go.nSpans].ub = lb + j;
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    span[s->go.nSpans].to = to;
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    s->go.nSpans++;
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	}
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	for(j = nGoTos; j-- > 0;)
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	    goTo[goTo[j].ch - lb].to = NULL;
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	s->go.span = malloc(sizeof(Span)*s->go.nSpans);
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	memcpy((char*) s->go.span, (char*) span, s->go.nSpans*sizeof(Span));
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	Action_new_Match(s);
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    free(work);
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    free(goTo);
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    free(span);
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return d;
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgDFA_delete(DFA *d){
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    State *s;
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    while((s = d->head)){
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	d->head = s->next;
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	State_delete(s);
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid DFA_addState(DFA *d, State **a, State *s){
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->label = d->nStates++;
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->next = *a;
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *a = s;
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if(a == d->tail)
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	d->tail = &s->next;
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgState *DFA_findState(DFA *d, Ins **kernel, unsigned int kCount){
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    Ins **cP, **iP, *i;
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    State *s;
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    kernel[kCount] = NULL;
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cP = kernel;
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for(iP = kernel; (i = *iP); ++iP){
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	 if(i->i.tag == CHAR || i->i.tag == TERM){
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	     *cP++ = i;
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	} else {
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	     unmark(i);
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	}
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    kCount = cP - kernel;
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    kernel[kCount] = NULL;
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for(s = d->head; s; s = s->next){
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	 if(s->kCount == kCount){
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	     for(iP = s->kernel; (i = *iP); ++iP)
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		 if(!isMarked(i))
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org		     goto nextState;
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	     goto unmarkAll;
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	 }
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	 nextState:;
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s = State_new();
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    DFA_addState(d, d->tail, s);
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->kCount = kCount;
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->kernel = malloc(sizeof(Ins*)*(kCount+1));
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    memcpy(s->kernel, kernel, (kCount+1)*sizeof(Ins*));
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    s->link = d->toDo;
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    d->toDo = s;
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgunmarkAll:
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for(iP = kernel; (i = *iP); ++iP)
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org	 unmark(i);
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return s;
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
254