Programmation Perl
Fiche N°1
Généralités
•	Perl (Practical Extraction and Report Language) est un langage Open Source (logiciel libre distribué sous licence GPL).
•	Perl est langage semi-interprété (le code est d'abord compilé dans un bytecode intermédiaire puis exécuté par l'interpréteur).
•	On peut trouver des interpréteurs Perl pour la plupart des systèmes (Linux, Windows, MacOs, etc.).
•	Créé par Larry Wall en 1987, Perl reprend les fonctionnalités du langage C en y intégrant des langages de scripts issus de l'environnement Unix, tel que Awk, Sed, Sh. Familièrement appelé "Le couteau suisse des langages de programmations", il est conçu pour traiter de façon économique et compacte des flux de caractères issus de fichiers textes.
•	Une vaste librairie de scripts (15,4 millions de lignes) est diffusée gratuitement sur le CPAN (Comprehensive Perl Archive Network, www.cpan.org), ainsi qu'une documentation complète.
•	Perl peut être interfacé avec le moteur d'interface graphique TK.
•	Depuis la version 5, Perl permet de déclarer des objets.
•	Pour le TAL, les fonctionnalités les plus intéressantes de Perl sont :
- Les facilités de lecture / écriture dans les fichiers textes
- Le traitement des expressions régulières pour la recherche et le remplacement de chaînes de caractère
- Les tableaux associatifs
Premiers pas
Perl est un langage très compact et parfois assez cryptique. 
Tapez le code suivant. Que fait-il ?

open(IN,"toto.txt");
open(OUT,">toto2.txt");
while (<IN>) {
	chomp;
	tr/àéèùâêîôûäëïöüç/aeeuaeiouaeiouc/i;
	tr/[a-z]/[A-Z]/;
	print OUT "$_\n";
}
close IN;
close OUT;
Les listes
•	Déclaration d'une liste: @l
•	Affectation de valeurs constantes à une liste : @mois = ("janvier","février","mars","avril")
•	Accès au ième élément (le premier indice est 0) : $mois[0] vaut "janvier", $mois[2] vaut "mars".
•	Longueur d'une liste : opérateur $# ou affectation de la liste en contexte scalaire
	avec $l = $#mois, $l vaut 3 (indice le plus élevé).

