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:
| M | attvtfd.c | | | 21 | ++++++++++++++++++++- |
| M | tfd.c | | | 130 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | tfd.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