La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

IFT313 Introduction aux langages formels

Présentations similaires


Présentation au sujet: "IFT313 Introduction aux langages formels"— Transcription de la présentation:

1 IFT313 Introduction aux langages formels
Froduald Kabanza Département d’informatique Université de Sherbrooke Automates à pile LR Notion de poignée

2 Sujets Automate à pile LR Notion de poignée (handle)
Définition Simulation Notion de poignée (handle) Ébauche d’un pilote (driver) LR IFT313 © Froduald Kabanza

3 Pouvoir définir et simuler un automate à pile LR.
Objectifs Pouvoir définir et simuler un automate à pile LR. Pouvoir définir la notion de poignée (handle). Introduction aux défis fondamentaux de l’analyse LR. IFT313 © Froduald Kabanza

4 Références [2] Appel, A. and Palsberg. J. Modern Compiler Implementation in Java. Second Edition. Cambridge, 2004. Section 3.3 [4] Aho, A., Lam, M., Sethi R., Ullman J. Compilers: Principles, Techniques, and Tools, 2nd Edition. Addison Wesley, 2007. Section 4.5 IFT313 © Froduald Kabanza

5 Rappel Un générateur d’analyseurs syntaxiques LL(1) fonctionne comme suit : Son entrée est une grammaire. Le générateur LL(1) a accès à un driver LL(1). À partir de la grammaire, le générateur calcule une table d’analyse capable de déterminer (prédire) la production à appliquer, en fonction du non-terminal (partie gauche de la règle de production) au sommet de la pile et du prochain token. La sortie est juste une combinaison du driver LL(1) et de la table d’analyse. La sortie est équivalente à un automate à pile LL(1). IFT313 © Froduald Kabanza

6 Rappel Un analyseur LL(1) effectue la dérivation la plus à gauche, dans ce sens que: à chaque instant, la chaîne restant à lire est dérivable du contenu de la pile par une dérivation la plus à gauche. Par conséquent les étapes d’un analyseur LL(1) consistent à : Développer le non terminal au sommet de la pile en le remplaçant par la partie droite d’une règle de production commençant par ce non terminal (prédiction d’une étape de dérivation à gauche). Enlever le terminal au sommet de la pile lorsqu’il correspond au prochain token (reconnaître le préfixe de la chaîne dérivée jusqu’à cet étape par une dérivation à gauche) IFT313 © Froduald Kabanza

7 Rappel L’analyse LL(1) détermine la production à appliquer au non-terminal au sommet de la pile juste en lisant le prochain token sur l’entrée. Toutefois, ceci est faisable seulement si la grammaire ne contient pas des productions récursives à gauche, partageant un préfixe, ou ambigües. Si une grammaire ne remplit pas ces conditions, nous devons la transformer en une grammaire équivalente les satisfaisant. Très souvent, cela donne lieu à une grammaire moins intuitive, ne reflétant pas naturellement la grammaire de notre langage de programmation. Une telle grammaire peut être difficile à déboguer et à mettre à jour. La méthode d’analyse LR évite ces problèmes. Le devoir #4 illustre bien les limites de l’analyse LL(1), c-à-d., le caractère non naturel de la grammaire LL(1). IFT313 © Froduald Kabanza

8 LL vs LR Un analyseur LL Commence avec une chaîne de tokens et un symbole de départ de la grammaire. Répétitivement, il détermine la production à utiliser pour dériver le reste de la chaîne de tokens : on remplace le symbole au sommet de la pile correspondant à la la partie gauche d’une règle de production, par la partie droite. C’est une approche de haut en bas (du symbole de départ vers la chaîne des tokens). Cela donne une dérivation la plus à gauche de la chaîne de tokens à partir du symbole de départ. Un analyseur LR Commence aussi par la chaîne de tokens, mais le symbole de départ de la grammaire n’est pas impliqué dès le départ. Répétitivement, on met autant de tokens que possible sur la pile, jusqu’à avoir une sous-chaîne au sommet de la pile correspond à la partie droite d’une production; on peut alors remplacer la sous-chaîne sur la pile par la partie gauche de la production. C’est une approche de bas en haut (de la chaîne de tokens vers le symbole de départ). Cela donne la dérivation la plus à droite à partir du symbole de départ. IFT313 © Froduald Kabanza

9 Exemple – Automate à pile LL
ε, S/aABe – Prédire S ® aABe ε, A/Abc - Prédire A ® Abc ε, A/b - Prédire A ® b ε, B/d - Prédire B ® d a, a/ε - reconnaître ‘a’ b, b/ε - reconnaître ‘b’ c, c/ε - reconnaître ‘c’ d, d/ε - reconnaître ‘d’ e, e/ε - reconnaître ‘e’ p ε, ε/S q Grammaire G = (V,A,R,S), avec V = {S, A, B} A = {a, b, c, d , e} R = { S ® aABe, A ® Abc | b B ® d } IFT313 © Froduald Kabanza

10 Exemple – Automate à pile LL
ε, S/aABe ε, A/Abc ε, A/b ε, B/d a, a/ε b, b/ε c, c/ε d, d/ε e, e/ε p ε, ε/S q Grammaire G = (V,A,R,S), avec V = {S, A, B} A = {a, b, c, d , e} R = { S ® aABe, A ® Abc | b B ® d } IFT313 © Froduald Kabanza

11 Exemple – Automate à pile LL
Règles de la grammaire S ® aABe, A ® Abc | b B ® d Entrée: abbcde (pile, entrée) Action Symbole de départ sur pile 1. ( S$, abbcde$) Prédire S ® aABe 2. ( aABe$, abbcde$) Reconnaître ‘a’ 3. ( ABe$, bbcde$) Prédire A ® Abc 4. ( AbcBe$, bbcde$) Prédire A ® b 5. ( bbcBe$, bbcde$) Reconnaître ‘b’ 6. ( bcBe$, bcde$) Reconnaître ‘b’ 7. ( cBe$, cde$) Reconnaître ‘c’ 8. ( Be$, de$) Prédire B ® d 9. ( de$, de$) Reconnaître ‘d’ 10. ( e$, e$) Reconnaître ‘e’ 11. ( $, $) Accept ε, S/aABe ε, A/Abc ε, A/b ε, B/d a, a/ε b, b/ε c, c/ε d, d/ε e, e/ε p ε, ε/S q IFT313 © Froduald Kabanza

12 Automate à pile LR : description informelle
La technique utilisée par les analyseurs LR est appelée “shift-reduce” (avance-réduit) par opposition à “predict-match” des analyseurs LL. L’idée est de lire les tokens, un à un, en les mettant sur la pile. À chaque étape, on analyse la pile pour vérifier si elle contient une sous-chaîne au sommet correspondant à une partie droite d’une production. Si oui, on remplace la sous-chaîne par la partie gauche. Ceci équivaut à une étape de dérivation. Cette étape est appelée “reduire (la pile)”. Sinon, on continue à lire les tokens, en les déplaçant au sommet de la pile, jusqu’à avoir une sous-chaîne correspondant à la partie droite d’une production. Cette étape est appelée « shifting (avancer) (la tête de lecture des tokens) » (après avoir déplacé le token courant sur la pile) . C’est ça un automate à pile LR … IFT313 © Froduald Kabanza

