automate [func] but first edge only if matches
This commit is contained in:
parent
91cd13c422
commit
1fbc440c58
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
42
src/linter.c
42
src/linter.c
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue