automate [func] but first edge only if matches

This commit is contained in:
xdrm-brackets 2017-05-15 03:34:44 +02:00
parent 91cd13c422
commit 1fbc440c58
3 changed files with 157 additions and 82 deletions

View File

@ -12,38 +12,68 @@
int browse(struct Automate pAutomate, const char* pString){ unsigned int browse(struct Automate* pAutomate, const char* pString){
/* [0] Initialize variables /* [0] Initialize variables
=========================================================*/ =========================================================*/
unsigned int strIndex = 0; // String current char index unsigned int strIndex = 0; // String current char index
unsigned int recursive;
int c, len, i, l; // counters int c, len, i, l; // counters
char* buffer = malloc(1);
char* ptr = NULL;
struct AutomateDot dotPtr;
/* [1] For each char /* [1] For each char
=========================================================*/ =========================================================*/
c = 0; len = strlen(pString); c = 0; len = strlen(pString);
buffer = realloc(buffer, len+1);
pAutomate->dCurrent = 0;
for( ; c < len ; c++ ){ for( ; c < len ; c++ ){
/* (1) Check if the current char can lead to a state /* (1) Check if the current char can lead to a state
---------------------------------------------------------*/ ---------------------------------------------------------*/
/* (1) Check current state choices */ /* (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++ ){ for( ; i < l ; i++ ){
/* (2) If part of set */ /* (2) If STRING match */
if( is_part(pString[strIndex], pAutomate.set[pAutomate.states[pAutomate.sCurrent].set[i]]) == 1 ){ if( dotPtr.type[i] == 0 ){
pAutomate.sCurrent = pAutomate.states[pAutomate.sCurrent].state[i];
strIndex++; 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 /* [1] Create n values
=========================================================*/ =========================================================*/
automate.n_state = 0; automate.dots = 0;
automate.n_set = 0; automate.sedges = 0;
automate.sCurrent = 0; automate.aedges = 0;
automate.sFinal = 0;
automate.dCurrent = 0;
automate.dFinal = 0;
/* [2] First allocation /* [2] First allocation
=========================================================*/ =========================================================*/
automate.states = malloc( 0 ); automate.dot = malloc( 0 );
automate.set = malloc( 0 ); automate.sedge = malloc( 0 );
automate.aedge = malloc( 0 );
/* [3] Return initialized automate /* [3] Return initialized automate
@ -147,87 +180,117 @@ struct Automate createAutomate(){
char addState(struct Automate* pAutomate){ char addDot(struct Automate* pAutomate){
/* [0] Initialize variables /* [0] Initialize variables
=========================================================*/ =========================================================*/
char index = pAutomate->n_state++; char index = pAutomate->dots++;
/* [1] Reallocate memory for the state /* [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->dot[index].n = 0;
pAutomate->states[index].set = malloc( 0 ); pAutomate->dot[index].type = malloc( 0 );
pAutomate->states[index].state = malloc( 0 ); pAutomate->dot[index].dot = malloc( 0 );
pAutomate->dot[index].edge = malloc( 0 );
/* [3] Set new state as final /* [3] Set new state as final
=========================================================*/ =========================================================*/
pAutomate->sFinal = index; pAutomate->dFinal = index;
return index; return index;
} }
char addSet(struct Automate* pAutomate, const char* pSet){
char addStringTransition(struct Automate* pAutomate, const char* pSedge){
/* [0] Initialize variables /* [0] Initialize variables
=========================================================*/ =========================================================*/
char index = pAutomate->n_set++; char index = pAutomate->sedges++;
/* [1] Reallocate memory for sedge
/* [1] Add the set
=========================================================*/ =========================================================*/
/* (1) Reallocate memory for the set */ pAutomate->sedge = realloc(pAutomate->sedge, sizeof(char) * pAutomate->sedges );
pAutomate->set = realloc( pAutomate->set, sizeof(char*) * pAutomate->n_set ); pAutomate->sedge[index] = malloc( strlen(pSedge)+1 );
pAutomate->set[index] = realloc( pAutomate->set[index], strlen(pSet) + 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; 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 /* [0] Initialize variables
=========================================================*/ =========================================================*/
char c; // counter char c; // counter
int setIndex = -1; char index = pAutomate->dot[pIn].n++;
char index = pAutomate->states[pIn].n++;
/* [1] Reallocate memory for link /* [1] Reallocate memory for link
=========================================================*/ =========================================================*/
pAutomate->states[pIn].set = realloc( pAutomate->states[pIn].set, pAutomate->states[pIn].n ); pAutomate->dot[pIn].dot = realloc( pAutomate->dot[pIn].dot, pAutomate->dot[pIn].n );
pAutomate->states[pIn].state = realloc( pAutomate->states[pIn].state, pAutomate->states[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 */ pAutomate->dot[pIn].dot[index] = pOut;
for( c = 0 ; c < pAutomate->n_set ; c++ ) pAutomate->dot[pIn].type[index] = 0;
if( strcmp(pAutomate->set[c], pSet) == 0 ) pAutomate->dot[pIn].edge[index] = pSedge;
setIndex = c;
/* (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; char c; // counter
pAutomate->states[pIn].state[index] = pOut; 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;
} }

View File

@ -15,19 +15,24 @@
#include <unistd.h> #include <unistd.h>
struct AutomateState{ struct AutomateDot{
unsigned int n; // number of associations char n; // number of edges
char* set; // list of set_id char* type; // type of Transition (according to index) (0=string;1=automate)
char* state; // list of state_id char* dot; // list of dot_id
char* edge; // list of [sa]edge_id
}; };
struct Automate{ struct Automate{
struct AutomateState* states; // states char sedges; // Max sedge index
char n_state; // Max state index char aedges; // Max aedge index
char sCurrent; // current state index char dots; // Max dot index
char sFinal; // final state index
char n_set; // Max set index struct AutomateDot* dot; // dots
char** set; // list of sets 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<int> The final state we can browse to * @return state<int> 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 /* Builds an automate from a regexp
@ -65,14 +70,15 @@
* *
*/ */
struct Automate createAutomate(); struct Automate createAutomate();
// struct Automate clone(const struct Automate* pOriginal);
/* Adds a state to an automate /* Adds a dot to an automate
* *
* @return index<char> The created state index * @return index<char> The created dot index
* *
*/ */
char addState(struct Automate* pAutomate); char addDot(struct Automate* pAutomate);
/* Adds a set to an automate /* Adds a set to an automate
@ -82,11 +88,13 @@
*/ */
char addSet(struct Automate* pAutomate, const char* pSet); 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 /* 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);

View File

@ -22,32 +22,36 @@ int main(int argc, char* argv[]){
/** TEST **/ /** TEST **/
/** BUILD AUTOMATE **/ /** 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(); 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); printf("browse 'acd' : %d ; finalState = %d\n", browse(&a, "acd"), a.dCurrent);
addState(&a); printf("browse 'ad' : %d ; finalState = %d\n", browse(&a, "ad"), a.dCurrent);
addState(&a); printf("browse 'acccd' : %d ; finalState = %d\n", browse(&a, "acccd"), a.dCurrent);
printf("browse 'aaaacccd' : %d ; finalState = %d\n", browse(&a, "aaaacccd"), a.dCurrent);
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"));
/* Build RegExp */ /* Build RegExp */
// char regex[40] = "(a([abc](b+a)(b+e)+ahd)*(b+i)c)sd"; // 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)"; char regex[40] = "(a[c(e[g(i+j)h]f)d]b)";
buildFromRegExp(regex); // buildFromRegExp(regex);
/** TEST **/ /** TEST **/
{ /* [1] Check arguments { /* [1] Check arguments