|
Université Paris 6 Licence d'informatique Maîtrise de Sciences et Techniques (Experts en Systèmes Informatiques) |
Module de Programmation Année 1999-2000 |
|---|
<decl> :: = let <nom> = <expr>;;où
<expr> désigne n'importe quelle expression. Un <nom>
est une séquence ininterrompue de lettres de l'alphabet.
Les expressions sont définies par la grammaire suivante au format BNF
(Bachus Naur Form):
<expr> ::= if <expr> then <expr> else <expr>
| let <nom> = <expr> in <expr>
| function <nom> -> <expr>
| rec <nom> <nom> = <expr>
| <expr> <expr>
| ( <expr> )
| <expr>,<expr>
| fst <expr>
| snd <expr>
| <nom>
| i
| true | false
| <expr> <op> <expr>
| <infix> <expr>
<op> ::= + | - | * | / | < | > | <= | >= | != | =
<infix>::= -
Une expression peut être une expression conditionnelle (if), une
déclaration locale (let), une fonction, une fonction récursive,
une application de fonction, une expression entre parenthèses, une
paire de deux expressions, un accès à la première composante d'une
paire (fst), un accès à la deuxième (snd), une
variable (nom), une constante entière (i), un booléen
(true et false), une expression
arithmétique infixe ou une expression arithmétique préfixe.
let f =
function x -> function y -> if y = x then let x = 2 in x+y else 3;;
let resultat = f 2 3;;
let rec fact x = if x = 0 then 1 else x * (fact (x-1));;
let app f g x = f (g x);;
type decl = ... and expr = ... and immediat = .. and localisation = ... and typ = ... and var_type = ... and schema_de_type = ...Cette partie définit les déclarations, les expressions, les valeurs dites immédiates (entiers, booléens), une information donnant la position de l'expression analysée dans le fichier source, les types du langage, les variables de type et les schémas de type. Ce module vous est donné.
global déclarant l'environnement de typage global ainsi qu'une
exception qui sera levée lorsqu'une erreur est survenue lors de l'analyse du
programme (erreur de syntaxe ou erreur de typage).exception Erreur;; value env_global : (string * schema_de_type) list ref;; value ajout_global : (string * schema_de_type) list -> unit;; value env_global : unit -> (string * schema_de_type) list;;Ce module vous est donné.
lexing du manuel de référence de Caml Light
(page 151).lire_decl_chaine : string -> decl lire_expr_chaine : string -> expr lire_decl : lexing__lexbuf -> declCette partie vous est donnée.
subst_type dans la suite du
texte. Par exemple, les deux types:
exception Unification;; value reinit_var_de_type : unit -> unit;; value gen_var_type : unit -> var_type;; value vars : var_type list -> var_type list -> typ -> var_type list;; value var_libres : typ -> var_type list;; value var_libres_env : (string * schema_de_type) list -> var_type list;; value substituer : (var_type * typ) list -> typ -> typ;; value unifier : (var_type * typ) list -> typ -> typ -> (var_type * typ) list;; value generaliser : (string * schema_de_type) list -> typ * (var_type * typ) list -> schema_de_type;; value instancier : schema_de_type -> typ;;La fonction
gen_var_type rend une nouvelle variable de type et
reinit_var_de_type permet d'initialiser cette fonction.substituer subst_type t où subst_type est une
substitution de type (associant des types à des variables de type) et
t, un type, rend un type t' déduit de t en
remplaçant les variables de t figurant dans subst_type
par les types qui leur sont associés.unifier subst_type t1 t2, où subst_type est une
substitution de type, t1 et t2 sont des types, rend une
nouvelle substitution subst_type' telle que
substituer subst_type' t1 = substituer subst_type' t2.
Lorsque les deux types ne sont pas unifiables, l'exception
Unification est levée.
value unifier_exp :
(var_type * typ) list -> expr -> typ -> typ -> (var_type * typ) list;;
value typer :
(string * schema_de_type) list -> (var_type * typ) list
-> expr -> typ * (var_type * typ) list;;
value typer_decl : decl -> unit;;
unifier_exp subst_type e typ_obtenu typ_attendu unifie le type
typ_obtenu pour l'expression e avec le type
typ_attendu. Si l'unification a échoué (l'exception
Unification a été levée), cette fonction devra émettre un
message d'erreur approprié.typer env_de_type subst_type e rend le type obtenu pour
l'expression e ainsi qu'une nouvelle substitution de type (on
peut en effet supposer que le typage de e a fait apparaitre de
nouvelles contraintes de type). Elle est paramétrée par un
environnement de type env_type (associant des schémas de type
aux variables du
programme) et subst_type. typer_decl s'occupe du typage des déclarations: cette fonction
type une déclaration, modifie l'environnement global et affiche le
type obtenu.initialiser_localisation : string -> in_channel -> lexing__lexbuf -> unit afficher_source : syntaxe_abstraite__localisation -> unit
initialiser_localisation fichier ic lexbuf permet d'initialiser
les fonctions du module: fichier est le nom du fichier dans
lequel se trouvent les déclarations, ic est son descripteur de
fichier (voir page 126 du manuel Caml Light), lexbuf est un
buffer lexical. Cette fonction doit impérativement être
exécutée avant d'utiliser la fonction afficher_source sur un
programme écrit dans un fichier.afficher_source loc permet d'afficher une partie du code source
autour de la localisation loc.
value erreur_de_syntaxe : localisation -> unit;;
value erreur_identificateur : localisation -> string -> unit;;
value erreur_de_type :
localisation -> typ -> typ -> unit;;
erreur_de_syntaxe loc traite des erreurs de syntaxe.
erreur_identificateur loc x indique que x n'est pas
déclaré en montrant la ligne concernée.
erreur_de_type loc ty_obtenu ty_attendu indique que le type
obtenu n'est pas unifiable avec le type attendu.main_decl : unit -> unit main_string : string -> unitCe module est à écrire.
main_decl lance l'analyse syntaxique et le typage
de la suite des déclarations apparaissant dans un fichier. Les
déclarations sont analysées les unes après les autres. L'analyse
d'un fichier s'arrête dès que l'analyse d'une déclaration échoue.typer et
main. Dans un
premier temps, vous considèrerez que les expressions ne sont pas
polymorphes (elles ne contiennent pas de variables de type). Vous
traiterez ensuite le cas général. Pour cela, vous
devrez développer votre implantation à l'aide d'un Makefile et
de manière interactive en vérifiant qu'à chaque étape, la succession
des étapes élémentaires est correcte.Non_implante pourra être levée.1 + 3 est vue comme une double application de la
variable + à la constante 1 puis à la constante
3.if c then e1 else e2 est bien typée si c est un booléen
et si e1 et e2 sont de même type.
(string * schema_de_type) listQuestion 4
typer et la fonction principale dans le module
main. Il faudra pour cela ouvrir le fichier en lecture, lancer
l'analyse syntaxique puis le typage et enfin, mettre à jour
l'environnement de type global.
typer pour qu'elle traite les
expressions ayant des types polymorphes. fst et snd dont le
type est polymorphe.
env_type est:
fst et
snd ainsi que le traitement des expressions arithmétiques en remarquant
qu'il suffit, pour les typer, de charger un environnement initial
donnant le schéma de type associé à chaque opérateur arithmétique. Par
exemple:
+ : Tpour_tout([],Tfleche(int,Tfleche(int,int)))Indication: L'ensemble de ces déclarations pourra être rassemblé dans un module d'initialisation.
typer complète peut
être écrite en moins de 100 lignes.
/Infos/caml-ens/99-00/tp2.
Vous y trouverez un fichier LISEZMOI qui décrit les différents
fichiers ainsi qu'un Makefile donnant l'architecture générale de
l'évaluateur. Ce fichier est à modifier suivant vos besoin. Enfin, le
fichier exemples.txt vous donne quelques exemples de programmes du
langage et le résultat rendu par le typage.typer qui prend en entrée un
fichier fichier.mml et qui affiche sur la sortie standard le
résultat du typage.
Ce document a été traduit de LATEX par HEVEA.