From 6a43928c0eb9575756d339817c919579f21d4038 Mon Sep 17 00:00:00 2001 From: Anna Date: Sun, 15 Dec 2024 17:40:12 +0000 Subject: [PATCH] =?UTF-8?q?T=C3=A9l=C3=A9verser=20les=20fichiers=20vers=20?= =?UTF-8?q?"Anna=20et=20Ethan"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Anna et Ethan/regexp_tonfa.c | 400 +++++++++++++++++++++++++++++++++++ 1 file changed, 400 insertions(+) create mode 100644 Anna et Ethan/regexp_tonfa.c diff --git a/Anna et Ethan/regexp_tonfa.c b/Anna et Ethan/regexp_tonfa.c new file mode 100644 index 0000000..d2d35e0 --- /dev/null +++ b/Anna et Ethan/regexp_tonfa.c @@ -0,0 +1,400 @@ + +#include "regexp_tonfa.h" + +#include +#include + +#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; }