Réaliser un Compilateur Licence Informatique



Documents pareils
Cours 1 : La compilation

Machines virtuelles fonctionnelles (suite) Compilation ML Java

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

Cours de Programmation 2

Théorie de la Programmation

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Théorie des Langages

Logiciel Libre Cours 3 Fondements: Génie Logiciel

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

Évaluation et implémentation des langages

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

Les structures de données. Rajae El Ouazzani

Classes et Objets en Ocaml.

Arbres binaires de recherche

Définitions. Numéro à préciser. (Durée : )

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

Machines virtuelles Cours 1 : Introduction

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Initiation à l algorithmique

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

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

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

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Algorithmique et Programmation, IMA

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Architecture des ordinateurs TD1 - Portes logiques et premiers circuits

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

# 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>

Analyse de sécurité de logiciels système par typage statique

Grandes lignes ASTRÉE. Logiciels critiques. Outils de certification classiques. Inspection manuelle. Definition. Test

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

Informatique Théorique : Théorie des Langages, Analyse Lexicale, Analyse Syntaxique Jean-Pierre Jouannaud Professeur

Chapitre VI- La validation de la composition.

Solutions du chapitre 4

OCL - Object Constraint Language

Java Licence Professionnelle CISII,

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Cours 1 : Qu est-ce que la programmation?

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

Recherche dans un tableau

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

Anne Tasso. Java. Le livre de. premier langage. 10 e édition. Avec 109 exercices corrigés. Groupe Eyrolles, , ISBN :

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

UE C avancé cours 1: introduction et révisions

CH.6 Propriétés des langages non contextuels

Cours d algorithmique pour la classe de 2nde

Compilation (INF 564)

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


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

Algorithmique et programmation : les bases (VBA) Corrigé

Représentation d un entier en base b

Formula Negator, Outil de négation de formule.

Introduction à MATLAB R

Résolution de systèmes linéaires par des méthodes directes

Programmer en JAVA. par Tama

Licence Sciences et Technologies Examen janvier 2010

Jade. Projet Intelligence Artificielle «Devine à quoi je pense»

Gestion mémoire et Représentation intermédiaire

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

LES TYPES DE DONNÉES DU LANGAGE PASCAL

Examen Médian - 1 heure 30

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)

ACTIVITÉ DE PROGRAMMATION

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

Initiation. àl algorithmique et à la programmation. en C

Intelligence Artificielle et Systèmes Multi-Agents. Badr Benmammar

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

4. Utilisation d un SGBD : le langage SQL. 5. Normalisation

Présentation du langage et premières fonctions

L informatique en BCPST

Arithmétique binaire. Chapitre. 5.1 Notions Bit Mot

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

Cours d Algorithmique et de Langage C v 3.0

Cours de Master Recherche

Programmation C++ (débutant)/instructions for, while et do...while

Algorithmique des Systèmes Répartis Protocoles de Communications

Transmission d informations sur le réseau électrique

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

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Utilisation d objets : String et ArrayList

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

Déroulement. Evaluation. Préambule. Définition. Définition. Algorithmes et structures de données 28/09/2009

Quelques Algorithmes simples

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Rappels sur les suites - Algorithme

modules & compilation

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

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Logique binaire. Aujourd'hui, l'algèbre de Boole trouve de nombreuses applications en informatique et dans la conception des circuits électroniques.

Programmes des classes préparatoires aux Grandes Ecoles

Souad EL Bernoussi. Groupe d Analyse Numérique et Optimisation Rabat http ://

Algorithme. Table des matières

MATHÉMATIQUES. Les préalables pour l algèbre MAT-P020-1 DÉFINITION DU DOMAINE D EXAMEN

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

Introduction au langage C

Informatique Générale

Notions fondamentales du langage C# Version 1.0

Transcription:

Réaliser un Compilateur Licence Informatique Paul Feautrier ENS de Lyon Paul.Feautrier@ens-lyon.fr perso.ens-lyon.fr/paul.feautrier 28 janvier 2009 1 / 49

GENERALITES 2 / 49

A quoi sert un compilateur Un ordinateur exécute du code binaire Les programmeurs veulent un langage de haut niveau : clarté, mnémotechnie, compacité redondance (permet les vérifications) proximité avec les usages (mathématique, transactionnel, schématique, etc) Il faut une traduction, et donc un programme traducteur. 3 / 49

