Machine virtuelle pour le transfert
Jump to navigation
Jump to search
Contents
Jeu d'instructions[edit]
La colonne Opcode (in hex) de la page anglaise qui était vide n'est pas reproduite dans ce tableau.
Mnémonique | Autre opérandes | Pile [avant]→[après] (haut, haut-1, ...) |
Description |
---|---|---|---|
push | value | [vide] → valeur | Pousse une chaîne de caractères ou une valeur variable dans la pile. Les chaînes vont entre quotes ("chaîne") mais pas les noms de variables |
pushbl | aucun | [vide] → blanc | Pousse un blanc dans la pile |
pushsb | pos | [vide] → superblanc | Pousse le superblanc à 'pos' dans la pile |
append | N | valeurN, ..., valeur1, NomVar → [vide] | Récupère 'N' éléments et les rajoute à une variable ou clip |
concat | N | valeurN, ..., valeur1 → valeur1...valeurN | Récupère 'N' éléments et les empile concaténés |
clip | aucun | partie → valeur | Obtient la 'partie' dans la seule langue présente (inter/post-chunk) et pousse la valeur dans la pile |
clipsl | link-to | partie, pos → valeur | Obtient la 'partie' dans la langue source en position 'pos' et pousse la 'valeur' dans la pile. Un opérande optionnel est utilisé pour les clips avec les balises link-to, ex: "clipsl <3>". |
cliptl | link-to | partie, pos → valeur | Obtient la 'partie' dans la langue cible en position 'pos' et pousse la 'valeur' dans la pile. Un opérande optionnel est utilisé pour les clips avec les balises link-to, ex: "cliptl <3>". |
storecl | aucun | valeur, partie → [vide] | Stocke 'valeur' dans la seule langue présente (inter/post-chunk) |
storesl | aucun | valeur, partie, pos → [vide] | Stocke 'valeur' comme la 'partie' de la langue source en position 'pos' |
storetl | aucun | valeur, partie, pos → [vide] | Stocke 'valeur' comme la 'partie' de la langue cible en position 'pos' |
storev | aucun | valeur, NomVar → [vide] | Stocke 'valeur' dans la variable appelée 'NomVar' |
addtrie | adresse | N, modèleN, ..., modèle1 → [vide] | Récupère 'N' modèles et crée une entrée d'essai pointant vers 'adresse' |
lu | N | valeurN, ..., valeur1 → ^(unité_lexicale)$ | Récupère 'N' valeurs de la pile, crée une unité lexicale ^...$ avec elles et pousse l'unité lexicale dans la pile |
mlu | N | luN, ..., lu1 → multi-mot | Récupère 'N' unités lexicales de la pile, crée un multi-mot avec elles et pousse le multi-mot dans la pile |
lu-count | aucun | [vide] → nombre | Pousse le nombre d'unité lexicales mentionné (mots dans le fragment) dans la règle vers la pile (???) |
chunk | N | elemN-2, ... , elem1, <tags>, nom → ^nom<tags>{elem1...elemN-2}$ | Récupère 'N' blocs de données de la pile, crée le fragment et le pousse dans la pile |
out | N | valeurN, ..., valeur1 → [vide] | Récupère 'N' valeurs de la pile et les affiche |
cmp | aucun | valeur2, valeur1 → resultat | Récupère 'valeur1' et 'valeur2', les compare, si elles sont égales pousse un 1 (vrai), sinon pousse un 0 (faux) |
cmpi | aucun | valeur2, valeur1 → resultat | Récupère 'valeur1' et 'valeur2', les compare (en ignorant la case des caractères de chaque chaîne), si elles sont égales pousse un 1 (vrai), sinon pousse un 0 (faux) |
cmp-substr | aucun | valeur2, valeur1 → resultat | Teste si 'valeur1' contient la sous-chaîne 'valeur2', le résultat peut être 1 (vrai) ou 0 (faux). |
cmpi-substr | aucun | valeur2, valeur1 → resultat | Teste si 'valeur1' contient la sous-chaîne 'valeur2' (en ignorant la case des caractères de chaque chaîne), le résultat peut être 1 (vrai) ou 0 (faux). |
not | N | valeur → resultat | Complémente la valeur du haut de la pile, 0 -> 1 or 1 -> 0 |
and | N | valeurN, ..., valeur1 → resultat | Opération et de 'N' valeurs, le résultat peut être 1 (vrai) ou 0 (faux) |
or | N | valeurN, ..., valeur1 → resultat | Opération ou de 'N' valeurs, le résultat peut être 1 (vrai) ou 0 (faux) |
in | aucun | liste, valeur → resultat | Recherche la 'valeur' dans une 'liste' |
inig | aucun | liste, valeur → resultat | Recherche (en ignorant la case des caractères) la 'valeur' dans une 'liste' |
jmp | étiq | [vide] → [vide] | Saute à l'étiquette étiq, sans condition |
jz | étiq | haut → [vide] | Saute à l'étiquette étiq si le haut de pile (stack.top) vaut 0 |
jnz | étiq | haut → [vide] | Saute à l'étiquette étiq si le haut de pile (stack.top) vaut 1 |
call | nom_macro | N, argN, ..., arg1 → [vide] | Appelle une macro avec les arguments dans la pile |
ret | aucun | [vide] → [vide] | Retourne d'une macro, PC (adresse de retour ??) sera supporté automatiquement par la machine virtuelle. |
nop | aucun | [vide] → [vide] | Aucune opération |
case-of | aucun | container → cas | Récupère le cas du container dans la pile. Le container devrait habituellement être le résultat d'une instruction clip mais peut être n'importe quelle chaîne de caractères. |
get-case-from | aucun | pos → cas | Récupère le cas de l'unité lexicale en position 'pos' |
modify-case | aucun | nouv_cas, container → containerModifie | Modifie le cas du 'container' à 'nouv_cas' et laisse le container modifié dans la pile |
begins-with | aucun | valeur2, valeur1 → resultat | Vérifie si 'valeur1' commence par 'valeur2' et pousse 1 (vrai) ou 0 (faux), 'valeur2' peut être une liste |
begins-with-ig | aucun | valeur2, valeur1 → resultat | Vérifie si 'valeur1' commence par 'valeur2' (en ignorant la case des caractères) et pousse 1 (vrai) ou 0 (faux), 'valeur2' peut être une liste |
ends-with | aucun | valeur2, valeur1 → resultat | Vérifie si 'valeur1' se termine par 'valeur2' et pousse 1 (vrai) ou 0 (faux), 'valeur2' peut être une liste |
ends-with-ig | aucun | valeur2, valeur1 → resultat | Vérifie si 'valeur1' se termine par 'valeur2' (en ignorant la case des caractères) et pousse 1 (vrai) ou 0 (faux), 'valeur2' peut être une liste |
- Les listes sont représentées comme la concaténation d'items séparés par '|', ex: uno|otro|poco|cuánto|menos|mucho|tanto|demasiado
- Le cas est représenté comme "aa" (tout en minuscules), "Aa" (premier caractère en majuscule) and "AA", (tout en majuscules).
Génération de code[edit]
Sections de code[edit]
Le code généré par le compilateur est divisé en plusieurs sections. En plus, la machine virtuelle lit et mémorise le code dans ses propres sections.
Section | Code | section mach virt | Information |
---|---|---|---|
Header | #<assembly> |
---- | Cette section établit le type de code généré et l'étape de transfert. |
Initialisation | push "genere" |
Code section | Dans cette section on initialise les variables avec leur valeur par défaut et on exécute les autres initialisations. À la fin on saute à la section rules, bien que les règles seront seulement exécutées lorsqu'un modèle est rencontré, on a besoin de traiter tous les modèles qui sont dans la section rules. |
Macros | macro_firstWord_start: |
Macros code section | Cette section contient tous les codes de macros délimités par des étiquettes. Chaque macro peut être appelée avec l'instruction 'call'. |
Patterns | section_rules_start: |
Preprocess code section | Dans cette section tous les modèles seront ajoutés au système d'essai. Dans cet exemple on peut voir que deux modèles sont poussés, puis le nombre de modèles est poussé et finalement l'instruction addtrie les récupère et ajoute une entrée dans l'essai pour la règle 0. |
Rules | action_0_start: |
Rules code section | Finalement la section rules contient chaque règle délimitée par ses étiquettes et tout son code. |
- Les lignes de commentaires peuvent être faites en utilisant le symbole '#' en début de ligne.
Exemples de code[edit]
Exemple de macro[edit]
Fichier de transfert (.t1x)[edit]
<transfer default="chunk">
<section-def-attrs>
<def-attr n="nbr">
<attr-item tags="sg"/>
<attr-item tags="pl"/>
<attr-item tags="sp"/>
<attr-item tags="ND"/>
</def-attr>
</section-def-attrs>
<section-def-vars>
<def-var n="nombre" v="<sg>"/>
<def-var n="genere" v="<m>"/>
</section-def-vars>
<section-def-macros>
<def-macro n="nombre_nom" npar="1">
<let>
<var n="nombre"/>
<lit v=""/>
</let>
<choose>
<when>
<test>
<and>
<equal>
<clip pos="1" side="sl" part="nbr"/>
<lit-tag v="sg"/>
</equal>
<equal>
<clip pos="1" side="tl" part="nbr"/>
<lit-tag v="pl"/>
</equal>
</and>
</test>
<let>
<var n="nombre"/>
<lit-tag v="pl_slsg"/>
</let>
</when>
<when>
<test>
<and>
<equal>
<clip pos="1" side="sl" part="nbr"/>
<lit-tag v="pl"/>
</equal>
<equal>
<clip pos="1" side="tl" part="nbr"/>
<lit-tag v="sg"/>
</equal>
</and>
</test>
<let>
<var n="nombre"/>
<lit-tag v="sg_slpl"/>
</let>
</when>
<otherwise>
<let>
<var n="nombre"/>
<clip pos="1" side="tl" part="nbr"/>
</let>
</otherwise>
</choose>
</def-macro>
</section-def-macros>
</transfer>
Code généré[edit]
#<assembly>
#<transfer default="chunk">
#<def-var v="<sg>" n="nombre">
push "nombre"
push "<sg>"
storev
#<def-var v="<m>" n="genere">
push "genere"
push "<m>"
storev
jmp section_rules_start
#<def-macro npar="1" n="nombre_nom">
macro_nombre_nom_start:
#<var n="nombre">
push "nombre"
#<lit v="">
push ""
storev
#<clip part="nbr" pos="1" side="sl">
push 1
push "<sg>|<pl>|<sp>|<ND>"
clipsl
#<lit-tag v="sg">
push "<sg>"
cmp
#<clip part="nbr" pos="1" side="tl">
push 1
push "<sg>|<pl>|<sp>|<ND>"
cliptl
#<lit-tag v="pl">
push "<pl>"
cmp
and 2
jz when_0_end
#<var n="nombre">
push "nombre"
#<lit-tag v="pl_slsg">
push "<pl_slsg>"
storev
jmp choose_0_end
when_0_end:
#<clip part="nbr" pos="1" side="sl">
push 1
push "<sg>|<pl>|<sp>|<ND>"
clipsl
#<lit-tag v="pl">
push "<pl>"
cmp
#<clip part="nbr" pos="1" side="tl">
push 1
push "<sg>|<pl>|<sp>|<ND>"
cliptl
#<lit-tag v="sg">
push "<sg>"
cmp
and 2
jz when_1_end
#<var n="nombre">
push "nombre"
#<lit-tag v="sg_slpl">
push "<sg_slpl>"
storev
jmp choose_0_end
when_1_end:
#<otherwise>
#<var n="nombre">
push "nombre"
#<clip part="nbr" pos="1" side="tl">
push 1
push "<sg>|<pl>|<sp>|<ND>"
cliptl
storev
choose_0_end:
macro_nombre_nom_end: ret
#<section-rules>
section_rules_start:
section_rules_end:
Exemple de modèle de règles[edit]
Fichier de transfert (.t1x)[edit]
<transfer default="chunk">
<section-def-cats>
<def-cat n="all">
<cat-item lemma="all" tags="predet.sp"/>
</def-cat>
<def-cat n="adj2">
<cat-item tags="adj"/>
<cat-item tags="adj.*"/>
<cat-item tags="adj.sint"/>
<cat-item tags="adj.sint.*"/>
<cat-item tags="adj.comp"/>
<cat-item tags="adj.sup"/>
</def-cat>
<def-cat n="nomcomu">
<cat-item tags="n.*"/>
</def-cat>
<def-cat n="nompropi">
<cat-item tags="np.*"/>
</def-cat>
<def-cat n="nploc">
<cat-item tags="np.loc.*"/>
</def-cat>
</section-def-cats>
<rule>
<pattern>
<pattern-item n="all"/>
<pattern-item n="adj2"/>
</pattern>
<action>
...
</action>
</rule>
<rule>
<pattern>
<pattern-item n="nomcomu"/>
<pattern-item n="nompropi"/>
<pattern-item n="nploc"/>
</pattern>
<action>
...
</action>
</rule>
</section-rules>
</transfer>
Code généré[edit]
#<assembly>
#<transfer default="chunk">
jmp section_rules_start
#<section-rules>
section_rules_start:
patterns_start:
push "all<predet><sp>"
push "<adj>|<adj><*>|<adj><sint>|<adj><sint><*>|<adj><comp>|<adj><sup>"
push 2
addtrie action_0_start
push "<n><*>"
push "<np><*>"
push "<np><loc><*>"
push 3
addtrie action_1_start
patterns_end:
action_0_start:
...
action_0_end:
action_1_start:
...
action_1_end:
section_rules_end:
Liste de souhaits[edit]
- Faire les options de compilation comme avec lt-comp/cg-comp (ex: vous n'avez pas besoin de -i/-o pour dire ce que sont les fichiers d'entrée/sortie), juste
apertium-compiler [options] <fich_entree> <fich_sortie>