Programmation Perl
Fiche N°5 - Listes de listes, listes de hashes, h de h, etc.
Les références
Une liste (ou un tableau) ne peut contenir que des scalaires. Dès lors comment créer une structure complexe équivalente à une liste de listes ou de hashes ?
La solution est simple : on enregistre une liste de références, chaque référence étant un scalaire représentant l'adresse où se situe chaque sous liste.
Obtenir l'adresse d'une liste
L'opérateur de référence est le backslash : \@l représente l'adresse de la liste @l
Obtenir la liste pointée par une adresse
Il existe plusieurs manières de déréférencer une adresse pour obtenir la structure qui est pointée. 
Supposons que $adr soit une adresse pointant une liste. On obtient la liste en écrivant @{$adr}. Pour obtenir le 1er élément de la liste on peut écrire ${$adr}[0].
Si c'est un hash que l'on déréférence, on écrira %{$adr} pour désigner le hash en entier, et ${$adr}{$key} pour obtenir la valeur correspondant à $key.

Tapez le code suivant et analyser les résultats. @l1 et @l2 sont-elles totalement identiques  ?
my @l1=("V","N","Adj","Adv");
my %h1=(V=>"Verbe",N=>"Nom",Adj=>"Adjectif",Adv=>"Adverbe");
my @l2=@l1;
my $adr1=\@l1;
my $adr2=\@l2;
my $adr3=\%h1;
print "$adr1 est l'adresse de la liste l1 = @{$adr1} \n";
print "${$adr1}[0] est le premier élément de l1\n";
print "$adr2 est l'adresse de la liste l2 = @{$adr2} \n";
print "$adr3 est l'adresse du hash h1.\n";
print "valeur correspondant à V = ".${$adr3}{"V"}."\n";
Exprimer une liste de listes en littéral
Les crochets, encadrant une suite de scalaires, jouent le rôle de constructeurs de liste. Ils créent une liste et en renvoie l'adresse. Pour construire une référence à un hash vide on écrit $adr={}; 
Quelle est la différence entre les deux séquences suivantes ?
$adr = [1,2,3]; @l=@{$adr} 	et 
@l=(1,2,3);$adr=\@l; 
Pour affecter une valeur littérale à une liste de listes, on notera donc par exemple :
@l=(	["Verbe","Nom","Adjectif","Adverbe"],
	["Verbo","Nome","Adjectivo","Adverbo"],
	["Verb","Noun","Adjective","Adverb"] );
Quel est le scalaire correspondant à $l[2][3] ?
De même pour affecter un hash de listes on pourra écrire :
%h=(	fr=>["Verbe","Nom","Adjectif","Adverbe"],
	it=>["Verbo","Nome","Adjectivo","Adverbo"],
	en=>["Verb","Noun","Adjective","Adverb"] );
Quel est le scalaire correspondant à  $h{en}[2] ?
Passer des listes et des hashes comme argument
Les arguments d'une fonction sont récupérés dans la liste @_. Si on veut passer des listes ou des hashes, il faut donc passer leurs références (avec l'opérateur \). 
Exercice : Ecrire une fonction inclusion( ) qui prend deux listes comme argument et renvoie 1 si les éléments de la première liste sont inclus dans la deuxième, 0 sinon. On pourra écrire deux versions : inclusion avec répétition et sans répétition.

Exercice : Reprendre le dictionnaire de la fiche 4, et modifier la fonction de lecture afin d'obtenir un hachage dont les clés sont des formes simples, et dont les valeurs pointent les listes des différentes analyses liées aux formes simples.

Par exemple, pour les entrées suivantes :

empêche	empêcher	Ver:Imp+SG+P2
empêche	empêcher	Ver:IPre+SG+P1
empêche	empêcher	Ver:IPre+SG+P3
empêche	empêcher	Ver:SPre+SG+P1
empêche	empêcher	Ver:SPre+SG+P3

on aura :

$dico{"empêche"}=["empêcher Ver:Imp+SG+P2", "empêcher Ver:Ipre+SG+P1", "empêcher Ver: IPre+SG+P3", "empêcher Ver:Spre+SG+P1", "empêcher Ver: SPre+SG+P3"];

Modifier la fonction texteToCesana( ) afin d'ajouter les élements <msd></msd> comportant la liste des traits morphosyntaxique. 

On aura par exemple, en sortie :

…
<tok id="t1163">
	<orth>empêche</orth>
	<lex>
		<base>empêcher</base>
		<ctag>Ver</ctag>
		<msd>Imp+SG+P2</msd>
	</lex>
	<lex>
		<base>empêcher</base>
		<ctag>Ver</ctag>
		<msd>IPre+SG+P1</msd>
	</lex>
	<lex>
		<base>empêcher</base>
		<ctag>Ver</ctag>
		<msd>IPre+SG+P3</msd>
	</lex>
	<lex>
		<base>empêcher</base>
		<ctag>Ver</ctag>
		<msd>SPre+SG+P1</msd>
	</lex>
	<lex>
		<base>empêcher</base>
		<ctag>Ver</ctag>
		<msd>SPre+SG+P3</msd>
	</lex>
</tok>
…