#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef union Node Node;
|
|
typedef struct Exploration Exploration;
|
|
|
|
|
|
enum opcode {
|
|
<<<<<<< HEAD
|
|
String,
|
|
And,
|
|
Or,
|
|
Star,
|
|
Plus,
|
|
Class,
|
|
Question_mark,
|
|
Exclamation_mark,
|
|
Dot
|
|
=======
|
|
STRING,
|
|
AND,
|
|
OR,
|
|
STAR,
|
|
PLUS,
|
|
CLASS,
|
|
QUESTION_MARK,
|
|
EXCLAMATION_MARK,
|
|
DOT
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
};
|
|
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];
|
|
}
|
|
<<<<<<< HEAD
|
|
=======
|
|
|
|
char *currentText(Exploration *exploration)
|
|
{
|
|
return exploration->text + exploration->position;
|
|
}
|
|
|
|
struct String { enum opcode type; char *stringValue; int len;};
|
|
struct Class { enum opcode type; char *stringValue; int len;};
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
|
|
char *currentText(Exploration *exploration)
|
|
{
|
|
return exploration->text + exploration->position;
|
|
}
|
|
|
|
struct String { enum opcode type; char *stringValue; int len;};
|
|
struct Class { enum opcode type; char *stringValue; int len;};
|
|
struct And { enum opcode type; Node *children[2];};
|
|
struct Or { enum opcode type; Node *children[2];};
|
|
struct Star { enum opcode type; Node *children[1];};
|
|
struct Plus { enum opcode type; Node *children[1];};
|
|
struct Question_mark { enum opcode type; Node *children[1];};
|
|
struct Exclamation_mark { enum opcode type; Node *children[1];};
|
|
struct Dot { enum opcode type;};
|
|
union Node
|
|
{
|
|
enum opcode type;
|
|
<<<<<<< HEAD
|
|
struct String String;
|
|
struct Class Class;
|
|
struct And And;
|
|
struct Star Star;
|
|
struct Plus Plus;
|
|
struct Or Or;
|
|
struct Question_mark Question_mark;
|
|
struct Exclamation_mark Exclamation_mark;
|
|
struct Dot Dot;
|
|
=======
|
|
union {
|
|
struct String STRING;
|
|
struct Class CLASS;
|
|
Node *children[2];
|
|
};
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
};
|
|
|
|
|
|
|
|
Node *mkNode(size_t size,enum opcode type)
|
|
{
|
|
Node *node= calloc(1, size);
|
|
node->type= type;
|
|
return node;
|
|
}
|
|
#define new(type) mkNode(sizeof(struct type),type)
|
|
|
|
Node *mkString(char *value)
|
|
{
|
|
<<<<<<< HEAD
|
|
Node *node= new(String);
|
|
node->String.stringValue= value;
|
|
node->String.len=strlen(value);
|
|
=======
|
|
Node *node= mkNode(STRING);
|
|
node->STRING.stringValue= value;
|
|
node->STRING.len=strlen(value);
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
return node;
|
|
}
|
|
|
|
Node *mkAnd(Node *node1, Node *node2)
|
|
{
|
|
Node *node= new(And);
|
|
node->And.children[0]= node1;
|
|
node->And.children[1]= node2;
|
|
return node;
|
|
}
|
|
|
|
|
|
Node *mkStar(Node *child)
|
|
{
|
|
Node *node= new(Star);
|
|
node->Star.children[0]= child;
|
|
return node;
|
|
}
|
|
|
|
Node *mkPlus(Node *child)
|
|
{
|
|
Node *node= new(Plus);
|
|
node->Plus.children[0]= child;
|
|
return node;
|
|
}
|
|
|
|
Node *mkOr(Node *node1, Node *node2)
|
|
{
|
|
Node *node= new(Or);
|
|
node->Or.children[0]= node1;
|
|
node->Or.children[1]= node2;
|
|
return node;
|
|
}
|
|
|
|
Node *mkClass(char* str)
|
|
{
|
|
Node *node= new(Class);
|
|
node->Class.stringValue= str;
|
|
node->Class.len=strlen(str);
|
|
return node;
|
|
}
|
|
|
|
Node *mkQuestionMark(Node *child)
|
|
{
|
|
Node *node= new(Question_mark);
|
|
node->Question_mark.children[0]= child;
|
|
return node;
|
|
}
|
|
|
|
<<<<<<< HEAD
|
|
Node *mkExclamationMark(Node *child)
|
|
{
|
|
Node *node= new(Exclamation_mark);
|
|
node->Exclamation_mark.children[0]= child;
|
|
return node;
|
|
}
|
|
|
|
|
|
|
|
Node *mkDot()
|
|
{
|
|
static Node *node= 0;
|
|
if (node==0){
|
|
node=new(Dot);
|
|
}
|
|
=======
|
|
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->STRING.stringValue= str;
|
|
node->STRING.len=strlen(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);
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
return node;
|
|
}
|
|
|
|
Node *_checktype(Node *object, enum opcode type)
|
|
{
|
|
if (object->type == type) return object;
|
|
fprintf(stderr, "\naccesing type %i as if it were a %i\n", object->type, type);
|
|
exit(1);
|
|
return 0;
|
|
}
|
|
|
|
#define get(object, type, member) (_checktype(object, type)->type.member)
|
|
|
|
const char* getTypeName(enum opcode type)
|
|
{
|
|
switch (type)
|
|
{
|
|
<<<<<<< HEAD
|
|
case Star: return "Star";
|
|
case Exclamation_mark: return "NOT";
|
|
case Dot: return "Dot";
|
|
case Question_mark: return "QMARK";
|
|
case Plus : return "Plus";
|
|
case Class : return "Class";
|
|
=======
|
|
case STAR: return "STAR";
|
|
case EXCLAMATION_MARK: return "NOT";
|
|
case DOT: return "DOT";
|
|
case QUESTION_MARK: return "QMARK";
|
|
case PLUS : return "PLUS";
|
|
case CLASS : return "CLASS";
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
default : printf("unexpected use");return 0;
|
|
abort();
|
|
}
|
|
}
|
|
|
|
void println(Node *node, int indent)
|
|
{
|
|
for(int i=0;i<indent;i++){
|
|
printf("----");
|
|
|
|
}
|
|
indent++;
|
|
switch (node->type) {
|
|
<<<<<<< HEAD
|
|
case String: printf("%.*s", get(node, String, len), get(node, String, stringValue)); return;
|
|
case And: {
|
|
printf("AND\n");
|
|
println(get(node,And,children[0]),indent);printf("\n");
|
|
println(get(node,And,children[1]),indent);printf("\n");return;
|
|
}
|
|
case Or: {
|
|
printf("OR\n");
|
|
println(get(node,Or,children[0]),indent);printf("\n");
|
|
println(get(node,Or,children[1]),indent);printf("\n");return;
|
|
}
|
|
case Dot:{
|
|
printf("DOT\n");return;
|
|
}
|
|
case Class:{
|
|
printf("Class : Char in [%.*s]\n",get(node, Class, len),get(node, Class, stringValue));return;
|
|
}
|
|
case Plus:{
|
|
printf("Plus\n");
|
|
println(get(node,Plus,children[0]),indent);printf("\n");return;
|
|
}
|
|
case Question_mark:{
|
|
printf("Question_mark\n");
|
|
println(get(node,Question_mark,children[0]),indent);printf("\n");return;
|
|
}
|
|
case Exclamation_mark:{
|
|
printf("Exclamation_mark\n");
|
|
println(get(node,Exclamation_mark,children[0]),indent);printf("\n");return;
|
|
}
|
|
case Star:{
|
|
printf("Star\n");
|
|
println(get(node,Star,children[0]),indent);printf("\n");return;
|
|
}
|
|
|
|
}
|
|
printf("Unexpected type %i",node->type);
|
|
=======
|
|
case STRING: printf("%.*s", get(node, STRING, len), get(node, STRING, stringValue)); return;
|
|
case AND: {
|
|
printf("AND\n");
|
|
println(node->children[0],indent);printf("\n");
|
|
println(node->children[1],indent);printf("\n");return;
|
|
}
|
|
case OR: {
|
|
printf("OR\n");
|
|
println(node->children[0],indent);printf("\n");
|
|
println(node->children[1],indent);printf("\n");return;
|
|
}
|
|
case DOT:{
|
|
printf("DOT\n");return;
|
|
}
|
|
case CLASS:{
|
|
printf("CLASS : Char in [%.*s]\n",get(node, CLASS, len),get(node, CLASS, stringValue));return;
|
|
}
|
|
default : {
|
|
printf("%s\n",getTypeName(node->type));
|
|
println(node->children[0],indent);printf("\n");return;
|
|
}
|
|
}
|
|
abort();
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
}
|
|
|
|
|
|
|
|
int execute(Node *node, Exploration *in)
|
|
{
|
|
switch (node->type) {
|
|
<<<<<<< HEAD
|
|
case String: {
|
|
if (strncmp(currentText(in), get(node,String,stringValue), get(node,String,len))) {
|
|
return 0;
|
|
}
|
|
advance(in, get(node,String,len));
|
|
return 1;
|
|
}
|
|
case And: {
|
|
int pos= getPosition(in);
|
|
if (!execute(get(node,And,children[0]), in)) //si il y a eu une erreur
|
|
{
|
|
return 0;
|
|
} //si ça s'est bien passé
|
|
if (!execute(get(node,And,children[1]), in)) {
|
|
setPosition(in, pos);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
case Or: {
|
|
if (execute(get(node,Or,children[0]), in)) {
|
|
return 1;
|
|
}
|
|
return execute(get(node,Or,children[1]), in);
|
|
}
|
|
case Star: {
|
|
while (execute(get(node,Star,children[0]), in));
|
|
return 1;
|
|
}
|
|
case Plus: {
|
|
if (!execute(get(node,Plus,children[0]), in)) {
|
|
return 0;
|
|
}
|
|
while (execute(get(node,Plus,children[0]), in));
|
|
return 1;
|
|
}
|
|
case Class: {
|
|
if (!currentChar(in)) {
|
|
return 0;
|
|
}
|
|
if (strchr(get(node,Class,stringValue), currentChar(in))) {
|
|
=======
|
|
case STRING: {
|
|
if (strncmp(currentText(in), node->STRING.stringValue, node->STRING.len)) {
|
|
return 0;
|
|
}
|
|
advance(in, node->STRING.len);
|
|
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->STRING.stringValue, currentChar(in))) {
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
advance(in, 1);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
<<<<<<< HEAD
|
|
case Question_mark: {
|
|
execute(get(node,Question_mark,children[0]), in);
|
|
return 1;
|
|
}
|
|
case Exclamation_mark: {
|
|
int pos= getPosition(in);
|
|
if (!execute(get(node,Exclamation_mark,children[0]), in)) {
|
|
=======
|
|
case QUESTION_MARK: {
|
|
execute(node->children[0], in);
|
|
return 1;
|
|
}
|
|
case EXCLAMATION_MARK: {
|
|
int pos= getPosition(in);
|
|
if (!execute(node->children[0], in)) {
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
return 1;
|
|
}
|
|
setPosition(in, pos);
|
|
return 0;
|
|
}
|
|
<<<<<<< HEAD
|
|
case Dot: {
|
|
=======
|
|
case DOT: {
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
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"))));*/
|
|
|
|
|
|
<<<<<<< HEAD
|
|
Node *program= mkOr(mkString("don't match pls"),mkStar(mkDot()));
|
|
=======
|
|
Node *program= mkStar(mkClass("abc"));
|
|
>>>>>>> c0cb24584cb692cf472ced68d40700ba949cdeee
|
|
Node *program3=mkAnd(mkAnd(mkPlus(mkString("hello world")),mkExclamationMark(mkString("how are u world !?"))),mkStar(mkClass("abcde")));
|
|
|
|
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
|
|
println(program3,0);
|
|
|
|
|
|
return 0;
|
|
}
|