IFT313 Introduction aux langages formels

Slides:



Advertisements
Présentations similaires
IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke planiart.usherbrooke.ca/kabanza/cours/ift313.
Advertisements

IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke planiart.usherbrooke.ca/kabanza/cours/ift313.
IFT313 Introduction aux langages formels
IFT313 Introduction aux langages formels
IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke planiart.usherbrooke.ca/kabanza/cours/ift313.
IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke Analyseurs récursifs LL (1)
IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke Automates à pile LR Notion de poignée.
Réalisé par R. MARRAKHA. KHAYAR Khayar-marrakh Université Hassan-II Faculté des sciences Aïn chock Casablanca Professeurs assistants - département de physique.
Comment utiliser le débogueur de Visual Studio /8/2015 INF145 1 Créé par Julien Galarneau Allaire, révisé par Eric Thé S.E.G.
Cours COMPOSANTES DES VECTEURS Dimitri Zuchowski et Marc-Élie Lapointe.
UE2 - M22 Licence acoustique
Calcul de probabilités
Les Instructions Itératives (Les Boucles)
Introduction au Langage Pascal
Ce videoclip produit par l’Ecole Polytechnique Fédérale de Lausanne
Dimitri Zuchowski et Marc-Élie Lapointe
Coloration de graphe, backtracking, branch and bound
IFT313 Introduction aux langages formels
Algorithme et programmation
Instructions de contrôle
Algorithmique AU El harchaoui noureddine
SNMP - Comment calculer l'utilisation de la Bande passante
Lois fondamentales de l'algèbre de Boole
Algorithmique demander jeu du pendu.
Ce videoclip produit par l’Ecole Polytechnique Fédérale de Lausanne
Les opérations sur les nombres
L’Instruction de Test Alternatif
IFT 615 – Intelligence artificielle Recherche heuristique
Javadoc et débogueur Semaine 03 Version A16.
Bddictionnairique Phase 1
Les Instructions – Organigramme
L’I NSTRUCTION DE T EST A LTERNATIF Réalisé par : OUZEGGANE Redouane Département de Technologie Faculté de Technologie – Université A.Mira, Bejaia Année.
L ES I NSTRUCTIONS I TÉRATIVES (L ES B OUCLES ) Réalisé par : OUZEGGANE Redouane Département de Technologie Faculté de Technologie – Université A.Mira,
Information, Communication, Calcul
IFT313 IFT313 Introduction aux langages formels Froduald Kabanza Département d’informatique Université de Sherbrooke planiart.usherbrooke.ca/kabanza/cours/ift313.
Cours N°10: Algorithmiques Tableaux - Matrices
PROGRAMMATION ET ENSEIGNEMENT
Chapter 12: Structures de données
Introduction aux langages formels
Exercice PHP DEUST TMIC
Réseaux de neurones appliqués à la reconnaissance de caractères
Formation sur les bases de données relationnelles.
NUMERATION et REPRESENTATION DES NOMBRES
IFT313 Introduction aux langages formels
IFT313 Introduction aux langages formels
Semaine #2 INF130 par Frédérick Henri.
IFT313 Introduction aux langages formels
Université de la méditerranée
IFT313 Introduction aux langages formels
IFT313 Introduction aux langages formels
IFT313 Introduction aux langages formels
Le code de Huffman: est une méthode de compression statistique de données qui permet de réduire la longueur du codage d'un alphabet. Le code de Huffman.
Chapitre 3: Les scriptes
IFT313 Introduction aux langages formels
IFT313 Introduction aux langages formels
Global Challenge Capteur de nuit Leçon 2.
Reconnaissance de formes: lettres/chiffres
IFT313 Introduction aux langages formels
PRO1026 Programmation et enseignement
IFT313 Introduction aux langages formels
H. Wertz -- Exécution Symbolique
PROGRAMMATION ET ENSEIGNEMENT
Chapitre 12 : Notion de fonction
Introduction à L’Informatique
Chapter 11: Récursivité Java Software Solutions Second Edition
Introduction à L’Informatique
Python Nicolas THIBAULT
Type Tableau Partie 1 : Vecteurs
La loi des signes.
Dérivation – Fonctions cosinus et sinus
Transcription de la présentation:

IFT313 Introduction aux langages formels Froduald Kabanza Département d’informatique Université de Sherbrooke planiart.usherbrooke.ca/kabanza/cours/ift313 Ensembles first et follow

