[update] automate
This commit is contained in:
parent
ecad8a63e2
commit
ac0c3650c5
|
@ -1,5 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
DIR=`dirname $(realpath $0)`;
|
||||
|
||||
usage(){
|
||||
echo -e "Usage: php-linter {path}\n";
|
||||
}
|
||||
|
@ -36,12 +38,12 @@ if [ -d $FILENAME ]; then
|
|||
|
||||
count=`expr $count + 1`;
|
||||
echo "($count) file $phpfile";
|
||||
./src/linter $phpfile;
|
||||
exec $DIR/src/linter $phpfile;
|
||||
|
||||
done;
|
||||
|
||||
else
|
||||
## {2} Exec file ##
|
||||
./src/linter $FILENAME;
|
||||
exec $DIR/src/linter $FILENAME;
|
||||
fi;
|
||||
|
||||
|
|
|
@ -29,13 +29,13 @@ int browse(struct Automate pAutomate, const char* pString){
|
|||
/* (1) Check if the current char can lead to a state
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Check current state choices */
|
||||
i = 0; l = pAutomate.states[pAutomate.state].n;
|
||||
i = 0; l = pAutomate.states[pAutomate.sCurrent].n;
|
||||
|
||||
for( ; i < l ; i++ ){
|
||||
|
||||
/* (2) If part of set */
|
||||
if( is_part(pString[strIndex], pAutomate.set[pAutomate.states[pAutomate.state].set[i]]) == 1 ){
|
||||
pAutomate.state = pAutomate.states[pAutomate.state].state[i];
|
||||
if( is_part(pString[strIndex], pAutomate.set[pAutomate.states[pAutomate.sCurrent].set[i]]) == 1 ){
|
||||
pAutomate.sCurrent = pAutomate.states[pAutomate.sCurrent].state[i];
|
||||
strIndex++;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ int browse(struct Automate pAutomate, const char* pString){
|
|||
|
||||
}
|
||||
|
||||
return pAutomate.state;
|
||||
return pAutomate.sCurrent;
|
||||
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,127 @@ int browse(struct Automate pAutomate, const char* pString){
|
|||
|
||||
|
||||
|
||||
struct Automate buildFromRegExp(const char* pRegExp){
|
||||
|
||||
/* [0] Initialize variables
|
||||
=========================================================*/
|
||||
struct Automate result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct Automate createAutomate(){
|
||||
|
||||
/* [0] Initialize variables
|
||||
=========================================================*/
|
||||
struct Automate automate;
|
||||
|
||||
/* [1] Create n values
|
||||
=========================================================*/
|
||||
automate.n_state = 0;
|
||||
automate.n_set = 0;
|
||||
automate.sCurrent = 0;
|
||||
automate.sFinal = 0;
|
||||
|
||||
/* [2] First allocation
|
||||
=========================================================*/
|
||||
automate.states = malloc( 0 );
|
||||
automate.set = malloc( 0 );
|
||||
|
||||
|
||||
/* [3] Return initialized automate
|
||||
=========================================================*/
|
||||
return automate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char addState(struct Automate* pAutomate){
|
||||
|
||||
/* [0] Initialize variables
|
||||
=========================================================*/
|
||||
char index = pAutomate->n_state++;
|
||||
|
||||
|
||||
/* [1] Reallocate memory for the state
|
||||
=========================================================*/
|
||||
pAutomate->states = realloc( pAutomate->states, sizeof(struct AutomateState) * pAutomate->n_state );
|
||||
|
||||
|
||||
/* [2] Allocate memory for the state data + initalize n
|
||||
=========================================================*/
|
||||
pAutomate->states[index].n = 0;
|
||||
pAutomate->states[index].set = malloc( 0 );
|
||||
pAutomate->states[index].state = malloc( 0 );
|
||||
|
||||
|
||||
/* [3] Set new state as final
|
||||
=========================================================*/
|
||||
pAutomate->sFinal = index;
|
||||
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
char addSet(struct Automate* pAutomate, const char* pSet){
|
||||
|
||||
/* [0] Initialize variables
|
||||
=========================================================*/
|
||||
char index = pAutomate->n_set++;
|
||||
|
||||
|
||||
/* [1] Add the set
|
||||
=========================================================*/
|
||||
/* (1) Reallocate memory for the set */
|
||||
pAutomate->set = realloc( pAutomate->set, sizeof(char*) * pAutomate->n_set );
|
||||
pAutomate->set[index] = realloc( pAutomate->set[index], strlen(pSet) + 1 );
|
||||
|
||||
/* (2) Copy the set */
|
||||
strcpy(pAutomate->set[index], pSet);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
void linkStates(struct Automate* pAutomate, const unsigned int pIn, const unsigned int pOut, const char* pSet){
|
||||
|
||||
/* [0] Initialize variables
|
||||
=========================================================*/
|
||||
char c; // counter
|
||||
int setIndex = -1;
|
||||
char index = pAutomate->states[pIn].n++;
|
||||
|
||||
|
||||
/* [1] Reallocate memory for link
|
||||
=========================================================*/
|
||||
pAutomate->states[pIn].set = realloc( pAutomate->states[pIn].set, pAutomate->states[pIn].n );
|
||||
pAutomate->states[pIn].state = realloc( pAutomate->states[pIn].state, pAutomate->states[pIn].n );
|
||||
|
||||
|
||||
/* [2] Search for set in set list
|
||||
=========================================================*/
|
||||
/* (1) Search for existing set */
|
||||
for( c = 0 ; c < pAutomate->n_set ; c++ )
|
||||
if( strcmp(pAutomate->set[c], pSet) == 0 )
|
||||
setIndex = c;
|
||||
|
||||
/* (2) If not found, create one */
|
||||
if( setIndex == -1 )
|
||||
setIndex = addSet(pAutomate, pSet);
|
||||
|
||||
|
||||
/* [3] Create the link
|
||||
=========================================================*/
|
||||
pAutomate->states[pIn].set[index] = setIndex;
|
||||
pAutomate->states[pIn].state[index] = pOut;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define _LIB_AUTOMATE_AUTOMATE_H_
|
||||
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
|
||||
struct AutomateState{
|
||||
|
@ -20,11 +21,12 @@
|
|||
};
|
||||
|
||||
struct Automate{
|
||||
struct AutomateState* states; // states
|
||||
unsigned int n_state; // Max state index
|
||||
unsigned int state; // current state index
|
||||
unsigned int n_set; // Max set index
|
||||
char** set; // list of sets
|
||||
struct AutomateState* states; // states
|
||||
char n_state; // Max state index
|
||||
char sCurrent; // current state index
|
||||
char sFinal; // final state index
|
||||
char n_set; // Max set index
|
||||
char** set; // list of sets
|
||||
};
|
||||
|
||||
|
||||
|
@ -40,6 +42,45 @@
|
|||
int browse(struct Automate pAutomate, const char* pString);
|
||||
|
||||
|
||||
/* Builds an automate from a regexp
|
||||
*
|
||||
* @pRegExp Regular expression to build from
|
||||
*
|
||||
* @return pAutomate The created automate
|
||||
*
|
||||
*/
|
||||
struct Automate buildFromRegExp(const char* pRegExp);
|
||||
|
||||
|
||||
|
||||
/* Initializes an automate
|
||||
*
|
||||
*/
|
||||
struct Automate createAutomate();
|
||||
|
||||
|
||||
/* Adds a state to an automate
|
||||
*
|
||||
* @return index<char> The created state index
|
||||
*
|
||||
*/
|
||||
char addState(struct Automate* pAutomate);
|
||||
|
||||
|
||||
/* Adds a set to an automate
|
||||
*
|
||||
* @return index<char> The created set index
|
||||
*
|
||||
*/
|
||||
char addSet(struct Automate* pAutomate, const char* pSet);
|
||||
|
||||
|
||||
/* Adds a link between 2 states with a set
|
||||
*
|
||||
*/
|
||||
void linkStates(struct Automate* pAutomate, const unsigned int pIn, const unsigned int pOut, const char* pSet);
|
||||
|
||||
|
||||
|
||||
/* Checks if a char is part of a set
|
||||
*
|
||||
|
|
|
@ -0,0 +1,300 @@
|
|||
/**************************
|
||||
* Scope *
|
||||
***************************
|
||||
* Designed & Developed by *
|
||||
* Adrien Marquès *
|
||||
* <xdrm-brackets> *
|
||||
***************************
|
||||
* doowap31@gmail.com *
|
||||
**************************/
|
||||
#include "regex.h"
|
||||
|
||||
// int match(const char* pPattern, char* pBuffer);
|
||||
|
||||
char madeOfSet(char* pBuffer, const char* pSet){
|
||||
|
||||
unsigned int a, b;
|
||||
unsigned int A = strlen(pBuffer);
|
||||
unsigned int B = strlen(pSet);
|
||||
char in = 0;
|
||||
|
||||
/* [1] For each char of pBuffer
|
||||
=========================================================*/
|
||||
for( a = 0 ; a < A ; a++ ){
|
||||
|
||||
/* (2) Check if char is one of each of @pSet
|
||||
---------------------------------------------------------*/
|
||||
for( b = 0 ; b < B ; b++ )
|
||||
if( pBuffer[a] == pSet[b] )
|
||||
break;
|
||||
|
||||
/* If char not in */
|
||||
if( b == B )
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int developSingle(const char* pPattern, struct RegExpDevSets* pCases, struct RegExpDevSets* pGroups){
|
||||
|
||||
/* [0] Init vars
|
||||
=========================================================*/
|
||||
unsigned int level = 0;
|
||||
unsigned int c, c2, C = strlen(pPattern);
|
||||
unsigned int start, end;
|
||||
int pair[2];
|
||||
char recursive[2] = { 0, 0 }; // no [] into [] ; no () in ()
|
||||
|
||||
|
||||
|
||||
/* [1] Get all level-0 groups
|
||||
=========================================================*/
|
||||
c = 0;
|
||||
pair[0] = 0;
|
||||
pair[1] = 0;
|
||||
|
||||
while( c < C ){
|
||||
|
||||
/* (1) Seek GROUP START char
|
||||
---------------------------------------------------------*/
|
||||
for( ; c < C ; c++ ){
|
||||
if( pPattern[c] == REGEX_CASE_START ) pair[0]++;
|
||||
if( pPattern[c] == REGEX_CASE_STOP ) pair[0]--;
|
||||
if( pPattern[c] == REGEX_GROUP_START ) pair[1]++;
|
||||
if( pPattern[c] == REGEX_GROUP_STOP ) pair[1]--;
|
||||
|
||||
if( pair[0] == 2 ) recursive[0] = 1;
|
||||
if( pair[1] == 2 ) recursive[1] = 1;
|
||||
|
||||
/* (1) If found and level-0 -> got it */
|
||||
if( pPattern[c] == REGEX_GROUP_START && pair[0] == 0 && pair[1] == 1 )
|
||||
break;
|
||||
}
|
||||
|
||||
/* (2) If not found -> exit */
|
||||
if( c >= C )
|
||||
break;
|
||||
|
||||
/* (3) else -> store */
|
||||
start = c++;
|
||||
|
||||
|
||||
/* (2) Seek GROUP STOP char
|
||||
---------------------------------------------------------*/
|
||||
for( ; c < C ; c++ ){
|
||||
if( pPattern[c] == REGEX_CASE_START ) pair[0]++;
|
||||
if( pPattern[c] == REGEX_CASE_STOP ) pair[0]--;
|
||||
if( pPattern[c] == REGEX_GROUP_START ) pair[1]++;
|
||||
if( pPattern[c] == REGEX_GROUP_STOP ) pair[1]--;
|
||||
|
||||
if( pair[0] == 2 ) recursive[0] = 1;
|
||||
if( pair[1] == 2 ) recursive[1] = 1;
|
||||
|
||||
/* (1) If found and level-0 -> got it */
|
||||
if( pPattern[c] == REGEX_GROUP_STOP && pair[0] == 0 && pair[1] == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
/* (2) If not found -> exit */
|
||||
if( c >= C )
|
||||
break;
|
||||
|
||||
/* (3) else -> store */
|
||||
end = c++;
|
||||
|
||||
|
||||
|
||||
/* (3) Save set to groups
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Store set */
|
||||
pGroups->n++;
|
||||
pGroups->sets = realloc(pGroups->sets, sizeof(struct RegExpDevSet) * pGroups->n );
|
||||
pGroups->sets[pGroups->n-1].start = start;
|
||||
pGroups->sets[pGroups->n-1].end = end;
|
||||
pGroups->sets[pGroups->n-1].n = end-start-1;
|
||||
pGroups->sets[pGroups->n-1].set = malloc( pGroups->sets[pGroups->n-1].n +1 );
|
||||
sprintf(pGroups->sets[pGroups->n-1].set, "%.*s", pGroups->sets[pGroups->n-1].n, pPattern+pGroups->sets[pGroups->n-1].start+1);
|
||||
|
||||
/* (2) Try to find quantifier */
|
||||
c++;
|
||||
if( pPattern[c-1] == REGEX_QUANTIFIER_BINARY )
|
||||
pGroups->sets[pGroups->n-1].quantifier = REGEX_QUANTIFIER_BINARY;
|
||||
else if( pPattern[c-1] == REGEX_QUANTIFIER_ANY )
|
||||
pGroups->sets[pGroups->n-1].quantifier = REGEX_QUANTIFIER_ANY;
|
||||
else if( pPattern[c-1] == REGEX_QUANTIFIER_MULTI )
|
||||
pGroups->sets[pGroups->n-1].quantifier = REGEX_QUANTIFIER_MULTI;
|
||||
else
|
||||
c--;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* [2] Get all level-0 cases
|
||||
=========================================================*/
|
||||
c = 0;
|
||||
pair[0] = 0;
|
||||
pair[1] = 0;
|
||||
while( c < C ){
|
||||
|
||||
/* (1) Seek CASE START char
|
||||
---------------------------------------------------------*/
|
||||
for( ; c < C ; c++ ){
|
||||
if( pPattern[c] == REGEX_CASE_START ) pair[0]++;
|
||||
if( pPattern[c] == REGEX_CASE_STOP ) pair[0]--;
|
||||
if( pPattern[c] == REGEX_GROUP_START ) pair[1]++;
|
||||
if( pPattern[c] == REGEX_GROUP_STOP ) pair[1]--;
|
||||
|
||||
if( pair[0] == 2 ) recursive[0] = 1;
|
||||
if( pair[1] == 2 ) recursive[1] = 1;
|
||||
|
||||
/* (1) If found and level-0 -> got it */
|
||||
if( pPattern[c] == REGEX_CASE_START && pair[0] == 1 && pair[1] == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
/* (2) If not found -> exit */
|
||||
if( c >= C )
|
||||
break;
|
||||
|
||||
/* (3) else -> store */
|
||||
start = c++;
|
||||
|
||||
|
||||
/* (2) Seek CASE STOP char
|
||||
---------------------------------------------------------*/
|
||||
for( ; c < C ; c++ ){
|
||||
if( pPattern[c] == REGEX_CASE_START ) pair[0]++;
|
||||
if( pPattern[c] == REGEX_CASE_STOP ) pair[0]--;
|
||||
if( pPattern[c] == REGEX_GROUP_START ) pair[1]++;
|
||||
if( pPattern[c] == REGEX_GROUP_STOP ) pair[1]--;
|
||||
|
||||
if( pair[0] == 2 ) recursive[0] = 1;
|
||||
if( pair[1] == 2 ) recursive[1] = 1;
|
||||
|
||||
/* (1) If found and level-0 -> got it */
|
||||
if( pPattern[c] == REGEX_CASE_STOP && pair[0] == 0 && pair[1] == 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
/* (2) If not found -> error */
|
||||
if( c >= C )
|
||||
break;
|
||||
|
||||
/* (3) else -> store */
|
||||
end = c++;
|
||||
|
||||
|
||||
/* (3) Save set to cases
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Store set */
|
||||
pCases->n++;
|
||||
pCases->sets = realloc(pCases->sets, sizeof(struct RegExpDevSet) * pCases->n );
|
||||
pCases->sets[pCases->n-1].start = start;
|
||||
pCases->sets[pCases->n-1].end = end;
|
||||
pCases->sets[pCases->n-1].n = end-start-1;
|
||||
pCases->sets[pCases->n-1].set = malloc( pCases->sets[pCases->n-1].n +1 );
|
||||
sprintf(pCases->sets[pCases->n-1].set, "%.*s", pCases->sets[pCases->n-1].n, pPattern+pCases->sets[pCases->n-1].start+1);
|
||||
|
||||
/* (2) Try to find quantifier */
|
||||
c++;
|
||||
if( pPattern[c-1] == REGEX_QUANTIFIER_BINARY )
|
||||
pCases->sets[pCases->n-1].quantifier = REGEX_QUANTIFIER_BINARY;
|
||||
else if( pPattern[c-1] == REGEX_QUANTIFIER_ANY )
|
||||
pCases->sets[pCases->n-1].quantifier = REGEX_QUANTIFIER_ANY;
|
||||
else if( pPattern[c-1] == REGEX_QUANTIFIER_MULTI )
|
||||
pCases->sets[pCases->n-1].quantifier = REGEX_QUANTIFIER_MULTI;
|
||||
else
|
||||
c--;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* [2] If no set found return 1
|
||||
=========================================================*/
|
||||
if( recursive[0] == 1 || recursive[1] == 1 )
|
||||
return 2;
|
||||
|
||||
if( pCases->n+pGroups->n == 0 )
|
||||
return 1;
|
||||
|
||||
|
||||
/* [3] Try to develop recursively
|
||||
=========================================================*/
|
||||
// printf("Got %d cases\n", cases.n);
|
||||
// for( c = 0 ; c < cases.n ; c++ )
|
||||
// printf("\tCase.%d: '%.*s' (quantifier: %c)\n", c, cases.sets[c].end-cases.sets[c].start-1, pPattern+cases.sets[c].start+1, cases.sets[c].quantifier);
|
||||
// printf("Got %d groups\n", groups.n);
|
||||
// for( c = 0 ; c < groups.n ; c++ )
|
||||
// printf("\tGroup.%d: '%.*s' (quantifier: %c)\n", c, groups.sets[c].end-groups.sets[c].start-1, pPattern+groups.sets[c].start+1, groups.sets[c].quantifier);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int developMulti(const char* pPattern, struct RegExpDevSets* pCases, struct RegExpDevSets* pGroups, const char pDepth){
|
||||
|
||||
/* [0] Init vars
|
||||
=========================================================*/
|
||||
char depth = pDepth;
|
||||
unsigned int c, d;
|
||||
unsigned int boundary[2];
|
||||
struct RegExpDevSets groups = { 0, malloc(1) };
|
||||
struct RegExpDevSets cases = { 0, malloc(1) };
|
||||
int devRtn;
|
||||
char buffer[MAX_DEV_SIZE];
|
||||
|
||||
|
||||
|
||||
/* [1] Get all level-0 groups+cases
|
||||
=========================================================*/
|
||||
boundary[0] = 0; // min boundary
|
||||
boundary[1] = strlen(pPattern); // max boundary
|
||||
|
||||
// while there is a depth to do
|
||||
do{
|
||||
|
||||
strncpy(buffer, pPattern+boundary[0], boundary[1]);
|
||||
devRtn = developSingle(buffer, pGroups, pCases);
|
||||
|
||||
// if( devRtn == 0 ){
|
||||
// groups = realloc(groups, sizeof(struct RegExpDevSets) * depth);
|
||||
// cases = realloc(cases, sizeof(struct RegExpDevSets) * depth);
|
||||
// }
|
||||
|
||||
|
||||
for( c = 0 ; c < pGroups->n ; c++ ){
|
||||
for( d = 0 ; d < depth ; d++ ) printf(" ");
|
||||
printf("Group.%d-%d: '%s' (quantifier: %c)\n", depth, c, pGroups->sets[c].set, pGroups->sets[c].quantifier);
|
||||
|
||||
strcpy(buffer, pGroups->sets[c].set);
|
||||
for( d = 0 ; d < depth ; d++ ) printf(" ");
|
||||
printf("dev: %d\n", developMulti(buffer, &groups, &cases, depth+1));
|
||||
|
||||
}
|
||||
|
||||
for( c = 0 ; c < pCases->n ; c++ ){
|
||||
for( d = 0 ; d < depth ; d++ ) printf(" ");
|
||||
printf("Case.%d-%d: '%s' (quantifier: %c)\n", depth, c, pCases->sets[c].set, pCases->sets[c].quantifier);
|
||||
|
||||
strcpy(buffer, pCases->sets[c].set);
|
||||
for( d = 0 ; d < depth ; d++ ) printf(" ");
|
||||
printf("dev: %d\n", developMulti(buffer, &groups, &cases, depth+1));
|
||||
}
|
||||
|
||||
}while( devRtn == 10 );
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/**************************
|
||||
* Scope *
|
||||
***************************
|
||||
* Designed & Developed by *
|
||||
* Adrien Marquès *
|
||||
* <xdrm-brackets> *
|
||||
***************************
|
||||
* doowap31@gmail.com *
|
||||
**************************/
|
||||
#ifndef _LIB_REGEX_REGEX_H_
|
||||
#define _LIB_REGEX_REGEX_H_
|
||||
|
||||
|
||||
/* CONSTANTS */
|
||||
#define MAX_MATCH_SIZE 256
|
||||
#define MAX_DEV_SIZE 512
|
||||
|
||||
#define REGEX_GROUP_START '('
|
||||
#define REGEX_GROUP_STOP ')'
|
||||
#define REGEX_CASE_START '['
|
||||
#define REGEX_CASE_STOP ']'
|
||||
#define REGEX_CASE_DELIMITER '|'
|
||||
#define REGEX_QUANTIFIER_BINARY '?'
|
||||
#define REGEX_QUANTIFIER_ANY '*'
|
||||
#define REGEX_QUANTIFIER_MULTI '+'
|
||||
#define REGEX_SET_ALPHA_LOWER '\5'
|
||||
#define REGEX_SET_ALPHA_UPPER '\6'
|
||||
#define REGEX_SET_DIGIT '\7'
|
||||
#define REGEX_SET_ALPHANUMERIC '\8'
|
||||
#define REGEX_SET_PHPVAR '\9'
|
||||
|
||||
#define REGEX_ALPHA_LOWER "[abcdefghijklmnopqrstuvwxyz]"
|
||||
#define REGEX_ALPHA_UPPER "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]"
|
||||
#define REGEX_DIGIT "[0123456789]"
|
||||
#define REGEX_ALPHANUMERIC "[\1\2\3]"
|
||||
#define REGEX_PHPVAR "[\1\2_][\4_]+"
|
||||
|
||||
/* TYPES */
|
||||
struct RegExpMatch{
|
||||
char match[MAX_MATCH_SIZE];
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
};
|
||||
|
||||
struct RegExpMatches{
|
||||
unsigned int n;
|
||||
struct RegExpMatch* matches;
|
||||
};
|
||||
|
||||
struct RegExpDevSet{
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
char quantifier;
|
||||
char* set;
|
||||
char n;
|
||||
};
|
||||
|
||||
struct RegExpDevSets{
|
||||
unsigned int n;
|
||||
struct RegExpDevSet* sets;
|
||||
};
|
||||
|
||||
|
||||
/* GLOBAL */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* SIGNATURES */
|
||||
// struct RegExpMatches match(const char* pPattern, char* pBuffer);
|
||||
|
||||
/* Check if buffer is made of characters from pSet */
|
||||
char madeOfSet(char* pBuffer, const char* pSet);
|
||||
|
||||
/* Develops a pattern's sets (error:-1, else:0) */
|
||||
int developSingle(const char* pPattern, struct RegExpDevSets* pCases, struct RegExpDevSets* pGroups);
|
||||
|
||||
int developMulti(const char* pPattern, struct RegExpDevSets* pCases, struct RegExpDevSets* pGroups, const char pDepth);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
int main(){
|
||||
|
||||
struct RegExpMatches matches;
|
||||
|
||||
|
||||
matches = match("([(public)(private)] )?(static )?function\(($\a)\)");
|
||||
|
||||
"[abc]*" == "(a|b|c)*" // Any of the chars inside any time
|
||||
"[abc]?" == "(a|b|c)?" // Any of the chars inside zero or one time
|
||||
"[abc]+" == "(a|b|c)+" // Any of the chars inside at least one time
|
||||
|
||||
"(abc)*" // The chain inside any time
|
||||
"(abc)?" // The chain inside zero or one time
|
||||
"(abc)+" // The chain inside at least one time
|
||||
|
||||
"(abc|xyz)*" // Any of the chains inside any time
|
||||
"(abc|xyz)?" // Any of the chains inside zero or one time
|
||||
"(abc|xyz)+" // Any of the chains inside at least one time
|
||||
|
||||
"." // Any character
|
||||
"[a-z]" // Any letters between 'a' and 'z' (included)
|
||||
"[0-8]" // Any letters between '0' and '8' (included)
|
||||
|
||||
"(a[bx]c)" == "(abc|axc)"
|
||||
"[a(bx)c]" == "(a|bx|c)"
|
||||
"(a[bc]d[ef]g)" == "(abdeg|abdfg|acdeg|acdfg)"
|
||||
"[a(bc)d(ef)g]" == "(a|bc|d|ef|g)"
|
||||
|
||||
"* The NF is a group '()' with no case '[]'"
|
||||
|
||||
"* For instance with the undevelopped form: "
|
||||
"((public|private) *)?(static *)? *function\([abc]*\)"
|
||||
"* Will be developped into: "
|
||||
"(((public|private) *)?(static *)? *function\([abc]*\))" // surrounding with '(' and ')'
|
||||
"(((public|private) *)?(static *)? *function\((a|b|c)\))" // develop cases '[...]'
|
||||
|
||||
"* For instance with the undevelopped form: "
|
||||
"[a-z0-9_\.]+@[a-z0-9_\.]\.[a-z]+"
|
||||
"* Will be developped into: "
|
||||
"([a-z0-9_\.]+@[a-z0-9_\.]\.[a-z]+)"
|
||||
"((a-z|0-9|_|\.)+@(a-z|0-9|_|\.)\.(a-z)+)"
|
||||
"((a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|0|1|2|3|4|5|6|7|8|9|_|\.)+@(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|0|1|2|3|4|5|6|7|8|9|_|\.)\.(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)+)"
|
||||
|
||||
|
||||
"* For instance with the undevelopped form: "
|
||||
"[ \t]*$[a-zA-Z_][a-zA-Z0-9_]+ *[+-/*|&]?= *.+"
|
||||
"* Will be developped into: "
|
||||
"([ \t]*$[a-zA-Z_][a-zA-Z0-9_]+ *[+-/*|&]?= *.+)" // surrounding by ()
|
||||
"([ \t]*$[a-zA-Z_][a-zA-Z0-9_]+( )*[+-/*|&]?=( )*(.)+)" // replacing non-captured chains
|
||||
"(( |\t)*$(a-z|A-Z|_)(a-z|A-Z|0-9|_)+( )*(+|-|/|*|||&)?=( )*(.)+)" // develop []
|
||||
|
||||
"* So we have the following matching automate :"
|
||||
"( |\t)*$(a-z|A-Z|_)(a-z|A-Z|0-9|_)+( )*(+|-|/|*|||&)?=( )*(.)+)" // develop []
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/**************************
|
||||
* Scope *
|
||||
***************************
|
||||
* Designed & Developed by *
|
||||
* Adrien Marquès *
|
||||
* <xdrm-brackets> *
|
||||
***************************
|
||||
* doowap31@gmail.com *
|
||||
**************************/
|
||||
#include "scope.h"
|
|
@ -0,0 +1,24 @@
|
|||
/**************************
|
||||
* Scope *
|
||||
***************************
|
||||
* Designed & Developed by *
|
||||
* Adrien Marquès *
|
||||
* <xdrm-brackets> *
|
||||
***************************
|
||||
* doowap31@gmail.com *
|
||||
**************************/
|
||||
#ifndef _LIB_SCOPE_SCOPE_H_
|
||||
#define _LIB_SCOPE_SCOPE_H_
|
||||
|
||||
/* GLOBAL */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* LOCAL */
|
||||
#include "../php-const.h"
|
||||
|
||||
/* SIGNATURES */
|
||||
int is_function_start(char* pLine);
|
||||
|
||||
|
||||
#endif
|
85
src/linter.c
85
src/linter.c
|
@ -12,19 +12,97 @@
|
|||
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
/* [0] Init variables
|
||||
=========================================================*/
|
||||
FILE* source;
|
||||
char* line = malloc( MAX_LINE );
|
||||
char c;
|
||||
char eof = 0;
|
||||
|
||||
|
||||
/** TEST **/
|
||||
/** BUILD AUTOMATE **/
|
||||
struct Automate a = createAutomate();
|
||||
|
||||
addState(&a);
|
||||
addState(&a);
|
||||
addState(&a);
|
||||
|
||||
addSet(&a, "ba\0");
|
||||
addSet(&a, "be\0");
|
||||
addSet(&a, "bi\0");
|
||||
|
||||
linkStates(&a, 0, 1, "ba\0");
|
||||
linkStates(&a, 1, 1, "be\0");
|
||||
linkStates(&a, 1, 2, "bi\0");
|
||||
|
||||
printf("browse 'aei' : %d\n", browse(a, "aei"));
|
||||
printf("browse 'bbb' : %d\n", browse(a, "bbb"));
|
||||
printf("browse 'abi' : %d\n", browse(a, "abi"));
|
||||
printf("browse 'abb' : %d\n", browse(a, "abb"));
|
||||
printf("browse 'i' : %d\n", browse(a, "i"));
|
||||
printf("browse 'b' : %d\n", browse(a, "b"));
|
||||
/** TEST **/
|
||||
|
||||
{ /* [1] Check arguments
|
||||
=========================================================*/
|
||||
/* (1) argc */
|
||||
if( argc < 2 )
|
||||
if( argc < 2 ){
|
||||
fprintf(stderr, "Missing argument.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* (2) argv[1] : absolute path */
|
||||
if( argv[1][0] != '/' )
|
||||
if( argv[1][0] != '/' ){
|
||||
fprintf(stderr, "Path must be absolute.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* (3) argv[1] : */
|
||||
if( access(argv[1], F_OK) == -1 )
|
||||
if( access(argv[1], F_OK) == -1 ){
|
||||
fprintf(stderr, "Path unknown.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{ /* [2] Read file line by line
|
||||
=========================================================*/
|
||||
/* (1) Open file */
|
||||
source = fopen(argv[1], "r");
|
||||
|
||||
if( source == NULL ){
|
||||
fprintf(stderr, "Cannot read the file.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* (2) For each line
|
||||
---------------------------------------------------------*/
|
||||
while( 1 ){
|
||||
|
||||
/* (1) Get each line */
|
||||
if( fgets(line, MAX_LINE, source) == NULL )
|
||||
if( feof(source) ) return EXIT_SUCCESS;
|
||||
else return EXIT_FAILURE;
|
||||
|
||||
/* (2) Remove trailing EOL */
|
||||
if( line[strlen(line)-1] == '\n' )
|
||||
line[strlen(line)-1] = 0;
|
||||
|
||||
/* (3) Get indentation level */
|
||||
int indentLevel = getIndentation(line, strlen(line));
|
||||
|
||||
/* (4) Isolate line */
|
||||
isolate_line(line, strlen(line));
|
||||
|
||||
printf("line/%d: '%s'\n", indentLevel, line);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (n) Close file */
|
||||
fclose(source);
|
||||
|
||||
}
|
||||
|
||||
|
@ -32,6 +110,5 @@ int main(int argc, char* argv[]){
|
|||
|
||||
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -11,8 +11,17 @@
|
|||
#ifndef _LINTER_H_
|
||||
#define _LINTER_H_
|
||||
|
||||
/* GLOBAL */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <malloc.h>
|
||||
|
||||
/* LOCAL */
|
||||
#include "lib/php-const.h"
|
||||
#include "lib/common/common.h"
|
||||
#include "lib/scope/scope.h"
|
||||
#include "lib/automate/automate.h"
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue