Analyse lexicale

La solution complète est ici.

Un exemple d'analyseur

L'analyseur untag.mll se compile par « ocamllex untag.mll ; ocamlc -o untag untag.ml » (ou par « make untag » à l'aide de ce Makefile), en une commande qui prend un nom de fichier HTML en argument en affiche le contenu du fichier moins les balises et les commentaires. Récupérez ces deux fichiers tout de suite, ainsi que ce document lui même (menu File, entrée Save,en format source). Compilez, puis essayez « ./untag index.html ».

HTML est effet structuré à l'aide d'éléments, qui s'ouvrent par une balise d'ouverture et se ferment (parfois) par une balise de fermeture. Par exemple, on met un texte en italique à l'aide de l'élément « I » , soit <I>en italiques</I> donne en italiques.

Un autre exemple est celui des hyperliens introduits par l'élément « A », soit :
       <A HREF="http://pauillac.inria.fr/~maranget/">chez moi</A>
qui donne
chez moi.
On remarquera que la référence distante (url) est donnée comme la valeur de l'attribut « HREF » de la balise d'ouverture de l'élément « A ».

Enfin une image incluse dans le texte est codée par un élément « IMG » qui consiste en l'unique balise « <IMG SRC=...> ». Par example :
     <IMG ALT="Le tango.gif en SRC" SRC=tango.gif>
nous donne
Le tango.gif en SRC
Ici la référence distante (le fichier qui contient l'image) est la valeur de l'attribut « SRC ».

L'analyseur untag est votre point de départ pour les exercices de cette semaine.

On remarquera que les points suivants :

1  Extraire toutes les balises d'un document

C'est une première étape, cela revient en quelque sorte à inverser l'analyseur untag.

Il est vivement conseillé de commencer par copier untag.mll dans un nouveau fichier tag.mll (par cp untag.mll tag.mll). Dès lors vous pourrez vous servir de la commande « make tag » pour fabriquer l'analyseur tag (à condition bien entendu d'avoir récupéré le Makefile). Évidemment il faut d'abord modifier les règles d'analyse (et seulement elles, veillez bien à garder tout le code du prélude (entre accolades au début) et du postlude (entre accolades à la fin).

Rapelons que par « balise » on entend tout ce que est de la forme <...>. Normalement « ./tag index.html » devrait produire ce fichier :
001: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
002: <HTML>
003: <HEAD>
004: <TITLE>

  ...

320: <FONT SIZE=2>
321: <sup>
322: </sup>
323: </FONT>
324: </A>
325: </EM>
326: </BLOCKQUOTE>
327: </BODY>
328: </HTML>
(Les numéros de ligne sont là pour aider à comparer avec la sortie de votre programme. On affiche un entier i comme ci-dessus par Printf.printf "%03" i.)
Voir la solution, si besoin est.

2  Extraire toutes les références distantes d'un document

Écrire l'analyseur url qui extrait toutes les références distantes d'une page HTML. Comme on l'a déjà vu, les références distantes sont les valeurs des attributs HREF des balises <A ...> et les valeurs des attributs SRC des balise <IMG ...>, C'est à dire que l'on cherge maintenant les arg dans des constructions du genre:
  <A ... href=arg ... >
  <iMg ... SrC=arg ... >
On notera : À vous donc d'écrire le lexer url.mll, vous pourrez le compiler directement ou toujours avec le même Makefile par « make url ».

La démarche suggérée est de démarer de tag.mll (en oubliant pas de le nommer url.mll). Dans le source, notez cette fois la présence d'une définition de l'expression régulière reconaissant les blancs.

Il va falloir: Cela donne assez naturellement quatre analyseurs mutuellement récursifs. Attention certains analyseurs devront renvoyer quelque chose, typiquement le type du dernier analyseur sera Lexing.lexbuf -> string, tandis que le type du premier sera Lexing.lexbuf -> unit.

Pour le dernier analyseur, qui récupére les arguments des attributs, inspirez vous du traitement des chaînes dans le poly. Vous pouvez aussi lire les explications de l'exemple de la calculette, toujours dans le poly. Vous aurez sans doute besoin de travailller un peu sur les chaînes, voir le module String.

Une fois votre analyseur terminé, si vous l'appliquez, après sa récupération, à ce document lui-même par « ./url index.html », vous devriez obtenir ce fichier :
01: sol.html
02: sol/untag.mll
03: sol/Makefile
04: http://pauillac.inria.fr/~maranget/
05: tango.gif
06: sol/Makefile
07: balises.txt
08: sol.html#tag
09: http://www.w3.org/TR/html401/intro/sgmltut.html
10: sol/Makefile
11: ../../poly/lexical.html#chaine
12: ../../poly/lexical.html#lexcalc
13: http://caml.inria.fr/ocaml/htmlman/libref/String.html
14: urls.txt
15: sol.html#un
16: ftp://ftp.inria.fr/lang/caml-light/
17: //www.ics.uci.edu/pub/ietf/uri/rfc2396.txt
18: /
19: index.html
20: http://caml.inria.fr/ocaml/htmlman/libref/Str.html
21: ../../poly/lexical.html#libstr
22: sol.html#deux
23: http://pauillac.inria.fr/~maranget/hevea/index.html
(Les urls sont numérotées pour faciler la comparaison avec votre sortie à vous).
Voir la solution, si besoin est.

3  Interpréter les références distantes

Une fois récupérées les réferences distantes, on remarque qu'elle ont des aspects assez variables. Dans l'url complète http://pauillac.inria.fr/~maranget/, on note un protocole http (qui pourrait être autre chose, par exemple, ftp), un nom de machine pauillac.inria.fr et ensuite un chemin d'accès /~maranget/. Rien que pour compliquer un peu, voici une url de protocole ftp ftp://ftp.inria.fr/lang/caml-light/.

Protocole et nom de machine peuvent être omis, lorqu'ils sont les mêmes que ceux du document (c'est une vue très simplifiée, voir le document de référence idoine, mais plus tard !). Par exemple l'url minimale « / » renvoie normalement à la racine du serveur, tandis que « index.html » renvoie à ce document lui-même.

Il vous est demandé de completer l'analyseur url, afin de destructurer les url. Il est demandé cette fois d'utiliser une expression régulière de la bibliothèque Str de Caml (voir aussi éventuellement l'exemple du poly).

Cette bibliothèque n'est pas disponible par défaut, il faut l'ajouter explicitement à l'édition de liens, donc on compile par les commandes suivantes :
# ocamllex url.mll
# ocamlc -o url str.cma url.cmo
Le Makefile donné fait cela pour vous.
Voir la solution, si besoin est.



Ce document a été traduit de LATEX par HEVEA.