Sujets C’est quoi un symbole nullable pour une grammaire? C’est quoi un ensemble first pour une grammaire ? C’est quoi un ensemble follow pour une grammaire ? Quel l’algorithme pour calculer ces symboles et ces ensembles ? Quel est le rôle de ces concepts dans l’analyse syntaxique descendante (prédictive) ? C’est quoi une table d’analyse LL ? Comment la calculer. IFT313 © Froduald Kabanza

Exemple Entrée : n+n*n Algorithm LLDriver En d’autres mots: 1. E ® TE’ 2. E’ ® + TE’ | 3. ε 4. T ® FT’ 5. T’ ® *FT’ | 6. ε 7. F ® ( E ) | n Entrée : n+n*n S Þ déjà lu + pile * Étape Règle Pile Entrée * 0. 3. 2. 1. E ® TE’ T ® FT’ F ® n T’ ® ε E’ ® +TE’ T’ ® *FT’ T’® ε E’® ε E$ TE’$ FT’E’$ nT’E’$ T’E’$ E’$ +TE’$ FT’É’$ *FT’E’$ $ n+n*n$ +n*n$ n*n$ *n$ n$ $ E Þ TE’ FT’E’ nT’E’ nE’ n +TE’ n+TE’ n+FT’E’ n+nT’E’ n+n*FT’E’ n+n*nT’E’ n+n*nE’ n+n*n Algorithm LLDriver 0. stack = ($S); a = in.read(); x=stack.top(); while (true) { 1. if (x = = $) && (a= = $) return true ; 2. if (x = = a) { pop a from stack; a = in.read(); continue;} 3. if x is a nonterminal { find x  y; pop x from stack; push y on stack; continue; } 4. exit with error;} Grammaire pour les expressions arithmétiques et pilote d’analyse LL Deux observations importantes 1. L’exécution du driver LL, sur une chaîne d’entrée donne la dérivation la plus à gauche de l’entrée dans la mesure où si on concatène le préfixe de la chaîne déjà scannée avec le contenu de la pile, on obtient une forme sententielle gauche de la grammaire. 2. (Corollaire) Ceci veut dire à tout instant durant l’exécution du driver LL, la chaîne restant à scanner doit être dérivable de la chaîne de symbole sur la pile pour que la chaîne de départ soit acceptée. En d’autres mots: Soit alpha le contenu de la pile à une étape quelconque, v le reste de la chaîne à lire et w la chaîne d’entrée originale (donc w = uv avec u la chaîne déjà lue; forcément dans A*). Alors, on doit avoir alpha => v pour que la chaîne d’entrée soit acceptée, c’est-à-dire, pour que S => w (avec S le symbole de départ de la grammaire). return true IFT313 © Froduald Kabanza

