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
|
||||
=========================================================*/
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
|
42
src/linter.c
42
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
|
||||
|
|
Loading…
Reference in New Issue