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 Froduald Kabanza Département dinformatique Université de Sherbrooke Analyseurs LR(0)

Présentations similaires


Présentation au sujet: "IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke Analyseurs LR(0)"— Transcription de la présentation:

1 IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke Analyseurs LR(0)

2 IFT313© Froduald Kabanza2 Sujets Préfixes viables. Éléments LR(0). AFD LR(0) pour reconnaître les préfixes viables. Analyseur LR(0).

3 IFT313© Froduald Kabanza3 Objectifs Pouvoir calculer lAFD qui reconnait les préfixes viables. Pouvoir générer une table danalyse LR(0). Pouvoir décrire le driver LR(0) et le simuler.

4 IFT313© Froduald Kabanza4 Références [1] Sudkamp, T. A.. Languages and Machines. Third Edition Edition. Addison-Wesley, – Sections 20.1 à 20.4 [2] Appel, A. and Palsberg. J. Modern Compiler Implementation in Java. Second Edition. Cambridge, – Section 3.3 [4] Aho, A., Lam, M., Sethi R., Ullman J. Compilers: Principles, Techniques, and Tools, 2 nd Edition. Addison Wesley, – Section 4.6

5 IFT313© Froduald Kabanza5 Rappel : 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 lentré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 nest 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; }

6 IFT313© Froduald Kabanza6 Exemple Grammaire G = (V, A, R, E), avec V= {E, F, T} A = {(, ), +, *, num} R = { E E + T E T T T * F T F F ( E) F num} Grammaire augmentée G = (V, A, R, E) : V= {E, E, F, T} A = {(, ), +, *, num} R = { E E E + T E T T T * F T F F ( E) F num}

7 IFT313© Froduald Kabanza7 Exemple, suite Simulation du driver LR 1. ($, (num)$) Shift 2. ($(, num)$) Shift 3. ($(num, )$) Reduce 7 4. ($(F, )$) Reduce 5 5. ($(T, )$) Reduce 3 6. ($(E, )$) Shift 7. ($(E), $) Reduce 6 8. ($F, $) Reduce 5 9. ($T, $) Reduce ($E, $) Reduce ($E, $) Accepte Dérivation correspondante : (num) <= (num) <= (num) <= (F) <= (T) <= (E) <= (E) <= F <= T <= E <= E Productions 1. E 2. E E + T 3. E T 4. T T * F 5. T F 6. F ( E) 7. F num Observation Le contenu de la pile ( ) concaténé avec les tokens restant à lire (w) est une forme sententielle pour une dérivation la plus à droite : S => * R

8 IFT313© Froduald Kabanza8 Rappel : Contexte LR(0) 1/2 On aurait pu formuler lanalyser LR(0) à laide 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 => w => w, alors A dans la position juste après est une poignée pout w Étant donné une grammaire (V, Σ, P, S), la chaîne est un contexte LR(0) pour la règle de production A sil existe une dérivation S => w => w, avec et (V U Σ)* et w Σ*. Autrement dit, est un contexte LR(0) pour la règle de production A ssi A est un poignée pour w, avec et (V U Σ)* et w Σ*. R * R R * R