13 Exemple G = (V,A,R,S), avec V = {S, A, B} A = {a, b, c, d , e} R = {
Grammaire G = (V,A,R,S), avec V = {S, A, B} A = {a, b, c, d , e} R = { S ® aABe, A ® Abc | b B ® d } Entrée: abbcde (pile, entrée) action Initialization 1. ( $, abbcde$) Shift ‘a’ 2. ( a$, bbcde$) Shift ‘b’ 3. ( ba$, bcde$) Reduce ‘b’ (A ® b) 4. ( Aa$, bcde$) Shift ‘b’ 5. ( bAa$, cde$) Shift ‘c’ 6. ( cbAa$, de$) Reduce ‘Abc’ (A ® Abc) 7. ( Aa$, de$) Shift ‘d’ 8. ( dAa$, e$) Reduce ‘d’ (B ® d) 9. ( BAa$, e$) Shift ‘e’ 10. ( eBAa$, $) Reduce ‘aABe’ (S ® aABe) 11. ( S$, $) Finish : Accept 12. ( $, $) IFT313 © Froduald Kabanza

14 Vu de l’automate pile avec le fond à gauche
Grammaire G = (V,A,R,S), avec V = {S, A, B} A = {a, b, c, d , e} R = { S ® aABe, A ® Abc | b B ® d } Entrée: abbcde (pile, entrée) action 1. ($, abbcde$) Initialization 2. ($a, bbcde$) Shift ‘a’ 3. ($ab, bcde$) Shift ‘b’ 4. ($aA, bcde$) Reduce ‘b’ (A ® b) 5. ($aAb, cde$) Shift ‘b’ 6. ($aAbc, de$) Shift ‘c’ 7. ($aA, de$) Reduce ‘Abc’ (A ® Abc) 8. ($aAd, e$) Shift ‘d’ 9. ($aAB, e$) Reduce ‘d’ (B ® d) 10. ($aABe, $) Shift ‘e’ 11. ($S, $) Reduce ‘aABe’ (S ® aABe) 12. ($, $) Finish : Accept Pour l’analyse LR, c’est plus pratique de voir l’automate à pile avec le fond mis à gauche plutôt qu’à droite. IFT313 © Froduald Kabanza

15 Observation importante
A chaque étape, le contenu de la pile (a) concaténé avec le reste de l’entrée (v), est une forme sententielle pour une dérivation la plus à droite : c.-à-d., S => a v * R 1. ($, abbcde$) Initialization 2. ($a, bbcde$) Shift ‘a’ 3. ($ab, bcde$) Shift ‘b’ 4. ($aA, bcde$) Reduce ‘b’ (A ® b) 5. ($aAb, cde$) Shift ‘b’ 6. ($aAbc, de$) Shift ‘c’ 7. ($aA, de$) Reduce ‘Abc’ (A ® Abc) 8. ($aAd, e$) Shift ‘d’ 9. ($aAB, e$) Reduce ‘d’ (B ® d) 10. ($aABe, $) Shift ‘e’ 11. ($S, $) Reduce ‘aABe’ (S ® aABe) 12. ($, $) Finish : Accept abbcde <= abbcde <= abbcde <= aAbcde <= aAbcde <= aAbcde <= aAde <= aAde <= aABe <= aABe <= S G = (V,A,R,S), avec V = {S, A, B} A = {a, b, c, d , e} R = {S ® aABe, A ® Abc | b B ® d } Vous rappelez-vous de la propriété comparable pour l’analyse LL (ou l’automate LL)? 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 Pour un automate à pile LL, on avait vu qu’à chaque étape, si on concatène le préfixe de la chaîne déjà scannée avec le contenu de la pile (dans cet ordre), on obtient une forme sententielle: S *=>L u alpha (on a aussi alpha *=>L v), ou *=>L symbolise une dérivation à gauche À l’inverse, pour un automate à pile LR, il faut concaténer le contenu de la pile et le reste de l’entrée: S *=>R alpha v, *=>R symbolise une dérivation à droite IFT313 © Froduald Kabanza

16 Conflits shift-reduce et reduce-reduce
L’automate LR est non déterministe parce qu’on peut avoir des conflits shift-reduce et reduce-reduce. Par exemple, à l’étape 6 on a la possibilité de déplacer (shift) ‘c’ et de réduire ‘b’ (avec A ® b). Dans l’exemple précédent, on a choisi shift. Un choix de reduce aurait donné lieu à une exécution différente. Entrée: abbcde (pile, entrée) action 1. ($, abbcde$) Initialization 2. ($a, bbcde$) Shift ‘a’ 3. ($ab, bcde$) Shift ‘b’ 4. ($aA, bcde$) Reduce ‘b’ (A ® b) 5. ($aAb, cde$) Shift ‘b’ 6. ($aAA, cde$) Reduce ‘b’ (A ® b) . Rejet Grammaire G = (V,A,R,S), avec V = {S, A, B} A = {a, b, b, c, d , e} R = { S ® aABe, A ® Abc | b B ® d } IFT313 © Froduald Kabanza

17 Analyseurs LR déterministes
Les questions fondamentales dans l’analyse LR sont : Quand faire shift, quand faire reduce ? S’il y a plusieurs productions dont les parties droites correspondent à des chaînes au sommet de la pile, quelle production utiliser pour faire reduce. Pour une exécution déterministe, on ne devrait avoir aucun conflit entre les choix d’actions possibles (shift ou reduce). En fait, plus tard nous allons imposer des restrictions sur les grammaires acceptable pour une approche LR, afin d’éviter de tels conflits. Différentes restrictions nous donnerons différentes versions d’analyseurs LR déterministes: SLR(1), LR(1) and LALR(1). IFT313 © Froduald Kabanza

18 D’où viennent les termes “Shift” et “Reduce”?
L’action de lire un token est de le déplacer au sommet de la pile est communément connu sous le vocable « shift » (on avance la tête de lecture des tokens, après avoir déplacé le token actuel sur la pile). L’action de remplacer une chaînes de symboles au sommet de la pile par un non terminal (partie gauche d’une règle de production) est appelée “reduce” (on réduit la longueur de la pile puisque la partie droite d’une règle a toujours plus de symboles que la partie gauche pour une GHC; la seule exception est le cas des productions avec une partie droite qui est la chaîne vide). Par conséquent, l’automate à pile LR est aussi connu sous le nom d’automate à pile shift-reduce. IFT313 © Froduald Kabanza

19 Poignées (handles) 1/ 2 Une sous-chaîne au sommet de la pile qui correspond à une partie droite d’une production est appelée poignée (handle), pourvu qu’elle mène à une exécution qui accepte. En effet, nous avons déjà vu une situation où il y avait une sous-chaîne au sommet de la pile, correspondant à une partie droite d’une règle de production, mais ne menant pas à l’acceptation de l’entrée. La sous-chaîne n’était pas une poignée. Plus précisément, une poignée d’une forme sententielle droite γ est une règle de production A ® b et une position dans γ à la quelle la chaîne b peut être trouvée et remplacée par A afin de générer la forme sententielle précédente dans une dérivation de droite de γ. Autrement dit, si S => aAw =>ab w, alors A ® b dans la position juste après a est une poignée de ab w Ici alpha ϵ (V U Σ)* et w ϵ Σ* (V étant l’ensemble des non terminaux de la grammaire et Σ l’ensemble des terminaux). * R R IFT313 © Froduald Kabanza

20 Poignées (handles) 1/ 2 Si S => aAw =>ab w, alors A ® b dans la position juste après a est une poignée de ab w Par abus de langage, si A ® b dans la position juste après a est une poignée de ab w, nous allons aussi dire que b est une poignée pour en fait dire la partie droite d’une poignée A ® b . Lorsque ab est le contenu de la pile et w le restant de l’entrée, si b est une poignée, on va réduire b par la production correspondante A ® b . Vous remarquerez que jusque là l’on parle d’une poignée et non de la poignée. C’est parce, si la grammaire est ambiguë, il peut y avoir plusieurs poignées pour une dérivation la plus droite. Si la grammaire est non ambigüe, on a toujours une seule dérivation la plus à droite, donc, une seule poignée à chaque étape. * R R (Au besoin, voir Aho, A., Lam, M., Sethi R., Ullman J. Compilers: Principles, Techniques, and Tools, Addison Wesley, 1985, page 196) IFT313 © Froduald Kabanza

21 Automate à pile LR : description formelle
On peut maintenant expliquer formellement la méthode pour construire un automate à pile LR (non déterministe) pour une GHC. Il faut se rappeler que selon notre convention, une transition de l’automate a la forme : (état, prochain-token, sommet-de-pile) → (nouvel-état, nouveau-sommet) On aura une transition pour enlever le symbole de départ S de la pile lorsque l’automate a fini de lire toute l’entrée. Nous aurons aussi des transitions pour réduire la pile (reduce); c.-à-d., remplacer une partie droite d’une règle de production par la partie gauche, sur la pile. Finalement, nous aurons des transitions pour déplacer les tokens sur la pile (shift). IFT313 © Froduald Kabanza

22 Générer un automate LR pour une GHC
Étant donné une grammaire G = (Nonterminaux, Terminaux, Productions, S), l’automate à pile LR correspondant est M=({p,q}, Nonterminaux U Terminaux, Terminaux, R, p, {q}, $), tel que la relation des transitions R est définie comme suit : (p, $, S$) → (q, ε) (Accept) (p, ε, Yk …Y1 ) → (p, A) pour chaque production A → Y1 … Yk (Reduce) (Rappel : Yk va être au sommet de la pile). (p, a, ε) → (p, a) pour chaque terminal a (Shift) Toutes les configurations vont avoir l’état p, sauf éventuellement la dernière qui aura l’état q. Se rappeler qu’un automate à pile lit les symboles au sommet de la pile à partir du sommet. Pour la transition (q, ε, Yk …Y1 )  (q, A), cela veut dire que nous aurons Y_k au sommet de la pile pour la règle de production A → Y1 … Yk . C.-à-d., le contenu de la pile est de la forme «$... Y1 … Yk ». IFT313 © Froduald Kabanza

23 Exemple Automate à pile
M = ({p,q}, {S,A,B}, {a, b, c, d, e}, R, p,{q},$) R = { (p, $, S$) → (q, ε) 2. (p, ε, eBAa) → (p, S) 3. (p, ε, cbA) → (p, A) 4. (p, ε, b) → (p, A) 5. (p, ε, d) → (p, B) 6. (p, a, ε) → (p, a) 7. (p, b, ε) → (p, b) 8. (p, c, ε) → (p, c) 9. (p, d, ε) → (p, d) 10. (p, e, ε) → (p, e) } Grammaire: G = (V,A,R,S), avec V = {S, A, B} A = {a, b, c, d , e} R = {S ® aABe, A ® Abc | b B ® d } IFT313 © Froduald Kabanza

24 Exemple, suite Trace s’exécution.
Je montre seulement (pile, entrée). Toutes les configurations sont dans l’état p, sauf la dernière qui est dans l’état q. 1. ($, abbcde$) Transition (Shift) 6 2. ($a, bbcde$) Transition (Shift) 7 3. ($ab, bcde$) Transition (Reduce) 4 4. ($aA, bcde$) Transition (Shift) 7 5. ($aAb, cde$) Transition (Shift) 8 6. ($aAbc, de$) Transition (Reduce) 3 7. ($aA, de$) Transition (Shift) 9 8. ($aAd, e$) Transition (Reduce) 5 9. ($aAB, e$) Transition (Shift) 10 10. ($aABe, $) Transition (Reduce) 2 11. ($S, $) Transition (Accept) 1 12. ($, $) Dérivation correspondante: abbcde <= abbcde <= abbcde <= aAbcde <= aAbcde <= aAde <= aAde <= aABe <= aABe <= S Transitions 1. (p, $, S$) → (q, ε) 2. (p, ε, eBAa) → (p, S) 3. (p, ε, cbA) → (p, A) 4. (p, ε, b) → (p, A) 5. (p, ε, d) → (p, B) 6. (p, a, ε) → (p, a) 7. (p, b, ε) → (p, b) 8. (p, c, ε) → (p, c) 9. (p, d, ε) → (p, d) 10. (p, e, ε) → (p, e) } IFT313 © Froduald Kabanza

