trafi

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

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:
Mtfd.c | 83+++++++++++++++++--------------------------------------------------------------
Mtfd.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