Pourquoi un projet de compilation? C est un sujet de recherche actif, parce que les processeurs modernes devienenent de plus en plus complexes, et demandent des compilateurs de plus en plus sophistiqués. En particulier les processeurs Dual Core et multicore posent un problème non résolu : paralléliser un programme arbitraire. Les compilateurs les plus utilisés (gcc, javac,...) sont des logiciels libres. Beaucoup de problémes se résolvent élégamment en définissant un langage spécialisé et en écrivant son compilateur (exemple : la synthèse matérielle). 4 / 49

Organisation du Projet Le but du projet est de réaliser un compilateur naïf pour un langage simple (une réduction de Pascal) Prélude au cours de Compilation de M1, excercice de programmation substantiel, travail en commun. Le projet doit être réalisé par binomes Quelques cours magistraux (éléments de compilation, présentation du langage Pascal- et de la machine cible), puis travail personnel et séances de d assistance avec Colin Riba et Bogdan Pasca Langage de réalisation recommandé : OCaml Evaluation du module : démonstration du compilateur, manuel de l utilisateur et rapport d implémentation. 5 / 49

Comment marche un compilateur RI Vérification Transformations RI Analyse Optimisation Generation de code Source Langage machine Le code source est analysé suivant une grammaire formelle et codé en binaire (représentation intermédiaire). On vérifie que le programme est sémantiquement correct. Exemple : un identificateur est utilisé conformément à sa déclaration. On applique des transformation successives qui rapprochent le programme de haut niveau d un programme en langage machine. Exemples : Boucle combinaison de tests et de goto. Eclatement des expressions complexes : code à un opérateur par instruction. Lorsque le code est suffisamment proche du langage machine, on le transcrit en langage d assemblage. Au passage, on essaie d améliorer le programme (optimisation). 6 / 49

Le langage Ocaml, I Le langage Ocaml est particulièrement bien adapté pour l écriture de compilateurs. C est un langage mixte fonctionnel et impératif à typage fort. Structure de données récursives : type operon = {op : string; args : expression list; } and expression = None Var of string Const of int SubExpression of expression ;; Ocaml possède un ramasse-miette : le programmeur n a pas à détruire les structures de données devenues inutiles. Pas de fuite de mémoire, pas de pointeurs brisés. 7 / 49

Le langage Ocaml, II pattern matching match x with None ->... SubExpression e ->... (List.fst e.args)... _ -> () récursion, listes, chaînes de caractères, tableaux, piles, FIFO, fonctions anonymes, sérialisation, exceptions... objets et foncteurs : utilisation délicate 8 / 49

Le langage Ocaml, III Tables hashcodées. h=f(w1)=f(w2) w1 d1 w2 d2 Interface : let h = Hashtbl.create 127; Hashtbl.add h w d; let d = try Hashtbl.find h w with Not_found ->... in...; 9 / 49

Langages formels, I Un langage est un ensemble de conventions entre un émetteur et un récepteur qui leur permet de se comprendre. Emetteur : le programmeur. Récepteur : le compilateur. Comme le récepteur n est qu un programme, le langage doit être spécifié de fa con précise : langage formel. On distingue : La syntaxe (ou grammaire) : quel sont les programmes corrects. La sémantique : quels sont les programmes qui on un sens. Analogie avec les langues naturelles. 10 / 49

Langages formels, III Un langage formel est un sous ensemble de tous les mots possibles sur un alphabet donné A. Un langage peut être infini. Une grammaire est une représentation finie d un langage. Une grammaire formelle se définit à l aide d un alphabet auxiliaire N (les non terminaux) et de règles de réécriture a b où a et b sont des mots sur l alphabet A N. On passe d un mot u à un mot v à l aide de la régle a b en trouvant dans u une occurence de a et en la rempla cant par b. Le langage associé est l ensemble des mots terminaux engendrés par réécriture à partir d un non terminal Z (l axiome). 11 / 49

