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.

218 lignes
4.1 KiB

#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;
}