trafi

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

commit 1992fd6c95b5a9fd5ab3b0e23e8dfef4f8092879
parent 3062d7c4c818f8420f02cb0f1b2e8c701b86a223
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date:   Sat, 25 Apr 2026 23:24:04 -0400

Peaufiner mishka

Diffstat:
Mmishka.c | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
1 fichier modifié, 114 insertions(+), 44 suppressions(-)

diff --git a/mishka.c b/mishka.c @@ -1,72 +1,142 @@ +#define _POSIX_C_SOURCE 200809L + +#include <assert.h> #include <fcntl.h> -#include <stddef.h> +#include <stdint.h> #include <stdio.h> -#include <string.h> +#include <stdlib.h> +#include <sys/types.h> #include "itfd.h" +char *nomprog; + +/* Écrire l’utilisation dans le fichier f. */ +static void utilisation(FILE *f); + +/* Faire passer entree dans le transducteur contenu dans le fichier désigné par + * tfd et en écrire le résultat dans sortie. + * Renvoie 0, ou -1 en cas d’erreur. */ +static int transductionner(int tfd, FILE *entree, FILE *sortie); + int main(int argc, char **argv) { - int df; - struct itfd *itfd; - uint16_t symbs[256]; - size_t nsymbs; - size_t lngr; - size_t i; - struct interp *interp; - ssize_t rv; + int tfd; /* Descripteur de fichier du transducteur fini. */ - if ((df = open("a", O_RDONLY)) < 0) - return 1; - if ((itfd = itfd_ouvrir(df)) == NULL) + nomprog = argv[0]; + + if (argc != 2) { + utilisation(stderr); return 1; + } - if (argc != 2) + if ((tfd = open(argv[1], O_RDONLY)) < 0) { + fprintf(stderr, "%s: impossible d’ouvrir %s\n", + nomprog, argv[1]); return 1; + } - if ((lngr = strlen(argv[1])) > 256) + if (transductionner(tfd, stdin, stdout) < 0) { + fprintf(stderr, "%s: une erreur est survenue\n", nomprog); 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); - } +static void +utilisation(FILE *f) +{ + assert(f); + + fprintf(f, "Utilisation: %s <[mots]\n", nomprog); +} + +static int +transductionner(int tfd, FILE *entree, FILE *sortie) +{ + struct itfd *itfd; + struct interp *interp; + char *le; /* Tampon contenant la ligne d’entrée. */ + size_t lelngr; /* Longueur du tampon le. */ + uint16_t *symbs; /* Tampon contenant la chaîne de symboles. */ + size_t symbslngr; /* Longueur du tampon symbs. */ + ssize_t clus; /* Nombre de caractères lus. */ + size_t nsymbs; /* Nombre de symboles segmentés. */ + ssize_t vr; /* Valeur renvoyée. */ + size_t isymb; /* Indice dans la chaîne de symboles. */ + bool esp; /* Afficher un espace? */ + + assert(tfd > 0); + assert(entree); + assert(sortie); + + /* Ouvrir tfd. */ + if ((itfd = itfd_ouvrir(tfd)) == NULL) { + fprintf(stderr, "%s: impossible d’ouvrir le transducteur\n", + nomprog); + return -1; } - if ((interp = interp_init(itfd)) == NULL) - return 1; + /* Initialiser l’interpréteur. */ + if ((interp = interp_init(itfd)) == NULL) { + fprintf(stderr, "%s: erreur\n", nomprog); + return -1; + } + + le = NULL; + lelngr = 0; + symbslngr = 64; + if ((symbs = malloc(symbslngr * sizeof(uint16_t))) == NULL) { + fprintf(stderr, "%s: malloc(3)\n", nomprog); + return -1; + } + + /* Parcourir les lignes. */ + while ((clus = getline(&le, &lelngr, entree)) > 0) { + /* Ignorer la nouvelle ligne. */ + clus--; + /* Assurer que symbs soit assez grand. */ + if ((size_t)clus > symbslngr) { + symbslngr *= 2; + if ((symbs = realloc(symbs, symbslngr * sizeof(uint16_t))) + == NULL) { + fprintf(stderr, "%s: malloc(3)\n", nomprog); + return -1; + } + } - printf("---\n"); + /* Segmenter. */ + nsymbs = segmenter(itfd, (uint8_t *)le, clus, symbs); - while ((rv = interpreter(interp, symbs, nsymbs)) > 0) { - printf("\n"); - for (i = 0; i < ((size_t)rv - 1); i++) { - if (!(interp->css[i] & 0x01)) { - printf("*%c (%d)\n", interp->css[i] >> 1, interp->css[i] >> 1); - } else { - fwrite(itfd->symbs + 1 + (interp->css[i] >> 1), + /* Interpréter. */ + esp = 0; + while ((vr = interpreter(interp, symbs, nsymbs)) > 0) { + if (esp) putc(' ', sortie); + for (isymb = 0; isymb < (size_t)vr - 1; isymb++) { + if ((interp->css[isymb] & 0x01) == ITFD_SYMB_REC) { + fwrite(itfd->symbs + 1 + (interp->css[isymb] >> 1), 1, - itfd->symbs[interp->css[i] >> 1], - stdout); - printf(" (%d)\n", interp->css[i] >> 1); + itfd->symbs[interp->css[isymb] >> 1], + sortie); + } else { + putc(interp->css[isymb] >> 1, sortie); + } } + esp = 1; + } + putc('\n', sortie); + if (interp_reinit(interp, itfd) < 0) + return -1; + if (vr < 0) { + fprintf(stderr, "%s: erreur\n", nomprog); + return -1; } } - if (rv == -1) - return 1; + + free(le); interp_libr(interp); - if (itfd_fermer(itfd) < 0) - return 1; + itfd_fermer(itfd); return 0; }