trafi

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

commit fb98ad5e6153231e475e88ae66f27179af554ed3
parent f8affa7cbb007a8d8edfb2d57c80bf058bd43fe4
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date:   Mon, 16 Feb 2026 11:41:21 -0500

Créer l’entête pour le format .tfd

Diffstat:
Atfd.h | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 fichier modifié, 123 insertions(+), 0 suppressions(-)

diff --git a/tfd.h b/tfd.h @@ -0,0 +1,123 @@ +#ifndef TFD_H +#define TFD_H + +#include <stdio.h> + +#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 + * désérialiser pour l’interpréter, et les structures de données qu’il utilise + * dispense d’un maximum de recherche. L’asbsence de sérialisation et de + * désérialisation freine la portabilité du fichier. En particulier, le format + * utilise le boutisme de l’hôte qui le compile. + * Le format est composé de cinq segments, indexés dans une entête placée en + * début de fichier. Les segments sont les suivants: index des symboles, liste + * de symboles, segmenteur, automate, tableau des identifiants de symbole de + * sortie. + * + * L’entête contient les champs suivants: + * + * 00 02 Nombre magique (0h5407) + * 02 04 Version (0) + * 04 06 Position de l’index des symboles + * 06 08 Taille du l’index des symboles + * 08 0a Position de la liste de symboles + * 0a 0c Taille de la liste de symboles + * 0c 0e Position du segmenteur + * 0e 10 Taille du segmenteur + * 10 12 Position de l’automate + * 12 14 Taille de l’automate + * 14 16 Position des identifiants de symbole de sortie + * 16 18 Taille des identifiants de symbole de sortie + * + * 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 + * précédées d’un octet donnant la taille de la chaîne le suivant. + * + * L’index des symboles est un tableau de pointeurs vers les symboles de la + * liste de symboles. Les identifiants de symbole sont des indices dans l’index + * des symboles. + * + * La structure du segmenteur s’inspire de la structure à deux tableaux proposée + * par Aho (1989: An Efficient Digital Search Algorithm by Using a Double-Array + * Structure). Elle consiste en un tableau dont les cellules contiennent + * chacune deux champs: la base et l’origine. Chaque champ occupe 2 octets, pour + * un total de 4 octets par cellule. Ces deux champs contiennent un drapeau dans + * leur bit le plus à droite. Celui de la base marque un état comme final (1) ou + * comme non-final (0); celui de l’origine indique si le champ doit bel et bien + * être interprété comme une origine (0), ou comme un identifiant de symbole. + * Une paire (base, origine) représente un état. Un état peut être désigné par + * son indice i. On passe d’un état à l’autre par la formule + * + * i' = paire[i].base >> 1 + s, + * + * où s est un symbole d’entrée. Pour que la transition soit valide, il faut en + * plus satisfaire les équation suivante: + * + * paire[i'].orig & 1 == 0, + * paire[i'].orig >> 1 == i. + * + * Autrement, on pourrait quitter n’importe quel état avec n’importe quel + * symbole. + * Si, cependant, le drapeau de la base d’un symbole est brandi, + * + * i'' = paire[i'].base >> 1 et + * symbole = paire[i''].orig >> 1. + * + * La variable symbole contient l’identifiant du symbole. Elle est mise à jour + * chaque fois qu’un état final est rencontré parce que le segmenteur est + * glouton: il tente de reconnaître le symbole le plus long, ignorant ses + * préfixes qui sont aussi des symboles. Lorsque plus aucune transition n’existe + * qui n’accepte le prochain symbole d’entrée, le dernier symbole assigné est + * retourné et la position dans le mot entrée courante au moment où ce symbole + * a été assigné est restorée. + * + * La structure de l’automate est aussi un tableau double. Elle s’inspire + * cependant de l’extension de Mizobuchi, Sumitomo, Fuketa & Aoe (2000: An + * efficient representation for implementing finite state machines based on the + * double-array), qui augmente la structure d’Aho (1989) pour lui permettre de + * représenter des cycles. La structure originale n’en est pas capable, + * puisqu’elle force un état à n’avoir qu’une seule transition entrante, le + * champ orig ne pouvant contenir qu’un seul état. La solution proposée est de + * sélectionner une paire comme représentant canonique de l’état, les autres se + * chargeant de vérifier l’origine et de pointer vers le représentant canonique. + * Un drapeau placé dans le bit le plus à droite de la base indique que l’état + * de la paire à laquelle elle appartient est canonique (0) ou non (1). Cette + * solution ne fonctionne que pour les automates déterministes. Or, + * contrairement aux automates finis, les transducteurs finis ne peuvent pas + * tous être déterminisés: un symbole d’entrée peut mener à plus d’une + * transition. La solution que je propose est de créer, dans ces cas, une liste + * chaînée de transitions. Cette liste est signalée par un drapeau brandi dans + * le bit le plus à droite du champ origine. Les drapeaux de la base et de + * l’origine ne peuvent être brandis en même temps. On passe d’un état à l’autre + * par la formule: + * + * i' = paire[i].base >> 1 + s, + * + * si et seulement si + * + * paire[i'].orig & 1 == 0, + * paire[i'].orig >> 1 == i. + * + * Si, cepedant le drapeau de la base d’un symbole est brandi, + * + * i'' = paire[i'].base >> 1. + * + * Et si c’est le drapeau de l’origine qui est brandi, paire[i'].base >> 1 + * contient l’indice vers le début de la liste de transitions. Dans cette + * liste, le champ base contient l’indice de la prochaine paire ayant le + * même symbole d’entrée et le champ origine l’indice de l’état vers lequel + * pointe la transition. Une valeur de 1 dans l’origine marque la fin de la + * liste. + * + * Un deuxième tableau contient les identifiants de symbole de sortie. Les + * identifiants y sont disposés de telle sorte que l’indice dans le + * transducteur de l’état cible d’une transition permette d’y obtenir + * l’identifiant du symbole de sortie correspondant. */ + +/* Écrire une représentation .tfd du transducteur dans le fichier f. + * Renvoie 0, ou -1 en cas d’erreur. */ +int tfd_ecrire(FILE *f, struct tfm *tfm); + +#endif