Fonctions de manipulation sur les listes : push( ) (ajouter un élément à la fin) pop( ) (supprimer le dernier élément), unshift( )(ajouter un élément au début), shift( ) (supprimer le premier élément).
Exemple :
push(@mois,"mai") -> @mois vaut ("janvier","février","mars","avril","mai")
$m=pop(@mois) -> @mois vaut ("janvier","février","mars","avril",") et $m vaut "mai"

Exercice 1
Ecrire un script dont la sortie est un fichier en HTML donnant le calendrier de l'année 2006, sous la forme de 12 tableaux de 7 colonnes (portant les titre : lundi, mardi, etc.). Indications : on créera d'abord une fonction pour l'affichage d'un mois.
Les tableaux associatifs (hash) 
Déclaration d'un tableau associatif : %l
Affectation de valeurs constantes à un hash :

%lmd = ("Deug1", "L1", "Deug2", "L2", "Licence", "L3", "Maîtrise", "M1", "DEA", "M2, "Doctorat", "D") 

Il s'agit d'une liste clé => valeur qui peut aussi s'écrire :

%lmd = (Deug1=> "L1", Deug2=> "L2", Licence=> "L3", Maîtrise => "M1", DEA=>, "M2, Doctorat=> "D")

On accède aux valeurs grâce aux clés :
print $lmd{"L2"}

Pour ajouter un couple clé-valeur, il suffit de faire une affectation :
$lmd{"DESS"}="M2"

N.B : s'il existait déjà une valeur pour "DESS", la nouvelle valeur écrase l'ancienne.

Pour tester l'existence d'un couple, on utilise la fonction exists( ):
if (exists($lmd{"DESS"}) { print "Le DESS devient : ".$lmd{"DESS"};}

Pour supprimer un couple, on utilise la fonction delete( ).

Exercice 2
On enregistre dans un hash des dates particulières (événements, anniversaires, etc.) avec un texte court. Modifier le script de l'exercice 1 afin que, pour chaque date, le texte s'affiche dans la case correspondante.

Exercice 3
Programmer un Zipf rapide en utilisant la fonction split(/\s+/,$chaine) qui transforme une chaîne en liste de mots. Le script lira un fichier texte en entrée. La sortie du script consistera en une liste donnant, sur chaque ligne, un mot et la fréquence correspondante. Les mots seront triés par fréquence décroissante.
Les expressions régulières
La puissance de Perl tient à son traitement des expressions régulières. La principale fonction utilisant ce formalisme est la fonction de recherche d'une chaîne (string matching) grâce à l'opérateur =~ . L'expression régulière définissant le motif recherché est écrite entre slash / /. Par exemple : 
- la condition ($rep =~ /oui/) est vraie si la chaîne $rep contient la chaîne "oui"
Les principaux symboles sont :
- le point, désignant n'importe quel caractère. 
	($an =~ /199./) est vraie si $an contient 1990, mais aussi 199t 
- les crochets, désignant l'occurrence d'un caractère parmi un ensemble.
	($an =~ /199[0-9]/) est vraie si $an contient 1990, ou 1991, etc. 
	($rep =~ /[Oo]ui/) est vraie si la chaîne $rep contient la chaîne "oui" ou "Oui"
- le plus : désigne l'occurrence de 1 ou plusieurs motifs
	($an =~ /1[0-9]+/) est vraie si $an contient un nombre de plus d'un chiffre commençant par 1… 
	(p. ex. "182323").
- l'astérisque : désigne l'occurrence de 0 ou plusieurs motifs
	($an =~ /1[0-9]*/) est vraie si $an contient un nombre quelconque commençant par 1 (p. ex. "1").
- ^ et $ désignent le début et la fin de la chaîne.
	($rep =~ /^[Oo]ui$/) est vraie si la chaîne $rep est égale à "oui" ou "Oui"

La recherche par motif permet également d'isoler certains éléments reconnus et de les stocker : il suffit d'écrire le motif entre ( ) : on parle de parenthèses capturantes. Les variables $1, $2, etc… stockent ensuite les sous chaînes reconnues dans l'ordre d'apparition.
	("jeudi 22 janvier 2004" =~ /[a-z]+ ([0-9]+) ([a-z]+) ([0-9]+)/) est vraie 
	et on a $1= "22"     $2="janvier"     $3="2004".

Exercice 4
a) Ecrire une fonction prenant un mot en entrée, et renvoyant le mot mélangé en sortie.
b) Ecrire un script pour créer, à partir d'un texte lu dans un fichier, un texte constitué des mots mélangés. Seul l'intérieur des mots sera mélangé (la première et la dernière lettre resterons en place).

Exercice 5
On veut créer un jeu consistant à tirer au hasard une forme du dictionnaire, et à demander le lemme correspondant.

a) Ecrire un script en Perl permettant de lire les données du fichier "dico.txt" dans un tableau.
On utilisera les fonctions d'ouverture et de fermeture d'un fichier de nom symbolique DICO: 
open (DICO,"dico.txt") et close(DICO)

b) Implémenter le jeu. Indication : pour le tirage aléatoire, on utilisera la fonction ran(n), qui renvoie aléatoirement un nombre entre 0 et n. Lorsque l'utilisateur donnera une réponse erronée, l'ordinateur lui donnera la réponse correcte. Après chaque tour, l'ordinateur demandera à l'utilisateur s'il veut rejouer ou sortir.

c) Réécrire le script en recourant à un tableau associatif nommé %lem. Ce dernier pourra être sauvegardé dans une base de données grâce aux fonctions dbmopen(%lem,"lem_db",0600) et dbmclose(%lem).

d) Modifier le script précédent afin de créer un nouveau jeu : l'ordinateur tire au hasard un verbe conjugué à l'imparfait du subjonctif, et demande de donner la forme conjuguée à partir du lemme. Par exemple, à la question : "Quel est la forme conjuguée de 'aimer' à l'imparfait du subjonctif (PL+P3) ?", l'utilisateur devra répondre "amassent" pour avoir l'affichage du message "Bravo".

Des informations sur les fonctions Perl peuvent être obtenues à l'adresse suivante :
Perl pour les CGI : http://selfhtml.selfhtml.com.fr/cgiperl/langage/index.htm 
Documentation de référence : http://www.enstimac.fr/Perl/DocFr.html