trafi

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

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:
Mtfd.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; }