Langages formels, IV : classification X, Y, Z,... sont des symboles terminaux, u, v, w,... sont des mots terminaux a, b, c... sont des mots arbitraires. Grammaires régulières : règles X u ou X Yv. Grammaires algébriques ou hors contexte : règles X a. Grammaires sensibles au contexte : règles axb acb. Grammaires générales : pas de restrictions sur les règles. Seules les deux premières catégories engendrent des langages décidables. 12 / 49

Exemple : la grammaire des identificateurs I a,... I z I A,... I Z I Ia,... I Iz I IA,... I IZ I I0,... I I9 C est une grammaire régulière. 13 / 49

Expressions arithmétiques : une grammaire simplifiée E I E N E (E + E) E (E E) C est une grammaire hors contexte. Si l on omet les parenthèses, la grammaire devient ambigüe. Il y a plusieurs suites de réécritures pour engendrer le même mot. 14 / 49

Outillage Une grammaire peut être utilisée soit comme générateur, soit comme analyseur. Un mot étant donné, reconstituer la suite des productions qui permet de l engendrer à partir de l axiome, ou dire qu il n est pas dans le langage. Ceci n est possible que pour les deux premiers types de grammaires. Pour des raisons d efficacité, on emploie les deux types, bien que les langages réguliers soient inclus dans les langages hors contexte. Mais la puissance des grammaires hors contexte est insuffisante pour exprimer toutes les règles. On doit programmer des contrôles supplémentaires. 15 / 49

Lex et Yacc = découpage en mots à l aide de grammaires régulières. = découpage en phrases à l aide d une grammaire hors contexte. On peut inventer des langages formels permettant de décrire les grammaires : liste de productions, conventions lexicales pour distinguer les terminaux, les non terminaux et les opérateurs propres On peut écrire des compilateurs pour ces langages : à partir de la grammaire, ils engendrent un analyseur. Les deux plus connus sont Lex (pour les grammaires régulières) et Yacc (pour un sous ensemble des grammaires hors contexte). Il en existe de nombreuses implémentations qui diffèrent par le langage cible (C, Ocaml, Java,...) et le statut juridique. 16 / 49

Lex et Yacc, organisation x lex.mll x syntax.mly ocamllex ocamlyacc x lex.ml x syntax.ml ocamlc x syntax.mli ocamlc x lex x syntax RI caracteres jetons 17 / 49

ANALYSE LEXICALE 18 / 49

Automates finis 20 20 20 10 10 10 A B C D E café L automate fini de la machine à café. 10 Un alphabet d entrée (ici {10, 20}) et éventuellement un alphabet de sortie (ici { 10, cafe}). Un ensemble fini d états (ici, {A, B, C, D, E}). Un état initial, A qui ici est également terminal. Une relation de transition : A.10 B A.20 C B.10 C B.20 D C.10 D C.20 E D A/cafe E D/ 10 19 / 49

Définitions Un mot est accepté par l automate s il existe un chemin étiqueté par les lettres du mot allant de l état initial à un état terminal. L ensemble des mots acceptés est le langage reconnu par l automate. Le mot de longueur nulle se note ɛ. Un automate fini est déterministe si la relation de transition est une fonction. Un automate peut avoir des ɛ-transitions ; il est alors indéterministe. Un état est accessible s il existe un chemin passant par cet état et allant de l état initial à un état terminal. On peut éliminer les états non accessibles. Un automate est complet si pour tout état il y a au moins une transition par lettre de l alphabet. En général, on complète un automate par des transitions vers un état d erreur. 20 / 49

Expression régulières Une représentation textuelle des automates finis. Syntaxe : E L E E E E.E E E E L est l ensemble des lettres de l alphabet. Le point représente la concaténation. La barre représente l alternation. L étoile représente l itération. a.(a + b) se lit un a suivi d un nombre arbitraire de a ou de b et désigne donc les mots sur l alphabet {a, b} qui commencent par un a. Les automates finis et les expressions régulières definissent la même classe de langages. 21 / 49

Identités remarquables La concaténation est associative. Elle distribue par rapport à l alternation. L alternation est associative et commutative. X = ɛ (X.X ). 22 / 49

