Machine virtuelle pour le transfert

From Apertium
Jump to navigation Jump to search

In English

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>
#<transfer default="chunk">
---- Cette section établit le type de code généré et l'étape de transfert.
Initialisation push "genere"
push "<m>"
storev
...
jmp rules_section_start
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:
...
macro_firstWord_end:
...
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:
patterns_start:
push "all<predet><sp>"
push "<n><pl>"
push 2
addtrie action_0_start
...
patterns_end:
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:
...
action_0_end:
...
section_rules_end:
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="&lt;sg&gt;"/>
    <def-var n="genere" v="&lt;m&gt;"/>
  </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="&lt;sg&gt;" n="nombre">
 push "nombre"
 push "<sg>"
 storev
 #<def-var v="&lt;m&gt;" 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>