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
=========================================================*/
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;
}

View File

@ -15,19 +15,24 @@
#include <unistd.h>
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<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
@ -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<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
@ -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);

View File

@ -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