view regexParser/subsetConstraction.cc @ 176:c092dd0e1ae0 pairPro

implement appendState() and serchState()
author Masataka Kohagura <kohagura@cr.ie.u-ryukyu.ac.jp>
date Wed, 23 Dec 2015 15:41:27 +0900
parents 3be0fbcd4b52
children 8de9a33f6ae5
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "subsetConstraction.h"

CharClassPtr createCharClassWord(unsigned char *w, CharClassPtr cc1, CharClassPtr cc2) {
    CharClassPtr cc = NEW(CharClass);
    return cc;
}

CharClassPtr createCharClassRange(unsigned long begin, unsigned long end,unsigned long state, CharClassPtr left, CharClassPtr right) {
    CharClassPtr cc = NEW(CharClass);
    cc->type = 'r';
    cc->cond.range.begin = begin;
    cc->cond.range.end = end;
    cc->left = left;
    cc->right = right;
    cc->nextState.bitContainer = state;
    return cc;
}

CharClassPtr mergeCCTree(CharClassPtr cc,unsigned char mBegin,unsigned char mEnd,BitVector nextState) {
    CharClassPtr cc1;
    if (cc) {
        cc1 = charClassMerge(cc,mBegin,mEnd,nextState);
    } else {
        cc1 = createCharClassRange(mBegin,mEnd,nextState.bitContainer,NULL,NULL);
    }
    return cc1;
}

