From 315a8be97a3c09ecc3b0a7062e89fa487ddcffe1 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 15 May 2017 17:08:30 +0200 Subject: [PATCH] [bigupdate] `mergeAutomate` works well [todo] manage @pSlave removal from @pMaster + [update] now browse is successful --- src/lib/automate/automate.c | 309 +++++++++++++++++++++++++++++++----- src/lib/automate/automate.h | 49 ++++-- src/linter.c | 129 +++++---------- src/test | 82 ++++++++++ 4 files changed, 427 insertions(+), 142 deletions(-) create mode 100644 src/test diff --git a/src/lib/automate/automate.c b/src/lib/automate/automate.c index 6959a1a..1cd4ef2 100644 --- a/src/lib/automate/automate.c +++ b/src/lib/automate/automate.c @@ -12,7 +12,9 @@ -unsigned int browse(struct Automate* pAutomate, const char* pString){ +unsigned int browse(struct Automate* pAutomate, const char* pString, const char pDepth){ + + printf("%s>>> [browsing %s]\n", pad(pDepth), pAutomate->name); /* [0] Initialize variables =========================================================*/ @@ -23,9 +25,9 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ char* ptr = NULL; struct AutomateDot dotPtr; - char* pathmem = malloc( strlen(pString) ); // will contain edge number for each dot - unsigned int* indexmem = malloc( sizeof(unsigned int) * strlen(pString) ); // will contain offset of @pString for each dot - char* dotmem = malloc( strlen(pString) ); + char* pathmem = malloc( sizeof(char) ); // will contain edge number for each dot + unsigned int* indexmem = malloc( sizeof(unsigned int) ); // will contain offset of @pString for each dot + char* dotmem = malloc( sizeof(char) ); /* [1] For each char =========================================================*/ @@ -36,24 +38,21 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ pAutomate->steps = 0; - /* (1) Initialize path memory - ---------------------------------------------------------*/ - for( c = 0 ; c < len ; c++ ){ - pathmem[c] = 0; - indexmem[c] = 0; - } - - /* (2) For each char try to match + /* (1) For each char try to match ---------------------------------------------------------*/ - c = 0; - strIndex = 0; - while( c < len ){ + c = 0; + strIndex = 0; + pathmem[0] = 0; + + 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); - /* (1) Check if the current char can lead to a state + /* (2) Initialize local data ---------------------------------------------------------*/ /* (1) Check current state choices */ dotmem[c] = pAutomate->dCurrent; @@ -69,11 +68,23 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ break; - + /* (3) Try paths from the current dot + ---------------------------------------------------------*/ for( ; i < l ; i++ ){ - /* (3) If STRING match */ - if( dotPtr.type[i] == AUTOMATE_TYPE_STRING ){ + /* (1) If STRING match */ + if( dotPtr.type[i] == DIRECT_T ){ + + (ADB&&0x01) && printf("%s> q%d --d0--> q%d ?\n", pad(pDepth+1), dotmem[c], dotPtr.dot[i]); + + pAutomate->dCurrent = dotPtr.dot[i]; + pathmem[c] = i; + break; + + /* (2) If STRING match */ + }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]); ptr = pAutomate->sedge[dotPtr.edge[i]]; strncpy(buffer, pString+strIndex, strlen(ptr)); @@ -86,20 +97,24 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ break; } - /* (4) If RANGE match */ - }else if( dotPtr.type[i] == AUTOMATE_TYPE_RANGE ){ + /* (3) If RANGE match */ + }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]); ptr = pAutomate->redge[dotPtr.edge[i]]; if( pString[strIndex] >= ptr[0] && pString[strIndex] <= ptr[1] ){ pAutomate->dCurrent = dotPtr.dot[i]; strIndex += 1; - pathmem[c] = i; + pathmem[c] = i; break; } - /* (5) If LIST match */ - }else if( dotPtr.type[i] == AUTOMATE_TYPE_LIST ){ + /* (4) If LIST match */ + }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]); ptr = pAutomate->ledge[dotPtr.edge[i]]; @@ -112,15 +127,20 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ // if a char matches -> store it if( a < A ){ pAutomate->dCurrent = dotPtr.dot[i]; - strIndex += 1; - pathmem[c] = i; + strIndex += 1; + pathmem[c] = i; break; } - /* (6) If AUTOMATE match */ - }else{ + /* (5) If AUTOMATE match */ + }else if( dotPtr.type[i] == AUTOMATE_T ){ - recursive = browse(&pAutomate->aedge[dotPtr.edge[i]], pString+strIndex); + (ADB&&0x01) && printf("%s> q%d --a%d--> q%d ?\n", pad(pDepth+1), dotmem[c], dotPtr.edge[i], dotPtr.dot[i]); + + recursive = browse(&pAutomate->aedge[dotPtr.edge[i]], pString+strIndex, pDepth+1); + + if( pAutomate->aedge[dotPtr.edge[i]].steps > 0 ) + pAutomate->steps += pAutomate->aedge[dotPtr.edge[i]].steps-1; if( pAutomate->aedge[dotPtr.edge[i]].dCurrent == pAutomate->aedge[dotPtr.edge[i]].dFinal ){ pAutomate->dCurrent = dotPtr.dot[i]; @@ -134,8 +154,10 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ } - /* (7) If no more path */ - if( strIndex == indexmem[c] ){ + /* (4) Next dot or previous if locked + ---------------------------------------------------------*/ + /* (1) If no char procesed && same dot && no action performed */ + if( strIndex == indexmem[c] && dotmem[c] == pAutomate->dCurrent && i >= l ){ // {1} if not first branch -> go previous // if( c > 0 ) @@ -145,12 +167,19 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ strIndex = indexmem[c]; pathmem[c]++; pAutomate->dCurrent = dotmem[c]; - // printf("* back to q%d:%d\n", dotmem[c], pathmem[c]); + (ADB&&0x01) && printf("%s< not\n", pad(pDepth+1)); + (ADB&&0x01) && printf("%s* back to q%d:%d\n", pad(pDepth+1), dotmem[c], pathmem[c]); - /* (8) Next branch + reset data (if already browsed in other path) */ + + /* (2) Next branch + reset data (if already browsed in other path) */ }else{ - // printf("q%d -%.1s-> q%d\n", c, pString+indexmem[c], pAutomate->dCurrent); + (ADB&&0x01) && printf("%s< yes\n", pad(pDepth+1)); + c++; + pathmem = realloc(pathmem, sizeof(char) * (c+1) ); + indexmem = realloc(indexmem, sizeof(unsigned int) * (c+1) ); + dotmem = realloc(dotmem, sizeof(char) * (c+1) ); + pathmem[c] = 0; } @@ -163,7 +192,9 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ free(buffer); free(pathmem); free(indexmem); + free(dotmem); + (ADB&&0x01) && printf("%s>>> [done %s = %d/%d]\n", pad(pDepth), pAutomate->name, pAutomate->dCurrent, pAutomate->dFinal); return strIndex; @@ -242,7 +273,60 @@ struct Automate buildFromRegExp(const char* pRegExp){ -struct Automate createAutomate(){ +void debug(const struct Automate pAutomate){ + printf("== %s ==\n", pAutomate.name); + + /* [0] Initialize variables + =========================================================*/ + char a, b; + + + /* [1] Debug dots + =========================================================*/ + printf("* %d dots:\n", pAutomate.dots); + + + /* [2] Debug edges + =========================================================*/ + for( a = 0 ; a < pAutomate.dots ; a++ ){ + + + if( a != pAutomate.dFinal ) + printf(" * q%d\n", a); + else{ + printf(" * q%d final dot\n", a); + continue; + } + + for( b = 0 ; b < pAutomate.dot[a].n ; b++ ){ + + if( pAutomate.dot[a].type[b] == DIRECT_T ) + printf(" * q%d match direct\n", pAutomate.dot[a].dot[b]); + if( pAutomate.dot[a].type[b] == STRING_T ) + printf(" * q%d match string '%s'\n", pAutomate.dot[a].dot[b], pAutomate.sedge[pAutomate.dot[a].edge[b]]); + else if( pAutomate.dot[a].type[b] == LIST_T ) + printf(" * q%d match list '%s'\n", pAutomate.dot[a].dot[b], pAutomate.ledge[pAutomate.dot[a].edge[b]]); + 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]]); + 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("== END ==\n\n"); +} + + + + + + + +struct Automate createAutomate(const char* pName){ /* [0] Initialize variables =========================================================*/ @@ -266,6 +350,8 @@ struct Automate createAutomate(){ automate.redge = malloc( 0 ); automate.ledge = malloc( 0 ); automate.aedge = malloc( 0 ); + automate.name = malloc( strlen(pName) + 1 ); + strcpy(automate.name, pName); /* [3] Return initialized automate @@ -274,6 +360,131 @@ struct Automate createAutomate(){ } +void mergeAutomate(struct Automate* pMaster, const char pSlaveIndex){ + + /* [0] Initialize variables + =========================================================*/ + char a, d, e, dot, edge, edges, dotOffset, rtn, next_dot; + + char sedges = pMaster->sedges; + char ledges = pMaster->ledges; + char redges = pMaster->redges; + char aedges = pMaster->aedges; + char dots = pMaster->dots; + char final = pMaster->dFinal; + struct Automate* pSlave = &pMaster->aedge[pSlaveIndex]; + + + + /* [1] Merge @pSlave edges into @pMaster edges + =========================================================*/ + /* (1) String edges (sedges) */ + for( a = 0 ; a < pSlave->sedges ; a++ ){ + rtn = addStringTransition(pMaster, pSlave->sedge[a]); + (ADB&0x01) && printf("merge SLAVE.string.%d into MASTER.string.%d\n", a, rtn) ; + } + + /* (2) List edges (ledges) */ + for( a = 0 ; a < pSlave->ledges ; a++ ){ + rtn = addListTransition(pMaster, pSlave->ledge[a]); + (ADB&0x01) && printf("merge SLAVE.list.%d into MASTER.list.%d\n", a, rtn) ; + } + + /* (3) Range edges (redges) */ + for( a = 0 ; a < pSlave->redges ; a++ ){ + rtn = addRangeTransition(pMaster, pSlave->redge[a]); + (ADB&0x01) && printf("merge SLAVE.range.%d into MASTER.range.%d\n", a, rtn) ; + } + + /* (4) Automate edges (aedges) */ + for( a = 0 ; a < pSlave->aedges ; a++ ){ + rtn = addAutomateTransition(pMaster, &pSlave->aedge[a]); + (ADB&0x01) && printf("merge SLAVE.automate.%d into MASTER.automate.%d\n", a, rtn) ; + } + + + /* [2] For each use of @pSlave in pMaster, replace + =========================================================*/ + /* (1) For each fot of @pMaster */ + for( dot = 0 ; dot < dots ; dot++ ){ + + edges = pMaster->dot[dot].n; + + /* (2) For each edge of the current dot */ + for( edge = 0 ; edge < edges ; edge++ ){ + + /* (3) If not automate || not pSlave */ + if( pMaster->dot[dot].type[edge] != AUTOMATE_T || pMaster->dot[dot].edge[edge] != pSlaveIndex ) + continue; + + /* (4) Store current dot offset in @pMaster */ + dotOffset = pMaster->dots; + + /* (5) Add @pSlave dots number to @pMaster */ + for( d = 0 ; d < pSlave->dots ; d++ ){ + rtn = addDot(pMaster); + (ADB&0x01) && printf("duplicate SLAVE.dot.%d into MASTER.dot.%d for q%d to q%d transition with a%d\n", d, rtn, dot, pMaster->dot[dot].dot[edge], pMaster->dot[dot].edge[edge]) ; + } + + /* (6) For each @pSlave duplicated dot, add dot's edges to @pMaster */ + + // {1} Direct out from @pSlave replacement // + (ADB&0x01) && printf(" OUT: direct link from MASTER.dot.%d to MASTER.dot.%d\n", dotOffset+pSlave->dots-1, pMaster->dot[dot].dot[edge]) ; + linkDots(pMaster, dotOffset+pSlave->dots-1, pMaster->dot[dot].dot[edge], DIRECT_T, 0); + + // {2} Direct link to @pSlave replacement // + pMaster->dot[dot].type[edge] = DIRECT_T; + pMaster->dot[dot].dot[edge] = dotOffset; + (ADB&0x01) && printf(" IN: direct link from MASTER.dot.%d to MASTER.dot.%d\n", dot, dotOffset) ; + + // {3} Duplicate @pSlave dot's edges into @pMaster // + for( d = 0 ; d < pSlave->dots ; d++ ){ + + for( e = 0 ; e < pSlave->dot[d].n ; e++ ){ + + next_dot = dotOffset+pSlave->dot[d].dot[e]; + + if( pSlave->dot[d].type[e] == DIRECT_T ){ + (ADB&0x01) && printf(" MID: direct link from MASTER.dot.%d to MASTER.dot.%d\n", dotOffset+d, next_dot) ; + linkDots(pMaster, dotOffset+d, next_dot, pSlave->dot[d].type[e], 0); + }else if( pSlave->dot[d].type[e] == STRING_T ){ + (ADB&0x01) && printf(" MID: string link from MASTER.dot.%d to MASTER.dot.%d\n", dotOffset+d, next_dot) ; + linkDots(pMaster, dotOffset+d, next_dot, pSlave->dot[d].type[e], sedges+pSlave->dot[d].edge[e]); + }else if( pSlave->dot[d].type[e] == LIST_T ){ + (ADB&0x01) && printf(" MID: list link from MASTER.dot.%d to MASTER.dot.%d\n", dotOffset+d, next_dot) ; + linkDots(pMaster, dotOffset+d, next_dot, pSlave->dot[d].type[e], ledges+pSlave->dot[d].edge[e]); + }else if( pSlave->dot[d].type[e] == RANGE_T ){ + (ADB&0x01) && printf(" MID: range link from MASTER.dot.%d to MASTER.dot.%d\n", dotOffset+d, next_dot) ; + linkDots(pMaster, dotOffset+d, next_dot, pSlave->dot[d].type[e], redges+pSlave->dot[d].edge[e]); + }else if( pSlave->dot[d].type[e] == AUTOMATE_T ){ + (ADB&0x01) && printf(" MID: automate link from MASTER.dot.%d to MASTER.dot.%d\n", dotOffset+d, next_dot) ; + linkDots(pMaster, dotOffset+d, next_dot, pSlave->dot[d].type[e], aedges+pSlave->dot[d].edge[e]); + } + } + + + } + + } + + + } + + /* [3] Clean @pMaster + =========================================================*/ + /* (1) Remove @pSlave form @pMaster */ + pMaster->aedge = realloc(pMaster->aedge, sizeof(struct Automate) * --pMaster->aedges); + + /* (2) Keep old @pMaster.dFinal */ + (ADB&&0x01) && printf("restauring final to %d\n", final); + pMaster->dFinal = final; + + + (ADB&0x01) && printf("SLAVE.%s successfully merged into MASTER.%s\n\n", pSlave->name, pMaster->name) ; + +} + + char addDot(struct Automate* pAutomate){ /* [0] Initialize variables @@ -379,19 +590,26 @@ char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge){ } -void linkDots(struct Automate* pAutomate, const char pIn, const char pOut, const char pType, const char pEdge){ +void linkDots(struct Automate* pAutomate, const char pIn, const char pOut, const AutomateType pType, const char pEdge){ - /* [0] Initialize variables + /* [0] Initialization =========================================================*/ + /* (1) Check arguments */ + if( pIn >= pAutomate->dots || pOut >= pAutomate->dots ){ + printf("linkDots, pIn/pOut out of range!! Exiting\n"); + exit(1); + } + + /* (2) Initialize variables */ 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 ); + pAutomate->dot[pIn].dot = realloc( pAutomate->dot[pIn].dot, pAutomate->dot[pIn].n ); + pAutomate->dot[pIn].type = realloc( pAutomate->dot[pIn].type, sizeof(AutomateType) * pAutomate->dot[pIn].n ); + pAutomate->dot[pIn].edge = realloc( pAutomate->dot[pIn].edge, pAutomate->dot[pIn].n ); /* [2] Create the link @@ -409,6 +627,17 @@ void linkDots(struct Automate* pAutomate, const char pIn, const char pOut, const +char* pad(const char depth){ + char* buffer = malloc( depth+1 ); + char c = 0; + + for( ; c < depth ; c++ ) + buffer[c] = '\t'; + buffer[c] = 0; + + return buffer; +} + char* replaceAll(const char* pHaystack, const char* pNeedle, const char* pReplacement){ diff --git a/src/lib/automate/automate.h b/src/lib/automate/automate.h index 0ba5dd8..50e7f29 100644 --- a/src/lib/automate/automate.h +++ b/src/lib/automate/automate.h @@ -11,19 +11,26 @@ #define _LIB_AUTOMATE_AUTOMATE_H_ #include + #include #include #include - #define AUTOMATE_TYPE_STRING 0x00 - #define AUTOMATE_TYPE_RANGE 0x01 - #define AUTOMATE_TYPE_LIST 0x02 - #define AUTOMATE_TYPE_AUTOMATE 0x03 + typedef enum{ + DIRECT_T = 0x00, + STRING_T = 0x01, + RANGE_T = 0x02, + LIST_T = 0x03, + AUTOMATE_T = 0x04 + } AutomateType; + + + #define ADB 0x00 struct AutomateDot{ - char n; // number of edges - char* type; // type of Transition (according to index) (0=string;1=range;2=list;3=automate) - char* dot; // list of dot_id - char* edge; // list of [sa]edge_id + char n; // number of edges + AutomateType* type; // type of Transition (according to index) (0=direct;1=string;2=range;3=list;4=automate) + char* dot; // list of dot_id + char* edge; // list of [sa]edge_id }; struct Automate{ @@ -42,6 +49,8 @@ char dCurrent; // current dot index char dFinal; // final dot index char steps; // number of steps + + char* name; // automate name }; @@ -49,13 +58,14 @@ * * @pAutomate Current working automate * @pString String to test + * @pDepth Padding * * @return offset The @pString offset browsed to * * @NOTE: Automate.dCurrent is equal to Automate.dFinal if final state reached * */ - unsigned int browse(struct Automate* pAutomate, const char* pString); + unsigned int browse(struct Automate* pAutomate, const char* pString, const char pDepth); /* Builds an automate from a regexp @@ -71,14 +81,25 @@ - + void debug(const struct Automate pAutomate); /* Initializes an automate * + * @pName Automate name + * * @return new The created automate * */ - struct Automate createAutomate(); + struct Automate createAutomate(const char* pName); + + /* Merges an automate into another + * + * @pMaster Master automate that contains @pSlave + * @pSlaveIndex Slave automate index into @pMaster + * + * + */ + void mergeAutomate(struct Automate* pMaster, const char pSlaveIndex); /* Adds a dot to an automate @@ -134,14 +155,14 @@ * @pAutomate Current working automate * @pIn Input dot index * @pOut Output dot index - * @pType Transition type + * @pType Transition type * @pEdge Transition type-specific index * */ - void linkDots(struct Automate* pAutomate, const char pIn, const char pOut, const char pType, const char pEdge); - + void linkDots(struct Automate* pAutomate, const char pIn, const char pOut, const AutomateType pType, const char pEdge); + char* pad(const char depth); char* replaceAll(const char* pHaystack, const char* pNeedle, const char* pReplacement); char getGroups(const char* pString, int* pStart, int* pEnd); diff --git a/src/linter.c b/src/linter.c index 833356f..bc5fa8f 100644 --- a/src/linter.c +++ b/src/linter.c @@ -22,105 +22,58 @@ int main(int argc, char* argv[]){ /** TEST **/ /** BUILD AUTOMATE **/ + struct Automate digit = createAutomate("digit"); + addDot(&digit); // q0 + addDot(&digit); // q1 + addRangeTransition(&digit, "09\0"); // r0 + linkDots(&digit, 0, 0, RANGE_T, 0); // q0 --r0--> q0 + linkDots(&digit, 0, 1, RANGE_T, 0); // q0 --r0--> q1 + + struct Automate positive = createAutomate("positive"); + addDot(&positive); // q0 + addDot(&positive); // q1 + addDot(&positive); // q2 + addDot(&positive); // q3 + addStringTransition(&positive, ",\0"); // s0 + addAutomateTransition(&positive, &digit); // a0 + linkDots(&positive, 0, 1, AUTOMATE_T, 0); // q0 --a0--> q1 + linkDots(&positive, 0, 2, STRING_T, 0); // q0 --s0--> q2 + linkDots(&positive, 0, 3, AUTOMATE_T, 0); // q0 --a0--> q3 + linkDots(&positive, 1, 2, STRING_T, 0); // q1 --s0--> q2 + linkDots(&positive, 1, 3, STRING_T, 0); // q1 --s0--> q3 + linkDots(&positive, 2, 3, AUTOMATE_T, 0); // q2 --a0--> q3 // A = a+(bc[x-z]+bc[de]) - struct Automate a = createAutomate(); - addDot(&a); // q0 - addDot(&a); // q1 - addDot(&a); // q2 - addDot(&a); // q3 - addDot(&a); // q4 - addDot(&a); // q5 + struct Automate number = createAutomate("number"); + addDot(&number); // q0 + addDot(&number); // q1 + addDot(&number); // q2 + addListTransition(&number, "+-\0"); // l0 + addAutomateTransition(&number, &positive); // a0 - addStringTransition(&a, "a\0"); // s0 - addStringTransition(&a, "b\0"); // s1 - addStringTransition(&a, "c\0"); // s2 - addListTransition(&a, "de\0"); // l0 - addRangeTransition(&a, "xz\0"); // r0 + linkDots(&number, 0, 1, LIST_T, 0); // q0 --l0--> q1 + linkDots(&number, 0, 2, AUTOMATE_T, 0); // q0 --a0--> q2 + linkDots(&number, 1, 2, AUTOMATE_T, 0); // q1 --a0--> q2 - linkDots(&a, 0, 1, AUTOMATE_TYPE_STRING, 0); // q0 -s0-> q1 || branch-0 path-0 - linkDots(&a, 1, 1, AUTOMATE_TYPE_STRING, 0); // q1 -s0-> q1 || branch-1 path-0 - linkDots(&a, 1, 2, AUTOMATE_TYPE_STRING, 1); // q1 -s1-> q2 || branch-1 path-1 - linkDots(&a, 2, 3, AUTOMATE_TYPE_STRING, 2); // q2 -s2-> q3 || branch-2 path-0 - linkDots(&a, 3, 5, AUTOMATE_TYPE_RANGE, 0); // q2 -r0-> q5 || branch-3 path-0 - linkDots(&a, 1, 4, AUTOMATE_TYPE_STRING, 1); // q1 -s1-> q4 || branch-1 path-2 - linkDots(&a, 4, 4, AUTOMATE_TYPE_STRING, 2); // q4 -s2-> q4 || branch-4 path-0 - linkDots(&a, 4, 5, AUTOMATE_TYPE_LIST, 0); // q4 -l0-> q5 || branch-4 path-1 + + mergeAutomate(&positive, 0); + debug(positive); + // mergeAutomate(&number, 0); + // debug(number); + + // mergeAutomate(&number, 0); char string[40] = {0}; unsigned int browsed = 0; clock_t start, stop; - - strcpy(string, "abcx"); - start = clock(); browsed = browse(&a, string); stop = clock(); + strcpy(string, "123,4\0"); + start = clock(); browsed = browse(&positive, string, 0); stop = clock(); printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); + printf(" (*) final_state: %d/%d\n", positive.dCurrent, positive.dFinal); + printf(" (*) in %d steps\n", positive.steps); printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - strcpy(string, "abcy"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - - strcpy(string, "abcz"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - - strcpy(string, "abcd"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - - strcpy(string, "abce"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - - strcpy(string, "aaaaaaabcx"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - - strcpy(string, "aaabc"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - - strcpy(string, "aaabc"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - - strcpy(string, "aaabd"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); - - strcpy(string, "bc"); - start = clock(); browsed = browse(&a, string); stop = clock(); - printf("browse '%s' : %d/%d\n", string, browsed, (int) strlen(string)); - printf("* final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) final_state: %d/%d\n", a.dCurrent, a.dFinal); - printf(" (*) in %d steps\n", a.steps); - printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); + exit(0); /* 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)"; diff --git a/src/test b/src/test new file mode 100644 index 0000000..691d728 --- /dev/null +++ b/src/test @@ -0,0 +1,82 @@ +>>> [browsing number] + > q0 --l0--> q1 ? + < yes + > q1 --a0--> q2 ? + >>> [browsing positive] + > q0 --a0--> q1 ? + >>> [browsing digit] + > q0 --r0--> q0 ? + < yes + > q1 --r0--> q0 ? + < yes + > q2 --r0--> q0 ? + < yes + > q3 --r0--> q0 ? + < yes + >>> [done digit = 0/0] + automate leads us (positive) from state 0 to 1 + < yes + > q1 --s0--> q2 ? + > q1 --s0--> q3 ? + < not + * back to q0:1 + > q0 --s0--> q2 ? + > q0 --a0--> q3 ? + >>> [browsing digit] + > q0 --r0--> q0 ? + < yes + > q1 --r0--> q0 ? + < yes + > q2 --r0--> q0 ? + < yes + > q3 --r0--> q0 ? + < yes + >>> [done digit = 0/0] + automate leads us (positive) from state 0 to 3 + < yes + < not + * back to q0:3 + >>> [done positive = 0/3] + < not + * back to q0:1 + > q0 --a0--> q2 ? + >>> [browsing positive] + > q0 --a0--> q1 ? + >>> [browsing digit] + > q0 --r0--> q0 ? + < not + * back to q0:1 + >>> [done digit = 0/0] + automate leads us (positive) from state 0 to 1 + < yes + > q1 --s0--> q2 ? + > q1 --s0--> q3 ? + < not + * back to q0:1 + > q0 --s0--> q2 ? + > q0 --a0--> q3 ? + >>> [browsing digit] + > q0 --r0--> q0 ? + < not + * back to q0:1 + >>> [done digit = 0/0] + automate leads us (positive) from state 0 to 3 + < yes + < not + * back to q0:3 + >>> [done positive = 0/3] + < not + * back to q0:2 +>>> [done number = 0/2] +browse '+1234' : 0/5 + (*) final_state: 0/2 + (*) in 20 steps + (*) in 0.000 seconds + +line/0: '