Téléverser les fichiers vers "Anna et Ethan"
This commit is contained in:
400
Anna et Ethan/regexp_tonfa.c
Normal file
400
Anna et Ethan/regexp_tonfa.c
Normal file
@@ -0,0 +1,400 @@
|
||||
|
||||
#include "regexp_tonfa.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "shell_tools.h"
|
||||
#include "type_boolarray.h"
|
||||
#include "type_dequeue.h"
|
||||
|
||||
/****************************/
|
||||
/*+ Algorithme de Glushkov +*/
|
||||
/****************************/
|
||||
|
||||
uint reg_countletters(regexp *ptr_regex) {
|
||||
printf(" je suis dans reg_countletters\n");
|
||||
if (ptr_regex == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (ptr_regex->op == CHAR) {
|
||||
return 1;
|
||||
}
|
||||
uint left = reg_countletters(ptr_regex->left);
|
||||
uint right = reg_countletters(ptr_regex->right);
|
||||
printf(" je sors de reg_countletters\n");
|
||||
return left + right;
|
||||
}
|
||||
|
||||
glushkov_info *reg_create_gk_emp(uint nbr_letter) {
|
||||
printf(" je suis dans reg_create_gk_emp\n");
|
||||
glushkov_info *ptr = malloc(sizeof(glushkov_info));
|
||||
if (ptr == NULL) {
|
||||
ERROR("reg_create_gk_emp : malloc failed");
|
||||
}
|
||||
ptr->size = nbr_letter;
|
||||
ptr->epsilon = false;
|
||||
ptr->first = create_barray(nbr_letter);
|
||||
ptr->last = create_barray(nbr_letter);
|
||||
ptr->follow = create_barray(nbr_letter * nbr_letter);
|
||||
printf(" je sors de reg_create_gk_emp\n");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
glushkov_info *reg_create_gk_eps(uint nbr_letter) {
|
||||
printf(" je suis dans reg_create_gk_eps\n");
|
||||
glushkov_info *ptr = malloc(sizeof(glushkov_info));
|
||||
if (ptr == NULL) {
|
||||
ERROR("reg_create_gk_eps : malloc failed");
|
||||
}
|
||||
ptr->size = nbr_letter;
|
||||
ptr->epsilon = true;
|
||||
ptr->first = create_barray(nbr_letter);
|
||||
ptr->last = create_barray(nbr_letter);
|
||||
ptr->follow = create_barray(nbr_letter * nbr_letter);
|
||||
printf(" je sors de reg_create_gk_eps\n");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
glushkov_info *reg_create_gk_let(uint num_letter, uint nbr_letter) {
|
||||
printf(" je suis dans reg_create_gk_let\n");
|
||||
glushkov_info *ptr = malloc(sizeof(glushkov_info));
|
||||
if (ptr == NULL) {
|
||||
ERROR("reg_create_gk_let : malloc failed");
|
||||
}
|
||||
ptr->size = nbr_letter;
|
||||
ptr->epsilon = false;
|
||||
ptr->first = create_barray(nbr_letter);
|
||||
ptr->last = create_barray(nbr_letter);
|
||||
ptr->follow = create_barray(nbr_letter * nbr_letter);
|
||||
settrue_barray(ptr->first, num_letter);
|
||||
settrue_barray(ptr->last, num_letter);
|
||||
printf(" je sors de reg_create_gk_let\n");
|
||||
return ptr;
|
||||
}
|
||||
|
||||
glushkov_info *reg_gk_star(glushkov_info *ptr_glu) {
|
||||
printf(" je suis dans reg_gk_star\n");
|
||||
glushkov_info *new_ptr = malloc(sizeof(glushkov_info));
|
||||
if (new_ptr == NULL) {
|
||||
ERROR("reg_gk_star : malloc failed");
|
||||
}
|
||||
if (ptr_glu == NULL) {
|
||||
ERROR("reg_gk_star : ptr_glu is NULL");
|
||||
}
|
||||
new_ptr->size = ptr_glu->size;
|
||||
new_ptr->epsilon = true;
|
||||
new_ptr->first = copy_barray(ptr_glu->first);
|
||||
new_ptr->last = copy_barray(ptr_glu->last);
|
||||
new_ptr->follow = copy_barray(ptr_glu->follow);
|
||||
printf(" on a copié les tableaux\n");
|
||||
for (uint l = 0; l < ptr_glu->size; l++) {
|
||||
for (uint f = 0; f < ptr_glu->size; f++) {
|
||||
if (getval_barray(ptr_glu->last, l) &&
|
||||
getval_barray(ptr_glu->first, f)) {
|
||||
settrue_barray(new_ptr->follow, (l * ptr_glu->size) + f);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ptr_glu != NULL) reg_gk_delete(ptr_glu);
|
||||
printf(" je sors de reg_gk_star\n");
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
glushkov_info *reg_gk_union(glushkov_info *ptr_info_left,
|
||||
glushkov_info *ptr_info_right) {
|
||||
printf(" je suis dans reg_gk_union\n");
|
||||
glushkov_info *new_ptr = malloc(sizeof(glushkov_info));
|
||||
if (new_ptr == NULL) {
|
||||
ERROR("reg_gk_union : malloc failed");
|
||||
}
|
||||
new_ptr->size = ptr_info_left->size;
|
||||
new_ptr->epsilon = ptr_info_left->epsilon || ptr_info_right->epsilon;
|
||||
new_ptr->first = or_barray(ptr_info_left->first, ptr_info_right->first);
|
||||
new_ptr->last = or_barray(ptr_info_left->last, ptr_info_right->last);
|
||||
new_ptr->follow = or_barray(ptr_info_left->follow, ptr_info_right->follow);
|
||||
if (ptr_info_left != NULL) reg_gk_delete(ptr_info_left);
|
||||
if (ptr_info_right != NULL) reg_gk_delete(ptr_info_right);
|
||||
printf(" je sors de reg_gk_union\n");
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
static void print_array(barray *ptr) {
|
||||
for (uint i = 0; i < getsize_barray(ptr); i++) {
|
||||
printf("%d ", getval_barray(ptr, i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
glushkov_info *reg_gk_concat(glushkov_info *ptr_info_left,
|
||||
glushkov_info *ptr_info_right) {
|
||||
printf(" je suis dans reg_gk_concat\n");
|
||||
glushkov_info *new_ptr = malloc(sizeof(glushkov_info));
|
||||
if (new_ptr == NULL) {
|
||||
ERROR("reg_gk_union : malloc failed");
|
||||
}
|
||||
new_ptr->size = ptr_info_left->size;
|
||||
new_ptr->epsilon = (ptr_info_left->epsilon && ptr_info_right->epsilon);
|
||||
|
||||
printf("etat initials left puis right\n");
|
||||
|
||||
print_array(ptr_info_left->first);
|
||||
print_array(ptr_info_right->first);
|
||||
|
||||
printf("etat finals left puis right\n");
|
||||
print_array(ptr_info_left->last);
|
||||
print_array(ptr_info_right->last);
|
||||
|
||||
if (ptr_info_left->epsilon) {
|
||||
new_ptr->first = or_barray(ptr_info_left->first, ptr_info_right->first);
|
||||
} else {
|
||||
new_ptr->first = copy_barray(ptr_info_left->first);
|
||||
}
|
||||
|
||||
if (ptr_info_right->epsilon) {
|
||||
new_ptr->last = or_barray(ptr_info_left->last, ptr_info_right->last);
|
||||
} else {
|
||||
new_ptr->last = copy_barray(ptr_info_right->last);
|
||||
}
|
||||
print_array(ptr_info_left->follow);
|
||||
print_array(ptr_info_right->follow);
|
||||
|
||||
new_ptr->follow = or_barray(ptr_info_left->follow, ptr_info_right->follow);
|
||||
|
||||
printf(" etat initials et finals de new_ptr\n");
|
||||
print_array(new_ptr->first);
|
||||
print_array(new_ptr->last);
|
||||
print_array(new_ptr->follow);
|
||||
printf("size = %d\n", new_ptr->size);
|
||||
|
||||
for (uint l = 0; l < new_ptr->size; l++) {
|
||||
for (uint f = 0; f < new_ptr->size; f++) {
|
||||
printf("last = %d dans ptr_left\n", l);
|
||||
printf("first = %d dans ptr_right\n", f);
|
||||
printf(" left->last = %d\n",
|
||||
getval_barray(ptr_info_left->last, l));
|
||||
printf(" right->first = %d\n",
|
||||
getval_barray(ptr_info_right->first, f));
|
||||
if (getval_barray(ptr_info_left->last, l) &&
|
||||
getval_barray(ptr_info_right->first, f)) {
|
||||
int num = (l * new_ptr->size) + f;
|
||||
printf(" num = %d\n", num);
|
||||
settrue_barray(new_ptr->follow, num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* // On rempli le tableau de follow de new_ptr les follows des 2 cotés sont
|
||||
// vrais on rajoute en plus si une lettre (dans le tableau de first) et une
|
||||
// autre lettre (dans le tableau de last) sont toutes les deux vraies alors
|
||||
// on peut les mettres dans le tableau de follow
|
||||
// On parcourt le tableau de first*/
|
||||
print_array(new_ptr->follow);
|
||||
|
||||
printf(" je sors de reg_gk_concat\n");
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void reg_gk_delete(glushkov_info *ptr) {
|
||||
printf(" je suis dans reg_gk_delete\n");
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
delete_barray(ptr->first);
|
||||
delete_barray(ptr->last);
|
||||
delete_barray(ptr->follow);
|
||||
free(ptr);
|
||||
printf(" je sors de reg_gk_delete\n");
|
||||
return;
|
||||
}
|
||||
|
||||
glushkov_info *gk_indexleaves(regexp *ptr_regexp, uint nbr_letter,
|
||||
uint *ptr_index, char *ptr_map) {
|
||||
printf(" je suis dans gk_indexleaves\n");
|
||||
if (ptr_regexp == NULL) printf(" ptr_regexp est NULL\n");
|
||||
switch (ptr_regexp->op) {
|
||||
case EMPTY:
|
||||
printf(" ptr_regexp->op == EMPTY\n");
|
||||
return reg_create_gk_emp(nbr_letter);
|
||||
case EPSILON:
|
||||
printf(" ptr_regexp->op == EPSILON\n");
|
||||
return reg_create_gk_eps(nbr_letter);
|
||||
case CHAR:
|
||||
ptr_map[*ptr_index] = ptr_regexp->letter;
|
||||
// On renomme la lettre par un entier
|
||||
ptr_regexp->letter = *ptr_index;
|
||||
(*ptr_index)++;
|
||||
return reg_create_gk_let((*ptr_index - 1), nbr_letter);
|
||||
case UNION:
|
||||
printf(" ptr_regexp->op == UNION\n");
|
||||
glushkov_info *left_union = gk_indexleaves(
|
||||
ptr_regexp->left, nbr_letter, ptr_index, ptr_map);
|
||||
glushkov_info *right_union = gk_indexleaves(
|
||||
ptr_regexp->right, nbr_letter, ptr_index, ptr_map);
|
||||
return reg_gk_union(left_union, right_union);
|
||||
/*
|
||||
return reg_gk_union(gk_indexleaves(ptr_regexp->left, nbr_letter,
|
||||
ptr_index, ptr_map),
|
||||
gk_indexleaves(ptr_regexp->right, nbr_letter,
|
||||
ptr_index, ptr_map));*/
|
||||
case CONCAT:
|
||||
printf(" ptr_regexp->op == CONCAT\n");
|
||||
glushkov_info *left_concat = gk_indexleaves(
|
||||
ptr_regexp->left, nbr_letter, ptr_index, ptr_map);
|
||||
glushkov_info *right_concat = gk_indexleaves(
|
||||
ptr_regexp->right, nbr_letter, ptr_index, ptr_map);
|
||||
return reg_gk_concat(left_concat, right_concat);
|
||||
/*
|
||||
return reg_gk_concat(gk_indexleaves(ptr_regexp->left, nbr_letter,
|
||||
ptr_index, ptr_map),
|
||||
gk_indexleaves(ptr_regexp->right, nbr_letter,
|
||||
ptr_index, ptr_map));*/
|
||||
case STAR:
|
||||
printf(" ptr_regexp->op == STAR\n");
|
||||
return reg_gk_star(gk_indexleaves(ptr_regexp->left, nbr_letter,
|
||||
ptr_index, ptr_map));
|
||||
default:
|
||||
printf(" ptr_regexp->op == default\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nfa *reg_glushkov(regexp *ptr_regexp) {
|
||||
printf("début de reg_glushkov\n");
|
||||
// Si l'expression régulière n'est pas simple
|
||||
if (!reg_issimple(ptr_regexp)) {
|
||||
return NULL;
|
||||
}
|
||||
printf("reg n'est pas simple\n");
|
||||
// On compte le nombre de lettres dans l'expression régulière
|
||||
uint nb_letters = reg_countletters(ptr_regexp);
|
||||
// On initialise l'index des lettres
|
||||
uint index = 0;
|
||||
// On initialise le tableau de correspondance des lettres
|
||||
char *map = malloc(sizeof(char) * nb_letters);
|
||||
printf("le premier malloc marche : map\n");
|
||||
// On l'initialise à NULL
|
||||
for (uint i = 0; i < nb_letters; i++) {
|
||||
map[i] = '\0';
|
||||
}
|
||||
// On calcul l'objet de type glushkov_info
|
||||
glushkov_info *ptr_glu_info =
|
||||
gk_indexleaves(ptr_regexp, nb_letters, &index, map);
|
||||
// On crée un NFA
|
||||
printf(" avant malloc nfa\n");
|
||||
nfa *ptr_nfa = malloc(sizeof(nfa));
|
||||
printf(" après malloc nfa\n");
|
||||
if (ptr_nfa == NULL) {
|
||||
ERROR("reg_glushkov : malloc failed");
|
||||
return NULL;
|
||||
}
|
||||
// On initialise le NFA
|
||||
// On initialise le graph : un sommet pour chaque lettre
|
||||
// + un sommet si le mot vide est dans
|
||||
// l'expression le nombre de sommets est le
|
||||
// nombre de lettres si deux lettres sont dans
|
||||
// le tableau follow
|
||||
// alors on met une arrête entre les deux
|
||||
// sommets
|
||||
|
||||
// On calcul le nombre de sommets
|
||||
uint nb_sommet = ptr_glu_info->size + 1;
|
||||
printf("avant create_lgraph_noedges\n");
|
||||
ptr_nfa->trans = create_lgraph_noedges(nb_sommet, ptr_glu_info->size);
|
||||
printf("après create_lgraph_noedges\n");
|
||||
// On initialise le tableau edges
|
||||
// On parcourt le tableau de follow
|
||||
printf("avant le parcours de follow\n");
|
||||
for (uint ind_follow = 0;
|
||||
ind_follow < ptr_glu_info->size * ptr_glu_info->size; ind_follow++) {
|
||||
// Si la case est vraie alors les deux sommets indéxés par la case
|
||||
// sont reliés par une arrête indéxée par la deuxième lettre
|
||||
if (getval_barray(ptr_glu_info->follow, ind_follow)) {
|
||||
// On récupère les deux lettres / sommets
|
||||
uint sommet_b = ind_follow % ptr_glu_info->size;
|
||||
uint sommet_a = (ind_follow - sommet_b) / ptr_glu_info->size;
|
||||
// On ajoute une arrête à la liste triée entre les deux sommets
|
||||
insert_dequeue(ptr_nfa->trans->edges[sommet_a][sommet_b], sommet_b);
|
||||
}
|
||||
}
|
||||
printf("après le parcours de follow\n");
|
||||
// En plus tous les états initiaux sont reliés a epsilon
|
||||
// On parcourt les états initiaux et on modifie edges [O][i] pour i une
|
||||
// lettre dans la liste des états initiaux
|
||||
printf("avant le parcours des états initiaux\n");
|
||||
for (uint ind_init = 0; ind_init < ptr_glu_info->size; ind_init++) {
|
||||
if (getval_barray(ptr_glu_info->first, ind_init)) {
|
||||
insert_dequeue(ptr_nfa->trans->edges[nb_sommet - 1][ind_init],
|
||||
ind_init);
|
||||
}
|
||||
}
|
||||
printf("après le parcours des états initiaux\n");
|
||||
|
||||
// On initialise les états initiaux et finaux
|
||||
ptr_nfa->initials = create_dequeue();
|
||||
// On ajoute le sommet représenté par epsilon aux états initiaux
|
||||
// représenté par le numéro nb_sommet-1
|
||||
insert_dequeue(ptr_nfa->initials, nb_sommet - 1);
|
||||
|
||||
ptr_nfa->finals = create_dequeue();
|
||||
// On ajoute les sommets qui sont dans last aux états finaux + espilon
|
||||
// si est dans l'expression régulière totale On parcourt le tableau last
|
||||
printf("avant le parcours de last\n");
|
||||
for (uint ind_last = 0; ind_last < ptr_glu_info->size; ind_last++) {
|
||||
// Si la lettre est dans last
|
||||
if (getval_barray(ptr_glu_info->last, ind_last)) {
|
||||
// On ajoute le sommet i aux états finaux
|
||||
insert_dequeue(ptr_nfa->finals, ind_last);
|
||||
}
|
||||
}
|
||||
printf("après le parcours de last\n");
|
||||
// Si epsilon est dans l'expression régulière totale
|
||||
if (ptr_glu_info->epsilon) {
|
||||
// On ajoute le sommet représenté par epsilon aux états finaux
|
||||
insert_dequeue(ptr_nfa->finals, nb_sommet - 1);
|
||||
}
|
||||
|
||||
// On initialise le tableau du noms des lettres
|
||||
printf(" avant malloc alpha_names\n");
|
||||
ptr_nfa->alpha_names = malloc(ptr_nfa->trans->size_alpha * sizeof(char));
|
||||
printf(" après malloc alpha_names\n");
|
||||
// On récupère l'équivalence entre les lettres et leur numéro avec le
|
||||
// tableau map
|
||||
for (uint ind_map = 0; ind_map < nb_letters; ind_map++) {
|
||||
printf("ind_map = %d\n", ind_map);
|
||||
printf("map[ind_map] = %c\n", map[ind_map]);
|
||||
ptr_nfa->alpha_names[ind_map] = map[ind_map];
|
||||
}
|
||||
|
||||
// On initialise le tableau des noms des états
|
||||
/*ptr_nfa->state_names = malloc(ptr_nfa->trans->size_graph * sizeof(char
|
||||
*)); if (ptr_glu_info->epsilon) { for (uint ind_state = 0; ind_state <
|
||||
ptr_nfa->trans->size_graph - 1; ind_state++) {
|
||||
ptr_nfa->state_names[ind_state] = &map[ind_state];
|
||||
}
|
||||
ptr_nfa->state_names[ptr_nfa->trans->size_graph - 1] = "epsilon";
|
||||
} else {
|
||||
for (uint ind_state = 0; ind_state < ptr_nfa->trans->size_graph;
|
||||
ind_state++) {
|
||||
ptr_nfa->state_names[ind_state] = &map[ind_state];
|
||||
}
|
||||
}*/
|
||||
ptr_nfa->state_names = NULL;
|
||||
|
||||
printf("nb d'états = %d\n", ptr_nfa->trans->size_graph);
|
||||
printf("nb d'arrêtes = %d\n", ptr_nfa->trans->size_alpha);
|
||||
print_dequeue(ptr_nfa->initials);
|
||||
print_dequeue(ptr_nfa->finals);
|
||||
|
||||
printf("fin de reg_glushkov\n");
|
||||
if (ptr_glu_info != NULL) {
|
||||
reg_gk_delete(ptr_glu_info); // FIXME : free_glu_info
|
||||
}
|
||||
return ptr_nfa;
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/*+ Algorithme de Thompson +*/
|
||||
/****************************/
|
||||
|
||||
nfa *reg_thompson(regexp *) { return NULL; }
|
||||
Reference in New Issue
Block a user