Lex, flex, ocamllex Classification : on se donne une chaîne de caractères et une liste d expressions rationelles. Partitionner la chaîne en jetons dont chacun est une instance de l une des expressions rationelles. Il ne doit pas y avoir de portion de chaîne non classifiée. Pour chaque jeton, indiquer le nom de l expression rationelle en cause et le texte du jeton (sauf s il n y a aucune ambiguité). Méthode : construire et minimiser l automate qui reconnait (e 1 e 2... e N ) et signaler un jeton chaque fois que l on passe par l état terminal. 23 / 49

Expressions régulières augmentées Le programme soumis à Lex est de la forme : e 1 {j 1 } e 2 {j 2 }... Les expressions rationelles e i utilisent des raccourcis. Par exemple, a - z représente a b c... z. Le jeton est décrit par un bout de code dans le langage hote. L automate est construit, déterminisé, minimisé et implémenté sous forme de tables. Attention, la taille de l automate croit très vite avec la longueur des expressions rationelles e i. Utiliser des astuces (table de mots clef) 24 / 49

Ocamllex : un exemple { open Parser;; exception Eof;; linecount := ref(0);; } rule token = parse [ \t ] {token lexbuf } (* skip blanks *) [ \n ] {incr linecount; token lexbuf} [ 0-9 ]+ as lxm { INT(int_of_string lxm) } + { PLUS } - { MINUS } * { TIMES } / { DIV } ( { LPAREN } ) { RPAREN } eof { raise Eof } 25 / 49

ANALYSE SYNTAXIQUE 26 / 49

Grammaires hors-contexte Analyse bottom up Grammaires hors contexte Un ensemble T de symboles terminaux. Un ensemble N de symboles non terminaux. Un ensemble fini de productions : T w, T N, w (N T ). Un axiome S N. Dérivation immédiate : si T w est une production, alors utv uwv. Dérivation : u 0 u 1... u n : u 0 u n. Langage engendré : {w T S w}. Le problème : étant donné un mot et une grammaire, décider s il peut être engendré et décrire sa construction. 27 / 49

Grammaires hors-contexte Analyse bottom up Un exemple : les systèmes de parenthèses T = {(, ), [, ], a}. N = {S} S a S (S) S SS S [S] S [S] [SS] [as] [a(s)] [a(a)] Langage de Dick, ne peut être engendré par un automate fini. Le pouvoir expressif des grammaires hors contexte est supérieur à celui des grammaires rationelles. 28 / 49

Grammaires hors-contexte Analyse bottom up Exemple II : expressions arithmétiques T = {i, e, +,,, /, (, )} N = {E, T, F } E E + T E E T E T T T F T T /F E F F (E) F i F e E E+T E+F E+i T +i T F +i T i+i i i+i 29 / 49

Grammaires hors-contexte Analyse bottom up Arbre d analyse syntaxique T i E E T * + F T F i i Les noeuds sont les noms des productions (en général remplacés par le non terminal de gauche) Les feuilles sont les terminaux Pour chaque application d une production on crée un noeud étiqueté par le nom de laproduction ayant pour fils les lettres du mot de droite. Le mot engendré est la frontière de l arbre. 30 / 49

Ambiguïté, précédence Généralités Grammaires hors-contexte Analyse bottom up Une grammaire est ambiguë s il existe plusieurs arbres ayant la même frontière. E E + E E E (E) i i e On évite les grammaires ambiguës. E E * E On peut soit compliquer la grammaire, soit inciter l analyseur à choisir l une des analyses à l aide de règles de précédence. Ici, > +. + E i E I E i E * E i E + E i 31 / 49

Grammaires hors-contexte Analyse bottom up Le problème du retour arrière L algorithme d analyse naïf essaie toutes les productions possibles jusqu à trouver la bonne : complexité non linéaire. Existe-t-il des grammaires pour lesquelles on peut deviner la bonne production? Le seule information que l on possède est le caractère courant de la chaîne d entrée. Il faut que ce caractère détermine sans ambiguïté la production à utiliser. Par exemple, si toute production commence par un terminal, et si pour un non terminal donné, les premiers terminaux de gauche sont distincts, l analyse syntaxique peut se faire sans retour arrière. 32 / 49

