commit 0e4cabe751c1e08e8b55c78b993297d87701b7f5
parent d180f19cecf115e5f90cef21ae9ae57c729b81b3
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date: Fri, 10 Apr 2026 20:51:18 -0400
Écrire le transducteur
Diffstat:
| M | tfd.c | | | 68 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
1 fichier modifié, 64 insertions(+), 4 suppressions(-)
diff --git a/tfd.c b/tfd.c
@@ -512,13 +512,73 @@ erreur1:
static void *
transducteur(struct tfm *tfm)
{
- uint16_t *trans;
+ uint16_t *t;
+ size_t pos;
+ uint32_t *corr; /* Correspondances entre ietat et la position dans le
+ tampon. */
+ size_t ietat;
+ ssize_t itrans;
assert(tfm);
- /* Initialiser le transducteur. */
- if ((trans = tampex_init(TAMPON_LNGR_DEF, sizeof(uint16_t))) == NULL)
+ /* Initialiser le transducteur et le tampon corr. */
+ if ((t = tampex_init(TAMPON_LNGR_DEF, sizeof(uint16_t))) == NULL)
return NULL;
+ if ((corr = tampex_init(TAMPON_LNGR_DEF, sizeof(uint32_t))) == NULL)
+ goto erreur1;
+
+ /* Les transitions du tfm doivent être triées. */
+ tfm_trier(tfm);
+
+ pos = 0;
+
+ /* Parcourir les états. */
+ for (ietat = 0; tampex_dedans(tfm->etats, ietat); ietat++) {
+ /* Ajouter l’état à la correspondance. */
+ if (tampex_minim((void **)&corr, ietat) < 0)
+ goto erreur2;
+ assert(pos % 4 == 0);
+ corr[ietat] = pos << 2;
+
+ /* Écrire l’entête de l’état. */
+ if (tampex_minim((void **)&t, pos + 3) < 0)
+ goto erreur2;
+ /* Nombre d’éléments. */
+ t[pos] = tfm->etats[ietat].ntrans;
+ pos += 1;
+ /* Si l’état est final. */
+ if (tfm_tfinal(tfm, ietat))
+ t[pos] |= 0x01;
+ pos += 3;
+
+ /* Réserver de l’espace pour les transitions. */
+ tampex_minim((void **)&t, pos - 1 + tfm->etats[ietat].ntrans * 4);
+ /* Parcourir les transitions. */
+ for (itrans = tfm->etats[ietat].trans; itrans != -1;
+ itrans = tfm->trans[itrans].prch) {
+ t[pos++] = tfm->trans[itrans].se;
+ t[pos++] = tfm->trans[itrans].ss;
+ pos += 2;
+ }
+ }
+
+ /* Ajuster écrire les références vers les états. */
+ for (pos = 0, ietat = 0; tampex_dedans(t, pos); ietat++) {
+ pos += 4; /* Sauter l’entête. */
+ for (itrans = tfm->etats[ietat].trans; itrans != -1;
+ itrans = tfm->trans[itrans].prch) {
+ pos += 2;
+ ecrire_32(t + pos, corr[tfm->trans[itrans].ed]);
+ pos += 2;
+ }
+ }
- return trans;
+ tampex_libr(corr);
+ return t;
+
+erreur2:
+ tampex_libr(corr);
+erreur1:
+ tampex_libr(t);
+ return NULL;
}