[update] automate can contain himself (pointer) and browse to it

[todo] manage case where you have to go backwards into self (included self automate)
This commit is contained in:
xdrm-brackets 2017-05-17 08:54:15 +02:00
parent bae568e3f5
commit a92714a289
3 changed files with 258 additions and 107 deletions

View File

@ -11,29 +11,45 @@
struct AutomateContext getContext(const char pDot, const char pPath, const unsigned int pIndex){
struct AutomateContext rtn;
unsigned int browse(struct Automate* pAutomate, const char* pString, const char pDepth){ rtn.dot = pDot;
rtn.path = pPath;
rtn.index = pIndex;
printf("%s>>> [browsing %s]\n", pad(pDepth), pAutomate->name); return rtn;
}
unsigned int browse(struct Automate* pAutomate, const char* pString, struct AutomateContext* pCtx, unsigned int* pStep){
printf(">>> [browsing %s]\n", pAutomate->name);
/* [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;
unsigned int c, len, i, l, a, A; // counters unsigned int c, len, i, l, a, A; // counters
char* buffer = malloc(1); struct AutomateDot dotPtr;
char* ptr = NULL; char* ptr = NULL;
struct AutomateDot dotPtr; char* buffer = malloc(1);
unsigned int recursive = 0;
char* pathmem = malloc( sizeof(char) ); // will contain edge number for each dot unsigned int foreignStep = 0;
unsigned int* indexmem = malloc( sizeof(unsigned int) ); // will contain offset of @pString for each dot struct AutomateContext* foreignCtx = malloc( sizeof(struct AutomateContext) );
char* dotmem = malloc( sizeof(char) ); foreignCtx[0] = getContext(0, 0, 0);
pAutomate->path = realloc(pAutomate->path, 1 );
struct Automate* aPtr = NULL;
pCtx = realloc(pCtx, sizeof(struct AutomateContext) * (*pStep+1) );
/* [1] merge automates /* [1] merge automates
=========================================================*/ =========================================================*/
while( pAutomate->aedges > 0 ) if( pAutomate->aedges > 0 )
mergeAutomate(pAutomate, pAutomate->aedges-1); for( l = pAutomate->aedges-1 ; l > 0 ; l-- )
mergeAutomate(pAutomate, l);
@ -42,36 +58,27 @@ unsigned int browse(struct Automate* pAutomate, const char* pString, const char
/* [2] For each char /* [2] For each char
=========================================================*/ =========================================================*/
c = 0; len = strlen(pString);
len = strlen(pString); buffer = realloc(buffer, len+1);
buffer = realloc(buffer, len+1); c = *pStep;
pAutomate->dCurrent = 0;
pAutomate->steps = 0; pAutomate->dCurrent = pCtx[c].dot;
strIndex = pCtx[c].index;
/* (1) For each char try to match /* (1) For each char try to match
---------------------------------------------------------*/ ---------------------------------------------------------*/
c = 0;
strIndex = 0;
pathmem[0] = 0;
pAutomate->path[0] = 0;
while( pAutomate->dCurrent != pAutomate->dFinal && strIndex <= len ){ while( pAutomate->dCurrent != pAutomate->dFinal && strIndex <= len ){
pAutomate->steps++;
(ADB&&0x01) && printf("%s\b * step %d (remaining '%s')\n", pad(pDepth), pAutomate->steps, pString+strIndex);
/* (2) Initialize local data /* (2) Initialize local data
---------------------------------------------------------*/ ---------------------------------------------------------*/
/* (1) Check current state choices */ /* (1) Check current state choices */
dotmem[c] = pAutomate->dCurrent; pCtx[c].dot = pAutomate->dCurrent;
dotPtr = pAutomate->dot[dotmem[c]]; dotPtr = pAutomate->dot[pCtx[c].dot];
i = ( indexmem[c] == strIndex ) ? pathmem[c] : 0; i = ( pCtx[c].index == strIndex ) ? pCtx[c].path : 0;
// indexmem[c] = strIndex; l = dotPtr.n;
l = dotPtr.n;
/* (2) If no more path for this branch -> exit */ /* (2) If no more path for this branch -> exit */
@ -86,16 +93,16 @@ unsigned int browse(struct Automate* pAutomate, const char* pString, const char
/* (1) If STRING match */ /* (1) If STRING match */
if( dotPtr.type[i] == DIRECT_T ){ if( dotPtr.type[i] == DIRECT_T ){
(ADB&&0x01) && printf("%s> q%d --d0--> q%d ?\n", pad(pDepth+1), dotmem[c], dotPtr.dot[i]); (ADB&&0x01) && printf("> q%d --d0--> q%d ?\n", pCtx[c].dot, dotPtr.dot[i]);
pAutomate->dCurrent = dotPtr.dot[i]; pAutomate->dCurrent = dotPtr.dot[i];
pathmem[c] = i; pCtx[c].path = i;
break; break;
/* (2) If STRING match */ /* (2) If STRING match */
}else if( dotPtr.type[i] == STRING_T ){ }else if( dotPtr.type[i] == STRING_T ){
(ADB&&0x01) && printf("%s> q%d --s%d--> q%d ?\n", pad(pDepth+1), dotmem[c], dotPtr.edge[i], dotPtr.dot[i]); (ADB&&0x01) && printf("> q%d --s%d--> q%d ?\n", pCtx[c].dot, dotPtr.edge[i], dotPtr.dot[i]);
ptr = pAutomate->sedge[dotPtr.edge[i]]; ptr = pAutomate->sedge[dotPtr.edge[i]];
strncpy(buffer, pString+strIndex, strlen(ptr)); strncpy(buffer, pString+strIndex, strlen(ptr));
@ -104,28 +111,28 @@ unsigned int browse(struct Automate* pAutomate, const char* pString, const char
if( strcmp(buffer, ptr) == 0 ){ if( strcmp(buffer, ptr) == 0 ){
pAutomate->dCurrent = dotPtr.dot[i]; pAutomate->dCurrent = dotPtr.dot[i];
strIndex += strlen(ptr); strIndex += strlen(ptr);
pathmem[c] = i; pCtx[c].path = i;
break; break;
} }
/* (3) If RANGE match */ /* (3) If RANGE match */
}else if( dotPtr.type[i] == RANGE_T ){ }else if( dotPtr.type[i] == RANGE_T ){
(ADB&&0x01) && printf("%s> q%d --r%d--> q%d ?\n", pad(pDepth+1), dotmem[c], dotPtr.edge[i], dotPtr.dot[i]); (ADB&&0x01) && printf("> q%d --r%d--> q%d ?\n", pCtx[c].dot, dotPtr.edge[i], dotPtr.dot[i]);
ptr = pAutomate->redge[dotPtr.edge[i]]; ptr = pAutomate->redge[dotPtr.edge[i]];
if( pString[strIndex] >= ptr[0] && pString[strIndex] <= ptr[1] ){ if( pString[strIndex] >= ptr[0] && pString[strIndex] <= ptr[1] ){
pAutomate->dCurrent = dotPtr.dot[i]; pAutomate->dCurrent = dotPtr.dot[i];
strIndex += 1; strIndex += 1;
pathmem[c] = i; pCtx[c].path = i;
break; break;
} }
/* (4) If LIST match */ /* (4) If LIST match */
}else if( dotPtr.type[i] == LIST_T ){ }else if( dotPtr.type[i] == LIST_T ){
(ADB&&0x01) && printf("%s> q%d --l%d--> q%d ?\n", pad(pDepth+1), dotmem[c], dotPtr.edge[i], dotPtr.dot[i]); (ADB&&0x01) && printf("> q%d --l%d--> q%d ?\n", pCtx[c].dot, dotPtr.edge[i], dotPtr.dot[i]);
ptr = pAutomate->ledge[dotPtr.edge[i]]; ptr = pAutomate->ledge[dotPtr.edge[i]];
@ -139,24 +146,47 @@ unsigned int browse(struct Automate* pAutomate, const char* pString, const char
if( a < A ){ if( a < A ){
pAutomate->dCurrent = dotPtr.dot[i]; pAutomate->dCurrent = dotPtr.dot[i];
strIndex += 1; strIndex += 1;
pathmem[c] = i; pCtx[c].path = i;
break; break;
} }
/* (5) If AUTOMATE match */ /* (5) If AUTOMATE match */
}else if( dotPtr.type[i] == AUTOMATE_T ){ }else if( dotPtr.type[i] == AUTOMATE_T ){
(ADB&&0x01) && printf("%s> q%d --a%d--> q%d ?\n", pad(pDepth+1), dotmem[c], dotPtr.edge[i], dotPtr.dot[i]); (ADB&&0x01) && printf("> q%d --a%d--> q%d ?\n", pCtx[c].dot, dotPtr.edge[i], dotPtr.dot[i]);
aPtr = pAutomate->aedge[dotPtr.edge[i]];
recursive = browse(&pAutomate->aedge[dotPtr.edge[i]], pString+strIndex, pDepth+1); foreignStep = 0;
foreignCtx = realloc(foreignCtx, sizeof(struct AutomateContext));
foreignCtx[0] = getContext(0, 0, 0);
if( pAutomate->aedge[dotPtr.edge[i]].steps > 0 ) while( foreignStep != 0 || foreignCtx[foreignStep].path < aPtr->dot[foreignCtx[foreignStep].dot].n ){
pAutomate->steps += pAutomate->aedge[dotPtr.edge[i]].steps-1;
if( pAutomate->aedge[dotPtr.edge[i]].dCurrent == pAutomate->aedge[dotPtr.edge[i]].dFinal ){ // printf("browse start -> index: '%s'\n", pString+strIndex);
recursive = browse(aPtr, pString+strIndex, foreignCtx, &foreignStep);
// printf("browsed end -> index: %d/%d - state: %d/%d\n", recursive, (int)strlen(pString+strIndex), aPtr->dCurrent, aPtr->dFinal);
// If correct -> exit from while()
if( aPtr->dCurrent == aPtr->dFinal )
break;
// If have to go backwards
if( recursive == foreignCtx[foreignStep].index && foreignCtx[foreignStep].dot == aPtr->dCurrent && i >= l ){
// {1} if not first branch -> go previous //
if( foreignStep > 0 )
foreignStep--;
// {2} else next path of previous branch //
foreignCtx[foreignStep].path++;
foreignCtx = realloc(foreignCtx, sizeof(struct AutomateContext) * (foreignStep+1) );
}
}
if( aPtr->dCurrent == aPtr->dFinal ){
pCtx[c].path = i;
strIndex += recursive;
pAutomate->dCurrent = dotPtr.dot[i]; pAutomate->dCurrent = dotPtr.dot[i];
strIndex += recursive;
pathmem[c] = i;
break; break;
} }
@ -168,36 +198,30 @@ unsigned int browse(struct Automate* pAutomate, const char* pString, const char
/* (4) Next dot or previous if locked /* (4) Next dot or previous if locked
---------------------------------------------------------*/ ---------------------------------------------------------*/
/* (1) If no char procesed && same dot && no action performed */ /* (1) If no char procesed && same dot && no action performed */
if( strIndex == indexmem[c] && dotmem[c] == pAutomate->dCurrent && i >= l ){ if( strIndex == pCtx[c].index && pCtx[c].dot == pAutomate->dCurrent && i >= l ){
// {1} if not first branch -> go previous // // {1} if not first branch -> go previous //
if( c > 0 ) if( c > 0 )
c--; c--;
// {2} else next path of previous branch // // {2} else next path of previous branch //
strIndex = indexmem[c]; strIndex = pCtx[c].index;
pathmem[c]++; pCtx[c].path++;
pAutomate->dCurrent = dotmem[c]; pAutomate->dCurrent = pCtx[c].dot;
(ADB&&0x01) && printf("%s< not\n", pad(pDepth+1)); (ADB&&0x01) && printf("< not\n");
(ADB&&0x01) && printf("%s* back to q%d:%d\n", pad(pDepth+1), dotmem[c], pathmem[c]); (ADB&&0x01) && printf("* back to q%d:%d\n", pCtx[c].dot, pCtx[c].path);
pCtx = realloc(pCtx, sizeof(struct AutomateContext) * (c+1) );
/* (2) Next branch + reset data (if already browsed in other path) */ /* (2) Next branch + reset data (if already browsed in other path) */
}else{ }else{
(ADB&&0x01) && printf("%s< yes\n", pad(pDepth+1)); (ADB&&0x01) && printf("< yes\n");
c++; c++;
pathmem = realloc(pathmem, sizeof(char) * (c+1) ); pCtx = realloc(pCtx, sizeof(struct AutomateContext) * (c+1) );
indexmem = realloc(indexmem, sizeof(unsigned int) * (c+1) );
dotmem = realloc(dotmem, sizeof(char) * (c+1) );
pAutomate->n = c; pCtx[c].index = strIndex;
pAutomate->path = realloc(pAutomate->path, sizeof(char) * (c+1) ); pCtx[c].path = 0;
pAutomate->path[c] = pAutomate->dCurrent;
indexmem[c] = strIndex;
pathmem[c] = 0;
} }
@ -205,15 +229,18 @@ unsigned int browse(struct Automate* pAutomate, const char* pString, const char
} }
ptr = NULL; ptr = NULL;
free(buffer); free(buffer);
free(pathmem); free(foreignCtx);
free(indexmem);
free(dotmem);
(ADB&&0x01) && printf("%s>>> [done %s = %d/%d]\n", pad(pDepth), pAutomate->name, pAutomate->dCurrent, pAutomate->dFinal); (ADB&&0x01) && printf(">>> [done %s = %d/%d]\n", pAutomate->name, pAutomate->dCurrent, pAutomate->dFinal);
return strIndex;
*pStep = ( c == *pStep ) ? *pStep : c-1;
if( strIndex == 0 )
return 0;
else
return strIndex;
} }
@ -326,7 +353,7 @@ void debug(const struct Automate pAutomate){
else if( pAutomate.dot[a].type[b] == RANGE_T ) else if( pAutomate.dot[a].type[b] == RANGE_T )
printf(" * q%d match range '%s'\n", pAutomate.dot[a].dot[b], pAutomate.redge[pAutomate.dot[a].edge[b]]); printf(" * q%d match range '%s'\n", pAutomate.dot[a].dot[b], pAutomate.redge[pAutomate.dot[a].edge[b]]);
else if( pAutomate.dot[a].type[b] == AUTOMATE_T ) else if( pAutomate.dot[a].type[b] == AUTOMATE_T )
printf(" * q%d match automate '%s'\n", pAutomate.dot[a].dot[b], pAutomate.aedge[pAutomate.dot[a].edge[b]].name); printf(" * q%d match automate '%s'\n", pAutomate.dot[a].dot[b], ((struct Automate*)pAutomate.aedge[pAutomate.dot[a].edge[b]])->name);
} }
@ -360,8 +387,6 @@ struct Automate createAutomate(const char* pName){
automate.dCurrent = 0; automate.dCurrent = 0;
automate.dFinal = 0; automate.dFinal = 0;
automate.n = 0;
/* [2] First allocation /* [2] First allocation
=========================================================*/ =========================================================*/
automate.dot = malloc( 0 ); automate.dot = malloc( 0 );
@ -369,7 +394,6 @@ struct Automate createAutomate(const char* pName){
automate.redge = malloc( 0 ); automate.redge = malloc( 0 );
automate.ledge = malloc( 0 ); automate.ledge = malloc( 0 );
automate.aedge = malloc( 0 ); automate.aedge = malloc( 0 );
automate.path = malloc( 0 );
automate.name = malloc( strlen(pName) + 1 ); automate.name = malloc( strlen(pName) + 1 );
strcpy(automate.name, pName); strcpy(automate.name, pName);
@ -380,11 +404,83 @@ struct Automate createAutomate(const char* pName){
} }
void mergeAutomate(struct Automate* pMaster, const char pSlaveIndex){ void destroyAutomate(struct Automate* pAutomate){
/* [0] Initialize variables
=========================================================*/
char d, e;
/* [1] Destroy edges
=========================================================*/
/* (1) String Edges
---------------------------------------------------------*/
for( e = 0 ; e < pAutomate->sedges ; e++ )
free(pAutomate->sedge[e]);
free(pAutomate->sedge);
/* (2) List Edges
---------------------------------------------------------*/
for( e = 0 ; e < pAutomate->ledges ; e++ )
free(pAutomate->ledge[e]);
free(pAutomate->ledge);
/* (3) Range Edges
---------------------------------------------------------*/
for( e = 0 ; e < pAutomate->redges ; e++ )
free(pAutomate->redge[e]);
free(pAutomate->redge);
/* (4) Automate Edges
---------------------------------------------------------*/
free(pAutomate->aedge);
/* [2] Destroy dots
=========================================================*/
for( d = 0 ; d < pAutomate->dots ; d++ ){
free(pAutomate->dot[d].type);
free(pAutomate->dot[d].dot);
free(pAutomate->dot[d].edge);
free(&pAutomate->dot[d]);
}
free(pAutomate->dot);
/* [3] Destroy main pointer
=========================================================*/
free(pAutomate);
}
char mergeAutomate(struct Automate* pMaster, const char pSlaveIndex){
/* (1) If no such @pSlave -> abort */
if( pSlaveIndex >= pMaster->aedges ){
(ADB&0x01) && printf(" (!) merge error: no such slave automate\n");
return 0;
}
/* (2) If @pSlave == @pMaster -> do not do anything */
if( pMaster->aedge[pSlaveIndex] == pMaster ){
(ADB&0x01) && printf(" (!) merge error: slave is master\n");
return 0;
}
/* [0] Initialize variables /* [0] Initialize variables
=========================================================*/ =========================================================*/
char a, d, e, dot, edge, edges, dotOffset, rtn, next_dot; char a, d, e, dot, edge, edges, dotOffset, rtn, next_dot;
int sub;
char sedges = pMaster->sedges; char sedges = pMaster->sedges;
char ledges = pMaster->ledges; char ledges = pMaster->ledges;
@ -392,14 +488,18 @@ void mergeAutomate(struct Automate* pMaster, const char pSlaveIndex){
char aedges = pMaster->aedges; char aedges = pMaster->aedges;
char dots = pMaster->dots; char dots = pMaster->dots;
char final = pMaster->dFinal; char final = pMaster->dFinal;
struct Automate* pSlave = &pMaster->aedge[pSlaveIndex]; struct Automate* pSlave = pMaster->aedge[pSlaveIndex];
while( pSlave->aedges > 0 ) /* [1] Merge automates recursively
mergeAutomate(pSlave, pSlave->aedges-1); =========================================================*/
if( pSlave->aedges > 1 )
for( sub = pSlave->aedges-1 ; sub >= 0 ; sub-- )
if( sub != pSlaveIndex )
mergeAutomate(pMaster->aedge[pSlaveIndex], sub);
/* [1] Merge @pSlave edges into @pMaster edges /* [2] Merge @pSlave edges into @pMaster edges
=========================================================*/ =========================================================*/
/* (1) String edges (sedges) */ /* (1) String edges (sedges) */
for( a = 0 ; a < pSlave->sedges ; a++ ){ for( a = 0 ; a < pSlave->sedges ; a++ ){
@ -421,12 +521,12 @@ void mergeAutomate(struct Automate* pMaster, const char pSlaveIndex){
/* (4) Automate edges (aedges) */ /* (4) Automate edges (aedges) */
for( a = 0 ; a < pSlave->aedges ; a++ ){ for( a = 0 ; a < pSlave->aedges ; a++ ){
rtn = addAutomateTransition(pMaster, &pSlave->aedge[a]); rtn = addAutomateTransition(pMaster, pSlave->aedge[a]);
(ADB&0x01) && printf("merge SLAVE.automate.%d into MASTER.automate.%d\n", a, rtn) ; (ADB&0x01) && printf("merge SLAVE.automate.%d into MASTER.automate.%d\n", a, rtn) ;
} }
/* [2] For each use of @pSlave in pMaster, replace /* [3] For each use of @pSlave in pMaster, replace
=========================================================*/ =========================================================*/
/* (1) For each fot of @pMaster */ /* (1) For each fot of @pMaster */
for( dot = 0 ; dot < dots ; dot++ ){ for( dot = 0 ; dot < dots ; dot++ ){
@ -493,10 +593,22 @@ void mergeAutomate(struct Automate* pMaster, const char pSlaveIndex){
} }
/* [3] Clean @pMaster /* [4] Clean @pMaster
=========================================================*/ =========================================================*/
/* (1) Remove @pSlave form @pMaster */ /* (1) Remove @pSlave form @pMaster */
pMaster->aedge = realloc(pMaster->aedge, sizeof(struct Automate) * --pMaster->aedges);
// {1} Destroy @pSlave //
destroyAutomate(pMaster->aedge[pSlaveIndex]);
// {2} Shift back next automates //
for( d = pSlaveIndex+1 ; d < pMaster->aedges ; d++ )
memcpy(&pMaster->aedge[d-1], &pMaster->aedge[d], sizeof(struct Automate));
// {3} Decrement automate edges count //
pMaster->aedges--;
// {4} Free last automate //
pMaster->aedge = realloc(pMaster->aedge, sizeof(struct Automate) * pMaster->aedges);
/* (2) Keep old @pMaster.dFinal */ /* (2) Keep old @pMaster.dFinal */
(ADB&&0x01) && printf("restauring final to %d\n", final); (ADB&&0x01) && printf("restauring final to %d\n", final);
@ -505,6 +617,8 @@ void mergeAutomate(struct Automate* pMaster, const char pSlaveIndex){
(ADB&0x01) && printf("SLAVE.%s successfully merged into MASTER.%s\n\n", pSlave->name, pMaster->name) ; (ADB&0x01) && printf("SLAVE.%s successfully merged into MASTER.%s\n\n", pSlave->name, pMaster->name) ;
return 1;
} }
@ -602,12 +716,12 @@ char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge){
/* [1] Reallocate memory for aedge /* [1] Reallocate memory for aedge
=========================================================*/ =========================================================*/
pAutomate->aedge = realloc(pAutomate->aedge, sizeof(struct Automate) * pAutomate->aedges ); pAutomate->aedge = realloc(pAutomate->aedge, sizeof(void*) * pAutomate->aedges );
/* [2] Create the aedge /* [2] Create the aedge
=========================================================*/ =========================================================*/
memcpy(&pAutomate->aedge[index], pAedge, sizeof(struct Automate)); pAutomate->aedge[index] = pAedge;
return index; return index;
} }

View File

@ -24,7 +24,13 @@
} AutomateType; } AutomateType;
#define ADB 0x00 #define ADB 0x01
struct AutomateContext{
char dot;
char path;
unsigned int index;
};
struct AutomateDot{ struct AutomateDot{
char n; // number of edges char n; // number of edges
@ -44,31 +50,40 @@
char** sedge; // string edges char** sedge; // string edges
char** redge; // range edges (between char[0] and char[1]) char** redge; // range edges (between char[0] and char[1])
char** ledge; // list edges (in one of the given char-s) char** ledge; // list edges (in one of the given char-s)
struct Automate* aedge; // automate edges void** aedge; // automate (pointer) edges
char dCurrent; // current dot index char dCurrent; // current dot index
char dFinal; // final dot index char dFinal; // final dot index
unsigned int steps; // number of steps
char* name; // automate name char* name; // automate name
char* path; // automate path
unsigned int n; // automate path length
}; };
/* Creates an automate context
*
* @dot<char> Current
* @path<char> Current min path
* @index<unsigned int> Current stirng index
*
* @return context<struct AutomateContext> The created context
*
*/
struct AutomateContext getContext(const char pDot, const char pPath, const unsigned int pIndex);
/* Try to browse an automate with a string /* Try to browse an automate with a string
* *
* @pAutomate<struct Automate*> Current working automate * @pAutomate<struct Automate*> Current working automate
* @pString<const char*> String to test * @pString<const char*> String to test
* @pDepth<const char> Padding * @pCtx<struct AutomateContext*> Already browsed context
* *
* @return offset<int> The @pString offset browsed to * @return offset<int> The @pString offset browsed to
* *
* @NOTE: Automate.dCurrent is equal to Automate.dFinal if final state reached * @NOTE: Automate.dCurrent is equal to Automate.dFinal if final state reached
* *
*/ */
unsigned int browse(struct Automate* pAutomate, const char* pString, const char pDepth); unsigned int browse(struct Automate* pAutomate, const char* pString, struct AutomateContext* pCtx, unsigned int* pStep);
/* Builds an automate from a regexp /* Builds an automate from a regexp
@ -95,14 +110,22 @@
*/ */
struct Automate createAutomate(const char* pName); struct Automate createAutomate(const char* pName);
/* Destroys an automate
*
* @pAutomate<struct Automate*> Automate pointer
*
*/
void destroyAutomate(struct Automate* pAutomate);
/* Merges an automate into another /* Merges an automate into another
* *
* @pMaster<struct Automate*> Master automate that contains @pSlave * @pMaster<struct Automate*> Master automate that contains @pSlave
* @pSlaveIndex<const char> Slave automate index into @pMaster * @pSlaveIndex<const char> Slave automate index into @pMaster
* *
* @return status<char> 1 on success ; 0 on failure
* *
*/ */
void mergeAutomate(struct Automate* pMaster, const char pSlaveIndex); char mergeAutomate(struct Automate* pMaster, const char pSlaveIndex);
/* Adds a dot to an automate /* Adds a dot to an automate

View File

@ -104,23 +104,37 @@ int main(int argc, char* argv[]){
linkDots(&array, 1, 3, AUTOMATE_T, 0); // q1 --a0--> q3 linkDots(&array, 1, 3, AUTOMATE_T, 0); // q1 --a0--> q3
linkDots(&array, 1, 3, STRING_T, 1); // q1 --s1--> q3 linkDots(&array, 1, 3, STRING_T, 1); // q1 --s1--> q3
char str[80] = {0};
strcpy(str, "[null, \"abc\", \"def\", false, true, 12, -1.2, .54, -.3, 5., \"bla\\\"blo\\rbla\\n\"]\0");
clock_t start, stop;
unsigned int browsed = 0;
start = clock(); browsed = browse(&array, str, 0); stop = clock();
printf("browse '%s': %d/%d\n", str, browsed, (int) strlen(str));
printf(" (*) final_state: %d/%d\n", array.dCurrent, array.dFinal); struct Automate test = createAutomate("test");
printf(" (*) in %d steps\n", array.steps); addDot(&test); // q0
addDot(&test); // q1
addDot(&test); // q2
addDot(&test); // q3
addStringTransition(&test, "a\0"); // s0
addStringTransition(&test, "b\0"); // s0
addAutomateTransition(&test, &test); // a1
linkDots(&test, 0, 1, STRING_T, 0); // q0 --s0--> q1
linkDots(&test, 1, 2, AUTOMATE_T, 0); // q1 --s0--> q2
linkDots(&test, 1, 2, DIRECT_T, 1); // q1 --d0--> q2
linkDots(&test, 2, 3, STRING_T, 1); // q1 --s1--> q2
debug(test);
char str[80] = {0};
clock_t start, stop;
unsigned int step = 0;
struct AutomateContext* ctx = malloc( sizeof(struct AutomateContext) * 1 );
ctx[0] = getContext(0, 0, 0);
strcpy(str, "aaabbb\0");
start = clock();
unsigned int browsed = browse(&test, str, ctx, &step); stop = clock();
// printf("browse '%s': %d/%d\n", str, ctx[step].index, (int) strlen(str));
printf(" (*) final_state: %d/%d\n", test.dCurrent, test.dFinal);
printf(" (*) read: %d/%d\n", browsed, (int)strlen(str));
printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC);
for( c = 0 ; c < array.n ; c++ ){
if( c > 0 )
printf(" -> ");
printf("q%d", array.path[c]);
}
printf("\n");
exit(0); exit(0);
/* Build RegExp */ /* Build RegExp */