#include #include #include typedef struct Node Node; typedef struct Exploration Exploration; enum opcode { STRING, AND, OR, STAR, PLUS, CLASS, QUESTION_MARK, EXCLAMATION_MARK, DOT }; struct Exploration { int position; char *text; }; Exploration *mkExploration(char *text) { Exploration *exploration = calloc(1,sizeof(Exploration*)); //sizeof du type pointeur exploration->position= 0; exploration->text= text; return exploration; } void advance(Exploration *exploration, int add) { exploration->position+= add; } 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 { enum opcode type; union { char *stringValue; Node *children[2]; }; }; Node *mkNode(enum opcode type) { Node *node= calloc(1, sizeof(Node)); node->type= type; return node; } Node *mkString(char *value) { Node *node= mkNode(STRING); node->stringValue= value; return node; } Node *mkAnd(Node *node1, Node *node2) { Node *node= mkNode(AND); node->children[0]= node1; node->children[1]= node2; return node; } Node *mkStar(Node *child) { Node *node= mkNode(STAR); node->children[0]= child; return node; } Node *mkPlus(Node *child) { Node *node= mkNode(PLUS); node->children[0]= 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 length= strlen(node->stringValue); if (strncmp(currentText(in), node->stringValue, length)) { return 0; } advance(in, length); return 1; } case AND: { 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; } return 1; } case OR: { if (execute(node->children[0], in)) { return 1; } return execute(node->children[1], in); } case STAR: { while (execute(node->children[0], in)); return 1; } case PLUS: { 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"); abort(); } int main(int argc, char **argv) { Exploration *in= mkExploration("aabbcc"); /*Node *program= mkString("aabbcc"); Node *program= mkAnd(mkString("aab"), mkString("bcc"));*/ /*Node *program= mkAnd(mkString("aa"), mkAnd(mkString("bb"), mkString("cc")));*/ /*Node *program= mkOr(mkPlus(mkString("a")), // "a"*"b"*"c"* mkAnd(mkStar(mkString("b")), mkStar(mkString("c"))));*/ Node *program= mkStar(mkClass("abc")); if (!execute(program, in) || !atEnd(in)) { printf("no match, current position : %i\n", getPosition(in)); } else { printf("match, current position : %i\n", getPosition(in)); }// 0 => no match, 1 => match return 0; }