trafi

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

commit 2d372e4ae1dfe438d0d8500dcf914b5b77290fdd
parent 4c845ad81e7ded88b812e4d0a5bfb0da386a06db
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date:   Wed,  8 Apr 2026 21:52:07 -0400

Interpréter le segmenteur

Diffstat:
Minterp.c | 29+++++++++++++++++++++++++++--
Mitfd.c | 67++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mitfd.h | 15++++++++++++---
3 fichiers modifiés, 99 insertions(+), 12 suppressions(-)

diff --git a/interp.c b/interp.c @@ -1,19 +1,44 @@ #include <fcntl.h> #include <stddef.h> -/*#include <stdio.h>*/ +#include <stdio.h> +#include <string.h> #include "itfd.h" int -main(void) +main(int argc, char **argv) { int df; struct itfd *itfd; + uint16_t symbs[256]; + size_t nsymbs; + size_t lngr; + size_t i; if ((df = open("a", O_RDONLY)) < 0) return 1; if ((itfd = itfd_ouvrir(df)) == NULL) return 1; + if (argc != 2) + return 1; + + if ((lngr = strlen(argv[1])) > 256) + return 1; + + nsymbs = segmenter(itfd, (uint8_t *)argv[1], lngr, symbs); + + for (i = 0; i < nsymbs; i++) { + if (symbs[i] & 0x01) { + printf("*%c (%d)\n", symbs[i] >> 1, symbs[i] >> 1); + } else { + fwrite(itfd->symbs + 1 + (symbs[i] >> 1), + 1, + itfd->symbs[symbs[i] >> 1], + stdout); + printf(" (%d)\n", symbs[i] >> 1); + } + } + return 0; } diff --git a/itfd.c b/itfd.c @@ -8,8 +8,7 @@ #include "itfd.h" #include "tfd.h" -#include <stdio.h> - +/* Lire du tampon tp au décalage dec 16 ou 32 bits. */ #define LIRE_16(tp, dec) (*(uint16_t *)((tp) + (dec))) #define LIRE_32(tp, dec) (*(uint32_t *)((tp) + (dec))) @@ -56,16 +55,16 @@ itfd_ouvrir(int df) goto erreur2; /* Lire les informations sur les segments. */ - itfd->symbs_pos = itfd->f + LIRE_32(itfd->f, 0x06); + itfd->symbs = itfd->f + LIRE_32(itfd->f, 0x06); itfd->symbs_lngr = LIRE_32(itfd->f, 0x0A); - itfd->segm_pos = itfd->f + LIRE_32(itfd->f, 0x0E); + itfd->segm = itfd->f + LIRE_32(itfd->f, 0x0E); itfd->segm_lngr = LIRE_32(itfd->f, 0x12); - itfd->trans_pos = itfd->f + LIRE_32(itfd->f, 0x16); + itfd->trans = itfd->f + LIRE_32(itfd->f, 0x16); itfd->trans_lngr = LIRE_32(itfd->f, 0x1A); - if (itfd->symbs_pos + itfd->symbs_lngr != itfd->segm_pos) + if (itfd->symbs + itfd->symbs_lngr != itfd->segm) goto erreur2; - //if (itfd->segm_pos + itfd->segm_lngr != itfd->trans_pos) + //if (itfd->segm + itfd->segm_lngr != itfd->trans) //goto erreur2; return itfd; @@ -91,3 +90,57 @@ itfd_fermer(struct itfd *itfd) return 0; } + +size_t +segmenter(struct itfd *itfd, uint8_t *cc, size_t lngrcc, uint16_t *symbs) +{ + size_t i, pi; /* Indice et prochain indice dans le segmenteur. */ + uint16_t base, orig; + uint16_t (*segm)[2]; + uint8_t *prch; /* Fin du dernier symbole trouvé. */ + uint8_t *fin; /* Fin de cc. */ + int symb; /* Identifiant du dernier symbole trouvé. */ + size_t nsymbs; /* Nombre de symboles. */ + + assert(itfd); + assert(cc); + + fin = cc + lngrcc; + segm = (uint16_t (*)[2])itfd->segm; + nsymbs = 0; + + while (cc < fin) { + symb = (*cc << 1) | 0x01; + prch = cc + 1; + + for (i = 0; cc < fin; cc++) { + pi = (segm[i][0] >> 1) + *cc; + + base = segm[pi][0]; + orig = segm[pi][1]; + + /* Vérifier. */ + if (orig & 0x01 || orig >> 0x01 != i) { + cc = prch; + break; + } + + i = pi; + + /* Si état final. */ + if (base & 0x01) { + i = base >> 1; + orig = segm[i][1]; + symb = (orig >> 1) << 1; + prch = cc + 1; + } + } + + cc = prch; + *symbs++ = symb; + nsymbs++; + } + + assert(nsymbs <= lngrcc); + return nsymbs; +} diff --git a/itfd.h b/itfd.h @@ -10,11 +10,11 @@ struct itfd { uint8_t *f; /* Contenu du fichier. */ off_t lngr; /* Longueur du fichier, en octets. */ int version; /* Version du format tfd. */ - uint8_t *symbs_pos; /* Position de la liste de symboles. */ + uint8_t *symbs; /* Position de la liste de symboles. */ size_t symbs_lngr; /* Longueur de la liste de symboles. */ - uint8_t *segm_pos; /* Position du segmenteur. */ + uint8_t *segm; /* Position du segmenteur. */ size_t segm_lngr; /* Longueur du segmenteur. */ - uint8_t *trans_pos; /* Position du transducteur. */ + uint8_t *trans; /* Position du transducteur. */ size_t trans_lngr; /* Longueur du transducteur. */ }; @@ -26,4 +26,13 @@ struct itfd *itfd_ouvrir(int df); * Renvoie 0, ou -1 en cas d’erreur. */ int itfd_fermer(struct itfd *itfd); +/* Segmenter le tampon tp de longueur lngr selon itfd et en placer les + * identifiants de symbole dans symbs. + * Le tampon symbs doit être au moins aussi grand que lngrcc. Puisqu’un + * symbole compte pour au moins un caractère, il ne peut jamais y avoir plus de + * lngrcc symboles dans symbs. + * Renvoie le nombre de symboles placés dans symbs. */ +size_t segmenter(struct itfd *itfd, uint8_t *cc, size_t lngrcc, + uint16_t *symbs); + #endif