Grammaires hors-contexte Analyse bottom up Grammaires prédictives Pour généraliser, on définit deux fonctions First et Follows sur l alphabet des terminaux et non terminaux : x First(Y ) si il existe w tel que Y w et x est le premier caractère de w. ɛ First(Y ) s il existe une dérivation Y ɛ. En particulier, si y est terminal, First(y) = {y}. x Follows(Y ) s il existe une production A uyzv et x First(Z). First + (X ) = if ɛ First(X ) then First(X ) Follows(X ) else First(X ) ; Une grammaire est prédictive si les membre droits de ses productions ont des ensembles First + disjoints. 33 / 49

Analyse ascendante Généralités Grammaires hors-contexte Analyse bottom up Algorithme glouton (N+T)* T* w c c in Follows(A) A w caractère courant reduce A shift 1. On a analysé un préfixe de la chaîne d entrée. 2. On recherche une production A w telle que w soit un postfixe de la partie déja analysée et telle que le caractère courant puisse suivre A. 3. Si on trouve, on remplace w par A et on recommence (reduce). 4. Sinon, on transporte le caractère courant vers la partie déja analysée, on déplace le pointeur de lecture et on recommence (shift). 5. L algorithme s arrète quand tous les caractères ont été lu. La chaîne d entrée est acceptée si la partie analysée se réduit à l axiome. c 34 / 49

Grammaires hors-contexte Analyse bottom up Items, fermeture On veut éviter de parcourir toute la grammaire à l étape 2. Pour cela, on tient à jour un ensemble de productions candidates ou items. On note que la partie déja analysée est gérée comme une pile. On obtient un item en insérant un point dans le second membre d une production : A u v. Si A u v fait partie des productions candidates, cela signifie que u est un postfixe de la pile. Si A w est une production candidate, on peut réduire. Si A u Xv est candidate, il faut que l on puisse pousser un X sur la pile. Toute production de la forme X w est donc candidate. On construit ainsi la fermeture (closure) d un ensemble d items. 35 / 49

Grammaires hors-contexte Analyse bottom up Automate des items On note que l ensemble des items est fini, et que l on peut définir une fois pour toute l effet de l empilage d un caractère quelconque. On construit un automate fini dont les états sont les ensembles d items. Si I est un ensemble d items, son successeur par le caractére x, terminal ou non terminal, est I.x = closure({a ux v A u xv I }) Pour simplifier, on introduit un nouvel axiome S et la production S S. L état initial est {S S}. On utilise un algorithme à la demande pour éviter de construire des états inaccessibles. On remarque qu après une réduction on se retrouve dans un état antérieur de l algorithme, à partir duquel on doit construire le nouvel état courant. Les états doivent donc également être empilés. 36 / 49

Grammaires hors-contexte Analyse bottom up Algorithme glouton caractère courant cn sn c1 s1 c0 s0 action goto pile Automate à pile entrée while true do s = sommet.de.pile; c = caractere.courant; switch Action[s][c] do case shift push c; push goto[s][c]; case reduce A w pop 2 w symboles; push A; push goto[s][a]; case accept stop; case error error; stop; 37 / 49

Grammaires hors-contexte Analyse bottom up Ambiguïtés Lors de la construction de la table Action, on peut rencontrer des ambiguïtés (encore appelées conflits) : Il peut y avoir dans l état plusieurs productions réductibles : conflit reduce/reduce. On peut avoir le choix entre une réduction A w et un shift B u cv alors que le caractère courant est c. Pour résoudre le problème, on divise les états suivant le caractère courant attendu. Un item prend la forme [A u v, c]. Signification : u est sur la pile, et si on parvient à réduire u.v alors c sera le prochain caractère à lire en entrée. On améliore la précision, mais le nombre d états possibles augmente énormément. 38 / 49

Construction de l automate LR(1) Grammaires hors-contexte Analyse bottom up Le calcul de l automate est identique au cas où on n utilise pas de symbole look ahead. Par contre la table des actions est différente : S il y a plusieurs réduction possibles, on discrimine en fonction du symbole d entrée suivant. Il n y a de conflit reduce / reduce que s il y a deux items [A w, a] et [A w, a] avec le même terminal a. De même il y a conflit entre une réduction [A w, a] et un shift [B w xv, a] 39 / 49

Grammaires hors-contexte Analyse bottom up Résolution des conflits, I Premier cas : la grammaire est donnée. Elle ne doit pas avoir de conflit. Si cependant il y en a, l outil Yacc les résoud de manière arbitraire (en général, priorité au shift plutôt qu au reduce). Il est possible d agir sur ce choix en spécifiant des priorités ou des associativités. 40 / 49

