#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct Node Node;
|
|
typedef struct Exploration Exploration;
|
|
|
|
|
|
enum opcode {
|
|
STRING,
|
|
AND,
|
|
STAR,
|
|
PLUS,
|
|
QMARK
|
|
};
|
|
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;
|
|
}
|
|
|
|
char advance(Exploration *exploration)
|
|
{
|
|
return exploration->text[exploration->position++];
|
|
}
|
|
|
|
int endExploration(Exploration *exploration)
|
|
{
|
|
if (exploration->position >= strlen(exploration->text))
|
|
{
|
|
return 1;
|
|
} else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void setPosition(Exploration *exploration, int position)
|
|
{
|
|
exploration->position= 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 *mkQmark(Node *child)
|
|
{
|
|
Node *node= mkNode(QMARK);
|
|
node->children[0]= child;
|
|
return node;
|
|
}
|
|
|
|
int execute(Node *node, Exploration *in)
|
|
{
|
|
switch (node->type) {
|
|
case STRING: {
|
|
for (int i=0; i < strlen(node->stringValue);i++)
|
|
{
|
|
if (advance(in) != node->stringValue[i])
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
if (endExploration(in)==1)
|
|
{
|
|
return 1;
|
|
} else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
case AND: {
|
|
if (execute(node->children[0], in) == 0) //si il y a eu une erreur
|
|
{
|
|
return 0;
|
|
} else //si ça s'est bien passé
|
|
{
|
|
return execute(node->children[1], in);
|
|
}
|
|
}
|
|
case STAR: {
|
|
if(execute(node->children[0], in) == 1){
|
|
execute(node->children[0], in);
|
|
}
|
|
else return 1;
|
|
}
|
|
case PLUS: {
|
|
if(execute(node->children[0],in)==0){
|
|
return 0;
|
|
}
|
|
else{
|
|
while(execute(node->children[0], in) == 1){
|
|
|
|
execute(node->children[0], in);
|
|
|
|
}
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
case QMARK: {
|
|
// 0 ou 1
|
|
if(execute(node->children[0], in)==1) return execute(node->children[0], in);
|
|
return 1;
|
|
}
|
|
}
|
|
printf("this cannot happen\n");
|
|
abort();
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
Exploration *in= mkExploration("acc");
|
|
|
|
/*Node *program=
|
|
mkString("aabbcc");
|
|
|
|
Node *program=
|
|
mkAnd(mkString("aab"),
|
|
mkString("bcc"));*/
|
|
|
|
/*Node *program=
|
|
mkAnd(mkString("aa"),
|
|
mkAnd(mkString("bb"),
|
|
mkString("cc")));*/
|
|
|
|
/* Node *program=
|
|
mkAnd( mkString("aabbcc"),
|
|
mkAnd(mkStar(mkString("c")), // "a"*"b"*"c"*
|
|
mkAnd(mkStar(mkString("b")),
|
|
mkStar(mkString("c")))));
|
|
*/
|
|
Node *program=
|
|
mkAnd(mkQmark(mkString("a")), // "a"*"b"*"c"*
|
|
mkAnd(mkQmark(mkString("b")),
|
|
mkPlus(mkString("c"))));
|
|
|
|
if (execute(program, in)<=0)
|
|
{
|
|
printf("no match\n");
|
|
} else
|
|
{
|
|
printf("match\n");
|
|
}// 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;
|
|
}
|