CharClassPtr charClassMerge(CharClassPtr cc,unsigned long begin, unsigned long end, BitVector nextState) {
    // 重なっているccの領域を分割する
    // 必要ならばnextStateを重ねあわせる
    // 変更があった場合は新しくリストを作って返す
    if (end < cc->cond.range.begin ) { // 1
        if (cc->left) {
            return createCharClassRange(cc->cond.range.begin,cc->cond.range.end,charClassMerge(cc->left,begin,end,nextState),cc->right);
        } else {
            return createCharClassRange(begin,end,nextState.bitContainer,NULL,cc);
        }
    } else if (end == cc->cond.range.begin && begin != end ) { // 2
        CharClassPtr cc1 = mergeCCTree(cc->left,begin,end-1,nextState);
        if (cc->cond.range.begin == cc->cond.range.end) {
            return createCharClassRange(cc->cond.range.begin,cc->cond.range.end,
                cc->nextState.bitContainer | nextState.bitContainer, cc1,cc->right);
        }
        CharClassPtr cc3 = createCharClassRange(cc->cond.range.begin+1,cc->cond.range.end,cc->nextState.bitContainer,cc->left,cc->right);
        return createCharClassRange(cc->cond.range.begin,cc->cond.range.begin,
            cc->nextState.bitContainer | nextState.bitContainer,cc1,cc3);
    } else if (end < cc->cond.range.end) { // range.begin < end
        if (begin < cc->cond.range.begin) {  // 3
            CharClassPtr cc1 = mergeCCTree(cc->left,begin,cc->cond.range.begin-1,nextState);
            CharClassPtr cc3 = createCharClassRange(end+1,cc->cond.range.end,cc->nextState.bitContainer,cc->left,cc->right);
            return createCharClassRange(cc->cond.range.begin,end,cc->nextState.bitContainer | nextState.bitContainer,cc1,cc3);
        }
        if (begin == cc->cond.range.begin) {  // 6
            CharClassPtr cc2 = createCharClassRange(end+1,cc->cond.range.end,cc->nextState.bitContainer,NULL,cc->right);
            return createCharClassRange(begin,end,cc->nextState.bitContainer | nextState.bitContainer,cc->left,cc2);
        }
        // 9
        CharClassPtr cc2 = createCharClassRange(cc->cond.range.begin,begin-1,cc->nextState.bitContainer,cc->left,NULL);
        CharClassPtr cc3 = createCharClassRange(end+1,cc->cond.range.end,cc->nextState.bitContainer,NULL,cc->right);
        return createCharClassRange(begin,end,cc->nextState.bitContainer | nextState.bitContainer,cc2,cc3);
    } else if (end == cc->cond.range.end) {
        if (begin == cc->cond.range.begin) { // 7
            return createCharClassRange(begin,end,cc->nextState.bitContainer | nextState.bitContainer,cc->left,cc->right);
        } else if (begin < cc->cond.range.begin) { // 4
            CharClassPtr cc1 = mergeCCTree(cc->left,begin,cc->cond.range.begin-1,nextState);
            return createCharClassRange(cc->cond.range.begin,end,cc->nextState.bitContainer | nextState.bitContainer,cc1,cc->right);
        }
        // 10 cond.range.begin < begin
        CharClassPtr cc2 = createCharClassRange(begin,cc->cond.range.end,cc->nextState.bitContainer | nextState.bitContainer,NULL,cc->right);
        return createCharClassRange(cc->cond.range.begin,begin-1,cc->nextState.bitContainer,cc->left,cc2);
    }
    if (begin > cc->cond.range.end ) { // 13
        if (cc->right) {
            return createCharClassRange(cc->cond.range.begin,cc->cond.range.end,cc->left,charClassMerge(cc->right,begin,end,nextState));
        } else {
            return createCharClassRange(begin,end,nextState.bitContainer,cc,NULL);
        }
    }
    if (begin >= cc->cond.range.begin && begin <= cc->cond.range.end) {
        if (end > cc->cond.range.end) { // cond.range.end < end
            if (begin == cc->cond.range.begin) {    // 8
                CharClassPtr cc1 = mergeCCTree(cc->right,cc->cond.range.end+1,end,nextState);
                return createCharClassRange(cc->cond.range.begin,cc->cond.range.end,
                    cc->nextState.bitContainer | nextState.bitContainer,cc->left,cc1);
            }
            if (begin > cc->cond.range.begin) {  // 11
                CharClassPtr cc1 = mergeCCTree(cc->right,cc->cond.range.end+1,end,nextState);
                CharClassPtr cc3 = createCharClassRange(cc->cond.range.begin,begin-1,cc->nextState.bitContainer,cc->left,NULL);
                return createCharClassRange(begin,cc->cond.range.end,cc->nextState.bitContainer | nextState.bitContainer,cc3,cc1);
            }
        }
        // begin != end && end != cc->cond.range.end
        if (begin == cc->cond.range.end) { // 12
            CharClassPtr cc1 = mergeCCTree(cc->right,begin+1,end,nextState);
            if (cc->cond.range.begin == cc->cond.range.end) {
                return createCharClassRange(cc->cond.range.begin,cc->cond.range.end,cc->nextState.bitContainer | nextState.bitContainer,cc1,cc->right);
            }
            CharClassPtr cc3 = createCharClassRange(cc->cond.range.begin,cc->cond.range.end-1,cc->nextState.bitContainer,cc->left,NULL);
            return createCharClassRange(cc->cond.range.end,cc->cond.range.end,cc->nextState.bitContainer | nextState.bitContainer,cc1,cc3);
        }
    } else if (begin < cc->cond.range.begin) { // 5
        CharClassPtr cc1 = mergeCCTree(cc->left,begin,cc->cond.range.begin-1,nextState);
        CharClassPtr cc3 = mergeCCTree(cc->right,cc->cond.range.end+1,end,nextState);
        return createCharClassRange(cc->cond.range.begin,cc->cond.range.end,cc->nextState.bitContainer | nextState.bitContainer,cc1,cc3);
    } else {
        printf("charClassMerge Error : begin %lu end %lu cc->begin %lu cc->end %lu\n", begin,end,cc->cond.range.begin,cc->cond.range.end);
    }
    return cc;
}

CharClassWalkerPtr findLeftMost(CharClassPtr next,CharClassWalkerPtr walk) {
    while (next->left) {
        CharClassStackPtr ccs = NEW(CharClassStack);
        ccs->next = &walk->stack;
        ccs->left = false;
        ccs->cc = next;
        walk->stack = *ccs;
        next = next->left;
    }
    walk->next = next;
    return walk;
}

