diff --git a/src/lib/automate/automate.c b/src/lib/automate/automate.c index d168d7c..07d66de 100644 --- a/src/lib/automate/automate.c +++ b/src/lib/automate/automate.c @@ -12,38 +12,68 @@ -int browse(struct Automate pAutomate, const char* pString){ +unsigned int browse(struct Automate* pAutomate, const char* pString){ /* [0] Initialize variables =========================================================*/ unsigned int strIndex = 0; // String current char index + unsigned int recursive; int c, len, i, l; // counters - + char* buffer = malloc(1); + char* ptr = NULL; + struct AutomateDot dotPtr; /* [1] For each char =========================================================*/ c = 0; len = strlen(pString); + buffer = realloc(buffer, len+1); + pAutomate->dCurrent = 0; for( ; c < len ; c++ ){ + /* (1) Check if the current char can lead to a state ---------------------------------------------------------*/ /* (1) Check current state choices */ - i = 0; l = pAutomate.states[pAutomate.sCurrent].n; + dotPtr = pAutomate->dot[pAutomate->dCurrent]; + i = 0; l = dotPtr.n; + for( ; i < l ; i++ ){ - /* (2) If part of set */ - if( is_part(pString[strIndex], pAutomate.set[pAutomate.states[pAutomate.sCurrent].set[i]]) == 1 ){ - pAutomate.sCurrent = pAutomate.states[pAutomate.sCurrent].state[i]; - strIndex++; + /* (2) If STRING match */ + if( dotPtr.type[i] == 0 ){ + + ptr = pAutomate->sedge[dotPtr.edge[i]]; + strncpy(buffer, pString+strIndex, strlen(ptr)); + buffer[strlen(ptr)] = 0; + + if( strcmp(buffer, ptr) == 0 ){ + pAutomate->dCurrent = dotPtr.dot[i]; + strIndex += strlen(ptr); + } + } + + /* (3) If AUTOMATE match */ + else{ + + recursive = browse(&pAutomate->aedge[dotPtr.edge[i]], pString+strIndex); + + if( pAutomate->aedge[dotPtr.edge[i]].dCurrent == pAutomate->aedge[dotPtr.edge[i]].dFinal ){ + printf("rec %d from '%s'\n", recursive, pString+strIndex); + pAutomate->dCurrent = dotPtr.dot[i]; + strIndex += recursive; + } + } } } - return pAutomate.sCurrent; + free(buffer); + + return strIndex; } @@ -129,15 +159,18 @@ struct Automate createAutomate(){ /* [1] Create n values =========================================================*/ - automate.n_state = 0; - automate.n_set = 0; - automate.sCurrent = 0; - automate.sFinal = 0; + automate.dots = 0; + automate.sedges = 0; + automate.aedges = 0; + + automate.dCurrent = 0; + automate.dFinal = 0; /* [2] First allocation =========================================================*/ - automate.states = malloc( 0 ); - automate.set = malloc( 0 ); + automate.dot = malloc( 0 ); + automate.sedge = malloc( 0 ); + automate.aedge = malloc( 0 ); /* [3] Return initialized automate @@ -147,87 +180,117 @@ struct Automate createAutomate(){ -char addState(struct Automate* pAutomate){ +char addDot(struct Automate* pAutomate){ /* [0] Initialize variables =========================================================*/ - char index = pAutomate->n_state++; + char index = pAutomate->dots++; /* [1] Reallocate memory for the state =========================================================*/ - pAutomate->states = realloc( pAutomate->states, sizeof(struct AutomateState) * pAutomate->n_state ); + pAutomate->dot = realloc( pAutomate->dot, sizeof(struct AutomateDot) * pAutomate->dots ); - /* [2] Allocate memory for the state data + initalize n + /* [2] Allocate memory for the dot data + initalize n =========================================================*/ - pAutomate->states[index].n = 0; - pAutomate->states[index].set = malloc( 0 ); - pAutomate->states[index].state = malloc( 0 ); + pAutomate->dot[index].n = 0; + pAutomate->dot[index].type = malloc( 0 ); + pAutomate->dot[index].dot = malloc( 0 ); + pAutomate->dot[index].edge = malloc( 0 ); /* [3] Set new state as final =========================================================*/ - pAutomate->sFinal = index; + pAutomate->dFinal = index; return index; } -char addSet(struct Automate* pAutomate, const char* pSet){ +char addStringTransition(struct Automate* pAutomate, const char* pSedge){ /* [0] Initialize variables =========================================================*/ - char index = pAutomate->n_set++; + char index = pAutomate->sedges++; - - /* [1] Add the set + /* [1] Reallocate memory for sedge =========================================================*/ - /* (1) Reallocate memory for the set */ - pAutomate->set = realloc( pAutomate->set, sizeof(char*) * pAutomate->n_set ); - pAutomate->set[index] = realloc( pAutomate->set[index], strlen(pSet) + 1 ); + pAutomate->sedge = realloc(pAutomate->sedge, sizeof(char) * pAutomate->sedges ); + pAutomate->sedge[index] = malloc( strlen(pSedge)+1 ); - /* (2) Copy the set */ - strcpy(pAutomate->set[index], pSet); + + /* [2] Create the sedge + =========================================================*/ + strcpy(pAutomate->sedge[index], pSedge); + + return index; +} + +char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge){ + /* [0] Initialize variables + =========================================================*/ + char index = pAutomate->aedges++; + + /* [1] Reallocate memory for aedge + =========================================================*/ + pAutomate->aedge = realloc(pAutomate->aedge, sizeof(struct Automate) * pAutomate->aedges ); + + + /* [2] Create the aedge + =========================================================*/ + memcpy(&pAutomate->aedge[index], pAedge, sizeof(struct Automate)); return index; } -void linkStates(struct Automate* pAutomate, const unsigned int pIn, const unsigned int pOut, const char* pSet){ +void linkSEdge(struct Automate* pAutomate, const unsigned int pIn, const unsigned int pOut, const char pSedge){ /* [0] Initialize variables =========================================================*/ char c; // counter - int setIndex = -1; - char index = pAutomate->states[pIn].n++; + char index = pAutomate->dot[pIn].n++; /* [1] Reallocate memory for link =========================================================*/ - pAutomate->states[pIn].set = realloc( pAutomate->states[pIn].set, pAutomate->states[pIn].n ); - pAutomate->states[pIn].state = realloc( pAutomate->states[pIn].state, pAutomate->states[pIn].n ); + pAutomate->dot[pIn].dot = realloc( pAutomate->dot[pIn].dot, pAutomate->dot[pIn].n ); + pAutomate->dot[pIn].type = realloc( pAutomate->dot[pIn].type, pAutomate->dot[pIn].n ); + pAutomate->dot[pIn].edge = realloc( pAutomate->dot[pIn].edge, pAutomate->dot[pIn].n ); - /* [2] Search for set in set list + /* [2] Create the link =========================================================*/ - /* (1) Search for existing set */ - for( c = 0 ; c < pAutomate->n_set ; c++ ) - if( strcmp(pAutomate->set[c], pSet) == 0 ) - setIndex = c; + pAutomate->dot[pIn].dot[index] = pOut; + pAutomate->dot[pIn].type[index] = 0; + pAutomate->dot[pIn].edge[index] = pSedge; - /* (2) If not found, create one */ - if( setIndex == -1 ) - setIndex = addSet(pAutomate, pSet); +} - /* [3] Create the link +void linkAEdge(struct Automate* pAutomate, const unsigned int pIn, const unsigned int pOut, const char pAedge){ + + /* [0] Initialize variables =========================================================*/ - pAutomate->states[pIn].set[index] = setIndex; - pAutomate->states[pIn].state[index] = pOut; + char c; // counter + char index = pAutomate->dot[pIn].n++; + /* [1] Reallocate memory for link + =========================================================*/ + pAutomate->dot[pIn].dot = realloc( pAutomate->dot[pIn].dot, pAutomate->dot[pIn].n ); + pAutomate->dot[pIn].type = realloc( pAutomate->dot[pIn].type, pAutomate->dot[pIn].n ); + pAutomate->dot[pIn].edge = realloc( pAutomate->dot[pIn].edge, pAutomate->dot[pIn].n ); + + + /* [2] Create the link + =========================================================*/ + pAutomate->dot[pIn].dot[index] = pOut; + pAutomate->dot[pIn].type[index] = 1; + pAutomate->dot[pIn].edge[index] = pAedge; + } diff --git a/src/lib/automate/automate.h b/src/lib/automate/automate.h index 6fceab5..4be2204 100644 --- a/src/lib/automate/automate.h +++ b/src/lib/automate/automate.h @@ -15,19 +15,24 @@ #include - struct AutomateState{ - unsigned int n; // number of associations - char* set; // list of set_id - char* state; // list of state_id + struct AutomateDot{ + char n; // number of edges + char* type; // type of Transition (according to index) (0=string;1=automate) + char* dot; // list of dot_id + char* edge; // list of [sa]edge_id }; struct Automate{ - struct AutomateState* states; // states - char n_state; // Max state index - char sCurrent; // current state index - char sFinal; // final state index - char n_set; // Max set index - char** set; // list of sets + char sedges; // Max sedge index + char aedges; // Max aedge index + char dots; // Max dot index + + struct AutomateDot* dot; // dots + char** sedge; // string edges + struct Automate* aedge; // automate edges + + char dCurrent; // current dot index + char dFinal; // final dot index }; @@ -40,7 +45,7 @@ * @return state The final state we can browse to * */ - int browse(struct Automate pAutomate, const char* pString); + unsigned int browse(struct Automate* pAutomate, const char* pString); /* Builds an automate from a regexp @@ -65,14 +70,15 @@ * */ struct Automate createAutomate(); + // struct Automate clone(const struct Automate* pOriginal); - /* Adds a state to an automate + /* Adds a dot to an automate * - * @return index The created state index + * @return index The created dot index * */ - char addState(struct Automate* pAutomate); + char addDot(struct Automate* pAutomate); /* Adds a set to an automate @@ -82,11 +88,13 @@ */ char addSet(struct Automate* pAutomate, const char* pSet); - + char addStringTransition(struct Automate* pAutomate, const char* pSedge); + char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge); /* Adds a link between 2 states with a set * */ - void linkStates(struct Automate* pAutomate, const unsigned int pIn, const unsigned int pOut, const char* pSet); + void linkSEdge(struct Automate* pAutomate, const unsigned int pIn, const unsigned int pOut, const char pSedge); + void linkAEdge(struct Automate* pAutomate, const unsigned int pIn, const unsigned int pOut, const char pAedge); diff --git a/src/linter.c b/src/linter.c index 8d8bb32..524b059 100644 --- a/src/linter.c +++ b/src/linter.c @@ -22,32 +22,36 @@ int main(int argc, char* argv[]){ /** TEST **/ /** BUILD AUTOMATE **/ + // B = c*d + struct Automate b = createAutomate(); + addDot(&b); + addDot(&b); + addStringTransition(&b, "c\0"); + addStringTransition(&b, "d\0"); + linkSEdge(&b, 0, 0, 0); + linkSEdge(&b, 0, 1, 1); + + // A = a+B = a+c*d struct Automate a = createAutomate(); + addDot(&a); + addDot(&a); + addDot(&a); + addStringTransition(&a, "a\0"); + addAutomateTransition(&a, &b); + linkSEdge(&a, 0, 1, 0); + linkSEdge(&a, 1, 1, 0); + linkAEdge(&a, 1, 2, 0); - addState(&a); - addState(&a); - addState(&a); - - addSet(&a, "ba\0"); - addSet(&a, "be\0"); - addSet(&a, "bi\0"); - - linkStates(&a, 0, 1, "ba\0"); - linkStates(&a, 1, 1, "be\0"); - linkStates(&a, 1, 2, "bi\0"); - - printf("browse 'aei' : %d\n", browse(a, "aei")); - printf("browse 'bbb' : %d\n", browse(a, "bbb")); - printf("browse 'abi' : %d\n", browse(a, "abi")); - printf("browse 'abb' : %d\n", browse(a, "abb")); - printf("browse 'i' : %d\n", browse(a, "i")); - printf("browse 'b' : %d\n", browse(a, "b")); + printf("browse 'acd' : %d ; finalState = %d\n", browse(&a, "acd"), a.dCurrent); + printf("browse 'ad' : %d ; finalState = %d\n", browse(&a, "ad"), a.dCurrent); + printf("browse 'acccd' : %d ; finalState = %d\n", browse(&a, "acccd"), a.dCurrent); + printf("browse 'aaaacccd' : %d ; finalState = %d\n", browse(&a, "aaaacccd"), a.dCurrent); /* Build RegExp */ // char regex[40] = "(a([abc](b+a)(b+e)+ahd)*(b+i)c)sd"; char regex[40] = "(a[c(e[g(i+j)h]f)d]b)"; - buildFromRegExp(regex); + // buildFromRegExp(regex); /** TEST **/ { /* [1] Check arguments