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 :
- H1 pour un titre;
- P pour un paragraphe;
- B pour une phrase en caractères gras;
- Font pour une phrase avec une fonte particulière.
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:
Cours de programmation fonctionnelle
Ce TP noté
est très facile
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 "Bonjour
";
print "à tous"
permettent d'écrire
Bonjour
à tous
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
et 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"]}]