X O X X O O. Une partie de morpion est donc représentée par une chaîne de caractères. Par exemple, la partie ci-dessus est codée par "c1b3a1b1b2c3a3".

Documents pareils
modules & compilation

Machines virtuelles fonctionnelles (suite) Compilation ML Java

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

Classes et Objets en Ocaml.

Cours de Programmation 2

Algorithmique et Programmation, IMA

Correction Code nécessaire à la compilation : let bs ="\\" let nl = "\n" ;; let appliquer = List.map ;; (* affichage d'un noeud *)

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Représentation d un entier en base b

Chap 4: Analyse syntaxique. Prof. M.D. RAHMANI Compilation SMI- S5 2013/14 1

Les chaînes de caractères

Recherche dans un tableau

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

OCL - Object Constraint Language

Cours 1 : La compilation

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Présentation du langage et premières fonctions

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Vérification de programmes et de preuves Première partie. décrire des algorithmes

Licence Sciences et Technologies Examen janvier 2010

Cours d initiation à la programmation en C++ Johann Cuenin

Les structures de données. Rajae El Ouazzani

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

1. Structure d'un programme FORTRAN 95

STAGE IREM 0- Premiers pas en Python

Initiation à la programmation en Python

Cours No 3 : Identificateurs, Fonctions, Premières Structures de contrôle.

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

TP 1. Prise en main du langage Python

MATLAB : COMMANDES DE BASE. Note : lorsqu applicable, l équivalent en langage C est indiqué entre les délimiteurs /* */.

Conventions d écriture et outils de mise au point

Calcul matriciel. Définition 1 Une matrice de format (m,n) est un tableau rectangulaire de mn éléments, rangés en m lignes et n colonnes.

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

TP1 : Initiation à Java et Eclipse

TD3: tableaux avancées, première classe et chaînes

Langage SQL (1) 4 septembre IUT Orléans. Introduction Le langage SQL : données Le langage SQL : requêtes

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Introduction à MATLAB R

Conversion d un entier. Méthode par soustraction


Plan du cours : Zippers. Des fonctions sur les listes avec position. Des fonctions sur les listes avec position

Programmation en Java IUT GEII (MC-II1) 1

Utilisation d objets : String et ArrayList

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Programmer en JAVA. par Tama

INF 321 : mémento de la syntaxe de Java

Une dérivation du paradigme de réécriture de multiensembles pour l'architecture de processeur graphique GPU

Langage propre à Oracle basé sur ADA. Offre une extension procédurale à SQL

Définition 0,752 = 0,7 + 0,05 + 0,002 SYSTÈMES DE NUMÉRATION POSITIONNELS =

Initiation à l algorithmique

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Informatique Générale

Cours d algorithmique pour la classe de 2nde

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Programme Compte bancaire (code)

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Projet de programmation (IK3) : TP n 1 Correction

PROJET ALGORITHMIQUE ET PROGRAMMATION II

Plan du cours. Historique du langage Nouveautés de Java 7

Rappels Entrées -Sorties

Génie Logiciel avec Ada. 4 février 2013

Package Java.util Classe générique

Exercice 6 Associer chaque expression de gauche à sa forme réduite (à droite) :

TP3 : Manipulation et implantation de systèmes de fichiers 1

Java Licence Professionnelle CISII,

Corrigé des TD 1 à 5

introduction Chapitre 5 Récursivité Exemples mathématiques Fonction factorielle ø est un arbre (vide) Images récursives

Module 16 : Les fonctions de recherche et de référence

Arithmétique binaire. Chapitre. 5.1 Notions Bit Mot

Expression des contraintes. OCL : Object C o n t r a i n t L a n g u a g e

Les processus 2/54. Qu est-ce qu un processus? 3(6)/54. Se souvenir 1(1)/54. Le système de fichiers (exemple du disque dur)

Le prototype de la fonction main()

INF 232: Langages et Automates. Travaux Dirigés. Université Joseph Fourier, Université Grenoble 1 Licence Sciences et Technologies

Découverte de Python

STS SE. FreeRTOS. Programmation réseau WIFI. Programmation réseau. Socket Tcp. FlyPort smart Wi-Fi module

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Claude Delannoy. 3 e édition C++

Principes des langages de programmation INF 321. Eric Goubault

Cours Informatique Master STEP

Chapitre 1 I:\ Soyez courageux!

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Compléments de documentation Scilab : affichage de texte et formatage de nombres

Premiers Pas en Programmation Objet : les Classes et les Objets

Chapitre 10. Les interfaces Comparable et Comparator 1

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Rappels d architecture

Le langage SQL Rappels

IMAGES NUMÉRIQUES MATRICIELLES EN SCILAB

Résolution d équations non linéaires

Algorithmique et programmation : les bases (VBA) Corrigé

Génie Logiciel I. Cours VI - Typage statique / dynamique, fonctions virtuelles et classes abstraites, flots d entrées / sorties, et string

Tp 1 correction. Structures de données (IF2)

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Enseignement secondaire technique

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Transcription:

LFG - Ocaml - Exercices ATTENTION: En Ocaml, pour pouvoir utiliser le type stream, il faut charger le module approprié: #load "camlp4o.cma" ;; La fonction de conversion: Stream.of string : string -> char Stream.t Exercice 1 On donne la grammaire E T + E T, T a (E). Débrouillez-vous pour obtenir une grammaire LL(1). Ecrire un analyseur pour cette grammaire qui retourne un élément du type expr suivant type expr = A Plus of expr*expr ;; Exercice 2 Le jeu de morpion est un jeu entre deux joueurs appelés et O. commence le jeu en mettant un dans une des cases d un quadrillage de dimension 3 3 et c est le tour de O de mettre un O dans une des cases restantes. Ensuite c est le tour de et ainsi de suite. Le but de chaque joueur est d être le premier à établir une ligne ou une colonne ou une diagonale de trois cases contenant sa lettre. Celui qui réussit est déclaré gagnant. Voici un exemple d une partie de morpion où gagne. (1) (2) O (3) O (4) O O (5) O O (6) O O O (7) O O O gagne Notation du jeu de MORPION Dans plusieurs jeux de société, les joueurs sérieux se servent d une notation permettant de garder l historique d une partie pour pouvoir analyser le jeu plus tard ou le publier. C est surtout le cas du jeu d échecs. Voici une notation permettant de noter une partie de morpion: On donne un nom à chaque case a1 b1 c1 a2 b2 c2 a3 b3 c3 On écrit le nom de la case remplie à chaque coup. Une partie de morpion est donc représentée par une chaîne de caractères. Par exemple, la partie ci-dessus est codée par "c1b3a1b1b2c3a3". Une meilleure vision d un tel code est comme une suite de positions. Les facteurs gauches d un code sont des codes pour des positions antérieures. La chaîne vide, "" est le code pour la position initiale. Dans l exemple cidessus, la position (1) est codée par "c1", la position (2) par "c1b3",..., la position (7) par "c1b3a1b1b2c3a3". Le but de cet exercice est d écrire un programme Ocaml qui analyse une chaîne de caractères, supposée représenter une partie, ou suite de positions, de morpion, et d en extraire certaines informations, précisées dans la suite. 1

1. Définir une grammaire LL(1) qui engendre un langage permettant de coder les suites de positions du jeu de morpion. On se contentera d une grammaire qui permet de distinguer les coups de des coups de O et qui permet de distinguer le premier coup comme un coup de. Les terminaux seront les noms des cases. (Note: certains mots vont représenter des parties impossibles, sont trop longs ou contiennent des doublons. La grammaire ne permettra pas de distinguer le résultat d une partie.) 2. Ecrire un analyseur pour votre grammaire qui retourne un élément du type jeu suivant type jeu = J of coup list and coup = of string O of string ;; Par exemple, votre analyseur appliqué à la chaîne "c1b3a1b1b2c3a3" retournera - : jeu = J [ "c1"; O "b3"; "a1"; O "b1"; "b2"; O "c3"; "a3"]. 3. Ecrire une fonction appartient: a -> a list -> bool telle que l appel appartient e l teste si l élément e appartient à la liste l. 4. En utilisant la fonction appartient, écrire une fonction supprimer doublons: a list -> a list qui supprime les doublons dans une liste. 5. En utilisant la fonction supprimer doublons et la fonction List.length, écrire une fonction est valide: jeu -> bool qui teste si un élément du type jeu représente une partie de morpion valide. (Indice: quel est le résultat de l appel supprimer doublons l si l ne contient pas de doublon?). 6. Il y a trois lignes, trois colonnes et deux diagonales dans un quadrillage de dimension 3 3, donc il y a huit conditions à vérifier pour voir si a gagné une partie. Ecrire une fonction test victoire : jeu -> bool qui teste si a gagné une partie de morpion et une fonction test victoire O: jeu -> bool qui teste si O a gagné une partie de morpion. En déduire une fonction gagnant: jeu -> unit qui affiche le gagnant d une partie de morpion, si la partie n est pas nulle. 7. Dans le pot, /home/etudold/=pot/lcin5u44/, vous trouverez le fichier afficher morpion.ml qui contient la fonction afficher jeu : jeu -> unit qui permet d afficher une partie de morpion. En vous servant de cette fonction et des fonctions précédantes, écrivez une fonction qui prend en entrée une chaîne de caractères représentant une partie de morpion et qui affiche la partie. Exercice 3 La notation préfixée d une expression arithmétique consiste en l écriture de l expression avec l opérateur devant ses arguments. Par exemple, l addition de 3 et 4 s ecrit +34. Dans cet exercice nous considérons l analyse des expressions arithmétiques données en notation préfixée où les opérateurs sont +,,, / et seuls les nombres de 0 à 9 apparaissent. 1. Donner une grammaire pour les expressions arithmétiques en notation préfixée décrites ci-dessus. 2. Ecrire un analyseur pour cette grammaire qui retourne un élément du type arbre suivant type arbre = V B of arbre*string*arbre ;; Par exemple, l expression +34 sera convertie en B (B (V, "3", V), "+", B (V, "4", V)). On vous rappelle la fonction Char.escaped: char -> string qui transforme un caractère en une chaîne de caractères. 3. Ecrire une fonction valeur: arbre -> float qui évalue un élément de type arbre. Tester vos fonctions avec let test_string = "/*+32-41-7*/-+43-433/42" ;; Exercice 4 Le but de cet exercice est d écrire un analyseur qui reconnaît la table de transitions d un automate où l état initial est noté i; les états finaux sont notés f0, f1,... ; les autres états sont notés s0, s1,... ; les éléments du vocabulaire sont notés v0, v1,... ; le mot vide est noté mv; les transitions sont notés en utilisant. et =. Par exemple, s0.v0=s1 ou i.v6=f2. Ainsi, i.v0=s1 s1.v0=f2 s1.v1=i est un automate correcte. 1. Ecrire une grammaire appropriée pour les automates. 2

2. Ecrire l analyseur. L entrée sera de type string et retournera un élément de type automate, qui est défini par type automate = A of transition list and transition = T of etat*vocabulaire*etat and vocabulaire = V of int Mv and etat = I S of int F of int ;; Par exemple, l automate "i.v0=s1 s1.v0=f2 s1.v1=i" retournera - : automate = A [T (I, V 0, S 1); T (S 1, V 0, F 2); T (S 1, V 1, I)] Il sera utile d incorporer la fonction nettoyage suivante qui enlève les espaces, les tabulations et les retours à la ligne d un stream. let rec nettoyage = parser [< \t \n ; l = (nettoyage) >] -> l [< x; l = (nettoyage) >] -> [< x; l >] [< >] -> [< >] ;; 3

Exercice 5 En effectuant l analyse LALR pour la grammaire ab, on obtient la table a b # s 0 s 1 s 2 s 1 succès s 2 s 3 s 2 s 3 s 4 s 4 ab ab Le programme Ocaml suivant est un analyseur qui utilise cette table et retourne la dérivation d un mot donné en entrée. (Vous trouverez ce programme dans le pot - dans le fichier ab.lalr.ml ). La fonction principale est la fonction g qui modélise l analyse ascendante décrite en cours. Les arguments de g sont a les actions. Ici, c est une liste de chaînes de caractères. Les réductions y sont ajoutées en forme de chaînes de caractères. A la fin on retourne a. p la pile. En effet, on n a besoin que des états de l automate dans cette pile, sans les caractères, car toute l information nécessaire figure dans les réductions. Ici, la pile est représentée par une liste. Les états sont écrits dans l ordre inverse de celui des notes du cours, c.à.d. les nouvels états sont ajoutés en tête de la liste. m le mot à analyser. La fonction auxiliaire reste permet d enlever le premier caractère du mot. (* Fonction auxiliaire *) let reste s = String.sub s 1 (String.length s - 1) ;; (* Transitions pour les non-terminaux *) let t s x = match (s,x) with "s0","" -> "s1" "s2","" -> "s3" _ -> "Echec";; Analyseur pour la grammaire ab (* Implementation de la table LR *) let analyser s = let rec g a p m = match p with "s0"::p when m.[0] = a -> g a ("s2"::"s0"::p) (reste m) "s0"::p when m.[0] = # -> g ("->^"::a) ("s1"::"s0"::p) m "s1"::_ when m.[0] = # -> a "s2"::p when m.[0] = a -> g a ("s2"::"s2"::p) (reste m) "s2"::p when m.[0] = b -> g ("->^"::a) ("s3"::"s2"::p) m "s3"::p when m.[0] = b -> g a ("s4"::"s3"::p) (reste m) "s4"::_::_::s::p when m.[0] = b or m.[0] = # -> g ("->ab"::a) ((t s "")::s::p) m _ -> "Echec "::m::". Analyse partielle:"::a in g [] ["s0"] (s^"#") ;; analyser "aabb";; - : string list = ["->ab"; "->ab"; "->^"] 1. Trouvez la table d analyse LALR pour la grammaire ab. 2. Etudiez le programme ci-dessus et en vous inspirant, écrivez un analyseur LALR pour la grammaire ab. 4

Exercice 6 La notation postfixée d une expression arithmétique consiste en l écriture de l expression avec l opérateur après ses arguments. Par exemple, l addition de 1 et 1 s ecrit 11+. Dans cet exercice nous considérons l analyse des expressions arithmétiques données en notation postfixée où seuls l opérateur + et le nombre 1 apparaissent. 1. Donner une grammaire pour les expressions arithmétiques en notation postfixée décrites ci-dessus. 2. Ecrire un analyseur LALR (programme Ocaml) pour cette grammaire (dans le même style que l exercice précédent). 5

Solutions Exercice 1 : Solution type expr = A Plus of expr * expr ;; let rec axiome = parser [< res_e = (e); # >] -> res_e and e = parser [< res_t = (t); res_eprime = (eprime) >] -> res_eprime res_t and eprime = parser [< + ; res_e = (e) >] -> (function x -> Plus (x, res_e)) [< >] -> (function x -> x) and t = parser [< ( ; res_e = (e); ) >] -> res_e [< a >] -> A ;; val e : char Stream.t -> expr = <fun> val eprime : char Stream.t -> expr -> expr = <fun> val t : char Stream.t -> expr = <fun> let convertir s = axiome (Stream.of_string s) ;; val convertir : string -> expr = <fun> convertir "a#" ;; - : expr = A convertir "a+a#" ;; - : expr = Plus (A, A) convertir "a+(a+a)#" ;; - : expr = Plus (A, Plus (A, A)) convertir "(a+a)+(a+a)#" ;; - : expr = Plus (Plus (A, A), Plus (A, A)) convertir "aa+a#" ;; Exception: Stream.Error "". Exercice 2 : Solution Question 1 J -> -> C O ^ O -> C ^ C -> L N L -> a b c N -> 1 2 3 Question 2 type jeu = J of coup list and coup = of string O of string ;; let rec j = parser [< res_x = (x) >] -> J res_x and x = parser [< res_c = (c) ; res_o = (o) >] -> ( res_c) :: res_o [< >] -> [] and o = parser [< res_c = (c) ; res_x = (x) >] -> (O res_c) :: res_x [< >] -> [] 6

and c = parser [< a.. c as lettre ; 1.. 3 as chiffre >] -> (Char.escaped lettre) ^ (Char.escaped chiffre) ;; Question 3 let rec appartient e = function [] -> false h::t -> h=e or appartient e t ;; Question 4 let rec supprimer_doublons = function l -> match l with [] -> [] t::q -> if appartient t q then supprimer_doublons q else t::(supprimer_doublons q) ;; Question 5 let est_valide (J l) = let rec cases = function [] -> [] ( s)::q -> s::(cases q) (O s)::q -> s::(cases q) in let cl = cases l in (cl = supprimer_doublons cl) or (List.length cl > 9) ;; Question 6 let test_victoire_ = function (J l) -> ((appartient ( "a1") l) & (appartient ( "b1") l) & (appartient ( "c1") l)) or ((appartient ( "a2") l) & (appartient ( "b2") l) & (appartient ( "c2") l)) or ((appartient ( "a3") l) & (appartient ( "b3") l) & (appartient ( "c3") l)) or ((appartient ( "a1") l) & (appartient ( "a2") l) & (appartient ( "a3") l)) or ((appartient ( "b1") l) & (appartient ( "b2") l) & (appartient ( "b3") l)) or ((appartient ( "c1") l) & (appartient ( "c2") l) & (appartient ( "c3") l)) or ((appartient ( "a1") l) & (appartient ( "b2") l) & (appartient ( "c3") l)) or ((appartient ( "a3") l) & (appartient ( "b2") l) & (appartient ( "c1") l)) ;; let test_victoire_o = function (J l) -> ((appartient (O "a1") l) & (appartient (O "b1") l) & (appartient (O "c1") l)) or ((appartient (O "a2") l) & (appartient (O "b2") l) & (appartient (O "c2") l)) or ((appartient (O "a3") l) & (appartient (O "b3") l) & (appartient (O "c3") l)) or ((appartient (O "a1") l) & (appartient (O "a2") l) & (appartient (O "a3") l)) or ((appartient (O "b1") l) & (appartient (O "b2") l) & (appartient (O "b3") l)) or ((appartient (O "c1") l) & (appartient (O "c2") l) & (appartient (O "c3") l)) or ((appartient (O "a1") l) & (appartient (O "b2") l) & (appartient (O "c3") l)) or ((appartient (O "a3") l) & (appartient (O "b2") l) & (appartient (O "c1") l)) ;; let gagnant jj = if test_victoire_ jj then print_string " gagne\n\n\n" else if test_victoire_o jj then print_string " O gagne\n\n\n" else print_string " Match Nul\n\n\n" ;; Question 7 let morpion s = let rs = j (Stream.of_string s) in if est_valide rs then (afficher_jeu rs ; gagnant rs) else failwith "jeu non valide" ;; L appel morpion "c1b3a1b1b2c3a3" ;; retourne 7

================= - - - - - - - - ================= - - - - - - O - ================= - - - - - O - ================= O - - - - O - ================= O - - - O - ================= O - - - O O ================= O - - O O ================= gagne - : unit = () Le programme: type jeu = J of coup list and coup = of string O of string ;; let rec j = parser [< res_x = (x) >] -> J res_x and x = parser [< res_c = (c) ; res_o = (o) >] -> ( res_c) :: res_o [< >] -> [] and o = parser [< res_c = (c) ; res_x = (x) >] -> (O res_c) :: res_x [< >] -> [] and c = parser [< a.. c as lettre ; 1.. 3 as chiffre >] -> (Char.escaped lettre) ^ (Char.escaped chiffre) ;; let rec appartient e = function [] -> false h::t -> h=e or appartient e t ;; let rec supprimer_doublons = function l -> match l with [] -> [] t::q -> if appartient t q then supprimer_doublons q else t::(supprimer_doublons q) ;; let est_valide (J l) = let rec cases = function 8

[] -> [] ( s)::q -> s::(cases q) (O s)::q -> s::(cases q) in let cl = cases l in (cl = supprimer_doublons cl) or (List.length cl > 9) ;; let test_victoire_ = function (J l) -> ((appartient ( "a1") l) & (appartient ( "b1") l) & (appartient ( "c1") l)) or ((appartient ( "a2") l) & (appartient ( "b2") l) & (appartient ( "c2") l)) or ((appartient ( "a3") l) & (appartient ( "b3") l) & (appartient ( "c3") l)) or ((appartient ( "a1") l) & (appartient ( "a2") l) & (appartient ( "a3") l)) or ((appartient ( "b1") l) & (appartient ( "b2") l) & (appartient ( "b3") l)) or ((appartient ( "c1") l) & (appartient ( "c2") l) & (appartient ( "c3") l)) or ((appartient ( "a1") l) & (appartient ( "b2") l) & (appartient ( "c3") l)) or ((appartient ( "a3") l) & (appartient ( "b2") l) & (appartient ( "c1") l)) ;; let test_victoire_o = function (J l) -> ((appartient (O "a1") l) & (appartient (O "b1") l) & (appartient (O "c1") l)) or ((appartient (O "a2") l) & (appartient (O "b2") l) & (appartient (O "c2") l)) or ((appartient (O "a3") l) & (appartient (O "b3") l) & (appartient (O "c3") l)) or ((appartient (O "a1") l) & (appartient (O "a2") l) & (appartient (O "a3") l)) or ((appartient (O "b1") l) & (appartient (O "b2") l) & (appartient (O "b3") l)) or ((appartient (O "c1") l) & (appartient (O "c2") l) & (appartient (O "c3") l)) or ((appartient (O "a1") l) & (appartient (O "b2") l) & (appartient (O "c3") l)) or ((appartient (O "a3") l) & (appartient (O "b2") l) & (appartient (O "c1") l)) ;; let gagnant jj = if test_victoire_ jj then print_string " gagne\n\n\n" else if test_victoire_o jj then print_string " O gagne\n\n\n" else print_string " Match Nul\n\n\n" ;; let rec afficher_jeu (J l) = let rec aff_j = let maj jj = let rec chf = let modify f e r = function x -> if x=e then r else f x in function J [] -> (function _ -> "-") J (( s)::t) -> modify (chf (J t)) s "" J ((O s)::t) -> modify (chf (J t)) s "O" and p0 = [ "a1"; "b1"; "c1"; "a2"; "b2"; "c2"; "a3"; "b3"; "c3" ] in List.map (chf jj) p0 and aff_p = function a::b::c::d::e::f::g::h::i::[] -> print_string ("\n"^a^"\t"^b^"\t"^c^ "\n"^d^"\t"^e^"\t"^f^ "\n"^g^"\t"^h^"\t"^i^ "\n=================") _ -> failwith "jeu impossible" in function J [] -> print_string "\n=================" J (h::t) -> (aff_j (J t); aff_p (maj (J (h::t)) )) in aff_j (J (List.rev l)) ;; let test_jeu = "c1b3a1b1b2c3a3" ;; let morpion s = let rs = j (Stream.of_string s) in if est_valide rs then (afficher_jeu rs ; gagnant rs) 9

else failwith "jeu non valide" ;; morpion test_jeu ;; Exercice 3 : Solution 1. E -> O E E F O -> + - * / F-> 0... 9 2. let rec arith = parser [< ro = (o); ra1 = (arith); ra2 = (arith) >] -> ro (ra1,ra2) [< res_f = (f) >] -> res_f and o = parser [< + >] -> (function (x,y) -> B (x, "+", y)) [< - >] -> (function (x,y) -> B (x, "-", y)) [< * >] -> (function (x,y) -> B (x, "*", y)) [< / >] -> (function (x,y) -> B (x, "/", y)) and f = parser [< 0.. 9 as chiffre >] -> B (V, Char.escaped chiffre, V) ;; val arith : char Stream.t -> arbre = <fun> val o : char Stream.t -> arbre * arbre -> arbre = <fun> val f : char Stream.t -> arbre = <fun> 3. let rec valeur e = match e with B (x,"+",y) -> (valeur x) +. (valeur y) B (x,"-",y) -> (valeur x) -. (valeur y) B (x,"*",y) -> (valeur x) *. (valeur y) B (x,"/",y) -> (valeur x) /. (valeur y) B (_,r,_) -> float_of_string r ;; val valeur : arbre -> float = <fun> let convert s = arith (Stream.of_string s) ;; val convert : string -> arbre = <fun> let test_string = "/*+32-41-7*/-+43-433/42" ;; let cts = convert test_string ;; val cts : arbre = B (B (B (B (V, "3", V), "+", B (V, "2", V)), "*", B (B (V, "4", V), "-", B (V, "1", V))), "/", B (B (V, "7", V), "-", B (B (B (B (B (V, "4", V), "+", B (V, "3", V)), "-", B (B (V, "4", V), "-", B (V, "3", V))), "/", B (V, "3", V)), "*", B (B (V, "4", V), "/", B (V, "2", V))))) let v = valeur cts ;; val v : float = 5. 10

Exercice 4 : Solution 1. La grammaire: A -> T T A T -> E. V = E E -> i s N f N V -> v N mv N -> 0 1 N1... 9 N1 N1 -> ^ 0 N1 1 N1... 9 N1 2. L analyseur: let rec nettoyage = parser [< \t \n ; l = (nettoyage) >] -> l [< x; l = (nettoyage) >] -> [< x; l >] [< >] -> [< >] ;; val nettoyage : char Stream.t -> char Stream.t = <fun> let rec aut = parser [< res_a = (a) >] -> A res_a and a = parser [< res_t = (t); res_a_1 = (a_1) >] -> res_t :: res_a_1 and a_1 = parser [< res_a = (a) >] -> res_a [< >] -> [] and t = parser [< res_e1 = (e);. ; res_v = (v); = ; res_e2 = (e); ; >] -> T (res_e1, res_v, res_e2) and e = parser [< i >] -> I [< s ; res_n = (n) >] -> S res_n [< f ; res_n = (n) >] -> F res_n and v = parser [< m ; v >] -> Mv [< v ; res_n = (n) >] -> V res_n and n = parser [< 1.. 9 as digit; res_n_1 = (n_1) >] -> int_of_string ((Char.escaped digit)^res_n_1) [< 0 >] -> 0 and n_1 = parser [< 0.. 9 as digit; res_n_1 = (n_1) >] -> ((Char.escaped digit)^res_n_1) [< >] -> "" ;; val aut : char Stream.t -> automate = <fun> val a : char Stream.t -> transition list = <fun> val a_1 : char Stream.t -> transition list = <fun> val t : char Stream.t -> transition = <fun> val e : char Stream.t -> etat = <fun> val v : char Stream.t -> vocabulaire = <fun> val n : char Stream.t -> int = <fun> val n_1 : char Stream.t -> string = <fun> let automaton s = aut (nettoyage (Stream.of_string s)) ;; val automaton : string -> automate = <fun> automaton " i.v0=s1 s1.v0=f2 s1.v1=i 11

" ;; - : automate = A [T (I, V 0, S 1); T (S 1, V 0, F 2); T (S 1, V 1, I)] Exercice 5 : Solution (* Fonction auxiliaire *) let reste s = String.sub s 1 (String.length s - 1) ;; (* Transitions - non-terminaux *) let t s x = match (s,x) with "s4","" -> "s5" "s2","" -> "s3" "s0","" -> "s1" _ -> "" ;; (* Implementation de la table LR *) let analyser s = let rec g a p m = match p with "s0"::p when m.[0] = # -> g (" -> mv"::a) ((t "s0" "")::"s0"::p) m "s0"::p when m.[0] = a -> g a ("s2"::"s0"::p) (reste m) "s1"::_ when m.[0] = # -> a "s2"::p when m.[0] = a -> g a ("s2"::"s2"::p) (reste m) "s2"::p when m.[0] = b -> g (" -> mv"::a) ((t "s2" "")::"s2"::p) m "s3"::p when m.[0] = b -> g a ("s4"::"s3"::p) (reste m) "s4"::p when m.[0] = # -> g (" -> mv"::a) ((t "s4" "")::"s4"::p) m "s4"::p when m.[0] = a -> g a ("s2"::"s4"::p) (reste m) "s4"::p when m.[0] = b -> g (" -> mv"::a) ((t "s4" "")::"s4"::p) m "s5"::_::_::_::s::p when m.[0] = # -> g (" -> ab"::a) ((t s "")::s::p) m "s5"::_::_::_::s::p when m.[0] = b -> g (" -> ab"::a) ((t s "")::s::p) m _ -> failwith "probleme du mot" in g [] ["s0"] (s^"#") ;; analyser "aaabbabbab" ;; - : string list = [" -> ab"; " -> ab"; " -> mv"; " -> mv"; " -> ab"; " -> ab"; " -> mv"; " -> mv"; " -> ab"; " -> mv"; " -> mv"] Exercice 6 : Solution 1. E -> E E O F O -> + F-> 1 2. 12