CharClassWalkerPtr createCharClassWalker (CharClassPtr next) {
    CharClassWalkerPtr walk = NEW(CharClassWalker);
    walk->next = NULL;
    if (!next) return walk;
    if (!next->left) {
        walk->next = next;
        return walk;
    }
    walk = findLeftMost(next,walk);
    return walk;
}

bool hasNext(CharClassWalkerPtr walk) {
    return walk->next != NULL;
}

CharClassPtr getNext(CharClassWalkerPtr walk) {
    CharClassPtr current = walk->next;
    if (walk->next->left && current->right) {
        walk->stack.left = true;
        CharClassPtr next = findLeftMost(current->right,walk)->next;
        walk->next = next;
    } else {
        /*
        TransitionPtr tsOld = ts;
        ts = ts->next;
        free(tsOld);
        CharClassPtr ret;
        if (ts) ret = ts->cc;
        else ret = NULL;
        walk->next = ret;
        */
    }
    return current;
}

TransitionPtr mergeTransition(TransitionPtr x,TransitionPtr y) {
    CharClassWalkerPtr walk = createCharClassWalker(x->condition);
    CharClassPtr ccy = y->condition;
    BitVector bi;
    for (CharClassPtr cc = getNext(walk); hasNext(walk); cc=getNext(walk)) {
        unsigned long begin = cc->cond.range.begin;
        unsigned long end = cc->cond.range.end;
        bi = cc->nextState;
        ccy = charClassMerge(ccy,begin,end,bi);
    }
    TransitionPtr z = createTransition(ccy,&bi);
    free(walk);
    return z;
}

TGValue generateTransition(NodePtr n,TransitionGenerator tg) {
    TGValue tgv2;
    if (n->tokenType == '+') {
        TGValue tgv = generateTransition(n->right,tg);
        TGValue tgv1 = generateTransition(n->left,tg);
        if (tgv.asterisk) {
            tgv1.ts = mergeTransition(tgv.ts,tgv1.ts);
            return tgv1;
        }
        return tgv;
    } else if (n->tokenType == '|') {
        TGValue tgv  = generateTransition(n->left,tg);
        TGValue tgv1 = generateTransition(n->right,tg);
        tgv.tg = tgv1.tg;
        tgv.ts = mergeTransition(tgv.ts,tgv1.ts);
        tgv.asterisk |= tgv1.asterisk;
        return tgv;
    } else if (n->tokenType == '*') {
        TGValue tgv = generateTransition(n->left,tg);
        tgv.asterisk = true;
        return tgv;
    } else if (n->tokenType == 'c'){
        tgv2.ts = createTransition(n->cc,0);
        return tgv2;
    } else if (n->tokenType == 'a'){
        TGValue tgv;
        tgv.ts = NEW(Transition);
        tgv.ts->condition = n->cc;
        bitSet(&tgv.ts->condition->nextState,n->nodeNumber);
        tg.ts = appendTransition(tg.ts,tgv.ts);
        return tgv;
    } else {
        // error
    }
    return tgv2;
}

void printTransitionList(TransitionPtr ts) {
    for (;ts;ts = ts->next) {
        printf("\n");
    }
}

TransitionGenerator createTransitionGenerator() {
    TransitionGenerator tg;
    tg.ts = NEW(Transition);
    tg.state = NEW(State);
    tg.transitionList = NEW(Transition);
    // Init State : 00...00(64bit)
    BitVectorPtr initStateBi = NEW(BitVector);
    bitSet(initStateBi,INIT_STATE_BIT);
    StatePtr initState = createState(tg.stateArray,*initStateBi);
    // Last State : 10...00(64bit)
    BitVectorPtr lastStateBi = NEW(BitVector);
    bitSet(lastStateBi,END_STATE_BIT);
    StatePtr lastState = createState(tg.stateArray,*lastStateBi);
    tg.stateArray = appendState(initState,lastState);
    tg.stateArrayLast = lastState;
    tg.currentState = NEW(State);
    tg.nextState = NEW(State);
    return tg;
}

TransitionGenerator generateTransitionList(NodePtr n) {
    TransitionGenerator tg = createTransitionGenerator();
    generateTransition(n,tg);
    printTransitionList(tg.ts);
    return tg;
}