Utilisation de lex dans le monde XML

De Wicri Manuel

Lex est un générateur d'analyseur syntaxique qui associe simplement des actions à des règles.

En associant des règles à des éléments syntaxiques du langage XML, lex se comporte en fait comme un analyseur XML relativement élémentaire.

Quelques exemples d'applications

Changement de noms de balises d'un document XML

Pour changer un nom de balise (exemple remplacer <titre> par <title>), deux règles suffisent dans les cas simples :

%%
"</titre>"      printf("</title>";
"<titre"/[ >]   printf("<title");
%%
main() {
  yylex();
  return 0;
}


Pré-traitement de documents XML non conformes

Lex peut être très utile pour traiter un document approximatif vers un parser DOM ou SAX rigoureux.

Par exemple, la bibliothèque Dilib contient un programme qui normalise les entités Sgml des flux de données venant de l'INIST.

En voici un extrait :

/*   -*- coding: utf-8 -*-  */
%%
"&Eacute;"      printf("É");
"&Aacute;"      printf("Á");

...

"&ggr;"         printf("γ");
"&"             printf("========");  /* pour repérer les codes non traités */
%%
main()
{
  yylex();
}

Indexation par filtrage

Cet exemple montre comment extraire, dans le serveur Rabelais des termes terminés par « us » (en excluant le terme « plus ») dans un fichier bibliographique Sxml.

%{
#include <stdio.h>
 char *key;
%}
%%
^[0-9A-F]+/\t              strcpy(key, yytext);
plus/[ <,]                  ;
[A-Za-z][a-z]+"us"/[ <,]   {printf("%s\t%s\n", yytext, key);}
.              ;
\n             ;
%%
main()
{
  key=malloc(7);
  yylex();
}

Pour tester cet exemple sur le serveur Rabelais, recopier le programme dans un fichier, par exemple testRabelais.lex, et procéder ainsi :

. ~/Dilib/init.sh
lex testRabelais.lex
gcc lex.yy.c -ll -o testRabelais 
HfdCat $DILIB/Samples/RabelaisV1/Data/Main/Exploration/biblio.hfd   \
         | ./testRabelais | sort -u                                 \
         | IndexBuildRec                                            \
         | SxmlSelect -g idx/f/1 -g idx/k/1 -p @g1 -p @g2 | sort -rn | more

On obtient alors une liste telle que :

20      sous
16      Erasmus
15      nous
14      tous
9       Famous
8       corpus
7       Religious
6       processus
3       thus
3       focus
3       Sous
3       Bacchus
2       vertus
2       various
2       serous
2       refus
2       parus
2       mysterious
2       dessus
2       dangerous
2       Tous
2       Thus
2       Plus
2       Phallus
2       Nous
2       Neophilologus
2       Grobianus
2       Corpus
Exercices

Cet exemple peut être modifié pour analyser puis éliminer les termes en « ious ». On peut également rechercher les noms propres...

Repérage de composés chimiques

L'exemple précédent peut s'appliquer à la recherche de composés chimiques.

Par exemple sur la base EuropiumV3, les nouvelles règles du programme lex :

%%
^[0-9A-F]+/\t              strcpy(key, yytext);
[A-Za-z0-9]*"Eu"[A-Z][A-Za-z0-9]*    {printf("%s\t%s\n", yytext, key);}
.              ;
\n             ;
%%

donnent le résultat suivant :

176     EuO
170     EuS
164     EuBa
140     EuCl
103     EuTe
77      EuF
62      EuB
56      EuCu
53      EuSe
52      EuBa2Cu3O7
41      EuPd
36      EuNi
34      EuFe
24      EuMo
21      EuF3
21      EuB6
20      EuW
20      EuL
18      PbEuTe
18      EuTiO
18      EuGa
18      EuCo
18      EuAl
16      EuVO
16      EuP
16      EuCl3
16      EuBr
15      EuPO
15      EuAs
14      EuOCl
13      EuX
13      EuN
13      EuMnO
13      EuBa2Cu3Oy
12      EuI
10      EuMn
10      EuFeO