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