Compilation E. RAMAT ramat@lisic.univ-littoral.fr.

Slides:



Advertisements
Présentations similaires

Advertisements


Bonne nutrition et sécurité alimentaire et meilleurs moyens d’existence pour les communautés agricoles dans terrains arides Pourquoi cette étude sur des.
ECO1 Introduction à l’économie
REVISION du COURS E = En- Ep = h
Mémoires résistives : Monte Carlo nouvel acte?
Les Moteurs ASynchrones
REGARDS CROISéS SUR LA PROPORTIONNALITE
Fabian Bergès, Elise Maigné, Sylvette Monier-Dilhan et Thomas Poméon
Équipe MAREL novembre 2016 Modelica Un langage pour modéliser et simuler des systèmes dynamiques hybrides
COUR DE TRAITEMENT NUMERIQUE DES SIGNAUX
La suite bureautique OpenOffice.org
Les descentes de charge
African Economic Conference (AEC)
Notions d’éclairagisme pour les ouvrages intérieurs
RES 203 Applications Internet
Un ébranlement sur une corde se propage à la vitesse c=1 cm/s
Projet GEPET-EAU Etude de la résilience et optimisation de la gestion des réseaux de voies navigables dans un contexte de changement climatique.
Laboratoire de Structure du Nucléon
2. Approbation de l’agenda 3. Compte-rendu de la dernière rencontre
Cu2+(aq) Doser ?? Doser une espèce chimique… …efficacement…
La procédure PASAPAS et les procédures utilisateurs
Agrégation SII OPTION ingénierie des Constructions
BASE DE SONDAGE PRINCIPALE (BSP) LES STATISTIQUES AGRICOLES
RELATIONS BIOMÈTRIQUES D'UN CYPRINIDAE ENDÉMIQUE,
FRACTIONS ET NOMBRES DECIMAUX
Microcontrôleur.
mathématiques et physique-chimie au cycle 3
Electrochimie: réactions d’oxydo-réduction
ELECTROTECHNIQUE CM: 10h; TD: 20h; TP: 30h
La masse volumique.
TD 8 – Chaînes de montagnes - Tectonique des plaques

