Dynamic PEG for interpreted languages.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

194 lignes
3.6 KiB

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node Node;
typedef struct Exploration Exploration;
enum opcode {
STRING,
AND,
STAR,
PLUS
};
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 -1;
}
}
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;
}
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;
}
}
return endExploration(in);
}
case AND: {
int pos= in->position;
if (execute(node->children[0], in) == 0) //si il y a eu une erreur
{
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;
}
}
case STAR: {
int pos= in->position;
int result;
while ((result= execute(node->children[0], in)) == -1){
pos= in->position;;
}
if (result == 0) {
setPosition(in, pos);
}
return endExploration(in);
}
case PLUS: {
Node *newNode= mkAnd(node->children[0], mkStar(node->children[0]));
return execute(newNode,in);
}
}
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=
mkAnd(mkPlus(mkString("a")), // "a"*"b"*"c"*
mkAnd(mkStar(mkString("b")),
mkStar(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;
}