view regexParser/generateSequentialSearch.cc @ 324:879dc5d1cb6a default tip

fix
author mir3636
date Fri, 27 May 2016 21:21:09 +0900
parents c9ac6f06e706
children
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>

#include "generateSequentialSearch.h"
#include "CharClass.h"
#include "subsetConstruction.h"
#include "bmSearch.h"

static void
wordMatch(const char* cond,FILE* fp,unsigned long begin,CharClassPtr cc,BitVector bi) {
    fprintf(fp,"    else if (c%s'%c') { \n",cond,(unsigned char)begin);
    WordPtr w;
    for (w = &cc->cond.w;w;w = w->next) {
        // match the word.
        fprintf(fp,"        if (strncmp(\"%s\",(const char *)tsv.buff.buffptr-1,%d)==0) { tsv.buff.buffptr += %d;return state%lx(tsv);}\n",(const char *)w->word,w->length,w->length - 1,bi.bitContainer);
    }
    fprintf(fp,"        tsv=tsv.tg->stateSkip(tsv);return state0(tsv);;\n        } \n");
}

static void
generateState1(StatePtr state,long stateNum, bool accept, FILE *fp, TransitionGeneratorPtr tg) {
    fprintf(fp,"static TSValue state%lx(TSValue tsv) {\n",stateNum);
    if (accept && state->accept) {
        fputs("    tsv=tsv.tg->stateMatch(tsv);\n",fp);
    }
    fputs("    if (tsv.buff.buffptr >= tsv.buff.buffend) return tsv;\n",fp);
    CharClassWalkerPtr ccw = createCharClassWalker(state->cc);
    if (hasNext(ccw)) fputs("    unsigned char c = *tsv.buff.buffptr++;\n",fp);
    fputs("    if (0) ;\n",fp);
    while (hasNext(ccw)) {
        CharClassPtr cc = getNext(ccw);
        unsigned long begin = cc->cond.range.begin;
        unsigned long end = cc->cond.range.end;
        BitVector bi = cc->nextState;
        if (begin == end) {
            if (cc->cond.w.word) {
                wordMatch("==",fp,begin,cc,bi); 
            } else {
                fprintf(fp,"    else if (c=='%c') { return state%lx(tsv);}\n",(unsigned char)begin, bi.bitContainer);
            }
        } else {
            fprintf(fp,"    else if (c<'%c')  { tsv=tsv.tg->stateSkip(tsv);return state0(tsv);}\n",(unsigned char)begin);
            if (cc->cond.w.word) {
                wordMatch("<=",fp,begin,cc,bi); 
            } else {
                fprintf(fp,"    else if (c<='%c') { return state%lx(tsv);} \n",(unsigned char)end,  bi.bitContainer);
            }
        }
    }
    free(ccw);
    fprintf(fp,"    else { tsv=tsv.tg->stateSkip(tsv); return state0(tsv);}\n");
    fputs("}\n\n",fp);
} 

void
exportState(TransitionGeneratorPtr tg) {
    StatePtr state = tg->stateList;
    FILE *fp = fopen("state.cc","w");
    if (fp==NULL) {
        perror("");
        fprintf(stderr,"cannot write state.cc\n");
        exit(1);
    }
    for (;state;state = state->next) {
        if (state->bitState.bitContainer!=1)  // state1 always unused but state0
            fprintf(fp,"static TSValue state%lx(TSValue tsv);\n",state->bitState.bitContainer);
    }
    fputs("\n",fp);
    // initial state must not accept empty string
    generateState1(tg->stateList,0L,false,fp,tg);
    for (state = tg->stateList;state;state = state->next) {
        if (state->bitState.bitContainer!=1)  // state1 always unused but state0
            generateState1(state,state->bitState.bitContainer,true,fp,tg);
    }
    checkBMSearch(tg->stateStart->cc);
    tsv.current = generateTState(tg->stateStart,tg);
    fclose(fp);
}