Le problème du else Généralités Grammaires hors-contexte Analyse bottom up %{ type statement = Assign of string Nop If of string * statement * statement ;; %} %token IF THEN ELSE %token COND %token ASSIGN %type <string> COND ASSIGN %start stat %type <statement> stat %% stat : ASSIGN {Assign of $1} IF COND THEN stat {If ($2, $4, Nop)} IF COND THEN stat ELSE stat {If ($2, $4, $6)} ; %% 41 / 49

Le conflit Généralités Grammaires hors-contexte Analyse bottom up state 7 stat : IF COND THEN. stat (2) stat : IF COND THEN. stat ELSE stat (3) IF shift 3 ASSIGN shift 4. error stat goto 8 8: shift/reduce conflict (shift 9, reduce 2) on ELSE state 8 stat : IF COND THEN stat. (2) stat : IF COND THEN stat. ELSE stat (3) ELSE shift 9 $end reduce 2 42 / 49

Exemple : une grammaire ambiguë Grammaires hors-contexte Analyse bottom up %{ type expression = Ident of string Plus of expression * expression ;; %} %token IDENT PLUS %type <string> IDENT %start expr %type <expression> expr %% expr : IDENT {Ident $1} expr PLUS expr { Plus $1 $3} ; %% 43 / 49

La solution Généralités Grammaires hors-contexte Analyse bottom up %{ type expression = Ident of string Plus of expression * expression ;; %} %token IDENT PLUS %left PLUS %type <string> IDENT %start expr %type <expression> expr %% expr : IDENT {Ident $1} expr PLUS expr { Plus $1 $3} ; %% 44 / 49

Grammaires hors-contexte Analyse bottom up Résolution des conflits, II Deuxième cas : le langage est donné, mais pas la grammaire. On a probablement construit une grammaire ambigüe. L outil peut afficher l automate LALR et signale les états qui comportent un conflit. Rechercher en particulier les paires de productions qui sont préfixe l une de l autre. Factoriser. 45 / 49

Résolution des conflits, III Grammaires hors-contexte Analyse bottom up On élabore simultanément le langage et son compilateur. On peut ajuster la syntaxe pour simplifier la compilation. Prévoir des marqueurs terminaux (par exemple des points-virgules après chaque instruction). Utiliser les parenthèses ( begin, end, etc). Refermer toute les constructions : if.. then.. else.. fi (exemple) do.. end do, proc.. end proc 46 / 49

Gestion des erreurs Généralités Grammaires hors-contexte Analyse bottom up L analyseur signale une erreur quand il n existe aucune transition pour le caractère courant dans l état courant. Le minimum est de signaler l erreur en indiquant la ligne et le caractère (token) en cause. On peut ensuite soit terminer l analyse (méthode Ocaml) soit essayer de poursuivre (méthode C). Pour poursuivre, on choisit dans le langage une construction facile à repérer (par exemple le point virgule qui termine toute instruction en C). On avale les caractères d entrée jusqu à passer un point virgule. On dépile jusqu à trouver une instruction et on poursuit. 47 / 49

Interface avec Lex, I Généralités Grammaires hors-contexte Analyse bottom up Lex et Yacc doivent utiliser le même système de codage des tokens : techniquement, c est un type énuméré. Dans le contexte Ocaml, c est ocamlyacc qui construit le type des jetons à partir des déclarations de la grammaire. Lex doit importer le fichier d interface correspondant. type token = IF THEN ELSE COND of (string) ASSIGN of (string) val stat : (Lexing.lexbuf -> token) -> Lexing.lexbuf -> statement 48 / 49

Grammaires hors-contexte Analyse bottom up Interface avec Lex, II source bufferisation lexer parser représentation intermédiaire caractères caractères tokens L analyseur lexical et l analyseur syntaxique fonctionnent en pipeline. Techniquement, l analyseur syntaxique appelle l analyseur lexical chaque fois qu il a besoin du jeton suivant. let lexbuf = Lexing.from_channel (open_in fichier) in try ( let thesource = Grammar.design Lexicon.token lexbuf in... with Parse_error ->... 49 / 49