9 IFT313© Froduald Kabanza9 Rappel : Contexte LR(0) 2/2 Tout comme pour un poignée, un contextes LR(0) détermine quand faire une réduction durant lanalyse LR, sinon quand faire « shift ». 1.Si A est une poignée (c.-à-d., si le contenu de la pile ( ) est un contexte LR(0) de la règle A on réduit avec A 1.Sil ny a pas de poignée au sommet de la pile, mais le sommet de la pile contient un préfixe dune poignée (c.-à-d., si le contenu de la pile ( ) est nest pas un contexte LR(0) mais est un préfixe dun contexte LR(0) on met (shit) le prochain token sur la pile. 1.Si le sommet de la pile nest pas un préfixe pour une poignée quelconque (c.à-d., le contenu de la pile nest pas un préfixe pour un contexte LR(0) quelconque), on rejette la chaîne dentrée.

10 IFT313© Froduald Kabanza10 Le problème de trouver la poignée Pour une version déterministe, le défi est de trouver la poignée (méthodestack.findHandle()). Pour certaines classes de GHC, on peut trouver la poignée sans examiner tout le contenu la pile. Cela découle de la propriété suivante sur les automates à pile LR : Sil est possible de reconnaître une poignée seulement à partir du contenu de la pile, alors il existe un AFD, qui en lisant les symboles de la grammaire à partir du sommet de la pile, détermine quel poignée, sil y en a, est au sommet. On va démontrer cette propriété en montrant comment construire lAFD. Ensuite on va voir comment utiliser lAFD pour implémenter stack.findHandle(). Ceci nous conduira à deux techniques danalyse LR (SLR(1) et LALR(1)), résultant dune combinaison ingénieuse de lautomate à pile LR et de lAFD pour reconnaître les poignées.

11 IFT313© Froduald Kabanza11 Que doit être lalphabet de lAFD pour reconnaître les poignées ? Pour répondre à cette question, il faut garder à lesprit que lobjectif est davoir un AFD qui lit le contenu de la pile (à partir du sommet) pour indiquer sil y a une poignée au sommet de la pile. Étant donné que la pile contient des symboles de la grammaire (terminaux et non-terminaux), lalphabet de lAFD doit être les symboles de la grammaire. En dautre mots, les transitions de lAFD seront étiquetées par les symboles de la grammaires (terminaux et non terminaux). La question qui reste est de savoir quels devraient être les états de lAFD et quelles devraient être les transitions entre ces états.

12 IFT313© Froduald Kabanza12 Préfixes viables Pour répondre à la question précédente, rappelons dabord que le contenu de la pile ( ) concaténé avec le reste des tokens ( ) est une forme sententielle pour la dérivation la plus à droite. Par conséquent, le contenu de la pile est toujours un préfixe dune forme sententielle pour la dérivation la plus à droite. De tels préfixes de formes sententielles de dérivation à droite, pouvant apparaître sur la pile, sont appelées des préfixes viables. De façon équivalente, un préfixe viable est défini comme étant un préfixe dun contexte LR(0). On va voir comment construire un AFD pour reconnaître des préfixes viables. Ensuite on va expliquer comment lutiliser pour reconnaître des poignées.

13 IFT313© Froduald Kabanza13 AFN pour reconnaître les préfixes viables Les transitions de lAFN vont être étiquetées par des symboles dont la séquence forme un préfixe viable. En dautres mots, on aura les transitions si XYZ est un préfixe viable. Un état de lAFN sera une production de la grammaire avec un point («. ») à une position particulière dans la partie droite. Ainsi, à partir de la production A XYZ, on va générer 4 états de lAFN : A. XYZ A X. YZ A XY. Z A XYZ. Pour la production A on va générer un seul état : A. XYZ

14 IFT313© Froduald Kabanza14 Que signifient les états de lAFN? Intuitivement, un état de lAFN indique la portion de la partie droite dune production, reconnue au sommet de la pile, à un moment donnée durant lanalyse syntaxique LR. Par exemple létat A. XYZ indique quaucune portion nest encore reconnue sur la pile, et on espère que le reste des tokens à lire commence par un préfixe dérivable de XYZ. Létat A X.YZ indique quon vient juste de lire une sous-chaîne de tokens dérivable de X (c.-à-d., le préfixe viable X est au sommet de la pile) et on sattend à lire ensuite une suite de tokens formant un sous-chaîne dérivable de YZ. Un état de lAFN est appelé un élement LR(0) (item LR(0) en anglais; ou élément tout court) de la grammaire. On peut implémenter un élément LR(0) par une paire dentiers, le premier indiquant le numéro de la production, le deuxième indiquant la position du point. On peut maintenant expliquer la technique pour obtenir lAFN de la grammaire.

15 IFT313© Froduald Kabanza15 AFN pour reconnaître les préfixes viables 1.Létat initial est S. S 2.Pour chaque paire détats A X et A X. ajouter une transition du premier état vers le deuxième, étiquetée par X. Il faut garder à lesprit que A. X signifie : à un moment donné durant lanalyse syntaxique, on vient juste de scanner un sous-chaîne dérivable de et on sattend à scanner une sous-chaîne dérivable de X, ensuite une sous-chaîne dérivable de. Ainsi, la transition de A X à A X. étiquetée X, signifie quon vient juste de lire une sous-chaîne dérivable de X et on sattend maintenant à en lire une dérivable de. 3.Pour chaque paire détats A X et X. ajouter une transition du premier vers le deuxième, étiquetée Intuitivement, si on sattend à scanner une sous-chaîne dérivable de X et si X peut dériver on peut sattendre aussi bien à scanner une chaîne dérivable de

16 IFT313© Froduald Kabanza16 Éléments kernels (de base) et lopération closure (fermeture) 1.Létat initial est S. S 2.Pour chaque paire détats A X et A X. ajouter une transition du premier état vers le deuxième, étiquetée par X. 3.Pour chaque paire détats A X et X. ajouter une transition du premier vers le deuxième, étiquetée. Les éléments impliqués dans les deux premières opérations sont appelés des éléments kernels (c-à-d., des éléments du noyau, ou des élments de base). Il sagit de lélément S. S et des éléments dont le point ne commence pas la partie droite de la production. Les éléments dont le point apparaît au début de la partie droite de la production sont dits non kernel. La troisième opération est une fermeture.

17 IFT313© Froduald Kabanza17 Exemple 1/3 Grammaire augmentée G = (V, A, R, E) : V= {E, E, F, T} A = {(, ), +, *, num} R = { E E E + T E T T T * F T F F ( E) F num } Grammaire G = (V, A, R, E) : V= {E, F, T} A = {(, ), +, *, num} R = { E E + T E T T T * F T F F ( E) F num }

18 IFT313© Froduald Kabanza18 Exemple 2/3 Grammaire E E E+T E T T*F T F F (E) F num E E T.F T T*F E. E+T F. (E) E E E.+TE E+. T E E+T. T T. *F T T*. F T T*F. F (. E) E F num. F (E. ) F (E). T F. + E Seulement quelques transitions sont présentes ! Compléter les autres comme exercice. T F AFN pour les préfixes viables

19 IFT313© Froduald Kabanza19 Exemple 3/3 Grammaire E E E+T E T T*F T F F (E) F num EET(F)+*num 1. E 2. E 3. E.E+T 4. E E.+T 5. E E+.T 6. E E+T. 8. E 9. T T*F 10. T T.*F 11. T T*.F 12. T T*F. 13. T.F 14. T F. 15. F.(E) 16. F (E) 17. F (E) 18. F num 19. F num 2 7. E 3,7 Même AFN, avec table de transition. Seulement deux entrées complétées. Les autres sont laissées comme exercice.

20 IFT313© Froduald Kabanza20 AFD pour reconnaître les préfixes viables On obtient lAFD pour les préfixes viables en déterminisant lAFN (par la méthode subset construction). I0 E. E. E+T E. T. T*F T. F F. (E) F. num I1 E. E E. +T I2 E. T T. *F I3 T F. I4 F (. E) E. E+T E. T. T*F T. F F. (E) F. num I5 F num. I6 E E+. T T. T*F T. F F. (E) F. num I7 T T*. F F. (E) F. num I8 F (E. ) E E. +T I9 E E+T. T T. *F I0 T T*F. I11 F (E). I0I1I6I9 I2I7I10 I8I11 I5 ET+ F ( T num ( F* E) +T F ( * to I7 to I2 to I6 to I3 to I4 to I5 to I4 to I5 to I3 num I4 ( I3 F

21 IFT313© Froduald Kabanza21 AFD pour reconnaître les préfixes viables LAFD avec une table de transition. ET(F)+*num I1 E I0 I1 I2 I4 I3 I7 I5 I9 I8 I10 I6 I1 I2I3I5I4 I6 I7 I4I8I2I3I5 I10I4I5 I11 I9I3I4I5 I7 I6 I0 E. E. E+T E. T. T*F T. F F. (E) F. num I1 E. E E. +T I2 E. T T. *F I3 T F. I4 F (. E) E. E+T E. T. T*F T. F F. (E) F. num I5 F num. I6 E E+. T T. T*F T. F F. (E) F. num I7 T T*. F F. (E) F. num I8 F (E. ) E E. +T I9 E E+T. T T. *F I0 T T*F. I11 F (E).

22 IFT313© Froduald Kabanza22 AFD LR(0) pour reconnaître les préfixes viables Les états de lAFD sont donc des ensembles détats de lAFN, cest-à-dire, des ensembles déléments LR(0). Les états de lAFD sont aussi appelés des ensembles canoniques déléments LR(0). La fonction de transition de lAFD est appelée la fonction goto de lanalyseur syntaxique: Étant donné un état I de lAFD et un symbole de grammaire X, goto(I,X) est le successeur de I pour la transition étiqueté par X.

23 IFT313© Froduald Kabanza23 Méthode efficace de construction de lAFD pour les préfixes viables Une méthode efficace de construction de lAFD pour les préfixes viables est dappliquer la méthode de déterminisation (subset construction method), à la volée, sans construire lAFN au préalable. Pour ce faire, nous avons dabord besoin de définir deux fonctions auxiliaires: closer(I) et goto(I,X). closure(I) implémente la fermeture sous-jacente à méthode déterminisation, en éliminant notamment les transitions. goto(I,X) implémente les transitions entre les éléments du kernel.

24 IFT313© Froduald Kabanza24 Définition informelle de closure Soit I un ensemble déléments LR(0) dune grammaire. closure(I) est lensemble obtenu de I en appliquant les opérations suivantes : Initialement, chaque élément de I est mis dans closure(I). Ensuite on applique lopération suivante, jusquà ce quaucun nouvel élément ne peut plus être ajouté : Si A. X est dans closure(I) et X est une production, ajouter lélément X. à closure(I).

25 IFT313© Froduald Kabanza25 Définition formelle de closure(I) Algorithm closure(I) variables : I (ensemble déléments LR(0) : donnée dentrée) G (grammaire : donnée comme variable globale) J (ensemble déléments LR(0): contient le résultat) J = I; // initialisation do { for (each item A. X in J and each production X of G such that X. is not in J) add X. to J } while (J is modified) return J;

26 IFT313© Froduald Kabanza26 Fonction goto Soit I un état de lAFD (c.-à-d., un ensemble ditems LR(0)) et X un symbole de la grammaire. Soit I lensemble formé de tous les éléments A X. pour lesquels il existe un élément A. X dans I. goto(I,X) = closure(I). En dautre mots, goto(I,X) est défini comme étant la fermeture (closure) de lensemble formé de tous les éléments A X. pour lesquels il existe un élément A. X dans I. Rappelons que les états de lAFD sont aussi appelés des éléments (items) canoniques LR(0). Comme on connaît la fonction goto, pour définir lAFD il nous reste à donner lalgorithme pour calculer ces éléments (items).

27 IFT313© Froduald Kabanza27 Algorithme pour les états de lAFD LR(0) Algorithm Items(G) variables : G (entrée : grammaire augmentée avec symbole de départ S) et C (résultat : ensembles des états de lAFD.) Output : C et la fonction goto. C = { closure({S. S}) }; // état initial do { for (each state I in C and each grammar symbol X such that goto(I,X) is not empty and not in C) add goto(I,X) to C } while (C is modified) return C;

28 IFT313© Froduald Kabanza28 Éléments valides Un élément A. est dit valide pour un préfixe viable sil existe une dérivation la plus à droite telle que : S => w => w. On peut démontrer que lensemble des éléments valides pour un préfixe viable est précisément lensemble des éléments atteignables à partir de létat initial de lAFD des préfixes viables, en suivant un chemin étiqueté par. La validité de A. pour un préfixe nous indique sil faut faire shift ou alors reduce dès que est au sommet de la pile. En dautre mots, ça nous indique si est une poignée ou non. * * RR

29 IFT313© Froduald Kabanza29 Quand faire shift, quand faire reduce ? Supposons que est au sommet de la pile et que lélément A. est valide pour Alors : Si =, cela veut dire quau sommet de la pile nous avons la partie droite de la production A. C.-à-d., est une poignée, on peut donc réduire. Sinon, si cela veut dire quon doit faire shift des tokens de la sous- chaîne avant dobtenir C-à-d., on na pas encore une poignée sur la pile, on doit continuer de faire shift. De ces observations, on déduit que si on simule lAFD pour les préfixes viables en parallèle avec le driver LR (automate à pile LR), on sera capable de déterminer quand faire shift et quand faire reduce.

30 IFT313© Froduald Kabanza30 Idée de base Lidée de base pour simuler en parallèle lautomate à pile LR et lAFD pour les préfixes viables est la suivante. Initialement, lautomate est vide et lAFD est dans son état initial. Chaque fois quon shift un token sur la pile, lAFD change son état en suivant la transition étiquetée par le token. Ainsi, lorsque le sommet de la pile va contenir lAFD sera dans un état contenant lélément A., ce qui indique que nous devons faire une réduction avec la production A. En même temps que nous appliquons la réduction (en remplaçant par A sur la pile), on doit revenir en arrière dans lAFD (backtracking) le long du chemin étiqueté jusquà létat I qui est la racine du chemin étiqueté. Puisque A est le nouveau symbole au sommet de la pile, on doit faire une transition correspondante dans lAFD; c-à-d., létat courant de lAFD doit devenir létat retourné par goto(I,A) (c.-à-d., le successeur de I sous la transition A dans lAFD).

31 IFT313© Froduald Kabanza31 De lidée à limplémentation Pour implémenter cette idée, on met les états de lAFD sur la pile de sorte à garder une trace de lexécution de lAFD. Plus précisément, sur la pile on va alterner un état de lAFD avec un symbole de la grammaire (terminal ou non-terminal), en commençant avec létat initial de lAFD. Donc une configuration du driver LR est dorénavant de la forme (I 0 X 1 I 1 … X m I m, t i … t n $), tel que I j sont des états de lAFD, X j des symboles de la grammaire, et t i … t n le reste des tokens à lire. Nous navons plus besoin de mettre le $ pour reconnaître le fond de la pile. Létat initial de lAFD va remplir ce rôle.

32 IFT313© Froduald Kabanza32 De lidée à limplémentation Une configuration (I 0 X 1 I 1 … X m I m, t i … t n $) signifie que: lAFD est actuellement dans létat I m, le long dun chemin (trace) étiqueté X 1 … X m à partir de létat initial I 0, et le reste de lentrée à scanner est t i … t n. Ainsi, si X j … X m, est une poignée, pour un j quelconque : Il doit y avoir un élément « A X j … X m. » dans létat Im. Dans ce cas, on fait une réduction en remplaçant X j … X m par A sur la pile. Plus précisément, on enlève X j I j … X m I m de la pile, et on ajoute AI tel que I est létat retourné par goto(I j-1, A). La suppression de X j I j … X m I m de la pile revient à un retour arrière (backtracking) dans lAFD, le long du chemin X j … X m.

33 IFT313© Froduald Kabanza33 Analyseur LR(0) (1/2) Un analyseur (syntaxique) LR(0) na pas besoin danticiper le prochain token (lookahead) pour prendre une décision shift ou reduce. Il décide de laction appropriée (shift ou reduce) seulement en fonction de létat courant de lAFD pour les préfixes viables. Ce comportement est reflété par la version suivante de lanalyseur LR(0). Algorithm LR0Parser Input: stream of tokens Output: a derivation sequence Variables: stack (pile), a (prochain token), in (entrée : flux de tokens) AFD pour préfixes viables, avec état initial I0 et fonction de transition goto Initialement la pile contient I0

34 IFT313© Froduald Kabanza34 Analyseur LR(0) (2/2) while (true) { if (la pile contient I0S et lentrée est $ (vide)) return true; if (létat au sommet de la pile contient un élément A. reduce with the production A est une poignée et A la production correspondante c.-à-d. : Supprimer 2 | | symboles de la pile (| | états et | | symboles de grammaires). Soit I le nouvel état au sommet de la pile. Ajouter A au sommet de la pile. Ajouter létat retourné par goto(I,A) au sommet de la pile. print out the production A continue; if (létat au sommet de la pile contient un élément A. a tel que a est un token shift c.-à-d. : Soit I létat au sommet de la pile. Lire le prochain token a Ajouter a au sommet de la pile. Ajouter létat retourné par goto(I,a) au sommet de la pile. continue; error(); }

35 IFT313© Froduald Kabanza35 Exemple I0I1I6I9 I2I7I10 I8I11 I5 ET+ F ( T num ( F* E) +T F ( * to I7 to I2 to I6 to I3 to I4 to I5 to I4 to I5 to I3 num I4 ( I3 F I0 E. E. E+T E. T. T*F T. F F. (E) F. num I1 E. E E. +T I2 E. T T. *F I3 T F. I4 F (. E) E. E+T E. T. T*F T. F F. (E) F. num I5 F num. I6 E E+. T T. T*F T. F F. (E) F. num I7 T T*. F F. (E) F. num I8 F (E. ) E E. +T I9 E E+T. T T. *F I0 T T*F. I11 F (E).

36 IFT313© Froduald Kabanza36 Exemple 1 Trace 1. ( I0, (num)$) Shift T.(E) 2. ( I0 ( I4, num)$) Shift T.num 3. ( I0 ( I4 num I5, )$) Reduce F num. 4. ( I0 ( I4 F I3, )$) Reduce T F. 5. ( I0 ( I4 T I2, )$) Reduce E T. 6. ( I0 ( I4 E I8, )$) Shift F (E.) 7. ( I0 ( I4 E I8 )I 11, $) Reduce F (E). 8. ( I0 F I3, $) Reduce T F. 9. ( I0 T I2, $) Reduce E T. 10. ( I0 E I1, $) Reduce E E. 11. ( I0 E, $) Accept Dérivation correspondante : (num) <= (num) <= (num) <= (F) <= (T) <= (E) <= (E) <= F <= T <= E <= E I0I1I6I9 I2I7I10 I8I11 I5 ET+ F ( T num ( F* E) +T F ( * to I7 to I2 to I6 to I3 to I4 to I5 to I4 to I5 to I3 num I4 ( I3 F

37 IFT313© Froduald Kabanza37 Exemple 2 Trace 1. ( I0, (num)$) Shift T.(E) 2. ( I0 ( I4, num)$) Shift T.num 3. ( I0 ( I4 num I5, )$) Reduce F num. 4. ( I0 ( I4 F I3, )$) Reduce T F. 5. ( I0 ( I4 T I2, )$) Shift T T. *F 6. ( I0 ( I4 T I2), $) Error goto(I2, )) non défini. I0I1I6I9 I2I7I10 I8I11 I5 ET+ F ( T num ( F* E) +T F ( * to I7 to I2 to I6 to I3 to I4 to I5 to I4 to I5 to I3 num I4 ( I3 F Même entrée, mais à létape 9, on résoud le conflit en faveur de Shift

38 IFT313© Froduald Kabanza38 Exemple 3 Trace : 1. (I0, (num*num)$) Shift T.(E) 2. (I0(I4, num*num)$) Shift T.num 3. (I0(I4numI5, *num)$) Reduce F num. 4. (I0(I4FI3, *num)$) Reduce T F. 5. (I0(I4TI2, *num)$) … Poursuivre comme exercice … Remarquer le conflit Shift/Reduce à létape 5. Létat I2 contient élément Shift ( T T.*F) et un élément Reduce (E T.). Contrairement à lexemple précédent, cette fois-ci le conflit devrait être réglé en faveur de Shift. Pourquoi? I0I1I6I9 I2I7I10 I8I11 I5 ET+ F ( T num ( F* E) +T F ( * to I7 to I2 to I6 to I3 to I4 to I5 to I4 to I5 to I3 num I4 ( I3 F Une entrée différente


Télécharger ppt "IFT313 Introduction aux langages formels Froduald Kabanza Département dinformatique Université de Sherbrooke Analyseurs LR(0)"

Présentations similaires


Annonces Google