|
|
@ -9,8 +9,13 @@ typedef struct Exploration Exploration; |
|
|
|
enum opcode { |
|
|
|
STRING, |
|
|
|
AND, |
|
|
|
OR, |
|
|
|
STAR, |
|
|
|
PLUS |
|
|
|
PLUS, |
|
|
|
CLASS, |
|
|
|
QUESTION_MARK, |
|
|
|
EXCLAMATION_MARK, |
|
|
|
DOT |
|
|
|
}; |
|
|
|
struct Exploration |
|
|
|
{ |
|
|
@ -26,27 +31,34 @@ Exploration *mkExploration(char *text) |
|
|
|
return exploration; |
|
|
|
} |
|
|
|
|
|
|
|
char advance(Exploration *exploration) |
|
|
|
void advance(Exploration *exploration, int add) |
|
|
|
{ |
|
|
|
return exploration->text[exploration->position++]; |
|
|
|
exploration->position+= add; |
|
|
|
} |
|
|
|
|
|
|
|
int endExploration(Exploration *exploration) |
|
|
|
{ |
|
|
|
if (exploration->position >= strlen(exploration->text)) |
|
|
|
{ |
|
|
|
return 1; |
|
|
|
} else |
|
|
|
{ |
|
|
|
return -1; |
|
|
|
int atEnd(Exploration *exploration) { |
|
|
|
return exploration->text[exploration->position] == 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void setPosition(Exploration *exploration, int position) |
|
|
|
{ |
|
|
|
exploration->position= position; |
|
|
|
} |
|
|
|
|
|
|
|
int getPosition(Exploration *exploration) { |
|
|
|
return exploration->position; |
|
|
|
} |
|
|
|
|
|
|
|
int currentChar(Exploration *exploration) |
|
|
|
{ |
|
|
|
return exploration->text[exploration->position]; |
|
|
|
} |
|
|
|
|
|
|
|
char *currentText(Exploration *exploration) |
|
|
|
{ |
|
|
|
return exploration->text + exploration->position; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
struct Node |
|
|
|
{ |
|
|
@ -96,51 +108,112 @@ Node *mkPlus(Node *child) |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkOr(Node *node1, Node *node2) |
|
|
|
{ |
|
|
|
Node *node= mkNode(OR); |
|
|
|
node->children[0]= node1; |
|
|
|
node->children[1]= node2; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkClass(char* str) |
|
|
|
{ |
|
|
|
Node *node= mkNode(CLASS); |
|
|
|
node->stringValue= str; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkQuestionMark(Node *child) |
|
|
|
{ |
|
|
|
Node *node= mkNode(QUESTION_MARK); |
|
|
|
node->children[0]= child; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkExclamationMark(Node *child) |
|
|
|
{ |
|
|
|
Node *node= mkNode(EXCLAMATION_MARK); |
|
|
|
node->children[0]= child; |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
Node *mkDot() |
|
|
|
{ |
|
|
|
Node *node= mkNode(DOT); |
|
|
|
return node; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int execute(Node *node, Exploration *in) |
|
|
|
{ |
|
|
|
switch (node->type) { |
|
|
|
case STRING: { |
|
|
|
int pos= in->position; |
|
|
|
for (int i=0; i < strlen(node->stringValue);i++) |
|
|
|
{ |
|
|
|
if (advance(in) != node->stringValue[i]) |
|
|
|
{ |
|
|
|
setPosition(in, pos); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
int length= strlen(node->stringValue); |
|
|
|
if (strncmp(currentText(in), node->stringValue, length)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
return endExploration(in); |
|
|
|
advance(in, length); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case AND: { |
|
|
|
int pos= in->position; |
|
|
|
if (execute(node->children[0], in) == 0) //si il y a eu une erreur |
|
|
|
int pos= getPosition(in); |
|
|
|
if (!execute(node->children[0], in)) //si il y a eu une erreur |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} //si ça s'est bien passé |
|
|
|
if (!execute(node->children[1], in)) { |
|
|
|
setPosition(in, pos); |
|
|
|
return 0; |
|
|
|
} else //si ça s'est bien passé |
|
|
|
{ |
|
|
|
int result= execute(node->children[1], in); |
|
|
|
if (result == 0) { |
|
|
|
setPosition(in, pos); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case STAR: { |
|
|
|
int pos= in->position; |
|
|
|
int result; |
|
|
|
while ((result= execute(node->children[0], in)) == -1){ |
|
|
|
pos= in->position;; |
|
|
|
case OR: { |
|
|
|
if (execute(node->children[0], in)) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (result == 0) { |
|
|
|
setPosition(in, pos); |
|
|
|
return execute(node->children[1], in); |
|
|
|
} |
|
|
|
return endExploration(in); |
|
|
|
case STAR: { |
|
|
|
while (execute(node->children[0], in)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case PLUS: { |
|
|
|
Node *newNode= mkAnd(node->children[0], mkStar(node->children[0])); |
|
|
|
return execute(newNode,in); |
|
|
|
if (!execute(node->children[0], in)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
while (execute(node->children[0], in)); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case CLASS: { |
|
|
|
if (!currentChar(in)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if (strchr(node->stringValue, currentChar(in))) { |
|
|
|
advance(in, 1); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
case QUESTION_MARK: { |
|
|
|
execute(node->children[0], in); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
case EXCLAMATION_MARK: { |
|
|
|
int pos= getPosition(in); |
|
|
|
if (!execute(node->children[0], in)) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
setPosition(in, pos); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
case DOT: { |
|
|
|
if (atEnd(in)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
advance(in, 1); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
printf("this cannot happen\n"); |
|
|
@ -163,32 +236,24 @@ int main(int argc, char **argv) |
|
|
|
mkAnd(mkString("bb"), |
|
|
|
mkString("cc")));*/ |
|
|
|
|
|
|
|
Node *program= |
|
|
|
mkAnd(mkPlus(mkString("a")), // "a"*"b"*"c"* |
|
|
|
/*Node *program= |
|
|
|
mkOr(mkPlus(mkString("a")), // "a"*"b"*"c"* |
|
|
|
mkAnd(mkStar(mkString("b")), |
|
|
|
mkStar(mkString("c")))); |
|
|
|
mkStar(mkString("c"))));*/ |
|
|
|
|
|
|
|
|
|
|
|
Node *program= mkStar(mkClass("abc")); |
|
|
|
|
|
|
|
if (execute(program, in)<=0) |
|
|
|
|
|
|
|
if (!execute(program, in) || !atEnd(in)) |
|
|
|
{ |
|
|
|
printf("no match\n"); |
|
|
|
printf("no match, current position : %i\n", getPosition(in)); |
|
|
|
} else |
|
|
|
{ |
|
|
|
printf("match\n"); |
|
|
|
printf("match, current position : %i\n", getPosition(in)); |
|
|
|
}// 0 => no match, 1 => match |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*Input *in1= mkInput("hello"); |
|
|
|
Input *in2= mkInput("world"); |
|
|
|
Input *in3= mkInput("hello world"); |
|
|
|
Node *program= |
|
|
|
mkOr(mkString("hello"), // "hello" | "world" |
|
|
|
mkString("world")); |
|
|
|
printf("%i\n", execute(program, in)); // 0 => no match, 1 => match*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
} |