[update] automate added `list` edges which is a set of chars (string) and try to match any of these

This commit is contained in:
xdrm-brackets 2017-05-15 13:24:56 +02:00
parent 9c09953b9e
commit ffa0c03fd6
4 changed files with 130 additions and 112 deletions

View File

@ -18,7 +18,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){
=========================================================*/ =========================================================*/
unsigned int strIndex = 0; // String current char index unsigned int strIndex = 0; // String current char index
unsigned int recursive; unsigned int recursive;
unsigned int c, len, i, l; // counters unsigned int c, len, i, l, a, A; // counters
char* buffer = malloc(1); char* buffer = malloc(1);
char* ptr = NULL; char* ptr = NULL;
struct AutomateDot dotPtr; struct AutomateDot dotPtr;
@ -73,7 +73,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){
for( ; i < l ; i++ ){ for( ; i < l ; i++ ){
/* (3) If STRING match */ /* (3) If STRING match */
if( dotPtr.type[i] == 0 ){ if( dotPtr.type[i] == AUTOMATE_TYPE_STRING ){
ptr = pAutomate->sedge[dotPtr.edge[i]]; ptr = pAutomate->sedge[dotPtr.edge[i]];
strncpy(buffer, pString+strIndex, strlen(ptr)); strncpy(buffer, pString+strIndex, strlen(ptr));
@ -87,7 +87,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){
} }
/* (4) If RANGE match */ /* (4) If RANGE match */
}else if( dotPtr.type[i] == 1 ){ }else if( dotPtr.type[i] == AUTOMATE_TYPE_RANGE ){
ptr = pAutomate->redge[dotPtr.edge[i]]; ptr = pAutomate->redge[dotPtr.edge[i]];
@ -98,7 +98,26 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){
break; 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{ }else{
recursive = browse(&pAutomate->aedge[dotPtr.edge[i]], pString+strIndex); 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] ){ if( strIndex == indexmem[c] ){
// {1} if not first branch -> go previous // // {1} if not first branch -> go previous //
@ -128,7 +147,7 @@ unsigned int browse(struct Automate* pAutomate, const char* pString){
pAutomate->dCurrent = dotmem[c]; pAutomate->dCurrent = dotmem[c];
// printf("* back to q%d:%d\n", dotmem[c], pathmem[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{ }else{
// printf("q%d -%.1s-> q%d\n", c, pString+indexmem[c], pAutomate->dCurrent); // printf("q%d -%.1s-> q%d\n", c, pString+indexmem[c], pAutomate->dCurrent);
c++; c++;
@ -233,8 +252,9 @@ struct Automate createAutomate(){
=========================================================*/ =========================================================*/
automate.dots = 0; automate.dots = 0;
automate.sedges = 0; automate.sedges = 0;
automate.aedges = 0;
automate.redges = 0; automate.redges = 0;
automate.ledges = 0;
automate.aedges = 0;
automate.dCurrent = 0; automate.dCurrent = 0;
automate.dFinal = 0; automate.dFinal = 0;
@ -244,6 +264,7 @@ struct Automate createAutomate(){
automate.dot = malloc( 0 ); automate.dot = malloc( 0 );
automate.sedge = malloc( 0 ); automate.sedge = malloc( 0 );
automate.redge = malloc( 0 ); automate.redge = malloc( 0 );
automate.ledge = malloc( 0 );
automate.aedge = 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){ char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge){
/* [0] Initialize variables /* [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 /* [0] Initialize variables
=========================================================*/ =========================================================*/
@ -357,62 +397,12 @@ void linkSEdge(struct Automate* pAutomate, const char pIn, const char pOut, cons
/* [2] Create the link /* [2] Create the link
=========================================================*/ =========================================================*/
pAutomate->dot[pIn].dot[index] = pOut; pAutomate->dot[pIn].dot[index] = pOut;
pAutomate->dot[pIn].type[index] = 0; pAutomate->dot[pIn].type[index] = pType;
pAutomate->dot[pIn].edge[index] = pSedge; 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;
}

View File

@ -14,23 +14,29 @@
#include <malloc.h> #include <malloc.h>
#include <unistd.h> #include <unistd.h>
#define AUTOMATE_TYPE_STRING 0x00
#define AUTOMATE_TYPE_RANGE 0x01
#define AUTOMATE_TYPE_LIST 0x02
#define AUTOMATE_TYPE_AUTOMATE 0x03
struct AutomateDot{ struct AutomateDot{
char n; // number of edges 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* dot; // list of dot_id
char* edge; // list of [sa]edge_id char* edge; // list of [sa]edge_id
}; };
struct Automate{ struct Automate{
char sedges; // Max sedge index char sedges; // Max sedge index
char aedges; // Max aedge index char ledges; // Max ledge index
char redges; // Max redge index char redges; // Max redge index
char aedges; // Max aedge index
char dots; // Max dot index char dots; // Max dot index
struct AutomateDot* dot; // dots struct AutomateDot* dot; // dots
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)
struct Automate* aedge; // automate edges struct Automate* aedge; // automate edges
char dCurrent; // current dot index char dCurrent; // current dot index
@ -104,6 +110,16 @@
*/ */
char addRangeTransition(struct Automate* pAutomate, const char pRedge[2]); char addRangeTransition(struct Automate* pAutomate, const char pRedge[2]);
/* Adds a list transition
*
* @pAutomate<struct Automate*> Current working automate
* @pLedge<const char*> List to build transition from
*
* @return ledge<char> Index of the created transition
*
*/
char addListTransition(struct Automate* pAutomate, const char* pLedge);
/* Adds an automate transition /* Adds an automate transition
* *
* @pAutomate<struct Automate*> Current working automate * @pAutomate<struct Automate*> Current working automate
@ -113,36 +129,17 @@
*/ */
char addAutomateTransition(struct Automate* pAutomate, struct Automate* pAedge); 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<struct Automate*> Current working automate * @pAutomate<struct Automate*> Current working automate
* @pIn<const char> Input dot index * @pIn<const char> Input dot index
* @pOut<const char> Output dot index * @pOut<const char> Output dot index
* @pSedge<const char> String transition index * @pType<const char> Transition type
* @pEdge<const char> 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<struct Automate*> Current working automate
* @pIn<const char> Input dot index
* @pOut<const char> Output dot index
* @pRedge<const char> 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<struct Automate*> Current working automate
* @pIn<const char> Input dot index
* @pOut<const char> Output dot index
* @pAedge<const char> Automate transition index
*
*
*/
void linkAEdge(struct Automate* pAutomate, const char pIn, const char pOut, const char pAedge);

View File

@ -23,7 +23,7 @@ int main(int argc, char* argv[]){
/** TEST **/ /** TEST **/
/** BUILD AUTOMATE **/ /** BUILD AUTOMATE **/
// A = a+(bc(x-z)+bcd) // A = a+(bc[x-z]+bc[de])
struct Automate a = createAutomate(); struct Automate a = createAutomate();
addDot(&a); // q0 addDot(&a); // q0
addDot(&a); // q1 addDot(&a); // q1
@ -35,62 +35,92 @@ int main(int argc, char* argv[]){
addStringTransition(&a, "a\0"); // s0 addStringTransition(&a, "a\0"); // s0
addStringTransition(&a, "b\0"); // s1 addStringTransition(&a, "b\0"); // s1
addStringTransition(&a, "c\0"); // s2 addStringTransition(&a, "c\0"); // s2
addStringTransition(&a, "d\0"); // s3 addListTransition(&a, "de\0"); // l0
addRangeTransition(&a, "xz\0"); // r0 addRangeTransition(&a, "xz\0"); // r0
linkSEdge(&a, 0, 1, 0); // q0 -s0-> q1 || branch-0 path-0 linkDots(&a, 0, 1, AUTOMATE_TYPE_STRING, 0); // q0 -s0-> q1 || branch-0 path-0
linkSEdge(&a, 1, 1, 0); // q1 -s0-> q1 || branch-1 path-0 linkDots(&a, 1, 1, AUTOMATE_TYPE_STRING, 0); // q1 -s0-> q1 || branch-1 path-0
linkSEdge(&a, 1, 2, 1); // q1 -s1-> q2 || branch-1 path-1 linkDots(&a, 1, 2, AUTOMATE_TYPE_STRING, 1); // q1 -s1-> q2 || branch-1 path-1
linkSEdge(&a, 2, 3, 2); // q2 -s2-> q3 || branch-2 path-0 linkDots(&a, 2, 3, AUTOMATE_TYPE_STRING, 2); // q2 -s2-> q3 || branch-2 path-0
linkREdge(&a, 3, 5, 0); // q2 -r0-> q5 || branch-3 path-0 linkDots(&a, 3, 5, AUTOMATE_TYPE_RANGE, 0); // q2 -r0-> q5 || branch-3 path-0
linkSEdge(&a, 1, 4, 1); // q1 -s1-> q4 || branch-1 path-2 linkDots(&a, 1, 4, AUTOMATE_TYPE_STRING, 1); // q1 -s1-> q4 || branch-1 path-2
linkSEdge(&a, 4, 4, 2); // q4 -s2-> q4 || branch-4 path-0 linkDots(&a, 4, 4, AUTOMATE_TYPE_STRING, 2); // q4 -s2-> q4 || branch-4 path-0
linkSEdge(&a, 4, 5, 3); // q4 -s3-> q5 || branch-4 path-1 linkDots(&a, 4, 5, AUTOMATE_TYPE_LIST, 0); // q4 -l0-> q5 || branch-4 path-1
char string[40] = {0}; char string[40] = {0};
unsigned int browsed = 0;
clock_t start, stop;
strcpy(string, "abcx"); 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(" (*) 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"); 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(" (*) 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"); 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(" (*) 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"); 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(" (*) 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"); 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(" (*) 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"); 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(" (*) 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"); 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(" (*) 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"); 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(" (*) 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"); 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(" (*) 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 */ /* 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)";

View File

@ -17,6 +17,7 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <malloc.h> #include <malloc.h>
#include <time.h>
/* LOCAL */ /* LOCAL */
#include "lib/php-const.h" #include "lib/php-const.h"