Cinquième Chapitre 2: Solides
Quittons notre berceau
TD 7- Réactions minéralogiques et bilans chimiques
Information, Calcul, Communication
Dimitri Zuchowski et Marc-Élie Lapointe
JTED, Novembre 2016, Toulouse
La révolution numérique : comment s’emparer des opportunités sans négliger les dangers ? Virginie Fauvel, Membre du Comité Exécutif d’Allianz France en.
COURS D’INFORMATIQUE INDUSTRIELLE www. massaleidamagoe2015
A M E J Association des Médecins Experts Judiciaires
Module 1: Cinématique SPH3U4C.
ECO1 Introduction à l’économie
Stratégies en matière de plan de sondage et d’échantillonnage
Etalonnage d’une caméra (on parle aussi de calibrage)
Sciences de l’Ingénieur
Objectif : remplacer les tâches Répétitives Pénibles Complexes
PILES ET ACCUMULATEURS - RÉACTIONS D’OXYDORÉDUCTION
Introduction à l’économie Amphi 1 Qu’est ce que l’économie ?
Principe de fonctionnement d'une cellule photo voltaïque
Thème 3 : Défis du XXIe siècle..
Utilisez les flèches de droite et de gauche pour naviguer.
5.1 Systèmes d’équations linéaires
Optique géométrique Laboratoires de physique de 1ère année
Le projet interdisciplinaire CeraR : Céramique archéologique avec R
Les outils Word Les outils Word constituent la base des outils utilisés dans la presque totalité des logiciels applicatifs. Reconnaitre les icones des.
Télémédecine et Diabète de type 1 Le systeme Diabéo
VICTOR HUGO et la SRO Un partenariat ville-hopital en rhumatologie
Maladie d’Ollier / Maffucci Projet de dépistage des gliomes
Les plateformes de simulation au service des GHT et des territoires
Les pratiques en classe, notamment avec le numérique et le jeu.
Le dépistage de la déficience cognitive chez les adultes plus âgés: Recommandations 2015 Groupe d’étude canadien sur les soins de santé préventifs (GECSSP)
Les réformes de la formulation budgétaire en Ouganda
Préparation à l’examen
Une introduction à la démographie (L'étude de la population)
Travaux dirigés d’ Atomistique
Le premier principe de la thermodynamique
Thème 1 : Ondes et Matière.
Transcription de la présentation:

Compilation E. RAMAT ramat@lisic.univ-littoral.fr

Plan Introduction à la compilation Analyse lexicale Analyse syntaxique Analyse prédictive Analyse par descente récursive Analyse ascendante Précédence d’opérateurs Analyse LL(k) Analyse LR (SLR, LR canonique et LALR) Compilation

Plan (suite) Traduction Contrôle de type Production de code intermédiaire Production de code Optimisation de code Compilation

Introduction à la compilation

Introduction Tout programme écrit dans un « langage de haut niveau » (Pascal, C, C++, Ada…) doit être traduit en instructions exécutables par l’ordinateur Cette traduction peut être effectuée soit par un compilateur soit par un interpréteur Compilation

Compilateur Programme source Compilateur Programme objet Compilateur = préprocesseur + compilateur + assemleur Programme objet Editeur de liens Librairies Programme exécutable Données Compilation

Préprocesseur Production du texte d’entrée du compilateur : Macro-expansion : définition de « macro- définitions » (abréviations) et utilisation Inclusion de fichiers (ex. #include <stdio.h>) Préprocesseur « rationnels » : définition de « macro-instructions » dans des langages ne disposant pas d’instructions évoluées telles que tant que … faire... Compilation

Assembleur Certains compilateurs produisent du code en langage d’assemblage qui est traduit par un assembleur en langage machine. Langage mnémonique MOV a, R1 ADD #2, R1 MOV R1, b Langage machine 0001 01 00 00000000 0011 01 10 00000010 0010 01 00 00000100 Langage source b=a+2; Compilation

Editeur de liens Construire un unique programme à partir de plusieurs fichiers contenant du code machine translatable Code machine translatable : les références aux variables et fonctions locales sont relatives, les références aux variables et fonctions globales sont symboliques afin de permettre la compilation séparée. Compilation séparée : chaque fichier source est compilé séparément et donne naissance à un programme objet. Programme objet P1 Programme objet P2 Programme objet Pi Programme objet Pn Programme exécutable Lorsque l’éditeur de liens trouvent une référence symbolique alors il recherche l’existence de la variable ou de la fonction dans les autres programmes objets Compilation

Compilateur Programme source Analyse lexicale Gestion des erreurs Analyse syntaxique Gestion des erreurs Analyse sémantique Génération de code intermédiaire Gestion de la table des symboles Optimisation de code Génération de code Programme cible Compilation

Analyse lexicale Parcours du programme source de gauche à droite, caractère par caractère en ignorant les caractères superflus (espace, tabulation, retour chariot, commentaires…), en reconnaissant les unités lexicales (ou tokens ; BEGIN, identificateur, =, }…), en mémorisant les lexèmes correspondants et en envoyant ces informations à l’analyseur syntaxique Compilation

Analyse lexicale - Exemple Code source : superficie = largeur * longueur / 2 UL : Id OpAff Id OpMult Id OpDiv Cste lexème : superficie / largeur / longueur / 2 Compilation

Analyse syntaxique Vérification du respect des règles syntaxiques de la part de la séquence des unités lexiques analysées par l’analyseur lexical Exemple de grammaire : Expression ::= Identificateur Expression ::= Constante Expression ::= Expression OpMult Expression Expression ::= Expression OpDiv Expression Expression ::= Expression OpAdd Expression Expression ::= Expression OpSub Expression Instruction ::= Identificateur OpAff Expression Compilation

Analyse syntaxique - Exemple Instruction superficie = largeur * longueur / 2; Identificateur OpAff Expression Expression OpMult Identificateur Expression OpDiv Identificateur Constante Compilation

Analyse sémantique Contrôle des règles sémantiques : contrôle des types, portée des identificateurs correspondance entre paramètres formels et paramètres effectifs Collecte des informations pour la production de code Compilation

Génération de code intermédiaire Construction d’une représentation intermédiaire (pseudo-code) du programme source  programme pour une machine abstraite A partir de l’arbre sémantique, il est facile de produire du pseudo-code et de le traduire en langage cible Compilation

Optimisation de code Amélioration du code intermédiaire de façon que le code machine résultant s’exécute le plus rapidement possible. x = y + 2; z = x + 2; id1 OpAff id2 OpAdd Constante id3 OpAff id1 OpAdd Constante mov id2, R1 add #2, R1 mov R1, id1 mov id1, R1 mov #2, R1 mov R1, id3 Compilation

Génération de code Production de code machine ou du code en langage d’assemblage à partir du code intermédiaire optimisé Sélection des emplacements mémoire pour chaque variable utilisées dans le programme Assignation des variables aux registres du processeur Compilation

Gestion de la table des symboles Une tables des symboles est une structure de données contenant un enregistrement pour chaque identificateur Quand l’analyseur lexical détecte un identificateur dans le programme source, cet identificateur est entré dans la table des symboles (s’il n’existe pas déjà) L’analyse syntaxique permet de compléter le type et la portée de la variable L’analyse sémantique consulte la table des symboles pour contrôler les types Compilation

Gestion des erreurs Des erreurs peuvent être détectées aux différentes phases de la compilation Différents types d’erreurs : syntaxiques (caractères inconnus, unité lexicale invalide…), syntaxique (aucune règle syntaxique sélectionnée…), sémantique (type incompatible…) Certaines erreurs ne doivent pas empêcher la génération de code (warning) Compilation

Chapitre 1. Analyse lexicale Compilation

Rôle de l’analyseur lexical unité lexicale programme source Analyseur lexical Analyseur syntaxique Obtenir prochaine unité lexicale Table des symboles Compilation

Rôle de l’analyseur lexical Elimination des informations superflues (blancs, tabulation, retour chariot, commentaires…) Reconnaissance des unités lexicales (tokens) et des lexèmes Construction de la table des symboles Détection de certaines erreurs Tâches secondaires : compter le nombre de lignes, convertir les lettres en majuscules… Compilation

Définition Spécification Un modèle est une règle qui décrit l’ensemble des lexèmes pouvant représenter une unité lexicale Compilation

Unité lexicale - Lexème Quand différents lexèmes désignent la même unité lexicale, un attribut est associé à l’unité lexicale Compilation

Alphabet et chaîne Définition. Alphabet - Tout ensemble  fini de symboles Définition. Chaîne ou mot - Une chaîne sur un alphabet  est une séquence finie de symboles extraits de  On note |s| le nombre d’occurrences de symboles dans s La chaîne vide (de longueur 0) est notée  Compilation

Langage Définition. Langage - Un langage est un ensemble fini ou infini de chaînes construites sur un alphabet fixé , l’ensemble vide ou {} sont des langages La définition de langage n’attribue aucune signification aux chaînes d’un langage Compilation

Concaténation ou produit Si x et y sont des chaînes alors la concaténation de x et de y, qui s’écrit xy, est la chaîne formée en joignant x et y La chaîne vide est l’élément neutre pour la concaténation s=s=s Si l’on considère la concaténation comme un produit, on peut définir l’exponentiation de chaîne s0= et pour i>0 si=si-1s Compilation

Opérations sur les langages Définition Union de L et M noté LÈM LÈM = {s / s ÎL ou s ÎM} Concaténation de L et M notée LM LM = {st / s ÎL et t ÎM} Fermeture de Kleene de L notée L* L* = Èi=0..¥ Li Fermeture positive de L notée L+ L+ = Èi=1..¥ Li Compilation

Exemples de langages Soient L l’ensemble {A,B,…,Z,a,b,…,z} et C l’ensemble {0,1,…,9} - ensemble de mots d’un symbole Exemples de langages : LC est l’ensemble des lettres et des chiffres LC est l’ensemble des chaînes formées d’une lettre suivie d’un chiffre L4 est l’ensemble des chaînes de 4 lettres L* est l’ensemble de toutes les chaînes de lettres, y compris la chaîne vide  L(LC)* est l’ensemble de toutes les chaînes de lettres et de chiffres commençant par une lettre C+ est l’ensemble de toutes les chaînes d’au moins un chiffre Compilation

Expressions régulières Les expressions régulières permettent de spécifier les modèles Définition. Expression régulière  est une expression régulière si a   alors a est une expression régulière si s et t sont des expressions régulières définissant les langages réguliers L(s) et L(t) alors s|t est une expression régulière définissant L(s)L(t) st est une expression régulière définissant L(s)L(t) s* est une expression régulière définissant (L(s))* s2 est une expression régulière définissant (L(s))2 Compilation

Priorité des opérateurs L’opérateur unaire * a la plus haute priorité et est associatif à gauche La concaténation a la deuxième plus haute priorité et est associative à gauche | a la plus faible priorité et est associatif à gauche Exemple : (a)|((b)*(c)) est équivalent à a|b*c Compilation

Exemples Soit ={a,b} a|b  {a,b} (a|b)(a|b)  {aa, ab, ba, bb} a*  {, a, aa, aaa…} (a|b)*  {, a, b, aa, aab, bab…} ou (a*b*)* a|a*b  {a, b, ab, aab, aaab…} Compilation

Définitions régulières Pour des raisons de lisibilité, on peut donner des noms aux expressions régulières et définir des expressions régulières en utilisant ces noms Définition. Si  est un alphabet, une définition régulière est une suite de définitions de la forme : d1r1 ; d2r2 ; … ; dnrn où di est un nom et chaque ri est une expression régulière sur les symboles de {d1,d2,…,dn} Compilation

Exemple Les nombres sans signe sont des chaînes comme 5280, 39.37, 6.336E4 ou 1.894E-4 chiffre  0|1|2|3|4|5|6|7|8|9 chiffres  chiffre chiffre* decimal-opt  . chiffre |  exposant-opt  (E(+|-|)chiffres) |  nombre  chiffres decimal-opt exposant-opt Une abréviation existe : (+|-|)  (+|-)? Compilation

Diagramme de transition Reconnaissance Les diagrammes de transition décrivent les actions qui sont réalisées quand l’analyseur syntaxique appelle l’analyseur lexical pour fournir une unité lexicale Unité lexicale 1 2 3 4 < = > autre début retourner(oprel,LTE) retourner(oprel,NEQ) retourner(oprel,LT) * Attribut * signifie qu’il faudra reculer lors de la prochaine demande Compilation

Diagramme de transition lettre * début lettre autre 1 2 Retourner(UniLexId(),RangerId()) chiffre La fonction UniLexId() recherche le lexème dans la table des symboles. Si le lexème est un mot clé, l’unité lexicale correspondante est retournée; autrement, l’unité lexicale Identificateur est retournée La fonction rangerId() examine la table des symboles et si le lexème est un mot clé alors la fonction retourne 0 sinon le lexème est une variable et retourne un pointeur vers cette (nouvelle, si elle existe pas déjà) variable Compilation

Automate fini Définition. Automate fini - Un automate fini peut reconnaître les chaînes décrit par une expression régulière. Un automate fini est un diagramme de transition généralisé. Les arcs portent les symboles de l’alphabet Il existe deux types d’automates finis : déterministes et non déterministes (plusieurs transitions sortant d’un état porte le même symbole) Propriété. Tout langage reconnu par un AFN peut être décrit par une expression régulière et réciproquement Compilation

Automate fini non déterministe Définition. AFN - Un automate fini non déterministe est un modèle mathématique qui consiste en : un ensemble d’états E un ensemble de symboles d’entrée  (alphabet) et la chaîne vide  une fonction de transition qui fait correspondre des couples (état;symbole) à des ensembles d’états un état initial e0 un ensemble F d’états finaux Un AFN peut être représenté graphiquement comme un graphe orienté étiqueté, graphe de transition, dans lequel les nœuds sont les états et les arcs étiquetés représentent la fonction de transition Compilation

Exemple d’AFN (a|b)*abb a b 1 a 2 b 3 b Compilation Plusieurs arcs étiquetés a partent de l’état 0 Compilation

Algorithme de reconnaissance L=(a|b)*abb Chaîne à reconnaître = ababb a a b 1 2 b 3 b 2 b Echec 1 a a b 1 a 2 b 3 b Compilation

Transformation d’une expression régulière en un AFN Décomposer l’expression régulière en sous-expressions élémentaires (, a, s|t, st, s* ou s+) Appliquer et composer les transformations suivantes : s t st i f i f  s* i f  s i f a s|t i f  s t s+ i f  s Compilation

Automate fini déterministe Définition. Un automate fini déterministe est un cas particulier d’automate fini non déterministe dans lequel : aucun état n’a de -transition (arc porteur de ) pour chaque état e et chaque symbole d’entrée a, il y a au plus un arc étiqueté a qui quitte e Avantage : il est très facile de déterminer si une chaîne est reconnu par l’AFD Inconvénient : l’AFD contient plus d’états ou plus de transitions que l’AFN équivalent Compilation

Exemple d’AFD L=(a|b)*abb b a a b b 1 2 3 a b a Compilation

Transformation d’un AFN en AFD -fermeture(T) = T  ensemble des états de l’AFN accessibles à l’aide de transitions étiquetées  à partir des états de T transition(ei,a) = ensemble des états de l’AFN vers lesquels il existe une transition sur le symbole d’entrée a à partir de l’état ei Compilation

Transformation d’un AFN en AFD L’état initial de l’AFD, noté f0, est -fermeture(e0) Tant qu’il existe un état non traité de l’AFD Faire Soit fk un état de l’AFD non traité Pour chaque symbole d’entrée a Faire U=-fermeture(transition(fk,a)) Si U n’appartient pas à l’AFD Alors Ajouter U comme état fi non traité à l’AFD Fin Si transition(fk,a)=U Fin Pour Fin Tant que fk est un ensemble d’états de l’AFN Compilation

Exemple/Exercice (a|(ab|c)+)*   a b 5 7 8     10 11 2 4     6 9 1 13 14  a  3 12  Compilation

Exemple -fermeture(0)={0,1,2,3,4,5,6,14}=A -fermeture(transition(A,a))= -fermeture({7,12}) ={7,12,13,14,1,2,3,4,5,6}=B -fermeture(transition(A,b))= -fermeture(transition(A,c))={9,10,4,5,6,11,13,14,1,2,3}=C -fermeture(transition(B,a))={7,12,13,14,1,2,3,4,5,6}=B -fermeture(transition(B,b))={8,10,1,2,3,4,5,6,11,13,14}=D -fermeture(transition(B,c))={9,10,4,5,6,11,13,14,1,2,3}=C … Compilation

Exemple (a|(ab|c)+)* a b a A B D a c b c C c Compilation

Minimisation d’un AFD Un AFD est minimal s’il n’existe pas d’AFD reconnaissant le même langage avec un nombre d’états strictement inférieur Tout langage régulier est reconnu par un AFD minimal et unique Compilation

Algorithme de minimisation Construire une partition initiale  de l’ensemble des états en deux sous-ensembles : états d’acceptation et états de non-acceptation Tant qu’un sous-ensemble de la partition  peut être partitionné Faire Choisir un sous-ensemble S qui peut être partitionné Choisir un état e de S tel qu’il existe au moins un symbole d’entrée ne menant pas au même état que les autres états de S Partitionner l’ensemble S en deux sous-ensemble S’=S-{e} et S"={e} Fin tant que Pour tout sous-ensemble de cardinal > 1, choisir un état représentant Reconstruire l’AFD en remplaçant les états des sous-ensembles de cardinal >1 par l’état représentant Si tous les sous-ensembles de la partition a pour cardinal 1 alors l’AFD initial est minimal Compilation

Exemple a (a|(ab|c)+)* b a A B D a c a c b c C c A B D a c b (ABCD) A ne possède pas de transition pour b contrairement à B,C et D  (A) (BCD) D ne possède pas de transition pour b contrairement à B et C  (A) (BC) (D) c C c A B D a c b Compilation

Chapitre 2. Analyse syntaxique Compilation

Introduction Tout langage de programmation a des règles pour définir la structure syntaxique des programmes On utilise des grammaires non contextuelles (ou BNF - Backus Naur Form) pour les construire Compilation

Langage de Chomsky Définition. Une grammaire est un quadruplet {VT,VN, S, P} tel que : VT : ensemble des terminaux (= unités lexicales) VN : ensemble des non-terminaux (ou auxiliaires = variables syntaxiques dénotant un ensemble de chaînes) S : axiome  VN (l’ensemble des chaînes est obtenu à partir de cet auxiliaire particulier) P : ensemble fini de règles de production ou de réécriture Conventions : Les terminaux sont notés en minuscule, les auxiliaires en majuscule et la partie gauche de la première règle est l’axiome Compilation

Classification de Chomsky Grammaire de type 0 : grammaire au sens général (système semi-thueien) Grammaire de type 1 (ou dépendante du contexte) : règles de réécriture du type    où A est un auxiliaire Grammaire de type 2 (ou indépendante du contexte ou grammaire de Chomsky ou C-grammaire) : règles de réécriture du type    où A est un auxiliaire Compilation

Classification de Chomsky Grammaire de type 3 (ou régulière ou de Kleene ou K-grammaire) : régulière à droite : toutes les règles de production sont de la forme : A  tB C  u régulière à gauche : toutes les règles de production sont de la forme A  Bt Compilation

Rôle de l’analyseur syntaxique programme source unité lexicale Analyseur lexical Analyseur syntaxique Analyseur sémantique arbre d’analyse Obtenir prochaine unité lexicale représentation intermédiaire Table des symboles Compilation

Types d’analyseurs syntaxiques Il existe trois types d’analyseurs syntaxiques : méthode universelle sur des grammaires de type 0  inefficace méthode descendante : construction de l’arbre d’analyse de la racine aux feuilles méthode ascendante : construction de l’arbre d’analyse des feuilles à la racine appliquées sur des sous-classes de grammaires LL et LR (LL  LR) Compilation

Gestion des erreurs syntaxiques L’analyseur syntaxique vérifie que la suite d’unités lexicales peut être engendrée par la grammaire du langage La gestion des erreurs consiste à : indiquer la présence d’erreurs de façon claire et précise traiter (récupérer) chaque erreur pour pouvoir détecter les erreurs suivantes Compilation

Récupération sur erreur Récupération en mode panique : éliminer les symboles d’entrée jusqu’à rencontrer une unités lexicales correctes Récupération au niveau du syntagme : corrections locales (remplacement d’une virgule par un point-virgule ou ajout d’une unité lexicale, par exemple) Production d’erreur : augmenter la grammaire avec des productions qui engendrent des constructions erronées Correction globale : détermination d’une séquence minimale de changements (ajout, suppression et changement d’unités lexicales)  idéale mais trop coûteuse Compilation

Les grammaires non contextuelles S  EXPR EXPR  EXPR OP EXPR EXPR  ( EXPR ) EXPR  - EXPR EXPR  id OP  + OP  - OP  * OP  / VN={S,EXPR,OP} VT={id,(,),-,+,*,/} OU S  EXPR EXPR  EXPR OP EXPR | ( EXPR ) | - EXPR | id OP  + | - | * | / Compilation

Dérivation Définition. Dérivation - 1 se dérive en 2 en une étape si 1= A et 1=    et il existe la règle de production A  On note 1  2 la dérivation de 1 en 2 On note si 1 se dérive en 2 en zéro ou plusieurs étapes On note si 1 se dérive en 2 en au moins une étape 𝛼 1 ⇒ 𝛼 2 𝛼 1 ⇒ + 𝛼 2 Compilation

Langage Le langage engendré par une grammaire G est l’ensemble des chaînes de terminaux que l’on peut dériver à partir de l’axiome ∀𝜔∈ 𝑉 𝑇 ,𝜔∈𝐿 𝐺 ⇔𝑆 ⇒ + 𝜔 Compilation

Exemple Soit la grammaire G suivante : S  EXPR EXPR  EXPR OP EXPR | ( EXPR ) | - EXPR | id OP  + | - | * | / La chaîne -(id+id) est engendrée par G car : S  EXPR  - EXPR  -( EXPR )  -( EXPR OP EXPR)  -(id OP EXPR)  -(id + EXPR)  -(id + id) 𝑆 ⇒ − 𝑖𝑑+𝑖𝑑 Compilation

Dérivation gauche et droite ⇒ 𝑔 Une dérivation gauche se dit d’une dérivation où l’auxiliaire le plus à gauche est remplacé Une dérivation droite se dit d’une dérivation où l’auxiliaire le plus à droite est remplacé ⇒ 𝑑 Compilation

Arbre d’analyse Un arbre d’analyse est une représentation graphique d’une dérivation dans laquelle l’ordre de rempla- cement n’apparaît pas S EXPR - EXPR ( ) EXPR EXPR + id Compilation

Grammaire ambiguë Une grammaire est dite ambiguë si elle produit plus d’un arbre d’analyse pour une phrase donnée Exemple : id+id*id SEXPREXPR+EXPRid+EXPRid+EXPR* EXPRid+id*EXPRid+id*id ou SEXPREXPR*EXPREXPR+EXPR*EXPR id+EXPR*EXPRid+id*EXPRid+id*id Compilation

Grammaire ambiguë S S EXPR EXPR EXPR + EXPR * id EXPR * EXPR + id id Compilation

Suppression des ambiguïtés Un « célèbre » exemple : le si-alors-sinon Instr  si Expr alors Instr | si Expr alors Instr sinon Instr | … si E1 alors si E2 alors S1 sinon S2 si E1 alors [ si E2 alors S1 ] sinon S2 ou si E1 alors [ si E2 alors S1 sinon S2 ] Compilation

Suppression des ambiguïtés Première règle : faire correspondre chaque sinon avec le alors précédent le plus proche Instr  Instr_close | Instr_non_close Instr_close  si expr alors Instr_close sinon Instr_close | autre Instr_non_close  si expr alors Instr | si expr alors Instr_close sinon Instr_non_close Deuxième règle : ajouter un fin_si Compilation

Ecriture d’une grammaire Toute construction qui peut être décrite par une expression régulière peut également être décrite une grammaire Exemple : (a|b)*abb S  aS | bS | a A1 A1  bA2 A2  bA3 A3   Compilation

Transformation d’un AFN en une grammaire Les symboles de l’alphabet devient les terminaux VT Pour chaque état i de l’AFN, on crée un auxiliaire (VN) - l’état initial de l’AFN devient l’axiome Si l’état i a une transition vers l’état j sur le symbole a, on introduit la production Ai  aAj Si l’état i a une transition vers l’état j sur , on introduit la production Ai  Aj Ajouter la production Ai   si i est un état terminal Compilation

Expressions régulières ou grammaire ? Pourquoi utiliser les expressions régulières pour définir la syntaxe de la partie lexicale ? Rendre modulaire et indépendant avec les symboles d’entrée Les unités lexicales nécessitent un formalisme simple et concis  les expressions régulières La syntaxe nécessite une notation plus puissante Compilation

Partie 1. Analyse descendante Compilation

Analyse descendante Les méthodes d’analyse descendante repose sur la dérivation à gauche Si une grammaire est récursive à gauche alors ces méthodes ne marchent pas Une grammaire est récursive à gauche si elle contient un auxiliaire A tel qu’il existe une dérivation où  est une chaîne quelconque 𝐴 ⇒ + 𝐴𝛼 Compilation

Suppression de la récursivité à gauche Cas d’une récursivité à gauche simple : A  A |  La récursivité à gauche est remplacée par une récursivité à droite : A  A’ A’  A’ |  Compilation

Suppression de la récursivité à gauche Exemple de récursivité à gauche en plusieurs étapes : S  Aa | b A  Ac | Sd |  S  Aa  Sda Compilation

Suppression de la récursivité à gauche ⇒ + Soit une grammaire G sans cycle ( A A) et sans production vide (A) Ordonner les auxiliaires A1, A2,…, An Pour i=2 à n faire Pour j=1 à i-1 faire Remplacer chaque production de la forme AiAj par les productions Ai1|2|…|k où Aj1|2|…|k Fin pour Eliminer les récursivités à gauche simples des Ai Compilation

Exemple G : S  Aa | b A  Ac | Sd |  S est récursif à gauche (S  Aa  Sda) A est immédiatement récursif à gauche A1=S et A2=A Pour i=2 et j=1 Remplacement : A  Ac | Aad | bd |  Elimination de la récursivité simple : A  bdA’ | A’ A’  cA’ | adA’ |  Compilation

Analyse par descente récursive Déterminer une dérivation gauche associée à la chaîne à analyser ou construire un arbre d’analyse de la chaîne d’entrée en partant de la racine et en créant les nœuds de l’arbre en préordre La plus simple à mettre en œuvre !!! Compilation

Exemple Soit la grammaire : et la chaîne w = cad S c A d R1 : S  cAd R2 : A  ab R3 : A  a et la chaîne w = cad S c A d Retour arrière R1 c A d R1 S a R3 a b R2 Compilation

Attention !!! Si la grammaire est récursive à gauche immédiatement ou non alors : A  A | b A A A ... Compilation

Exercices Soit la grammaire : S  aSbS | bSaS |  Analyser par une descente récursive avec rebroussement les chaînes suivantes : aabb ; abab ; abbab Quel langage est engendré par cette grammaire ? Compilation

Exercices -- Idée : un auxiliaire devient une fonction -- Soit la grammaire : E  E + T | E - T | T T  T * F | F F  F / A | A A  ( E ) | id | chiffre Supprimer la récursivité de cette grammaire Ecrire un algorithme mettant en œuvre l’analyse par descente récursive. On dispose deux fonctions : nextUL() qui retourne le code de l’unité lexicale suivante pushBack() qui revient en arrière d’une unité lexicale -- Idée : un auxiliaire devient une fonction -- Compilation

Analyse prédictive L’analyse par descente récursive implique l’utilisation du rebroussement Si la grammaire est non récursive à gauche et factorisée à gauche alors nous obtenons une grammaire qui peut être analysée par descente récursive sans rebroussement Exemple : Instr  si Expr alors Instr sinon Instr Instr  si Expr alors Instr Comment déterminer quelle règle utilisée à la vue de l’unité lexicale si ? Compilation

Factorisation à gauche Il est possible de différer la décision en étendant A en A’ où  est l’unité lexicale à gauche des règles A  1 | 2 devient A   A’ A’  1 | 2 Compilation

Exemple Soit la grammaire : S  i E t S | i E t S e S | a E  b devient S  i E t S S’ | a S’  e S |  Compilation

Analyse prédictive à l’aide d’une pile La récursivité est remplacée par l’utilisation d’une pile et d’une table d’analyse Chaîne d’entrée ... a b $ + Pile Programme d’analyse prédictive X Y Z $ Flot de sortie Table d’analyse M Compilation

Programme d’analyse prédictive Soit X, le symbole en sommet de pile et a, le symbole d’entrée courant Si X=a=$ alors l’analyseur s’arrête et la chaîne d’entrée est reconnue Si X=a$ alors l’analyseur enlève X de la pile et avance son pointeur d’entrée sur le symbole suivant Si X est un auxiliaire alors le programme consulte l’entrée M[X,a] de la table d’analyse Si M[X,a]=erreur alors l’analyseur appelle une procédure de récupération d’erreur sinon /* M[X,a] est de la forme X UVW */ l’analyseur remplace X en sommet de pile par UVW (U en sommet de pile) Compilation

Exemple E  T E’ E’  + T E’ |  T  F T’ T’  * F T’ |  F  ( E ) | id Compilation

Exemple $ E’ id*id$ T’ F $ E id+id*id$ $ E’ id*id$ T’ id $ E’

Exercices Vérifier que les chaînes suivantes appartiennent au langage des expressions à l’aide une analyse prédictive à pile : (id + id) * id (id * id + id) (id * * id) Définir en parallèle l’arbre d’analyse Compilation

Table d’analyse Pour construire la table d’analyse, on utilise deux fonctions : premier(X) détermine l’ensemble des terminaux qui commencent les chaînes qui se dérivent de X. suivant(A) détermine l’ensemble des terminaux qui peuvent se trouver immédiatement à droite de A après dérivations Compilation

Fonction Premier(X) Si X est un terminal alors Premier(X)={X} Si X est une production alors ajouter à Premier(X) Si XY1Y2…Yk est une production alors ajouter a dans Premier(X) s’il existe i tel que a dans Premier(Yi) et que  est dans tous les Premier(Y1),…,Premier(Yi-1) 𝑌 1 … 𝑌 𝑖−1 ⇒ 𝜀 Compilation

Exemple E  T E’ E’  + T E’ |  T  F T’ T’  * F T’ |  F  ( E ) | id Premier(E)=Premier(T)=Premier(F)={(,id} Premier(E’)= {+,} Premier(T)=Premier(F)={(,id} Premier(T’)= {*,} Premier(F)={(,id} Compilation

Fonction Suivant(A) Mettre $ dans Suivant(A) où A est l’axiome et $ est le marqueur droit indiquant la fin du texte source S’il y a une production BA, le contenu de Premier(), excepté , est ajouté à Suivant(A) S’il existe une production BA ou une production BA telle que Premier() contient , les éléments de Suivant(B) sont ajoutés à Suivant(A). Compilation

Exemple E  T E’ E’  + T E’ |  T  F T’ T’  * F T’ |  F  ( E ) | id Suivant(E)= {),$} Suivant(E’)=Suivant(E)={),$} Suivant(T)=Premier(E’)+Suivant(E’)+Suivant(E) ={+,),$} Suivant(T’)=Suivant(T)={+,),$} Suivant(F)=Premier(T’)+Suivant(T’)+Suivant(T) ={*,+,),$} Compilation

