Série 3 : Patrons syntaxiques



Il s'agit ici d'ajouter au programme de la série 2 un programme d'extraction de patrons syntaxiques.

TreeTagger

On modifie le programme précédent pour créer un fichier comportant l'ensemble des phrases étiquetées par le TreeTagger sur lequel on applique ensuite l'extraction.
Par exemple pour rechercher le patron NOM ADJ on utilise le fichier patron et on obtient cette extraction.
On obtient cette extraction en plus du fichier xml étiqueté.

Le contenu du programme (les changements par rapport à la série 2 sont en vert) :


#!/usr/bin/perl
<<DOC;
Format d\'entree : un texte étiqueté et lemmatisé par tree tagger
Format de Sortie : le même texte au format xml
DOC


# Usage
$ChaineUsage="Usage : tt2xml.pl <Fichier>\n";
if (@ARGV!=1) {
die $ChaineUsage;
}

$t=0;
&ouvre;
&entete;
my $rep="$arg";
# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;
print "Quelle est la balise à extraire ?\n";
$exp=<STDIN>;
chomp $exp;
# On choisit le nom du fichier qui contiendra les patrons extraits
print "choisis un nom de fichier pour contenir les termes extraits\n";
# Entrer le nom du fichier contenant les patrons
$fic=<STDIN>;
print "Quel est le fichier contenant les patrons?\n";
$pat=<STDIN>;

&parcoursarborescencefichiers($rep);
&fin;
&ferme;
# On appelle le sous programme d'extraction
&patron;



# Récupération des arguments et ouverture des tampons


sub ouvre {
$arg = $ARGV[0];
$FichierSortie= $arg . ".xml";
open(Sortie,">$FichierSortie");
open(TP,">pourpatron.txt");
}
# Entête de document XML
sub entete {
print Sortie "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n<?xml-stylesheet type=\"text/xsl\" href=\"StyleT.xsl\"?>\n";
print Sortie "<document>\n<Nom>Aurélia Trinquier</Nom>\n";
}

sub parcoursarborescencefichiers {
my $path = shift(@_);
opendir(DIR, $path) or die "ne peut ouvrir $path: $!\n";
my @files = readdir(DIR);
closedir(DIR);
foreach my $file (@files) {
next if $file =~ /^\.\.?$/;
$file = $path."/".$file;
if (-d $file) {
&parcoursarborescencefichiers($file); #recurse!
}
if (-f $file) {
# TRAITEMENT à réaliser sur chaque fichier

open(FILEINPUT,$file);

print Sortie "<fichier>\n<nom>$file</nom>\n";
while ($ligne = <FILEINPUT>)
{
if ($ligne=~/<$exp>(.*)<\/$exp>/)
{ open(OUTPUT,">resultats.txt");
print Sortie "<description>\n";
$ligne=$1;

# Rectification des problèmes de codage

$ligne=~s/(&#39;)/\'/g;
$ligne=~s/(&#34;)/\"/g;
$ligne=~s/à©/é/g;
$ligne=~s/é/é/g;
$ligne=~s/ê/ê/g;
$ligne=~s/è/è/g;
$ligne=~s/Ã/à/g;
$ligne=~s/ç/ç/g;
$ligne=~s/à§/ç/g;
$ligne=~s/à´/ô/g;
$ligne=~s/(é)/é/g;
$ligne=~s/(ê)/ê/g;

# Séparation du texte en 1 mot par ligne

$ligne=~s/( )/\n/g;
$ligne=~s/([,\;:!?\.'\"\(\)])/\n$1\n/g;
print OUTPUT $ligne;

#Fermeture du fichier resultats.txt

close(OUTPUT);


#Lancement du TreeTagger
system ("bin/tree-tagger.exe -token -lemma lib/french.par resultats.txt treetagger.txt");

open(TREE,"treetagger.txt");

while ($tree = <TREE>) {
# On imprime la phrase étiquetée dans le fichier pourpatron.txt
print TP $tree;

if ($tree!~/\ô\¯\:\.\ô\¯\:\.\./ ) {
# Remplacement des guillemets par <![CDATA["]]> (évite erreur d'interprétation XML)
$tree=~s/\"/<![CDATA[\"]]>/g;
$tree=~s/(<unknown>)/unknown/g;
# Suppression des caractères générés par TreeTagger empêchant la bonne formation du fichier xml
$tree=~s/(.*°I..)//g;
$tree=~s/([^\t]*)\t([^\t]*)\t([^\n]*)\n/<element>\n <data type=\"cat\">$2<\/data>\n <data type=\"lemme\">$3<\/data>\n <data type=\"mot\">$1<\/data>\n<\/element>/;

print Sortie $tree;
}

}
close(TREE);
print Sortie "\n</description>\n";
}
}


print Sortie "</fichier>\n";
}


# Fin de fichier
sub fin {
print Sortie "</document>\n";
close (TP);
}
}
}
# Fermeture des tampons
sub ferme {
close(Sortie);
}

# Insertion du programme d'extraction
sub patron {
# On change le nom du fichier à traiter
open(FIC, "pourpatron.txt");


# ouverture d un fichier de trace, destine a recevoir les
# informations de traitements
#---------------------------------------------------
# initialisation des variables
#---------------------------------------------------
open(FIC1, ">$fic");
my $i=0;
my $j=0;
my $k=0;
my @token=();
#---------------------------------------------------
# lecture du fichier de sortie TREETAGGER
# creation de 3 tableaux contenant les mots, les lemmes et les categories
#---------------------------------------------------
while (<FIC>) {
my $ligne=$_;
my @liste=split(/\t/,$ligne);
push(@token, $liste[$i++]." ");
push(@patron, "$liste[$i++]" ." ");
push(@lemme, "$liste[$i++]" ." ");
$i=0;
}
close(FIC);

#---------------------------------------------------
# on cree une liste vide destinee a recevoir les patrons
# presents dans le fichier lu a l etape precedente
# cette liste sera initialisee apres chaque construction
# de patron
#---------------------------------------------------
@sous_patron=();
#---------------------------------------------------
# creation de la liste des patrons lus dans le fichier
# issu de treetagger
#---------------------------------------------------
while (defined($element_patron=shift(@patron))) {
if ($element_patron !~ PUN && $element_patron !~ SENT) {
push(@sous_patron, $element_patron);
$j++;
next;
}
my @sous_token=@token[$k+1..$j-1];
# on va maintenant voir si le sous-patron construit est dans le
# liste des patrons cherches (dans le fichier des patrons scrutes)
&cherche_patron(@sous_patron);
@sous_patron=();
$k=$j;
$j++;
}

close (FIC1);
#=============================================
# procedure de recherche des patrons
#=============================================

sub cherche_patron {
my @liste=@_;
my $suite_de_patrons=join("",@liste);
$z=0;
$nb=0;
# ouverture du fichier des patrons cherches
# Ouvre le fichier dans lequel les patrons seront extraits
open(FIC, "$pat");

while(<FIC>) {
$ligne=$_;
chomp $ligne;
$nb=0;
while ($ligne=~m/ /g) {$nb++};
$nb++;
while ($suite_de_patrons=~m/$ligne/g) {
my $avant=substr ($suite_de_patrons, 0, pos($suite_de_patrons)-length($ligne));
while ($avant=~m/ /g) {$z++};
print FIC1 "@token[$k+$z+1..$k+$z+$nb]\n";
$z=0;
}
}
close(FIC)
}
}