From ffa0c03fd6ac521a500bdf398b4e2f9a0d8be62e Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 15 May 2017 13:24:56 +0200 Subject: [PATCH] [update] automate added `list` edges which is a set of chars (string) and try to match any of these --- src/lib/automate/automate.c | 110 ++++++++++++++++-------------------- src/lib/automate/automate.h | 47 ++++++++------- src/linter.c | 84 ++++++++++++++++++--------- src/linter.h | 1 + 4 files changed, 130 insertions(+), 112 deletions(-) diff --git a/src/lib/automate/automate.c b/src/lib/automate/automate.c index d2aa159..6959a1a 100644 --- a/src/lib/automate/automate.c +++ b/src/lib/automate/automate.c @@ -18,7 +18,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ =========================================================*/ unsigned int strIndex = 0; // String current char index unsigned int recursive; - unsigned int c, len, i, l; // counters + unsigned int c, len, i, l, a, A; // counters char* buffer = malloc(1); char* ptr = NULL; struct AutomateDot dotPtr; @@ -73,7 +73,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ for( ; i < l ; i++ ){ /* (3) If STRING match */ - if( dotPtr.type[i] == 0 ){ + if( dotPtr.type[i] == AUTOMATE_TYPE_STRING ){ ptr = pAutomate->sedge[dotPtr.edge[i]]; strncpy(buffer, pString+strIndex, strlen(ptr)); @@ -87,7 +87,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ } /* (4) If RANGE match */ - }else if( dotPtr.type[i] == 1 ){ + }else if( dotPtr.type[i] == AUTOMATE_TYPE_RANGE ){ ptr = pAutomate->redge[dotPtr.edge[i]]; @@ -98,7 +98,26 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ break; } - /* (5) If AUTOMATE match */ + /* (5) If LIST match */ + }else if( dotPtr.type[i] == AUTOMATE_TYPE_LIST ){ + + ptr = pAutomate->ledge[dotPtr.edge[i]]; + + // Checking match with each char of the list + A = strlen(ptr); + for( a = 0 ; a < A ; a++ ) + if( pString[strIndex] == ptr[a] ) + break; + + // if a char matches -> store it + if( a < A ){ + pAutomate->dCurrent = dotPtr.dot[i]; + strIndex += 1; + pathmem[c] = i; + break; + } + + /* (6) If AUTOMATE match */ }else{ recursive = browse(&pAutomate->aedge[dotPtr.edge[i]], pString+strIndex); @@ -115,7 +134,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ } - /* (6) If no more path */ + /* (7) If no more path */ if( strIndex == indexmem[c] ){ // {1} if not first branch -> go previous // @@ -128,7 +147,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){ pAutomate->dCurrent = dotmem[c]; // printf("* back to q%d:%d\n", dotmem[c], pathmem[c]); - /* (7) Next branch + reset data (if already browsed in other path) */ + /* (8) Next branch + reset data (if already browsed in other path) */ }else{ // printf("q%d -%.1s-> q%d\n", c, pString+indexmem[c], pAutomate->dCurrent); c++; @@ -233,8 +252,9 @@ struct Automate createAutomate(){ =========================================================*/ automate.dots = 0; automate.sedges = 0; - automate.aedges = 0; automate.redges = 0; + automate.ledges = 0; + automate.aedges = 0; automate.dCurrent = 0; automate.dFinal = 0; @@ -244,6 +264,7 @@ struct Automate createAutomate(){ automate.dot = malloc( 0 ); automate.sedge = malloc( 0 ); automate.redge = malloc( 0 ); + automate.ledge = malloc( 0 ); automate.aedge = malloc( 0 ); @@ -321,6 +342,25 @@ char addRangeTransition(struct Automate* pAutomate, const char pRedge[2]){ } +char addListTransition(struct Automate* pAutomate, const char* pLedge){ + /* [0] Initialize variables + =========================================================*/ + char index = pAutomate->ledges++; + + /* [1] Reallocate memory for sedge + =========================================================*/ + pAutomate->ledge = realloc(pAutomate->ledge, sizeof(char*) * pAutomate->ledges); + pAutomate->ledge[index] = malloc( strlen(pLedge)+1 ); + + + /* [2] Create the sedge + =========================================================*/ + strcpy(pAutomate->ledge[index], pLedge); + + return index; +} + + char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge){ /* [0] Initialize variables =========================================================*/ @@ -339,7 +379,7 @@ char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge){ } -void linkSEdge(struct Automate* pAutomate, const char pIn, const char pOut, const char pSedge){ +void linkDots(struct Automate* pAutomate, const char pIn, const char pOut, const char pType, const char pEdge){ /* [0] Initialize variables =========================================================*/ @@ -357,62 +397,12 @@ void linkSEdge(struct Automate* pAutomate, const char pIn, const char pOut, cons /* [2] Create the link =========================================================*/ pAutomate->dot[pIn].dot[index] = pOut; - pAutomate->dot[pIn].type[index] = 0; - pAutomate->dot[pIn].edge[index] = pSedge; + pAutomate->dot[pIn].type[index] = pType; + pAutomate->dot[pIn].edge[index] = pEdge; } -void linkREdge(struct Automate* pAutomate, const char pIn, const char pOut, const char pRedge){ - - /* [0] 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 ); - - - /* [2] Create the link - =========================================================*/ - pAutomate->dot[pIn].dot[index] = pOut; - pAutomate->dot[pIn].type[index] = 1; - pAutomate->dot[pIn].edge[index] = pRedge; - -} - - -void linkAEdge(struct Automate* pAutomate, const char pIn, const char pOut, const char pAedge){ - - /* [0] 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 ); - - - /* [2] Create the link - =========================================================*/ - pAutomate->dot[pIn].dot[index] = pOut; - pAutomate->dot[pIn].type[index] = 2; - pAutomate->dot[pIn].edge[index] = pAedge; - -} - - - - diff --git a/src/lib/automate/automate.h b/src/lib/automate/automate.h index d406713..0ba5dd8 100644 --- a/src/lib/automate/automate.h +++ b/src/lib/automate/automate.h @@ -14,23 +14,29 @@ #include #include + #define AUTOMATE_TYPE_STRING 0x00 + #define AUTOMATE_TYPE_RANGE 0x01 + #define AUTOMATE_TYPE_LIST 0x02 + #define AUTOMATE_TYPE_AUTOMATE 0x03 struct AutomateDot{ char n; // number of edges - char* type; // type of Transition (according to index) (0=string;1=range;2=automate) + 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 }; struct Automate{ char sedges; // Max sedge index - char aedges; // Max aedge index + char ledges; // Max ledge index char redges; // Max redge index + char aedges; // Max aedge index char dots; // Max dot index struct AutomateDot* dot; // dots char** sedge; // string edges char** redge; // range edges (between char[0] and char[1]) + char** ledge; // list edges (in one of the given char-s) struct Automate* aedge; // automate edges char dCurrent; // current dot index @@ -104,6 +110,16 @@ */ char addRangeTransition(struct Automate* pAutomate, const char pRedge[2]); + /* Adds a list transition + * + * @pAutomate Current working automate + * @pLedge List to build transition from + * + * @return ledge Index of the created transition + * + */ + char addListTransition(struct Automate* pAutomate, const char* pLedge); + /* Adds an automate transition * * @pAutomate Current working automate @@ -113,36 +129,17 @@ */ char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge); - /* Adds a link between 2 dots with a string + /* Adds a link between 2 dots with a given transition type * * @pAutomate Current working automate * @pIn Input dot index * @pOut Output dot index - * @pSedge String transition index + * @pType Transition type + * @pEdge Transition type-specific index * */ - void linkSEdge(struct Automate* pAutomate, const char pIn, const char pOut, const char pSedge); + void linkDots(struct Automate* pAutomate, const char pIn, const char pOut, const char pType, const char pEdge); - /* Adds a link between 2 dots with a range - * - * @pAutomate Current working automate - * @pIn Input dot index - * @pOut Output dot index - * @pRedge Range transition index - * - */ - void linkREdge(struct Automate* pAutomate, const char pIn, const char pOut, const char pRedge); - - /* Adds a link between 2 dots with an automate - * - * @pAutomate Current working automate - * @pIn Input dot index - * @pOut Output dot index - * @pAedge Automate transition index - * - * - */ - void linkAEdge(struct Automate* pAutomate, const char pIn, const char pOut, const char pAedge); diff --git a/src/linter.c b/src/linter.c index ffde014..833356f 100644 --- a/src/linter.c +++ b/src/linter.c @@ -23,7 +23,7 @@ int main(int argc, char* argv[]){ /** TEST **/ /** BUILD AUTOMATE **/ - // A = a+(bc(x-z)+bcd) + // A = a+(bc[x-z]+bc[de]) struct Automate a = createAutomate(); addDot(&a); // q0 addDot(&a); // q1 @@ -35,62 +35,92 @@ int main(int argc, char* argv[]){ addStringTransition(&a, "a\0"); // s0 addStringTransition(&a, "b\0"); // s1 addStringTransition(&a, "c\0"); // s2 - addStringTransition(&a, "d\0"); // s3 + addListTransition(&a, "de\0"); // l0 addRangeTransition(&a, "xz\0"); // r0 - linkSEdge(&a, 0, 1, 0); // q0 -s0-> q1 || branch-0 path-0 - linkSEdge(&a, 1, 1, 0); // q1 -s0-> q1 || branch-1 path-0 - linkSEdge(&a, 1, 2, 1); // q1 -s1-> q2 || branch-1 path-1 - linkSEdge(&a, 2, 3, 2); // q2 -s2-> q3 || branch-2 path-0 - linkREdge(&a, 3, 5, 0); // q2 -r0-> q5 || branch-3 path-0 - linkSEdge(&a, 1, 4, 1); // q1 -s1-> q4 || branch-1 path-2 - linkSEdge(&a, 4, 4, 2); // q4 -s2-> q4 || branch-4 path-0 - linkSEdge(&a, 4, 5, 3); // q4 -s3-> q5 || branch-4 path-1 + 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 char string[40] = {0}; + unsigned int browsed = 0; + clock_t start, stop; + strcpy(string, "abcx"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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\n", a.steps); + printf(" (*) in %d steps\n", a.steps); + printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); strcpy(string, "abcy"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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\n", a.steps); + printf(" (*) in %d steps\n", a.steps); + printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); strcpy(string, "abcz"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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\n", a.steps); + printf(" (*) in %d steps\n", a.steps); + printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); strcpy(string, "abcd"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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\n", a.steps); + 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"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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\n", a.steps); + printf(" (*) in %d steps\n", a.steps); + printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); strcpy(string, "aaabc"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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\n", a.steps); + printf(" (*) in %d steps\n", a.steps); + printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); strcpy(string, "aaabc"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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\n", a.steps); + printf(" (*) in %d steps\n", a.steps); + printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); strcpy(string, "aaabd"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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\n", a.steps); + printf(" (*) in %d steps\n", a.steps); + printf(" (*) in %.3lf seconds\n\n", (double)(stop-start)/CLOCKS_PER_SEC); strcpy(string, "bc"); - printf("browse '%s' : %d/%d\n", string, browse(&a, string), (int) strlen(string)); + 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); /* 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/linter.h b/src/linter.h index 82a3cf2..0c78388 100644 --- a/src/linter.h +++ b/src/linter.h @@ -17,6 +17,7 @@ #include #include #include + #include /* LOCAL */ #include "lib/php-const.h"