Construction de la table d’analyse prédictive Pour toute production A de la grammaire Faire Pour chaque terminal a dans Premier(), ajouter A à M[A,a] Si  est dans Premier( alors ajouter A à M[A,b] pour chaque terminal b dans Suivant(A) Fin Si Si  est dans Premier( et $ est dans Suivant(A) alors ajouter A à M[A,$] Fin Pour Toute entrée de M non définie est équivalente à une erreur d’analyse Compilation

Exemple E  T E’ ETE’ E’  + T E’ |  T  F T’ F  ( E ) | id ETE’ Premier(TE’)=Premier(T)={(,id} donc M[E,(]= ETE’ et M[E,id]= ETE’ E’+ T E’ Premier(E’)={+} donc M[E’,+]= E’+ T E’ E’ Suivant(E’)={),$} donc M[E’,)]= E’ et M[E’,$]= E’ Compilation

Grammaire LL(1) Une grammaire dont la table d’analyse n’a aucune entrée définie de façon multiple est appelée LL(1). LL(1) Analyse du flot d’entrée de gauche à droite Dérivation à gauche Un seul symbole de pré-vision à chaque étape Compilation

Grammaire LL(1) Une grammaire G est LL(1) si et seulement si Pour A   |  il n ’existe pas de terminal a tel que a  Premier() et a  Premier()  et  ne peuvent pas se dériver tous les deux en  si , ne se dérive pas en une chaîne commençant par un terminal de Suivant(A) 𝛽 ⇒ 𝜀 Compilation

Partie 2. Analyse ascendante Compilation

 Analyse par décalage - réduction Analyse ascendante Construire un arbre d’analyse pour une chaîne d’entrée des feuilles vers la racine ou déterminer une dérivation droite en « sens inverse » Il s’agit de « réduire » une chaîne  vers l’axiome de la grammaire  Analyse par décalage - réduction On regarde si dans la chaîne à analyser : il existe une sous-chaîne correspondant à la partie droite d’une production on la remplace par l’auxiliaire de la partie gauche de cette production Compilation

Exemple a b b c d e a A b c d e a A d e a A B e S S  aABe A  Abc | b B  d =abbcde Dérivation droite : S  aABe  aAde  aAbcde  abbcde a b b c d e On recherche les sous-chaînes correspondant à la partie droite d’une production a A b c d e Attention, le choix des sous-chaînes ne doit pas être quelconque a A d e a A B e S Compilation

Exemple Arbre d’analyse S A B A a b c d e Compilation

Manche On appelle manche de chaîne une sous-chaîne qui correspond à la partie droite d’une production et dont la réduction vers l’auxiliaire de la partie gauche de cette production représente une étape de la dérivation droite inverse 𝑠𝑖S ⇒ 𝑑 𝛼𝐴𝜔 ⇒ 𝑑 𝛼𝛽𝜔avec A→𝛽et𝜔∈ 𝑉 𝑇 𝑎𝑙𝑜𝑟𝑠𝛽est un manche de𝛼𝛽𝜔 Si la grammaire est ambiguë, il peut exister plusieurs manches dans une chaîne. Compilation

Analyseur par Décalage-Réduction à l’aide d’une pile Au départ $ $ Flot d’entrée  En cours On décale de l’entrée vers la pile 0, 1 ou plusieurs symboles jusqu’à ce qu’un manche se trouve en sommet de pile. On le remplace par la partie gauche de la production. Fin $ S Détection d’une erreur ou Compilation

Exemple E  E + E E  E * E E  (E) E  id  = id + id * id $ E + Compilation

Exercices Vérifier que les chaînes suivantes appartiennent au langage des expressions à l’aide une analyse par décalage- réduction à pile: (id + id) * id (id * * id) Soit la grammaire suivante : S  G=D | D G  *D | id D  G Vérifier que la chaîne *id=id appartient au langage Compilation

Conflits possibles Décaler ou réduire : en cours d’analyse, on ne peut pas décider s’il faut réduire le manche présent en sommet de pile ou décaler encore quelques symboles pour faire apparaître un autre manche. Réduire ou réduire : le manche en sommet de pile peut être réduire par plusieurs productions. Pour éviter ces conflits, nous allons définir une classe de grammaire LR(k) pour lesquelles l’analyse par décalage/réduction se déroule correctement Compilation

Les analyseurs LR LR(k) Nombre de symboles de pré-vision Analyse du flot d’entrée de gauche à droite Dérivation à droite inverse Nombre de symboles de pré-vision pour prendre les décisions d’analyse Les analyseurs LR sont plus puissants que les analyseurs prédictifs mais il est difficile de les programmer rapidement ! Compilation

Analyse LR Chaîne d’entrée a0 an $ a1 ... Sm-1 X1 S0 Pile Xm ... Sm Etats Symboles Programme d’analyse LR Flot de sortie Table d’action Table successeur Compilation

Algorithme d’analyse LR Au départ s0 $ Flot d’entrée  Compilation

Algorithme d’analyse LR Si Action[sm,a]=Décaler s’ Alors empiler a empiler s’ avancer p Fin Si Si Action[sm,a]=Réduire A Alors dépiler 2*|| symboles empiler A empiler Succ[sm-||,A] Si Action[Sm,a]=Accepter Alors Succès Fin Si Si Action [Sm,a]=Erreur Alors Routine de récupération sur erreur En cours sm xm sm-1 ... s0 ... ... a $ p Compilation

Exemple (1) E  E + T (2) E  T (3) T  T * F (4) T  F (5) F  ( E ) Grammaire : (1) E  E + T (2) E  T (3) T  T * F (4) T  F (5) F  ( E ) (6) F  id Notations : di : décaler et empiler l’état i rj : réduire avec la règle j acc : accepter Compilation

Exemple Compilation

Exemple id*id+id d7 T 2 id+id$ * 7 id*id+id$ T 2 +id$ * 7 d5 id 5 T 2 id+id$ * 7 id*id+id$ T 2 +id$ * 7 d5 id 5 *id+id$ id 5 d5 r6 *id+id$ F 3 r6 T 2 * 7 F 10 +id$ T 2 r3 +id$ T 2 r4 *id+id$ Compilation

Exemple T 2 E 1 + 6 T 9 $ r4 +id$ r2 E 1 +id$ E 1 $ r1 E 1 + 6 id$ d6 T 2 E 1 + 6 T 9 $ r4 +id$ r2 E 1 +id$ E 1 $ r1 E 1 + 6 id$ d6 E 1 + 6 id 5 $ d5 Acceptation E 1 + 6 F 3 $ r6 Compilation

Exercices Simuler le moteur d’analyse pour les chaînes d’entrée suivantes : (id + id) * id (id * * id) Définir en parallèle l’arbre d’analyse Compilation

Construction des tables d’analyse LR Il existe 3 méthodes pour construire ces tables d’analyse : SLR (Simple LR) : la plus facile mais la moins puissante LR canonique : la plus puissante et la plus coûteuse LALR (Look Ahead LR) : puissance et coût intermédiaire La puissance dénote le nombre de grammaires pour lesquelles l’analyse réussit. Compilation

Item Définition. Item - Un item est une production avec un point repérant une position dans la partie droite de celle-ci. Soit la production AXYZ  4 items possibles : A XYZ A XYZ A XYZ A XYZ La production A fournit uniquement A Intuitivement, un item indique la « quantité » de partie droite qui a été reconnue, à un moment donné, au cours du processus d’analyse. XYZ indique que nous venons de voir en entrée une chaîne dérivée de X et que nous espérons maintenant voir une chaîne dérivée de YZ Compilation

Proto-phrase et phrase 𝑆 ⇒ 𝛼 Définition. Proto-phrase - Si où  peut contenir certains auxiliaires, on dit que  est une proto-phrase. Une phrase est une proto-phrase sans auxiliaire. Définition. Proto-phrase droite - Une proto-phrase droite est une proto-phrase obtenue par dérivations droites. Compilation

Préfixe viable aAbcde 3 manches : Abc, b et d Définition. Préfixe viable - Un préfixe viable est un préfixe d’une proto-phrase droite qui ne s’étend pas au-delà de l’extrémité droite du manche le plus à droite de cette proto-phrase. Exemple : S  aABe A  Abc | b B  d Phrase =abbcde Dérivation droite : S  aABe  aAde  aAbcde  abbcde aAbcde 3 manches : Abc, b et d Préfixes viables : a, aA, aAb, aAbc et aAbcd Au delà de aAbcd, aucune réduction des symboles de droite sont possibles L’ensemble des préfixes viables est l’ensemble des configurations de la pile d’analyse. Compilation

Item valide L’item A12 est valide pour un préfixe viable 1 s’il existe une dérivation . 𝑆 ′ ⇒ 𝑑 𝛼𝐴𝜔 ⇒ 𝑑 𝛼𝛽 1 𝛽 2 𝜔 Lorsque 1 se trouve dans la pile d’analyse, il faut décaler le symbole d’entrée suivant dans la pile. En revanche, si 2= alors il faut réduire. Compilation

Construction des tables d’analyse SLR Idée : construire un AFD pour reconnaître les préfixes viables les items sont regroupés en ensembles qui constituent les états de l’analyseur SLR Pour construire la table d’analyse, on utilise deux fonctions : Fermeture(I) : ensemble des items que l’on peut voir apparaître lorsque les items de I apparaîtront Transition(I,X) : ensemble des items qui sont valides pour le préfixe viable X tel que I est l’ensemble des items qui sont valides pour un préfixe viable donné  Compilation

Fermeture(I) Début J=I Répéter Pour chaque item A  B de J et chaque production B   de G telle que B   n’est pas dans J Faire ajouter B   à J Fin Pour Jusqu’à ce qu’aucun autre item ne puisse être ajouté à J Retourner J Fin Compilation

Exemple E’  E E  E + T | T T  T * F | F F  ( E ) | id E’E Fermeture({E’E}) T  T * F E’   E E   E + T E   T T   T * F T   F F   ( E ) F   id T   F T   F F  ( E ) F  id F   ( E ) F   id Compilation

Transition(I,X) Transition(I,X) = fermeture de l’ensemble de tous les items AX tels que AX appartient à I Transition({E’  E , E  E  + T},+) = Fermeture({E  E +  T}) ={E  E +  T, T   T * F, T   T, F   ( E ), F   id } Compilation

Construction de l’AFD Début C=Fermeture({S’S}) Répéter Pour chaque ensemble d’items I de C et chaque symbole X de la grammaire tel que Transition(I,X) soit non vide et non encore dans C Faire ajouter Transition(I,X) à C Fin Pour Jusqu’à ce qu’aucun nouvel ensemble d’items ne puisse plus être ajouté à C Fin Compilation

+ E T T * F F E ) ( id I6 : E  E +  T T   T * F T   F F   id + E’  E E  E + T | T T  T * F | F F  ( E ) | id I1 : E’  E  E  E  + T E I9 : E  E + T  T  T  * F T I2 : E  T  T  T  * F T I7 : T  T *  F F   ( E ) F   id * I10 : T  T * F  F I0 : E’   E E   E + T E   T T   T * F T   F F   ( E ) F   id I3 : T  F  F I8 : F  ( E  ) E  E  + T E I11 : F  ( E )  ) I4 : F  (  E ) E   E + T E   T T   T * F T   F F   (E ) F   id ( I5 : F  id  id

I1 + T I9 I6 I2 * * F E + T T ( F I7 I10 F I3 id ( I0 F ) E I8 I11 ( E’  E E  E + T | T T  T * F | F F  ( E ) | id I1 + T I9 I6 I2 * * F E + T T ( F I7 I10 F I3 id ( I0 F ) E I8 I11 ( I4 id id id ( I5

Construction des tables d’analyse SLR On augmente la grammaire de la production S’  S et S’ devient le nouvel axiome I0 = fermeture({S’  S}) Construire C = {I0, I1, …, In} de l’AFD Pour tout état i de l’AFD Faire Pour toute transition de i vers j, Action[i,a]=dj où a est le terminal porté par la transition Pour tout item de Ii de la forme A, Action[i,a]=rj pour tout a Suivant(A) où j le n° de la règle A dans G Si S’S est dans Ii Alors Action[i,$]=Acc Fin Si Pour toute transition de i vers j, Successeur[i,A]=j où A est l’auxiliaire porté par la transition Fin Pour Tout Toute entrée non définie est équivalente à une erreur d’analyse L’état initial est celui qui est construit à partir de l’ensemble d’items contenant S’ S Compilation

Exemple pour I0 deux transitions sur des terminaux ( et id vers les états 4 et 5 respectivement d’où action[0,(]=d4 et action[0,id]=d5 aucun item du type A donc aucune réduction depuis l’état I0 trois transitions sur des auxiliaires E, T et F vers les états 1, 2 et 3 respectivement d’où successeur[0,E]=1, successeur[0,T]=2 et successeur[0,F]=3 Compilation

Exercices Construire la table d’analyse de la grammaire suivante : E  E + T | T T  T F | F F  F * | a | b Compilation

Exercices Soit la grammaire G suivante : S  G = D | D G  * D | id D  G Construire l’AFD d’analyse ascendante Construire la table d’analyse SLR Compilation

Correction Compilation I0 : S’  S S  G=D S  D G  *D G  id I4 : G  *  D D  G G   * D G  id I7 : G  *D  I8 : D  G I9 : S  G=D I5 : G  id  I1 : S’  S I6 : S  G=  D D  G G  *D G  id I2 : S  G  =D D  G  I3 : S  D  Compilation

Correction S I0 I1 G D = I6 I9 I2 D * I3 * G D id I4 I7 * id G I8 id Compilation I5

Correction Compilation

Construction des tables d’analyse LR canonique Dans la méthode SLR, l’état i indique une action de réduction par A à la vue du terminal a si l’ensemble des items Ii contient A et a appartient à Suivant(A) Cependant, dans certains cas, quand l’état i apparaît en sommet de pile, le préfixe viable  de la pile est tel que A ne peut être suivi par a dans aucune proto- phrase. Compilation

Aucune proto-phrase droite commence par D=… seulement par Exemple S  G = D | D G  * D | id D  G I2 : S  G  =D D  G  Etant donné que l’item D  G  appartient à l’état 2 et que le symbole = appartient à Suivant(D), l’analyseur SLR effectue une réduction par D  G avec = *id = id S  G = D  G = id  * D = id  * G = id  *id = id Aucune proto-phrase droite commence par D=… seulement par *D= ou *id ou *…*id ou id La règle de réduction D  G avec = est interdite car non viable Compilation

Exemple *id=id G = id $ G = G $ D = id $ G = D $ G 2 =id$ r3 *id=id$ G 2 =id$ r3 *id=id$ id=id$ * 4 d4 G = id $ * 4 id 5 =id$ d5 * 4 G 8 =id$ r4 D = id $ G = D $ G = G $ * 4 D 7 =id$ r4 La réduction par DG doit être utilisé après = ou plus précisément à condition que le symbole suivant soit $ Compilation

Construction des tables d’analyse LR canonique Attacher une information supplémentaire : symboles d’entrée qui peuvent suivre un manche  pour lequel il y a une réduction possible vers A (A   Définition. Item LR(1) - La forme générale d’un item devient [A  a] où A   est une production et a est soit un terminal soit $ L’ensemble des terminaux a est inclus dans Suivant(A) Compilation

Construction des tables d’analyse LR canonique Formellement, on dit qu’un item LR(1) [A  a] est valide pour un préfixe viable  s’il existe une dérivation telle que :  =  et soit a est le premier symbole de  soit = et a=$ 𝑆 ⇒ 𝑑 𝛿𝐴𝜔 ⇒ 𝑑 𝛿𝛼𝛽𝜔 Pré-vision = 1 Compilation

Construction des tables d’analyse LR canonique Construire l’ensemble des items LR(1)  utiliser les fonctions Fermeture et Transition adaptée aux items LR(1) Construire l’AFD Bâtir la table d’analyse LR canonique à partir de l’AFD Compilation

Fermeture(I) Début J=I Répéter Pour chaque item [A  B,a] de J et chaque production B   de G et chaque terminal b de Premier(a) telle que [B  ,b] n’est pas dans J Faire ajouter [B  ,b] à J Fin Pour Jusqu’à ce qu’aucun autre item ne puisse être ajouté à J Retourner J Fin Compilation

Exemple [S’  S,$] S  G = D | D G  * D | id D  G S  G = D S  D et Premier($)={$} [S  G = D,$] [S  D,$] Fermeture([S’  S,$]) = [S’  S,$] [S  G = D,$] [S   D,$] [G   * D,=] [G   id,=] [D   G,$] [S  G = D,$] G  * D G  id et Premier(=$)={=} [G   * D,=] [G   id,=] [S   D,$] D  G et Premier($)={$} [D   G,$] Compilation

Transition(I,X) Transition(I,X) = fermeture de l’ensemble de tous les items [AX,a] tels que [AX,a] appartient à I Compilation

Exemple S  G = D | D G  * D | id D  G VN={S,G,D} VT={=,*,id} Transition([G   * D,$],*) =Fermeture([G  *  D,$]) ={[G  *  D,$], [D   G,$]} Premier($)= {$} Compilation

Construction de l’AFD Début C=Fermeture({[S’S,$]}) Répéter Pour chaque ensemble d’items I de C et chaque symbole X de la grammaire tel que Transition(I,X) soit non vide et non encore dans C Faire ajouter Transition(I,X) à C Fin Pour Jusqu’à ce qu’aucun nouvel ensemble d’items ne puisse plus être ajouté à C Fin Compilation

S G S’  S S  G = D | D G  * D | id D  G D G = D * * G D id id I1 : [S’  S ,$] S I9 : [D  G ,$] G S’  S S  G = D | D G  * D | id D  G I10 : [S  G = D ,$] D I2 : [S  G  = D,$] [D  G ,$] G I6 : [S  G =  D,$] [D   G,$] = I0 : [S’   S,$] [S   G = D,$] [S   D,$] [G   * D,=] [G   id,=] [D   G,$] I3 : [S  D ,$] D I5 : [G  id ,=] id * * I4 : [G  *  D,=] [D   G,=] [G   * D,=] [G   id,=] G I7 : [D  G ,=] D I8 : [G  * D ,=] id

Exercices Soit la grammaire G suivante : S  CC C  cC | d Calculer la fermeture de [S’S,$] Calculer les ensembles d’items à l’aide de la fonction Transition Construire l’AFD Correction ... Compilation

Correction S C c C c C d c d c C d d Compilation I1 : S’S,$ I5 : S CC,$ C I0 : S’S,$ S CC,$ C cC,c|d C d,c|d c I2 : S CC,$ C cC,$ C d,$ C I4 : C d,c|d d I3 : C cC,c|d C cC,c|d C d,c|d c I6 : C cC,$ C cC,$ C d,$ c I7 : C d,$ d I9 : C cC ,$ C d c I8 : C cC,c|d C d Compilation

Construction des tables d’analyse LR canonique On augmente la grammaire de la production S’  S et S’ devient le nouvel axiome I0 = fermeture({[S’  S,$]}) Construire C = {I0, I1, …, In} de l’AFD Pour tout état i de l’AFD Faire Pour toute transition de i vers j, Action[i,a]=dj où a est le terminal porté par la transition Pour tout item de Ii de la forme [A,a], Action[i,a]=rj où j le n° de la règle A dans G Si [S’S,$] est dans Ii Alors Action[i,$]=Acc Fin Si Pour toute transition de i vers j, Successeur[i,A]=j où A est l’auxiliaire porté par la transition Fin Pour Tout Toute entrée non définie est équivalente à une erreur d’analyse L’état initial est celui qui est construit à partir de l’ensemble d’items contenant [S’ S,$] Compilation

Exercices Soit la grammaire G suivante : S  CC C  cC | d Construire la table d’analyse LR canonique Correction ... Compilation

Correction Compilation

Exercices Soit la grammaire G suivante : S  Aa | bAc | Bc | bBa A  d B  d Construire la table d’analyse LR canonique Compilation

Construction des tables d’analyse LALR Recherche des ensembles d’items LR(1) ayant le même cœur ; un cœur est un ensemble d’items LR(0) Fusion de ces ensembles en un seul ensemble Compilation

Exemple - Items S  CC S  cC S  d Compilation I3 : C cC,c|d C d,c|d I6 : C cC,$ C cC,$ C d,$ I36 : C cC,c|d|$ C cC,c|d|$ C d,c|d|$ I4 : C d,c|d I7 : C d,$ I47 : C d,c|d|$ I8 : C cC,c|d I9 : C cC ,$ I89 : C cC,c|d|$ Compilation

Exemple - AFD I1 S I5 C I2 C d I0 c I47 d I36 c I89 C c d Compilation

Exemple - Tables d’analyse Compilation

Exercices Soit la grammaire G suivante : S  Aa | bAc | dc | bda A  d Construire la table d’analyse LALR S  Aa | bAc | Bc | bBa B  d Compilation

CUP : un générateur d'analyseurs syntaxiques

Principe sym.java cup parser.java sym.java javac parser.java monProg Grammaire non contextuelle parser.java sym.java javac parser.java monProg yylex.java java monProg Résultat de l'analyse Source à analyser

Attributs Un symbole, terminal ou non terminal peut avoir un attribut dont la valeur contribue à la caractérisation du symbole Lex transmet à bison les attributs des unités lexicales à travers la variable yylval qui par défaut est de type int $1, $2, ... désignent les valeurs des attributs des symboles constituant le membre droit de la production concernée, tandis que $$ désigne la valeur de l'attribut du membre gauche

Conflits et ambiguïtés Si on utilise la grammaire suivante : %% session : session expression '=' { printf ... } | ; expression : expression '+' expression ; | expression '-' expression ; | expression '*' expression ; | nombre ; cup indique les conflits shift/reduce conflict : conflit décaler – réduire reduce/reduce conflict : conflit réduire - réduire

Analyse syntaxique avec CUP Installer et tester CUP Exemple de programmes CUP Utiliser CUP avec Jflex

Explications générales sur cup Fichier exemple1.cup 4 parties principales dans le fichiers : Déclarations générales : importations, initialisation et mode de récupération des tokens ; Déclaration des terminaux et des non terminaux. Les terminaux peuvent être déclarés avec ou sans type (ici Integer)  ; Précédences et associativités des règles ; Règles de grammaire proprement dites.

Communication CUP/JFlex L'analyseur syntaxique (obtenu avec CUP) reçoit les "tokens" de l'analyseur lexical L'analyseur lexical (obtenu avec JFlex) doit envoyer les bons "tokens" À partir de calcul.cup deux classes générées : sym.java parser.java L'analyseur syntaxique attend des valeurs de type Symbol

Exécution de cup Compilation cup exemple1.cup génération des fichiers parser.java et sym.java sym.java contient les déclarations de constantes, une pour chaque terminal return new Symbol(sym.PLUS) parser.java implémente le parseur proprement dit

Exemple de grammaire ; /* calcul.cup */ import java_cup.runtime.*; parser code {: public void report_fatal_error( String message, Object info ) throws Exception { report_error (message, info ) ; throw new Exception("Syntax Error"); } :} ; terminal INT,PLUS,MOINS, FOIS,DIV,PARENG,PAREND; non terminal expr ; expr ::= expr PLUS expr | expr MOINS expr expr FOIS expr expr DIV expr PARENG expr PAREND INT ;

Fichier JFlex pour CUP /* calcul.flex */ import java_cup.runtime.*; //Pour travailler avec cip %% %class Lexi %unicode %line %column %cup %{ private Symbol symbol(int type) { return new Symbol(type, yyline, yycolumn); } %}

// modèles entier = [0-9]+ %% //Règles {entier} {System.out.print(yytext()); return symbol (sym.INT); } \+ {System.out.print(yytext()); return symbol (sym.PLUS); } - {System.out.print(yytext()); return symbol (sym.MOINS); } \* {System.out.print(yytext()); return symbol (sym.FOIS); } \/ {System.out.print(yytext()); return symbol (sym.DIV); } \( {System.out.print(yytext()); return symbol (sym.PARENG); } \) {System.out.print(yytext()); return symbol (sym.PAREND); } \n { System.out.print(yytext()); } . { System.out.print(yytext()); }

L'analyseur syntaxique complet Un Main utilisant le parseur Compilation : cup calcul.cup ou java -jar /usr/share/java/cup.jar calcul.cup jflex calcul.flex javac -cp /usr/share/java/cup.jar:. Lexi.java javac -cp /usr/share/java/cup.jar:. parser.java javac -cp /usr/share/java/cup.jar:. sym.java javac Main.java -cp /usr/share/java/cup.jar:. utilisation java -cp .:/usr/share/java/cup.jar Main exemple.txt 15 + 15 * 9 file OK

Attribut synthétisé But : calculer la valeur de chaque expression Calcul d'un attribut synthétisé val sur la grammaire Définition de val : Règle expr ::= INT val(expr) = val(INT) Règle expr ::= expr(1) PLUS expr(2) val(expr) = val(expr1) + val(expr2) Val est synthétisé : la valeur sur le membre gauche d'une règle est fonction des valeurs sur les membres de droite

Exemple de grammaire /* attribut.cup */ import java_cup.runtime.*; parser code {: public void report_fatal_error( String message, Object info ) throws Exception { report_error (message, info ) ; throw new Exception("Syntax Error"); } :} ; terminal Integer INT; terminal PLUS, MOINS, FOIS, DIV, PARENG, PAREND; non terminal list_expr; non terminal Integer expr; expr ::= expr:e1 PLUS expr:e2 {: RESULT = new Integer(e1.intValue() + e2.intValue()); :} | INT:n {: RESULT = new Integer(n.intValue()); :} |expr:e1 FOIS expr:e2 {: RESULT = new Integer(e1.intValue()*e2.intValue()); :} ;

Attention – fichier attribut.flex %{ // fonction pour manipuler des tokens avec ligne, colonne, nombre private Symbol symbol(int type, Object value){ return new Symbol(type, yyline, yycolumn, value);} private Symbol symbol(int type) { return new Symbol(type, yyline, yycolumn); } %} // modèles chiffre = [0-9] entier = {chiffre}+ espace = [ \t\n] %% // Règles {entier} { return symbol (sym.INT, new Integer(yytext())); } \+ { return symbol (sym.PLUS); }

Chapitre 3. Traduction dirigée par la syntaxe Compilation

Introduction Objectifs : Produire du code : traduire un langage L1 en un langage L2 Interpréter, évaluer et exécuter Moyens : Attacher des attributs aux symboles de la grammaire Evaluer les attributs par des règles sémantiques associées aux productions de la grammaire Compilation

Définitions Définition. Définition dirigée par la syntaxe - Généralisation d’une grammaire non contextuelle, dans laquelle chaque symbole possède un ensemble d’attributs de deux types : attributs synthétisés et attributs hérités. Un attribut peut représenter tout ce que l’on veut : un nombre, une chaîne de caractères, un type, une adresse mémoire… Compilation

Définitions Définition. Attribut synthétisé - La valeur d’un attribut synthétisé en un nœud est calculée à partir des valeurs des attributs des nœuds fils dans l’arbre syntaxique Définition. Attribut hérité - La valeur d’un attribut hérité en un nœud est calculée à partir des valeurs des attributs des nœuds frères et père. Compilation

Définitions Définition. Dépendance - Les règles sémantiques (règles de calcul des attributs) impliquent des dépendances entre les attributs. Les dépendances sont représentées par un graphe. On déduit l’ordre d’évaluation des règles grâce aux dépendances. Un arbre syntaxique muni des valeurs des attributs à chaque nœud est appelé un arbre annoté ou décoré. Compilation

Définitions Dans une grammaire dirigée par la syntaxe, chaque production A de la grammaire possède un ensemble des règles sémantiques de la forme b=f(c1,c2,…,ck) où : f est une fonction soit b est un attribut synthétisé de A soit b est un attribut hérité d’un des symboles en partie droite de la production c1,c2,…, ck sont des attributs de symboles quelconques de la production. Compilation

Exemple - Grammaire des expressions On associe un attribut synthétisé val, de type entier, à chacun des auxiliaires E,T et F. Compilation

Exemple L 3*5+4n 19 n E.val E.val 15 T.val 4 + 15 T.val F.val 4 T.val chiffre.vallex 4 F.val 3 chiffre.vallex 5 3 chiffre.vallex Compilation

Exercices Construire, pour l’expression (4*7+1)*2, un arbre syntaxique décoré Dans la grammaire qui suit, l’attribut synthétisé val donnera la valeur (décimale) du nombre binaire engendré par S. Pour exemple pour le texte 101.101, S.val = 5,625 S  L . L | L L  L B | B B  0 | 1 Utiliser des attributs synthétisés pour déterminer S.val Compilation

Exemple - Attribut hérité Déclaration de variables entières ou réelles On attache : à l’auxiliaire T un attribut synthétisé type à l’auxiliaire L un attribut hérité typeh Compilation

Exemple réel id1, id2, id3 D L.typeh T.type réel réel réel L.typeh , Compilation

Graphes de dépendances Si un attribut b à un nœud d’un arbre syntaxique dépend d’un attribut c, la règle sémantique définissant b doit être évaluée après la règle sémantique qui définit c. Construction d’un graphe orienté Graphe de dépendances Compilation

Graphes de dépendances Avant de construire un graphe de dépendances, mettre toutes les règles sémantiques sont la forme b=f(c1,c2,…,ck) Ajouter des attributs fictifs pour toute règle faisant appel à des procédures Compilation

Exemple A  X Y A.a = f(X.x, Y.y) A X Y X.h = g(A.a, Y.y) a x y h Compilation

Ordre d’évaluation A partir d’un tri topologique du graphe de dépendances, on obtient un ordre d’évaluation des règles sémantiques. Un tri topologique consiste à ordonner les sommets tels que si mimj est un arc de mi à mj alors mi doit apparaître avant mj. Compilation

Exemple a 1 2 3 x y h x a y h Compilation

Construction des arbres abstraits Définition. Arbre abstrait - Un arbre abstrait est une forme condensée d’arbre syntaxique. Dans un arbre abstrait, les opérateurs et les mots clés n’apparaissent pas comme des feuilles mais comme des nœuds. Compilation

Exemple Expression : 3*5+4 4 5 3 + * F T E + * 4 3 5 Compilation

Construction d’arbres abstraits pour les expressions Nous allons définir trois fonctions qui seront appelées dans les règles sémantiques de la grammaire des expressions : CréerNoeud(op,gauche,droit) : création d’un nœud « opérateur » avec deux pointeurs sur les sous-arbres gauche et droit CréerFeuille(id,entrée) : création d’un nœud « identificateur » avec un pointeur vers la table des symboles CréerFeuille(nb,val) : création d’un nœud « nombre » avec un champ contenant la valeur Compilation

Construction d’arbres abstraits pour les expressions Compilation

Exemple a-4+c E + E - id T id + E nb T nb 4 - id T id Compilation pnoeud + E pnoeud - id T pnoeud id + E nb T pnoeud nb 4 - id T pnoeud id Compilation

Graphes orientés acycliques pour les expressions Définition. Graphe orienté acyclique (DAG) - Un graphe orienté acyclique correspondant à un graphe dans lequel on a identifie les sous-expressions identiques. Compilation

Exemple a + a * ( b - c ) + ( b - c ) * d On peut remarquer que deux sous-expressions sont identiques : a et b-c + * d a - b c Compilation

Exercice Construire le DAG de l’expression a+a+(a+a+a+(a+a+a+a)) en supposant que l’opérateur + est associatif à gauche Compilation

Evaluation ascendante des attributs synthétisés Définition. Définitions S-attribuées - Ce sont des définitions ne comportant que des attributs synthétisés. Idées : Evaluer au cours de l’analyse syntaxique L’analyseur syntaxique peut conserver dans sa pile les valeurs des attributs synthétisés associés aux symboles de la grammaire Chaque fois qu’une réduction est effectuée, les valeurs des nouveaux attributs sont calculés et empilés Compilation

Exemple 3*5+4 d7 T 2 5+4$ * 7 T 2 +4$ * 7 d5 nb 5 3*5+4$ 3 * *5+4$ nb T 2 5+4$ * 7 3*5+4 T 2 +4$ * 7 d5 nb 5 3*5+4$ 3 * *5+4$ nb 5 d5 r6 T 2 * 7 F 10 +4$ r6 *5+4$ F 3 3 * 5 3 T 2 r3 +4$ T 2 r4 *5+4$ 3 * 5 3 15 Compilation 3

Exemple T 2 +4$ E 1 + 6 T 9 $ r4 r2 E 1 +4$ 15 E 1 $ r1 15 + 4 E 1 + 6 T 2 +4$ E 1 + 6 T 9 $ r4 r2 E 1 +4$ 15 E 1 $ r1 15 + 4 E 1 + 6 4$ d6 15 E 1 + 6 nb 5 $ d5 19 15 + Acceptation E 1 + 6 F 3 $ r6 15 + 4 Compilation 15 + 4

Exercice Evaluer à l’aide de la pile d’analyse syntaxique ascendante les expressions suivantes : 1+3 (3+4)*3 Compilation