commit 53c246c8978eeebefb90199c2e52a289712c57f6
parent b2171f2be1a50b1fc13dfb2f152b1529e1ab4ef4
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date: Tue, 7 Apr 2026 12:03:40 -0400
Retirer l’index des symboles de sortie
Diffstat:
| M | tfd.c | | | 83 | +++++++++++++++++-------------------------------------------------------------- |
| M | tfd.h | | | 31 | ++++++++++++++----------------- |
2 fichiers modifiés, 32 insertions(+), 82 suppressions(-)
diff --git a/tfd.c b/tfd.c
@@ -18,12 +18,10 @@
* d’erreur. */
static char *symboles_liste(struct tfm *tfm, uint32_t **corr);
-/* Obtenir la liste des identifiants de symbole d’entrée (se) et de sortie (ss)
- * du transducteur tfm.
+/* Obtenir la liste des identifiants de symbole d’entrée du transducteur tfm.
* Renvoie un pointeur vers un tampex contenant cette liste, ou NULL en cas
* d’erreur. */
-static int symboles_id(struct tfm *tfm, uint32_t *corr, uint16_t **se,
- uint16_t **ss);
+static int symboles_id(struct tfm *tfm, uint32_t *corr, uint16_t **se);
/* Créer le segmenteur à partir d’une liste de symboles d’entrée.
* Renvoie un pointeur vers un tampex, ou NULL en cas d’erreur. */
@@ -56,7 +54,7 @@ tfd_ecrire(FILE *f, struct tfm *tfm)
unsigned char entete[TFD_ENTETE_TLL]; /* Contenu de l’entête. */
size_t dec; /* Décalage actuel dans le fichier. */
char *liste; /* Tampons extensibles. */
- uint16_t *tse, *tss; /* Autres tampons extensibles. */
+ uint16_t *tse; /* Autres tampons extensibles. */
uint32_t *corr; /* Correspondance entre les identifiants de symbole. */
uint16_t (*segm)[2]; /* Segmenteur. */
size_t lngr; /* Longueur du tampon. */
@@ -100,7 +98,7 @@ tfd_ecrire(FILE *f, struct tfm *tfm)
entete[0x0D] = (dec >> 16) & 0xFF;
entete[0x0E] = (dec >> 8) & 0xFF;
entete[0x0F] = (dec >> 0) & 0xFF;
- if (symboles_id(tfm, corr, &tse, &tss) < 0)
+ if (symboles_id(tfm, corr, &tse) < 0)
return -1;
tampex_libr(corr);
lngr = tampex_esp(tse);
@@ -114,50 +112,24 @@ tfd_ecrire(FILE *f, struct tfm *tfm)
dec += lngr;
- /* Écrire la liste des identifiants de symbole de sortie. */
+ /* Écrire le segmenteur. */
entete[0x14] = (dec >> 24) & 0xFF;
entete[0x15] = (dec >> 16) & 0xFF;
entete[0x16] = (dec >> 8) & 0xFF;
entete[0x17] = (dec >> 0) & 0xFF;
- lngr = tampex_esp(tss);
- entete[0x18] = (lngr >> 24) & 0xFF;
- entete[0x19] = (lngr >> 16) & 0xFF;
- entete[0x1a] = (lngr >> 8) & 0xFF;
- entete[0x1b] = (lngr >> 0) & 0xFF;
- res = fwrite(tse, 1, lngr, f);
- tampex_libr(tss);
- if (res != (ssize_t) lngr)
- return -1;
-
- dec += lngr;
-
- /* Écrire le segmenteur. */
- entete[0x1c] = (dec >> 24) & 0xFF;
- entete[0x1d] = (dec >> 16) & 0xFF;
- entete[0x1e] = (dec >> 8) & 0xFF;
- entete[0x1f] = (dec >> 0) & 0xFF;
if ((segm = segmenteur(liste, tse)) == NULL)
return -1;
tampex_libr(liste);
tampex_libr(tse);
lngr = tampex_esp(segm);
- entete[0x1c] = (lngr >> 24) & 0xFF;
- entete[0x1d] = (lngr >> 16) & 0xFF;
- entete[0x1e] = (lngr >> 8) & 0xFF;
- entete[0x1f] = (lngr >> 0) & 0xFF;
+ entete[0x18] = (lngr >> 24) & 0xFF;
+ entete[0x19] = (lngr >> 16) & 0xFF;
+ entete[0x1a] = (lngr >> 8) & 0xFF;
+ entete[0x1b] = (lngr >> 0) & 0xFF;
res = fwrite(segm, 1, lngr, f);
if (res != (ssize_t) lngr)
return -1;
- /*for (size_t z = 0; tampex_dedans(segm, z); z++) {
- printf("%lu\t%s%d\t%s%d\n",
- z,
- segm[z][0] & 0x01 ? "*" : "",
- segm[z][0]>>1,
- segm[z][1] & 0x01 ? "*" : "",
- segm[z][1]>>1);
- }*/
-
tampex_libr(segm);
entete[TFD_ENTETE_TLL-1] = 0xFF;
@@ -215,12 +187,10 @@ erreur1:
}
static int
-symboles_id(struct tfm *tfm, uint32_t *corr, uint16_t **se, uint16_t **ss)
+symboles_id(struct tfm *tfm, uint32_t *corr, uint16_t **se)
{
- char *dejala; /* Indique si l’identifiant est déjà dans se (& 1) ou
- dans ss (& 2). */
+ char *dejala; /* Indique si l’identifiant est déjà dans se. */
size_t ise; /* Indice dans se. */
- size_t iss; /* Indice dans ss. */
size_t ietat; /* Identifiant d’état. */
size_t ntrans; /* Nombre de transitions depuis un état. */
size_t itrans; /* Identifiant de transition. */
@@ -232,12 +202,10 @@ symboles_id(struct tfm *tfm, uint32_t *corr, uint16_t **se, uint16_t **ss)
/* Initialiser les listes et le dejala. */
if ((*se = tampex_init(TAMPON_LNGR_DEF, sizeof **se)) == NULL)
return -1;
- if ((*ss = tampex_init(TAMPON_LNGR_DEF, sizeof **ss)) == NULL)
- goto erreur1;
if ((dejala = tampex_init(TAMPON_LNGR_DEF, sizeof *dejala)) == NULL)
- goto erreur2;
+ goto erreur1;
- ise = iss = 0;
+ ise = 0;
/* Parcourir les états. */
for (ietat = 0; tampex_dedans(tfm->etats, ietat); ietat++) {
@@ -248,26 +216,13 @@ symboles_id(struct tfm *tfm, uint32_t *corr, uint16_t **se, uint16_t **ss)
/* Ignorer les symboles spéciaux. */
if ((isymb = tfm->trans[itrans].se) >= 0) {
if (tampex_minim((void **)&dejala, isymb) < 0)
- goto erreur3;
+ goto erreur2;
/* Ne pas ajouter le symbole s’il est déjà là. */
- if (!(dejala[isymb] & 1)) {
+ if (!dejala[isymb]) {
if (tampex_minim((void **)se, ise) < 0)
- goto erreur3;
+ goto erreur2;
(*se)[ise++] = corr[isymb];
- dejala[isymb] |= 1;
- }
- }
-
- /* Ignorer les symboles spéciaux. */
- if ((isymb = tfm->trans[itrans].ss) >= 0) {
- if (tampex_minim((void **)&dejala, isymb) < 0)
- goto erreur3;
- /* Ne pas ajouter le symbole s’il est déjà là. */
- if (!(dejala[isymb] & 2)) {
- if (tampex_minim((void **)ss, iss) < 0)
- goto erreur3;
- (*ss)[iss++] = corr[isymb];
- dejala[isymb] |= 2;
+ dejala[isymb] = 1;
}
}
}
@@ -276,10 +231,8 @@ symboles_id(struct tfm *tfm, uint32_t *corr, uint16_t **se, uint16_t **ss)
tampex_libr(dejala);
return 0;
-erreur3:
- tampex_libr(dejala);
erreur2:
- tampex_libr(ss);
+ tampex_libr(dejala);
erreur1:
tampex_libr(se);
return -1;
diff --git a/tfd.h b/tfd.h
@@ -5,40 +5,37 @@
#include "tfm.h"
-/* Le format .tfd est une représentation binaire du transducteur. Il a été
- * conçu pour être rapide à charger et à interpréter: nul besoin de le
+/* Le format .tfd est une représentation binaire d’un transducteur fini. Il a
+ * été conçu pour être rapide à charger et à interpréter: nul besoin de le
* désérialiser pour l’interpréter, et les structures de données qu’il utilise
* dispensent d’un maximum de recherche. L’absence de sérialisation et de
* désérialisation limite la portabilité du fichier. En particulier, le format
* utilise le boutisme de l’hôte qui l’a compilé.
- * Le format est composé de cinq segments, indexés dans une entête placée en
+ * Le format est composé de quatre segments, indexés dans une entête placée en
* début de fichier. Les segments sont les suivants:
*
* - liste des symboles,
* - liste des identifiants de symbole d’entrée
- * - liste des identifiants de symbole de sortie
* - segmentaur
* - automate
*
* L’entête contient les champs suivants:
*
- * 00 02 Nombre magique (0h5407)
- * 02 04 Version (0)
- * 04 08 Décalage de la liste des symboles
- * 08 0c Taille de la liste des symboles
- * 0c 10 Décalage de la liste des identifiants de symbole d’entrée
- * 10 14 Taille de la liste des identifiants de symbole d’entrée
- * 14 18 Décalage de la liste des identifiants de symbole de sortie
- * 18 0c Taille de la liste des identifiants de symbole de sortie
- * 0c 20 Décalage du segmenteur
- * 20 24 Taille du segmenteur
- * 24 28 Décalage de l’automate
- * 28 2c Taille de l’automate
+ * 00 01 Nombre magique (0h5407)
+ * 02 03 Version (0)
+ * 04 07 Décalage de la liste des symboles
+ * 08 0b Taille de la liste des symboles
+ * 0c 0f Décalage de la liste des identifiants de symbole d’entrée
+ * 10 13 Taille de la liste des identifiants de symbole d’entrée
+ * 14 17 Décalage du segmenteur
+ * 18 1b Taille du segmenteur
+ * 1c 1f Décalage de l’automate
+ * 20 23 Taille de l’automate
*/
#define TFD_MAGIQUE 0x5407
#define TFD_VERSION 0
-#define TFD_ENTETE_TLL 0x2c
+#define TFD_ENTETE_TLL 0x24
/* 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