Définition de l’ensemble First Étant donné a une chaîne de terminaux et de non-terminaux, alors First(a) est l’ensemble de terminaux commençant une chaîne dérivée de a. Exemple : First(TE’) = {(, n, +} First(+TE’) = { + } First(FT’) = { (, n} First(*FT’) = { * } First((E)) = { ( } First(n) = { n} G = (V, A, R, E) : V = {E, E’, T, T’} A = {(, ), +, *, n} R = { E ® TE’ E’ ® + TE’ | ε T ® FT’ | ε T’ ® *FT’ | ε F ® ( E ) | n} IFT313 © Froduald Kabanza

Utiliser l’ensemble First dans le driver LL Si le sommet de la pile contient un terminal X, le driver LL doit prédire la règle X ® a tel que le prochain token est dans First(a). Exemple : First((E)) = {( } First(n) = {n} Si le sommet de la pile est F : - si le prochain token est ( , le driver LL prédit F ® ( E ) - sinon, si le prochain token est n le driver LL prédit F ® n - sinon le driver sort avec une erreur. G = (V, A, R, E) : V = {E, E’, T, T’} A = {(, ), +, *, n} R = { E ® TE’ E’ ® + TE’ | ε T ® FT’ | ε T’ ® *FT’ | ε F ® ( E ) | n} IFT313 © Froduald Kabanza

Utiliser l’ensemble First dans le driver LL Si la grammaire ne contient pas deux productions X ® a et X ® b telles que First(a) et First(b) ont une intersection, alors le driver LL exécute de manière déterministe : Il y a zéro ou une production à prédire à chaque étape. Par contre si la grammaire contient deux productions X ® a and X ® b telles que First(a) et First(b) ont une intersection, le driver LL ne peut pas prédire la production à appliquer en lisant juste un token : le driver LL exécuterait de manière non-déterministe. On va justement éviter des grammaires qui donneraient lieu à un tel non-déterminisme. IFT313 © Froduald Kabanza

Exemple First(n) = {n} G = (V, A, R, E) : First((E)) = {(} V = {E} A = {(, ), +, *, n} R = { 1. E ® n 2. E ® (E) 3. E ® E+E 4. E® E*E} First(n) = {n} First((E)) = {(} First(E+E) = {n,(} First(E*E) = {n,(} Si le sommet de la pile est E : - Si le prochain token est n, le driver ne peut pas prédire laquelle des productions 1, 3 ou 4 est appropriée. - Si le prochain token est (, le driver ne peut pas prédire non plus laquelle des productions 2, 3 ou 4 est appropriée. IFT313 © Froduald Kabanza

Motivation pour l’ensemble Follow Nous venons de voir que la bonne production à prédire est une règle X ® a telle le prochain token est dans First(a ). Toute fois, cette ligne directrice doit être généralisée pour tenir compte des productions commençant par la chaîne vide. Pour ce faire, nous allons introduire les notions de symbolles nullables et d’ensemble Follow. IFT313 © Froduald Kabanza

Motivation pour les symboles nullables À première vue le calcul de l’ensemble First parait très simple. Si a= XY, on a l’impression que Y peut être ignoré et que First(a)= First(XY) = First(X). En fait, cela est vrai uniquement si X ne peut pas dériver la chaîne vide. Autrement, First(a) doit aussi inclure First(Y). Exemple : G = (V, A, R, S) : V = {X, Y, S} A = {a, b, c} R = { 1. S ® a | 2. S ® X Y S 3. X ® b | 4. X ® Y 5. Y ® ε | 6. Y ® c} First(S) = { a, b, c } First(X) = { b, c } First(Y) = { c } First(a) = { a } First(b) = { b } First(c) = { c} Puisque X peut dériver Y (production 4), une chaîne dérivée de XYS peut tout aussi bien être dérivée de YYS. Vu que Y peut dériver la chaîne vide (production 5), la chaîne peut tout aussi bien être dérivée de YS, ou de S. First(S) = { a, b, c } First(X) = { b, c } First(Y) = { c } First(a) = { a } First(b) = { b } First(c) = { c} Puisque X peut dériver Y (production 4), une chaîne dérivée de XYS peut tout aussi bien être dérivée de YYS. Vu que Y peut dériver la chaîne vide (production 5), la chaîne peut tout aussi bien être dérivée de YS, ou de S. IFT313 © Froduald Kabanza

Définition de symboles nullables On vient de voir qu’en calculant First(S) ou First(XYS) on doit tenir compte des non-terminaux qui pourraient dériver la chaîne vide et de ceux qui pourraient les suivre dans une dérivation. Les non-terminaux qui peuvent dériver la chaîne vides sont appelés des symboles nullables. Ainsi, X et Y sont nullables dans la grammaire ci après. Exemple : G = (V, A, R, S) : V = {X, Y, S} A = {a, b, c} R = { 1. S ® a | 2. S ® X Y S 3. X ® b | 4. X ® Y 5. Y ® ε | 6. Y ® c} First(S) = { a, b, c } First(X) = { b, c } First(Y) = { c } First(a) = { a } First(b) = { b } First(c) = { b } Puisque X peut dériver Y (production 4), une chaîne dérivée de XYS peut tout aussi bien être dérivée de YYS. Vu que Y peut dériver la chaîne vide (production 5), la chaîne peut tout aussi bien être dérivée de YS, ou de S. IFT313 © Froduald Kabanza

Définitions formelles nullable(X) est vrai si et seulement si X peut dériver la chaîne vide en zéro ou plusieurs étapes. First(a) est l’ensemble de terminaux qui pourraient commencer une chaîne dérivée de a. Follow(X) est l’ensemble de terminaux qui pourraient suivre X immédiatement, dans une forme sententielle. En d’autres mots, l’ensemble de terminaux a tels que S => g Xab pour g et b quelconques. En plus, si X peut être le dernier symbole dans une forme sententielle, on ajoute $ à Follow(X). Ceci arriverait aussi si une dérivation contient XY tel que Y peut dériver la chaîne vide. Récursivement, ceci arriverait aussi si une dérivation contient XYZ tel que Y et Z peuvent chacun dériver la chaîne vide. Ainsi de suite … * IFT313 © Froduald Kabanza

Définitions formelles Une définition plus formelle de nullable, First and Follow est que ce sont les plus petits ensembles pour lesquels les propriétés suivantes sont valides : If S is the start symbol, then Follow[S] contains $; For each terminal symbol a, First(a) = { a }; For each production X ® Y1 … Yk If Y1 … Yk are all nullable or (if k = 0) nullable[X] = true; for each i from 1 to k, if Y1… Yi-1 are all nullable (or if i=1) First[X] = Union(First[X], First[Yi]); if Yi+1… Yk are all nullable (or if i=k) Follow[Yi] = Union(Follow[Yi], Follow[X]); for each j from i + 1 to k if Yi+1… Yj-1 are all nullable (or if i+1=j) Follow[Yi] = Union(Follow[Yi], First[Yj]); Pour obtenir les ensembles nullable, First et Follow, on calcule le point fixe (ou la fermeture) de ces équations (c-à-d., on refait des itérations tant qu’on n’obtient pas une solution stable). Note: cet algorithme est tiré du livre [2] dans le plan de cours: Appel, A. W. Modern Compiler Implementation in Java. Second Edition. Cambridge University Press, 2004, page 49. Par contre, j’ai réorganisé les instructions un peu différemment. Dans la version originale, il y a une seule boucle itérant sur deux variables (i et j) à la fois, au lieu de deux boucles imbriquées. Cela parait plus simple et plus intuitif. Par contre, pour ceux qui veulent un pseudocode le plus proche du code, il y a deux incongruités. Premièrement, vu que l’instruction « if Y1… Yi-1 are all nullable (or if i=1) First[X] = Union(First[X], First[Yi]);” est mise dans la boucle pour j, on a que, pour i=1, on ne passe pas dans la boucle; ainsi pour une règle de production X->a, on ne calculerait pas First(X)={a}. Deuxièmement, l'instruction " if Yi+1…Yk are all nullable (or if i=k) Follow[Yi] = Union(Follow[Yi], Follow[X]);" ne porte pas sur "j“ et donc n’a pas de raison d’être dans la boucle sur “j”. IFT313 © Froduald Kabanza

Algorithme pour calculer nullable, First et Follow Algorithme nullableFirstFollow Entrée : une grammaire. Sortie : Trois vecteur (nullable, First et Follow) tel que pour chaque symbole de grammaire X (terminal ou non): nullable(X) est true si X est nullable First(X) est l’ensemble de terminaux qui peuvent commencer une chaîne dérivable de X Follow(X) est l’ensemble de terminaux qui peuvent suivre X dans une dérivation. IFT313 © Froduald Kabanza

Algorithme pour calculer nullable, First et Follow Algorithme nullableFirstFollow initialize all entries of First and Follow to the empty set and those of nullable to false; set Follow[S] = {$}, where S is the start symbol and $ the end marker; for each terminal symbol a, First(a) = {a}; do { for each production X ® Y1…Yk { if Y1…Yk are all nullable or (if k = 0) nullable[X] = true; for (i = 1; i <= k; i++) { if Y1…Yi-1 are all nullable (or if i=1) First[X] = Union(First[X], First[Yi]); if Yi+1…Yk are all nullable (or if i=k) Follow[Yi] = Union(Follow[Yi], Follow[X]); for (j = i+1; j <= k; j++) if Yi+1…Yj-1 are all nullable (or if i+1=j) Follow[Yi] = Union(Follow[Yi], First[Yj]); } } while First, Follow or nullable is modified in the current iteration La note dans la Slide 20 s’applique ici aussi. IFT313 © Froduald Kabanza

Exemple 1 S X Y G = (V, A, R, S) : V = {X, Y, S} A = {a, b, c} Iter 0. nullable false false false G = (V, A, R, S) : V = {X, Y, S} A = {a, b, c} R = { 1. S ® a 2. S ® X Y S 3. X ® b 4. X ® Y 5. Y ® ε 6. Y ® c} First {} {} {} Follow {$} {} {} Iter 1. nullable false false true First {a} {b} {c} Follow {$} {a, c} {a} Iter 2. nullable false true true First {a, b, c} {b, c} {c} Follow {$} {a, b, c} {a,b, c} IFT313 © Froduald Kabanza

Exemple 2 E E’ T T’ F G = (V, A, R, E) : V = {E, E’, T, T’, F, (, )} A = {(, ), +, *, n} R = { E ® TE’ E’ ® + TE’ | ε T ® FT’ T’ ® *FT’ | ε F ® ( E ) | n } nullable false true false true false First {(,n} {+} {(,n} {*} {(,n} Follow {), $} {), $} {+, ), $} {+, ), $} {+,*,), $} E E’ T T’ F Nullable false true false true false First (, n + (, n * (, n Follow ), $ ), $ +, ), $ +, ), $ +, *, ), $ IFT313 © Froduald Kabanza

Généralisation aux chaînes de symboles Il est utile de généraliser nullable et First à de chaînes de symboles d’une grammaire : Étant donne une chaîne a, nullable(a) si et seulement si chaque symbole de a est nullable. Étant donne un symbole X et une chaîne g : First(Xg)=First[X] if not nullable[X] First(Xg)=Union(First[X], First(g)) if nullable[X] IFT313 © Froduald Kabanza

Comment prédire une production ? Nous utilisons les ensembles First et Follow pour prédire une production en fonction du non-terminal au dessus de la pile et du prochain token (terminal) à l’entrée. L’idée de base est que si le sommet de la pile est A, et le prochain token est a, alors on prédit la production A ® a telle que a est dans First(a). Ainsi le driver LL va appliquer A ® a , en remplaçant A par a au sommet de la pile. La seule complication est lorsque a peut dériver la chaîne vide. Dans ce cas, nous allons prédire A ® a si a est dans Follow(A) (ceci inclus le cas où le prochain token est $ (EOF) et $ est dans Follow(A)). IFT313 © Froduald Kabanza

Exemple E E’ T T’ F G = (V, A, R, E) : V = {E, E’, T, T’, F, (, )} nullable First Follow true false {(,n} {+} {*} {), $} {+, ), $} T’ F {+,*,), $} G = (V, A, R, E) : V = {E, E’, T, T’, F, (, )} A = {(, ), +, *, n} R = { E ® TE’ E’ ® + TE’ | ε T ® FT’ T’ ® *FT’ | ε F ® ( E ) | n } IFT313 © Froduald Kabanza

Exemple E E’ T T’ F Entrée : n+n*n Algorithm LLDriver nullable First Follow true false {(,n} {+} {*} {), $} {+, ), $} T’ F {+,*), $} Exemple 1. E ® TE’ 2. E’ ® + TE’ | 3. ε 4. T ® FT’ 5. T’ ® *FT’ | 6. ε 7. F ® ( E ) | n Entrée : n+n*n Étape Règle Pile Entrée Algorithm LLDriver 0. stack = ($S); a = in.read(); x=stack.top(); while (true) { 1. if (x = = $) && (a= = $) return true ; 2. if (x = = a) { pop a from stack; a = in.read(); continue;} 3. if x is a nonterminal { find x  y; pop x from stack; push y on stack; continue; } 4. exit with error;} 0. 3. 2. 1. E ® TE’ T ® FT’ F ® n T’ ® ε E’ ® +TE’ T’ ® *FT’ T’® ε E’® ε E$ TE’$ FT’E’$ nT’E’$ T’E’$ E’$ +TE’$ FT’É’$ *FT’E’$ $ n+n*n$ +n*n$ n*n$ *n$ n$ $ return true IFT313 © Froduald Kabanza

Résumé Une fois de plus, voici les règles pour prédire une production: L’idée de base est que si le sommet de la pile est A, et le prochain token est a, alors on prédit la production A ® a telle que a est dans First(a). Ainsi le driver LL va appliquer A ® a , en remplaçant A par a au sommet de la pile. La seule complication est lorsque a peut dériver la chaîne vide. Dans ce cas, nous allons prédire A ® a si a est dans Follow(A) (ceci inclut le cas où le prochain token est $ (EOF) et $ est dans Follow(A)). Avec ces règles, on peut générer une table d’analyse M, telle que M[A,a] contient la règle de production à appliquer lorsque A est au sommet de la pile et a est le prochain token. Nous verrons comment à la prochaine leçon. IFT313 © Froduald Kabanza