diff --git a/src/lib/automate/automate.c b/src/lib/automate/automate.c index e738de2..d168d7c 100644 --- a/src/lib/automate/automate.c +++ b/src/lib/automate/automate.c @@ -63,10 +63,57 @@ struct Automate buildFromRegExp(const char* pRegExp){ /* [0] Initialize variables =========================================================*/ struct Automate result; + char* regexp = malloc( strlen(pRegExp) + 1 ); + char* buffer = malloc( strlen(pRegExp) + 1 ); + char* buffer2 = malloc( strlen(pRegExp) + 1 ); + char groupsFound, casesFound; + int* start = malloc(0); + int* end = malloc(0); - printf("or groups: %s\n", developOr(pRegExp) ); + + /* [1] Develop Cases + =========================================================*/ + strcpy(regexp, pRegExp); + + do{ + casesFound = getCases(regexp, start, end); + + if( casesFound > 0 ){ + strncpy(buffer, regexp+start[0]+1, end[0]-start[0]-1); + buffer[end[0]-start[0]-1] = 0; + + buffer2[0] = '['; + strcpy(buffer2+1, buffer); + buffer2[strlen(buffer)+1] = ']'; + buffer2[strlen(buffer)+2] = 0; + + + strcpy(regexp, replaceAll(regexp, buffer2, developCases(buffer))); + } + + groupsFound = getGroups(regexp, start, end); + + if( groupsFound > 0 ){ + strncpy(buffer, regexp+start[0]+1, end[0]-start[0]-1); + buffer[end[0]-start[0]-1] = 0; + + buffer2[0] = '('; + strcpy(buffer2+1, buffer); + buffer2[strlen(buffer)+1] = ')'; + buffer2[strlen(buffer)+2] = 0; + + strcpy(regexp, replaceAll(regexp, buffer2, developOr(buffer))); + } + + }while( casesFound > 0 || groupsFound > 0 ); + + + + + printf("NF: '%s'\n", replaceAll(replaceAll(regexp, "\1", "("), "\2", ")") ); + } @@ -247,9 +294,9 @@ char* replaceAll(const char* pHaystack, const char* pNeedle, const char* pReplac /* [2] Replace all occurences =========================================================*/ - i = 0; // index in new string - c = 0; // index in old string - rl = strlen(pReplacement); + i = 0; // index in new string + c = 0; // index in old string + rl = strlen(pReplacement); result = malloc( strlen(pHaystack) + 1 + found*rl - found*nl ); /* (1) For each found occurence */ @@ -262,11 +309,15 @@ char* replaceAll(const char* pHaystack, const char* pNeedle, const char* pReplac // Replace strncpy(result+i, pReplacement, rl); i += rl; - c = occur[f]+nl; + c = occur[f]+nl; } - result[i+1] = 0; + /* (2) Replace after */ + strncpy(result+i, pHaystack+c, hl-c+rl); + i += hl-c+rl; + + result[i-1] = 0; /* [3] Free memory @@ -346,6 +397,72 @@ char getGroups(const char* pString, int* pStart, int* pEnd){ } + return groups; +} + +char getCases(const char* pString, int* pStart, int* pEnd){ + + /* [0] Initialize variables + =========================================================*/ + int c, C = strlen(pString); + int lvl = 0; + int groups = 0; + int start, end; + + + /* [1] Find groups + =========================================================*/ + c = 0; + while( c < C ){ + + /* (1) Find group START character + ---------------------------------------------------------*/ + for( ; c < C ; c++ ){ + if( pString[c] == '[' ) lvl++; + if( pString[c] == ']' ) lvl--; + + /* (1) If found and level-0 -> got it */ + if( pString[c] == '[' && lvl == 1 ) + break; + } + + /* (2) If not found -> exit */ + if( c >= C ) + break; + + /* (3) else -> store */ + start = c++; + + + /* (2) Find group STOP character + ---------------------------------------------------------*/ + for( ; c < C ; c++ ){ + if( pString[c] == '[' ) lvl++; + if( pString[c] == ']' ) lvl--; + + /* (1) If found and level-0 -> got it */ + if( pString[c] == ']' && lvl == 0 ) + break; + } + + /* (2) If not found -> exit */ + if( c >= C ) + break; + + /* (3) else -> store */ + end = c++; + + + /* (3) Store group + ---------------------------------------------------------*/ + groups++; + pStart = realloc(pStart, sizeof(int) * groups ); + pEnd = realloc(pEnd, sizeof(int) * groups ); + + pStart[groups-1] = start; + pEnd[groups-1] = end; + + } return groups; } @@ -364,20 +481,50 @@ char* developOr(const char* pString){ /* [1] Split by '+' chars =========================================================*/ - c = 0; l = strlen(pString); + c = 0; l = strlen(string); for( ; c < l ; c++ ) - if( pString[c] == '+' ) + if( string[c] == '+' ) string[c] = '|'; - result[0] = '('; - strcpy(result+1, pString); - result[l+1] = ')'; + result[0] = '\1'; + strcpy(result+1, string); + result[l+1] = '\2'; result[l+2] = 0; free(string); + return result; + +} + +char* developCases(const char* pString){ + + /* [0] Initialize variables + =========================================================*/ + char* result = malloc( strlen(pString)*2 +2 ); + + int c, l, r; + + /* [1] Split by chars + =========================================================*/ + c = 0; l = strlen(pString); + r = 0; + + result[r++] = '('; + + for( ; c < l ; c++ ){ + if( c > 0 ) + result[r++] = '|'; + + result[r++] = pString[c]; + } + + result[r++] = ')'; + + + return result; } \ No newline at end of file diff --git a/src/lib/automate/automate.h b/src/lib/automate/automate.h index ca00581..6fceab5 100644 --- a/src/lib/automate/automate.h +++ b/src/lib/automate/automate.h @@ -12,6 +12,7 @@ #include #include + #include struct AutomateState{ @@ -101,7 +102,9 @@ char* replaceAll(const char* pHaystack, const char* pNeedle, const char* pReplacement); char getGroups(const char* pString, int* pStart, int* pEnd); + char getCases(const char* pString, int* pStart, int* pEnd); char* developOr(const char* pString); + char* developCases(const char* pString); #endif \ No newline at end of file diff --git a/src/linter.c b/src/linter.c index ce5beb3..8d8bb32 100644 --- a/src/linter.c +++ b/src/linter.c @@ -44,8 +44,8 @@ int main(int argc, char* argv[]){ printf("browse 'b' : %d\n", browse(a, "b")); /* Build RegExp */ - // char regex[20] = "(b+a)(b+e)*(b+i)"; - char regex[20] = "abc+bde+aslkdj+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)"; buildFromRegExp(regex); /** TEST **/