25 Grammaire augmentée Pour définir un driver LR, nous avons besoin du concept de « grammaire augmentée ». Étant donné une grammaire G, la grammaire augmentée correspondante est obtenue en ajoutant : un nouveau symbole de départ S’ et une production S’ ® S. Ceci permet d’indiquer au driver LR quand arrêter l’analyse et annoncer l’acceptation de l’entrée. Lorsque la pile contient seulement S et que l’entrée est vide, la production précédente provoque un remplacement de S par S’ sur la pile. Contrairement à notre automate à pile, le driver LR n’accepte pas quand la pile et l’entrée sont vides. Au contraire, il accepte quand la pile contient S’. Il est possible de définir une version de driver LR qui accepte sur une pile vide, mais la formulation présente est la plus fréquente dans les manuels académiques. IFT313 © Froduald Kabanza

26 Algorithme LRDriver Algorithm LRDriver
variables : stack, handle (sous-chaîne au sommet de la pile), a (token), in (entrée) initialement la pile est vide ($) et l’entrée est w$ (une chaîne w). while (true) { if (symbol on top of stack is S’ ) return (a = = $); //accepte handle = stack.findHandle(); //trouver une poignée. Étape cruciale ! if handle != void { // void si la poignée n’est pas trouvée soit ‘A → handle’ la règle correspondante // reduce (nondeterminisme si plusieurs règles) pop handle from the stack; push A on the stack; print out the production ‘A → handle’; // pour imprimer la séquence de dérivation } else { a = in.nextToken(); // shift if a = $ exit with error(); // erreur si ni reduce ni shift ne sont possibles push a on the stack; continue; Remarquer que cet algorithme suppose qu’on fait reduce d’abord avant de faire shift. Comme vu précédemment, dans le cas non-déterministe, à priori on peut avoir des situations pour lesquelles shift et reduce sont possibles. Toutefois, comme cet algorithme est une ébauche pour une version déterministe qu’on verra plus tard, les grammaires qu’on va utiliser n’auront pas de tels conflits. IFT313 © Froduald Kabanza

27 Exemple revisité G = (V,A,R,S’), avec V = {S, S’, A, B}
Trace d’exécution 1. ($, abbcde$) Shift 2. ($a, bbcde$) Shift 3. ($ab, bcde$) Reduce 4 4. ($aA, bcde$) Shift 5. ($aAb, cde$) Shift 6. ($aAbc, de$) Reduce 3 7. ($aA, de$) Shift 8. ($aAd, e$) Reduce 5 9. ($aAB, e$) Shift 10. ($aABe, $) Reduce 2 11. ($S, $) Accept 12. ($S’, $) Dérivation correspondante: abbcde <= abbcde <= abbcde <= aAbcde <= aAbcde <= aAbcde <= aAde <= aAde <= aABe <= aABe <= S <= S’ Grammaire G = (V,A,R,S’), avec V = {S, S’, A, B} A = {a, b, c, d , e} R = { 1. S’ ® S, 2. S ® aABe, 3. A ® Abc | 4. b B ® d } IFT313 © Froduald Kabanza

28 Contexte LR(0) 1/2 On aurait pu formuler l’analyser LR(0) à l’aide du concept de «contexte LR(0)» plutôt que celui « poignée » (Sudkamp [1] , page 596). Nous avons introduit la « poignée » comme suit: Si S => aAw =>ab w, alors A ® b dans la position juste après a est une poignée de ab w Étant donné une grammaire (V, Σ, P, S), la chaîne ab est un contexte LR(0) pour la règle de production A ® b s’il existe une dérivation S => aAw =>ab w, avec a et b ϵ (V U Σ)* et w ϵ Σ*. Autrement dit, ab est un contexte LR(0) pour la règle de production A ® b ssi A ® b est un poignée pour ab w, avec a et b ϵ (V U Σ)* et w ϵ Σ* . * R R * Dans le manuel du cours [1] (Sudkamp, T. A. Languages and Machines. Third Edition Edition. Addison-Wesley, 2005), on utilise le concept de “contexte LR(0)” plutôt que celui de “poignée”. En d’autres mots, un contexte LR(0) est un préfixe d’une forme sententielle droite (rappelons que le contenu de la pile est toujours un préfixe d’une forme sententielle droite) donnant lieu à une réduction; c-à-d., un préfixe d’une forme sententielle terminé par une poignée. Les deux concepts sont très proches et ont la même finalité : déterminer la bonne action à prendre (shift ou reduce). Les deux notions expriment relativement la même chose. Le poignée fait référence à un suffixe de la pile; le contexte LR(0) fait référence à tout le contenu de la pile. Cependant le concept de poigné est le plus fréquemment rencontré dans la littérature. R R IFT313 © Froduald Kabanza

29 Contexte LR(0) 2/2 Tout comme pour un poignée, un contextes LR(0) détermine quand faire une réduction durant l’analyse LR, sinon quand faire « shift ». Si A ® b est une poignée (c.-à-d., si le contenu de la pile (ab) est un contexte LR(0) de la règle A ® b) , on réduit avec A ® b. S’il n’y a pas de poignée au sommet de la pile, mais le sommet de la pile contient un préfixe d’un poignée (c.-à-d., si le contenu de la pile (ab) n’est pas un contexte LR(0) mais est un préfixe d’un contexte LR(0)), on met (shit) le prochain token sur la pile. Si le sommet de la pile n’est un préfixe pour une poignée quelconque (c.à-d., le contenu de la pile n’est pas un préfixe pour un contexte LR(0) quelconque), on rejette la chaîne d’entrée. Pour une grammaire non ambiguë, il y au plus une seule poignée à chaque étape d’une dérivation la plus à droite. De façon équivalente, il y a au plus un seul contexte LR(0). Donc, les deux premières étapes de l’algorithme donnent lieu à une seule action possible. Le contenu de la pile est un préfixe viable si et seulement si c’est un préfixe d’un contexte LR(0) (autrement dit, le contenu de la pile a un suffixe qui est une poignée). Si tel est le cas, une séquence de shift produit un contexte LR(0) (autrement dit, produit une poignée au sommet de la pile). Nous reviendrons sur le concept de préfixe viable plus tard. IFT313 © Froduald Kabanza

30 Récapitulation Le défi majeur pour implémenter un driver LR efficace est de trouver la poignée, c-à-d., l’étape ‘handle = stack.findHandle()’. Une approche naïve pour implémenter stack.findHandle() serait de comparer le contenu de la pile avec les parties droites des règles de production pour trouver une règle dont la partie droite est au sommet de la pile. Par contre, il faudra faire backtracking si on se trompe est que cette partie droite ne mène pas à l’acceptation (c.-à-d., ne s’avère pas être une poignée). Pour des sous-classes intéressantes des GHC, on peut éviter de scanner la pile et de faire backtracking pour trouver une poignée. Dans ce cours, on verra les grammaires SLR(1), LR(1) et LALR(1). De façon équivalente, le défi est de trouver les contexte LR(0). IFT313 © Froduald Kabanza

31 Récapitulation Le problème est donc de trouver une poignée sur la pile (partie droite d’une production menant à l’acceptation) et de déterminer avec quel non terminal la remplacer (avec quelle production réduire). Cette décision est plus difficile à faire que la décision correspondante dans l’analyse LL (prédire une production). Par conséquent, elle plus difficile à implémenter. Néanmoins, cette approche nous permet de mettre moins de restrictions sur les langages (et leurs grammaires) pouvant être analysés. Plus précisément, on a plus de chance d’avoir à spécifier une grammaire simple avec une approche LR qu’avec une approche LL, pour le même langage. IFT313 © Froduald Kabanza


Télécharger ppt "IFT313 Introduction aux langages formels"

Présentations similaires


Annonces Google