- Récupérer le patron
Les programmes de la BàO3 proposent à l'utilisateur de fournir le modèle soit en tapant le patron directement en ligne de commande soit en donnant le nom du fichier contenant les patrons. Dans le dernier cas, le programme est capable de traiter plusieurs patrons :
print "Donnez le patron ou le nom du fichier contenant le patron\n";
my $response = <STDIN>;
A l'intérieur du programme, le(s) patron(s) est/sont stocké(s) dans une liste :
push(@listedespatrons, $patron);
- Parcourir les fichiers étiquetés
Les deux programmes de la BàO3 utilisent le parcours d'arborescence de fichiers que l'on a vu dans les BàO précédentes. La différence est que maintenant on lance ce parcours sur sa sortie de la BàO2 ! Etant arrivé au niveau du fichier, on vérifie son format.
Dans la version de la BàO3 pour Cordial, on cherche les fichiers cnr ; dans celle pour TreeTagger, on s'intéresse aux fichiers dont les noms se terminent par ttg.xml :
if (-d $file) {
&parcoursarborescencefichiers($file);
}
if (-f $file) {
#Si le nom du fichier se termine par ttg.xml, on lance la fonction d'extraction de patron pour la sortie de Treetagger
#if ($file=~/\.cnr$/) {&ch_patron_rgxp($file);}
if ($file=~/ttg\.xml$/) {print "traitement de $file \n";
- Extraire le patron
Les procédés de récupération sont assez distincts pour les deux programmes de la BàO3. On les décrira donc séparément :
BàO3 Cordial : listes en parallèle
Si le parcours du répertoire RESULTATS trouve un fichier cnr, ce fichier est traité par la fonction ch_patron_rgxp.
On lit le fichier ligne par ligne. Lorsque une ligne contient un token, un lemme et une catégorie chaque élément separé par une tabulation, on peut diviser la ligne grâce à la fonction split :
if ($ligne =~ /(.+?)\t(.+?)\t(.+?$)/) {
chomp($ligne);
my @malignesegmentee = split(/\t/, $ligne);
Chaque partie de la ligne est stockée dans une liste correspondante, alors on obtient trois listes : une liste de tokens, une liste de lemmes et une liste de catégories.
push(@listedetokens, $malignesegmentee[0]);
push(@listedelemmes, $malignesegmentee[1]);
push(@listedepos, $malignesegmentee[2]);}
Maintenant, on crée une copie de la liste des catégories et on la parcourt grâce à la fonction shift mise dans la boucle while.
shift supprime le premier élément de la liste en le gardant dans une variable. Ici, on peut parcourir tous les éléments de la liste jusqu'à ce que le dernier soit épuisé.
Mais le compteur $indice, qui s'incremente à chaque pas de la boucle, permet de rapporter à la position initiale l'élément courant dans la liste de catégories :
my @tmplistedespos=@listedepos;
my $indice=0;
while (my $a =shift(@tmplistedespos)) {
#....
$i++}
Chaque patron de la liste de patrons sera également divisé et converti en une petite liste par la fonction split :
foreach my $patron (@listedespatrons) {
my @listedeterme=split(/\#/,$patron);
#...}
A chaque pas de la boucle while, on vérifie si la catégorie coïncide avec le premier élément du patron :
if ($a=~/$listedeterme[0]/) {
my $verif=0;
Si c'est le cas, on teste la suite. Par exemple, si un patron porte trois éléments, on testera encore deux positions dans la copie de la liste de catégories :
for (my $i=0;$i<=$#listedeterme-1;$i++) {
if ($tmplistedespos[$i]=~/$listedeterme[$i+1]/) {
$verif++ ;}}
Si le nombre de correspondances est égale au nombre d'éléments du patron, cela signifie que l'on a trouvé la coïncidence complète entre le patron et une séquence des catégories. On repère les tokens correspondants dans la liste de tokens et on les imprime dans le fichier de sortie :
if ($verif == $#listedeterme) {
for (my $i=0;$i<=$#listedeterme;$i++) {
print RES $listedetokens[$indice+$i]," ";
}
print RES "\n";
}
BàO3 TreeTagger : chemins XPath
Si le parcours du répertoire RESULTATS trouve un fichier cnr, ce fichier est traité par la fonction extract_pattern
Dans cette fonction, on utilise la bibliothèque XML::XPath :
D'abord, on passe chaque patrons de la liste à la fonction extract_pattern :
foreach my $pattern (@listedespatrons) {&extract_pattern($pattern, $file);}
On construit pour ce patron un chemin XPath grâce à une autre fonction construit_Xpath :
my ($search_path,@tokens) = &construit_XPath($patron);
Le chemin qu'on obtient indiquera un noeud élément qui contient le premier élément du patron et dont les frères suivants contiennet le reste :
my $search_path="//element[data[\@type=\"type\"][contains(text(),\"$tokens[0]\")]";
my $i=1;
while ($i < $#tokens) {print $i."\n";
$search_path.="[ancestor::element/following-sibling::element[$i]/data[\@type=\"type\"][contains(text(),\"$tokens[$i]\")]";
$i++;}
Puis, on repère le premier noeud et les noeuds suivants grâce aux méthodes de la bibliothèque XML::XPath :
my $xp = XML::XPath->new( filename => $tag_file ) or die "big trouble";
foreach my $noeud ( $xp->findnodes($search_path)) {
print MATCHFILE $noeud->getChildNode(3)->string_value," ";
while ( $following < $#tokens) {
$following++;
my $following_elmt="./following-sibling::element[".$following."]";
my @noeuds_suivants=$xp->find($following_elmt, $noeud_suivant)->get_nodelist();
$noeud_suivant=shift(@noeuds_suivants);
print MATCHFILE $noeud_suivant->getChildNode(3)->string_value," ";
}
BaO3 TreeTagger : feuille de style
Enfin, on peut utiliser le même chemin XPath que l'on a construit dans la version de la BàO3 précedente directement dans une feuille de style xsl. Cliquez ici pour voir le resultat.
Télécharger les scripts de la BàO3 pour Cordial et pour TreeTagger.