changement dossier
This commit is contained in:
353
Aloyse et Vincent/shell_languages.c
Normal file
353
Aloyse et Vincent/shell_languages.c
Normal file
@@ -0,0 +1,353 @@
|
||||
#include "shell_languages.h"
|
||||
|
||||
#include "error.h"
|
||||
#include "shell_languages.h"
|
||||
#include "nfa.h"
|
||||
#include "regexp.h"
|
||||
|
||||
// #define MAX_LANGUAGES 2048
|
||||
// language* languages[MAX_LANGUAGES];
|
||||
// int nb_languages = 0;
|
||||
|
||||
#define MAX_OBJECTS 2048
|
||||
object* objects[MAX_OBJECTS];
|
||||
int nb_objects = 0;
|
||||
|
||||
unsigned short minicount = 0;
|
||||
unsigned short syntcount = 0;
|
||||
|
||||
/************************/
|
||||
/* Création/Suppression */
|
||||
/************************/
|
||||
|
||||
object* object_language_new_reg(char* name, regexp* theregexp) {
|
||||
object* theobject;
|
||||
MALLOC(theobject, 1);
|
||||
theobject->name = strdup(name);
|
||||
theobject->type = LANGUAGE;
|
||||
theobject->parent = -1;
|
||||
language* lang;
|
||||
MALLOC(lang, 1);
|
||||
lang->type = SPE_REG;
|
||||
lang->reg = theregexp;
|
||||
lang->minauto = -1;
|
||||
theobject->lan = lang;
|
||||
return theobject;
|
||||
}
|
||||
|
||||
object* object_language_new_nfa(char* name, int i) {
|
||||
if (objects[i]->type != AUTOMATON) {
|
||||
fprintf(stderr, "Error: this is not an automata variable.\n");
|
||||
return NULL;
|
||||
}
|
||||
object* theobject;
|
||||
MALLOC(theobject, 1);
|
||||
theobject->name = strdup(name);
|
||||
theobject->type = LANGUAGE;
|
||||
theobject->parent = -1;
|
||||
language* lang;
|
||||
MALLOC(lang, 1);
|
||||
lang->type = SPE_NFA;
|
||||
lang->nfa = i;
|
||||
lang->minauto = -1;
|
||||
theobject->lan = lang;
|
||||
return theobject;
|
||||
}
|
||||
|
||||
object* object_automata_new(char* name, nfa* A) {
|
||||
object* theobject;
|
||||
MALLOC(theobject, 1);
|
||||
theobject->name = strdup(name);
|
||||
theobject->type = AUTOMATON;
|
||||
theobject->parent = -1;
|
||||
automata* aut;
|
||||
MALLOC(aut, 1);
|
||||
aut->nfa = A;
|
||||
theobject->aut = aut;
|
||||
return theobject;
|
||||
}
|
||||
|
||||
void object_free(object* theobject) {
|
||||
if (theobject == NULL) {
|
||||
return;
|
||||
}
|
||||
// Libération du nom
|
||||
free(theobject->name);
|
||||
|
||||
switch (theobject->type) {
|
||||
case AUTOMATON:
|
||||
if (theobject->aut == NULL) {
|
||||
free(theobject);
|
||||
return;
|
||||
}
|
||||
nfa_delete(theobject->aut->nfa);
|
||||
free(theobject->aut);
|
||||
break;
|
||||
case LANGUAGE:
|
||||
if (theobject->lan == NULL) {
|
||||
free(theobject);
|
||||
return;
|
||||
}
|
||||
// Si le langage est spécifié par une expression,
|
||||
// on la libère.
|
||||
if (theobject->lan->type == SPE_REG) {
|
||||
if (theobject->lan->reg) {
|
||||
reg_free(theobject->lan->reg);
|
||||
}
|
||||
}
|
||||
// Si le langage est spécifié par un NFA, on enlève
|
||||
// le flag qui protège ce NFA.
|
||||
else if (theobject->lan->type == SPE_NFA) {
|
||||
objects[theobject->lan->nfa]->parent = -1;
|
||||
}
|
||||
// Si le langage est associèe à un minimal, on enlève
|
||||
// le flag qui protège ce minimal.
|
||||
if (theobject->lan->minauto != -1) {
|
||||
objects[theobject->lan->minauto]->parent = -1;
|
||||
}
|
||||
free(theobject->lan);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(theobject);
|
||||
}
|
||||
|
||||
/*************************************/
|
||||
/* Récupération/insertion d'un objet */
|
||||
/*************************************/
|
||||
|
||||
int object_get_from_name(char* name) {
|
||||
for (int i = 0; i < nb_objects; i++) {
|
||||
if (objects[i] && strcmp(objects[i]->name, name) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int object_delete_from_name(char* name) {
|
||||
int i = object_get_from_name(name);
|
||||
if (i == -1) {
|
||||
fprintf(stderr, "Error: unknown variable.\n");
|
||||
return -1;
|
||||
}
|
||||
else if (objects[i] && objects[i]->parent != -1) {
|
||||
fprintf(stderr, "Error: this is a protected variable.\n");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
object_free(objects[i]);
|
||||
nb_objects--;
|
||||
if (nb_objects > 0) {
|
||||
objects[i] = objects[nb_objects];
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
int object_add_language_reg(char* name, regexp* theregexp) {
|
||||
if (theregexp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nb_objects == MAX_OBJECTS) {
|
||||
ERROR("Error: too many objects are already stored in memory.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i = object_get_from_name(name);
|
||||
|
||||
if (i != -1 && objects[i]->parent == -1) {
|
||||
// Si il y a déjà un objet à ce nom et qu'il n'est pas protégé
|
||||
DEBUG("Warning: an object with name %s already exists\n", name);
|
||||
object_free(objects[i]);
|
||||
objects[i] = object_language_new_reg(name, theregexp);
|
||||
return i;
|
||||
}
|
||||
else if (i != -1 && objects[i]->parent != -1) {
|
||||
fprintf(stderr, "Error: cannot assign a new object to a protected variable.\n");
|
||||
reg_free(theregexp);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
objects[nb_objects++] = object_language_new_reg(name, theregexp);
|
||||
return nb_objects - 1;
|
||||
}
|
||||
}
|
||||
|
||||
int object_add_language_nfa(char* name, int j) {
|
||||
if (j == -1 || objects[j]->type != AUTOMATON) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nb_objects == MAX_OBJECTS) {
|
||||
ERROR("Error: too many objects are already stored in memory.\n");
|
||||
return -1;
|
||||
}
|
||||
int i = object_get_from_name(name);
|
||||
|
||||
if (i != -1 && objects[i]->parent == -1) {
|
||||
// Si il y a déjà un objet à ce nom et qu'il n'est pas protégé
|
||||
DEBUG("Warning: an object with name %s already exists\n", name);
|
||||
object_free(objects[i]);
|
||||
objects[i] = object_language_new_nfa(name, j);
|
||||
objects[j]->parent = i;
|
||||
return i;
|
||||
}
|
||||
else if (i != -1 && objects[i]->parent != -1) {
|
||||
fprintf(stderr, "Error: cannot assign a new object to a protected variable.\n");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
objects[nb_objects++] = object_language_new_nfa(name, j);
|
||||
objects[j]->parent = nb_objects - 1;
|
||||
return nb_objects - 1;
|
||||
}
|
||||
}
|
||||
|
||||
int object_add_automata(char* name, nfa* A) {
|
||||
if (A == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nb_objects == MAX_OBJECTS) {
|
||||
ERROR("Error: too many objects are already stored in memory.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i = object_get_from_name(name);
|
||||
|
||||
// Si il y a déjà un objet à ce nom
|
||||
if (i != -1 && objects[i]->parent == -1) {
|
||||
DEBUG("Warning: an object with name %s already exists\n", name);
|
||||
object_free(objects[i]);
|
||||
objects[i] = object_automata_new(name, A);
|
||||
return i;
|
||||
}
|
||||
else if (i != -1 && objects[i]->parent != -1) {
|
||||
fprintf(stderr, "Error: cannot assign a new object to a protected variable.\n");
|
||||
nfa_delete(A);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
objects[nb_objects++] = object_automata_new(name, A);
|
||||
return nb_objects - 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int object_compare(const void* pob1, const void* pob2) {
|
||||
object* ob1 = *(object* const*)pob1;
|
||||
object* ob2 = *(object* const*)pob2;
|
||||
if (ob1 == NULL) {
|
||||
if (ob2 == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (ob2 == NULL) {
|
||||
return 1;
|
||||
}
|
||||
return strcmp(ob1->name, ob2->name);
|
||||
}
|
||||
|
||||
void object_sort_array(void) {
|
||||
qsort(objects, nb_objects, sizeof(object*), &object_compare);
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* Affichage d'informations */
|
||||
/****************************/
|
||||
|
||||
void object_print_langs(void) {
|
||||
// Calcul du nombre de langages
|
||||
ushort count = 0;
|
||||
for (int i = 0; i < nb_objects; i++) {
|
||||
if (objects[i]->type == LANGUAGE) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("#### There are %d language(s) in memory:\n\n", count);
|
||||
|
||||
if (count > 0) {
|
||||
count = 1;
|
||||
}
|
||||
for (int i = 0; i < nb_objects; i++) {
|
||||
if (objects[i]->type == LANGUAGE) {
|
||||
printf("#### %d: %s\n", count, objects[i]->name);
|
||||
if (objects[i]->lan->type == SPE_REG) {
|
||||
printf(" Specified by a regular expression\n");
|
||||
printf(" Regexp: ");
|
||||
reg_print(objects[i]->lan->reg);
|
||||
}
|
||||
else if (objects[i]->lan->type == SPE_NFA) {
|
||||
printf(" Specified by an automaton.\n");
|
||||
}
|
||||
printf("\n");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void object_print_autos(void) {
|
||||
// Calcul du nombre d'automates'
|
||||
ushort count = 0;
|
||||
for (int i = 0; i < nb_objects; i++) {
|
||||
if (objects[i]->type == AUTOMATON) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("#### There are %d automata in memory:\n\n", count);
|
||||
|
||||
if (count > 0) {
|
||||
count = 1;
|
||||
}
|
||||
for (int i = 0; i < nb_objects; i++) {
|
||||
if (objects[i]->type == AUTOMATON) {
|
||||
printf("#### %d: %s\n", count, objects[i]->name);
|
||||
if (objects[i]->parent != -1 && objects[objects[i]->parent]->type == LANGUAGE) {
|
||||
printf(" Protected: tied to the language %s.\n",
|
||||
objects[objects[i]->parent]->name);
|
||||
}
|
||||
printf("\n");
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Calculs d'informations sur un objet existant */
|
||||
/************************************************/
|
||||
|
||||
// Calcul du DFA minimal d'un langage
|
||||
int shell_compute_minimal(int i) {
|
||||
if (objects[i]->type != LANGUAGE) {
|
||||
fprintf(stderr, "Should be a language.\n");
|
||||
return -1;
|
||||
}
|
||||
language* lang = objects[i]->lan;
|
||||
if (lang->minauto == -1) {
|
||||
DEBUG("Computing the minimal automaton of a language");
|
||||
nfa* A;
|
||||
if (lang->type == SPE_REG) {
|
||||
A = reg_thompson(lang->reg);
|
||||
}
|
||||
else {
|
||||
A = objects[lang->nfa]->aut->nfa;
|
||||
}
|
||||
|
||||
char* newname;
|
||||
MALLOC(newname, 20);
|
||||
sprintf(newname, "SYSMINI%04d", minicount++);
|
||||
lang->minauto = object_add_automata(newname, nfa_brzozowski(A));
|
||||
free(newname);
|
||||
// On protège le NFA minimal qu'on a créé
|
||||
objects[lang->minauto]->parent = i;
|
||||
|
||||
nfa_delete(A);
|
||||
}
|
||||
return lang->minauto;
|
||||
}
|
||||
Reference in New Issue
Block a user