Introduction à la programmation fonctionnelle

TP 5 (Noté)

Séance de TP du 8 avril 2016.
Il est à rendre par mail à votre chargé de TP (stefania.dumbrava@lri.fr ou ulysse.gerard@inria.fr) avant minuit.

Important: Vous devez tester vos fonctions et votre programme au fur et à mesure.

Manipulation de fichiers HTML

Le but de cette partie est de réaliser une petite bibliothèque de manipulation de fichiers HTML. Les fichiers (très simples) qui nous intéressent sont constitués de phrases encadrées par des balises ouvrantes et fermantes. Chaque balise contient le nom d'un tag et une liste d'attributs. Les attributs, qui sont constitués d'une clé et d'une valeur, ne sont pas spécifiés. Par contre, on suppose que les balises sont formées à partir des quatre tags suivants :

Pour simplifier, nous supposons que les balises ne sont pas imbriquées. On va représenter ces fichiers HTML à l'aide des types OCaml suivants:

type t_tag = H1 | B | P | Font type t_balise = { tag : t_tag; attributs : (string * string) list } type phrase = { balise : t_balise; mots : string list } type document = phrase list

Le type énuméré t_tag représente les quatre tags H1, B, P et Font. Les balises sont représentées par des valeurs de type t_balise qui, en plus d'un tag, contiennent une liste de paires de chaînes de caractères pour représenter les attributs. Le type phrase est celui des phrases encadrées par des balises. Il contient un champ balise contenant la balise ainsi qu'un champ mots contenant la liste des mots de la phrase. Enfin, le type document permet de modéliser un fichier comme une liste de phrases. Par exemple, la liste f suivante :

let f = [ { balise = { tag = H1; attributs = ["align","center"]}; mots = ["Cours"; "de"; "programmation"; "fonctionnelle"] }; { balise = { tag = B; attributs = []}; mots = ["Ce"; "TP"; "noté"] }; { balise = { tag = P; attributs = []}; mots = [] }; { balise = { tag = Font; attributs = ["color","blue"]}; mots = ["est"; "très"; "facile!"] }; ] représente un fichier HTML avec un titre (Cours de programmation fonctionnelle), une phrase en caractères gras (Ce TP noté), un paragraphe vide et une phrase de couleur bleue (est très facile!).

Le but des cinq premières questions est de convertir des valeurs de type document en fichiers textes dans le format HTML. Par exemple, la valeur f précédente sera convertie en un fichier texte dont le contenu sera:

<H1 align=center > Cours de programmation fonctionnelle </H1> <B> Ce TP noté </B> <P> </P> <Font color=blue> est très facile </Font>

Pour cela, on se donne une fonction print : string -> unit permettant d'écrire une chaîne de caractères à la fin d'un fichier HTML dont le nom est passé sur la ligne de commande au moment de l'appel à votre programme (il n'est donc pas nécessaire de le passer en argument à cette fonction).

Le code de cette fonction est le suivant :

let cout = open_out (Sys.argv.(1)) let print s = output_string cout s

Ainsi, par exemple, les deux appels successifs suivants:

print "<H1>Bonjour</H1>"; print "<B>à tous</B>" permettent d'écrire <H1>Bonjour</H1><B>à tous</B> dans le fichier HTML.

Question 1

Écrire une fonction string_of_tag de type tag -> string qui renvoie la chaîne de caractères correspondante à un tag. Par exemple, string_of_tag H1 doit renvoyer la chaîne de caractères "H1".

Question 2

À l'aide de la fonction print, écrire une fonction ecrire_attributs de type (string * string) list -> unit qui écrit dans le fichier une liste d'attributs au format HTML en les séparant par un caractère espace.

Par exemple, ecrire_attributs [("a1","v1"); ("a2","v2")] doit écrire

a1=v1 a2=v2 dans le fichier HTML.

Question 3

À l'aide des fonctions précédentes, écrire deux fonctions ecrire_balise_ouvrante et ecrire_balise_fermante de type balise -> unit, qui écrivent respectivement la balise ouvrante et la balise fermante d'une valeur de type balise au format HTML.

Par exemple, si b est la balise

{ tag = Font; attributs = [("color", "blue")]} alors ecrire_balise_ouvrante b et ecrire_balise_fermante b doivent écrire respectivement <Font color=blue> et </Font> dans le fichier HTML.

Question 4

Écrire une fonction ecrire_mots de type string list -> unit qui écrit dans le fichier HTML une liste de chaînes de caractères en séparant chaque chaîne par un espace.

Par exemple, ecrire_mots ["est"; "tres"; "facile"] doit écrire

est très facile dans le fichier HTML.

Question 5

À l'aide des fonctions précédentes, écrire une fonction ecrire_document de type document -> unit qui écrit une valeur de type document dans un fichier texte au format HTML.


On va maintenant s'intéresser à l'écriture de deux fonctions particulières: la première permet de changer le tag de certaines balises dans un document et la seconde de renverser l'ordre des phrases et des mots dans un document.

Question 6

Écrire une fonction change_tag de type tag -> tag -> phrase -> phrase telle que change_tag t1 t2 p change le tag de la balise de la phrase p par t2 si son tag est égal à t1

Question 7

En utilisant la fonction précédente, écrire une fonction change_B_en_P de type document -> document qui change toutes les balises B d'un document par des balises P.

Question 8

Écrire une fonction renverse : document -> document qui renverse un document. Par exemple, pour le document f décrit au début de cette section, renverse f produit le document suivant: [ {balise = {tag = Font; attributs = [("color", "blue")]}; mots = ["facile!"; "tres"; "est"]}; {balise = {tag = P; attributs = []}; mots = []}; {balise = {tag = B; attributs = []}; mots = ["noté"; "TP"; "Le"]}; {balise = {tag = H1; attributs = [("align", "center")]}; mots = ["fonctionnelle"; "programmation"; "de"; "TP"]}]