trafi

Transducteurs finis
git clone git://git.asteride.xyz/trafi.git
Journaux | Fichiers | Références

commit 0d2886009331d132e05cfbe92968c3bc466edab5
parent 1b8cb41c3491c4ae91a4e5809249635828186dee
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date:   Wed, 18 Feb 2026 13:03:39 -0500

Commencer la conversion au fichier .tfd

Les six premiers champs de l’entête sont écrits. L’index des symboles
et la liste de symboles est générée.

Diffstat:
Mattvtfd.c | 21++++++++++++++++++++-
Mtfd.c | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtfd.h | 1+
3 fichiers modifiés, 151 insertions(+), 1 suppression(-)

diff --git a/attvtfd.c b/attvtfd.c @@ -1,16 +1,35 @@ +#include <stdio.h> + #include "att.h" #include "tfm.h" +#include "tfd.h" int -main(void) +main(int argc, char **argv) { struct tfm *tfm; + FILE *ftfd; + + if (argc != 2) { + fprintf(stderr, "attvtf: nombre d’arguments incorrect\n"); + return 1; + } if ((tfm = att_lire(stdin)) == NULL) { fprintf(stderr, "attvtf: erreur lors de la lecture\n"); return 1; } + if ((ftfd = fopen(argv[1], "wb")) == NULL) { + fprintf(stderr, "attvtf: impossible d’ouvrir %s\n", argv[1]); + return 1; + } + + if (tfd_ecrire(ftfd, tfm) < 0) { + fprintf(stderr, "attvtf: erreur dans l’écriture du fichier .tfd\n"); + return 1; + } + tfm_libr(tfm); return 0; diff --git a/tfd.c b/tfd.c @@ -1,15 +1,145 @@ #include <assert.h> #include <stddef.h> +#include <stdio.h> #include "tfd.h" #include "tfm.h" #define TAMPON_LNGR_DEF 64 +/* Obtenir la liste des symboles d’un transducteur. + * Renvoie un pointeur vers cette liste, ou NULL en cas d’erreur. */ +static struct tampinf *symboles_liste(struct tfm *tfm); + +/* Obtenir un index d’une liste de symboles telle que renvoyée par + * tampinf_liste. + * Renvoie un pointeur vers l’index, ou NULL en cas d’erreur. */ +static struct tampinf *symboles_index(struct tampinf *liste); + /* Créer un automate au format tfm à partir des symboles d’un tfm. * Renvoie un pointeur vers un tfm, ou NULL en cas d’erreur. */ static struct tfm *automate_symbs(struct tfm *tfm, struct tampinf **ti); +int +tfd_ecrire(FILE *f, struct tfm *tfm) +{ + struct tampinf *liste; /* Liste de symboles. */ + struct tampinf *index; /* Index de symboles. */ + size_t pos, tll; + + assert(f); + assert(tfm); + + /* Écrire le nombre magique. */ + fputc((TFD_MAGIQUE >> 8) & 0xff, f); + fputc((TFD_MAGIQUE >> 0) & 0xff, f); + + /* Écrire la version. */ + fputc((TFD_VERSION >> 8) & 0xff, f); + fputc((TFD_VERSION >> 0) & 0xff, f); + + /* Liste de symboles. */ + if ((liste = symboles_liste(tfm)) == NULL) + return -1; + + /* Index des symboles. */ + if ((index = symboles_index(liste)) == NULL) + return -1; + + /* Écrire la position de l’index des symboles. */ + pos = TFD_ENTETE_FIN; + fputc((pos >> 24) & 0xff, f); + fputc((pos >> 16) & 0xff, f); + fputc((pos >> 8) & 0xff, f); + fputc((pos >> 0) & 0xff, f); + + /* Écrire la taille de l’index des symboles. */ + tll = tampinf_esp(index); + fputc((tll >> 24) & 0xff, f); + fputc((tll >> 16) & 0xff, f); + fputc((tll >> 8) & 0xff, f); + fputc((tll >> 0) & 0xff, f); + + /* Écrire la position de la liste de symboles. */ + pos += tll; + fputc((pos >> 24) & 0xff, f); + fputc((pos >> 16) & 0xff, f); + fputc((pos >> 8) & 0xff, f); + fputc((pos >> 0) & 0xff, f); + + /* Écrire la taille de la liste de symboles. */ + tll = tampinf_esp(liste); + fputc((tll >> 24) & 0xff, f); + fputc((tll >> 16) & 0xff, f); + fputc((tll >> 8) & 0xff, f); + fputc((tll >> 0) & 0xff, f); + + return 0; +} + +static struct tampinf * +symboles_liste(struct tfm *tfm) +{ + struct tampinf *liste; + char symb[TFM_TLL_SYMB_MAX]; /* Tampon à symbole. */ + size_t id, tll; + unsigned char n; + + assert(tfm); + + /* Initialiser la liste. */ + if ((liste = tampinf_init(TAMPON_LNGR_DEF, sizeof(char))) == NULL) + return NULL; + + /* Parcourir les symboles. */ + id = 0; + while ((tll = tfm_parc_symbs(tfm, &id, symb, TFM_TLL_SYMB_MAX)) > 0) { + n = tll; + if (tampinf_ajt(liste, 1, &n) < 0) + goto erreur; + if (tampinf_ajt(liste, tll, symb) < 0) + goto erreur; + } + + return liste; + +erreur: + tampinf_libr(liste); + return NULL; +} + +static struct tampinf * +symboles_index(struct tampinf *liste) +{ + struct tampinf *index; + char *ctn; /* Contenu de la liste. */ + size_t pos; /* Position dans la liste. */ + unsigned n; /* Taille d’un symbole. */ + + assert(liste); + + /* Initialiser l’index des symboles. */ + if ((index = tampinf_init(TAMPON_LNGR_DEF, sizeof(size_t))) == NULL) + return NULL; + + /* Obtenir le contenu de la liste de symboles. */ + if ((ctn = tampinf_ctn(liste)) == NULL) + goto erreur; + + /* Parcourir les symboles. */ + for (pos = 0; tampinf_dedans(liste, pos); pos += n + 1) { + n = ((unsigned char *)ctn)[pos]; + if (tampinf_ajt(index, 1, &pos) < 0) + goto erreur; + } + + return index; + +erreur: + tampinf_libr(liste); + return NULL; +} + /* La routine fonction en parcourant tous les symboles d’un transducteur. Pour * chaque caractère du symbole courant converti à un symbole, en partant de * l’état zéro de l’automate de symboles, vérifier si une transition sortante diff --git a/tfd.h b/tfd.h @@ -34,6 +34,7 @@ #define TFD_MAGIQUE 0x5407 #define TFD_VERSION 0 +#define TFD_ENTETE_FIN 0x18 /* La liste des symboles se présente comme une suite chaînes de caractères * encodées à la Pascal, dans lesquelles les chaînes sont immédiatement