Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
1
IFT313 Introduction aux langages formels
Froduald Kabanza Département d’informatique Université de Sherbrooke planiart.usherbrooke.ca/kabanza/cours/ift313 Analyseurs SRL(1)
2
Sujets Algorithme générique pour l’analyse LR (Driver LR)
Table d’analyse SLR(1). IFT313 © Froduald Kabanza
3
Objectifs Pouvoir définir et simuler l’algorithme d’analyse LR (Driver LR) Pouvoir générer une table d’analyse SLR(1) pour une grammaire donnée. Pouvoir reconnaître les grammaires SLR(1). IFT313 © Froduald Kabanza
4
Références [1] Sudkamp, T. A.. Languages and Machines. Third Edition Edition. Addison-Wesley, 2005. Sections à 20.4 [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.6 IFT313 © Froduald Kabanza
5
(C) Froduald Kabanza & Éric Beaudry
Rappel : AFD LR(0) I0 I1 I6 I9 I2 I7 I10 I8 I11 I5 E T + F ( num * ) to I7 to I2 to I6 to I3 to I4 to I5 I4 I3 I0 E’ .E E .E+T E .T T.T*F T .F F .(E) F.num I1 E’ E. E E.+T I2 E T. TT.*F I3 T F. I4 F (.E) F .num I5 F num. I6 E E+.T T .T*F I7 TT*.F I8 F (E.) I9 E E+T. TT*F. I11 F (E). IFT313 / 2009E (C) Froduald Kabanza & Éric Beaudry
6
Rappel : Analyseur LR(0)
Un analyseur (syntaxique) LR(0) n’a pas besoin d’anticiper le prochain token (lookahead) pour prendre une décision shift ou reduce. Il décide de l’action appropriée (shift ou reduce) seulement en fonction de l’état courant de l’AFD pour les préfixes viables. Ce comportement est reflété par la version suivante de l’analyseur LR(0). Algorithm LR0Parser. Entrée : flux de tokens Sortie : dérivation de l’entrée ou erreur. 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 IFT313 © Froduald Kabanza
7
Rappel : Analyseur LR(0)
while (true) { if (la pile contient I0S’ et l’entrée est $ (vide)) return true; if (l’état au sommet de la pile contient un élément A ® a . ) { reduce with the production A ® a; // a est une poignée et A ® a la production correspondante c.-à-d. : Supprimer 2×|a| symboles de la pile (|a| états et |a| 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 ® a; continue; } if (l’état au sommet de la pile contient un élément A ® a . ab 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. error(); IFT313 © Froduald Kabanza
8
Rappel : Grammaires LR(0)
Un élément shift (shift item) est un élément de la forme « A ® a . ab » tel que a est un terminal. Un élément reduce (reduce item) est un élément de la forme « A ® a . » Si l’AFD LR(0) a un état contenant à la fois un élément shift et un élément reduce, ou plus d’un élément reduce, alors la grammaire correspondante n’est pas LR(0). Par exemple, la grammaire précédente n’est pas LR(0) parce que les états I1, I2 et I9 contiennent des conflits Shift/Reduce. Un analyseur LR(0) fonctionne correctement uniquement pour des grammaires LR(0). IFT313 © Froduald Kabanza
9
Exemple de grammaire LR(0)
S’® S (habituellement non numérotée; production interne) 1. S ® E; 2. E ® E + T 3. E ® T 4. T ® (E) 5. T ® num Terminaux : num, ‘+’ et‘;’ La terminaison de l’entrée ‘;’ fait partie des terminaux. Sans elle, la grammaire n’est plus LR(0). Pour montrer que la grammaire est LR(0), on construit l’AFD pour les préfixes viables et on vérifie qu’aucun état ne contient à la fois d’éléments shift et d’élément reduce, ou plus d’un élément reduce. Ci-après on donne aussi une simulation de l’analyseur LR(0) pour l’entrée ‘3 + 6;’, ce qui correspond au flot de tokens ‘num + num;’ IFT313 © Froduald Kabanza
10
AFD LR(0) I3 E® E+.T T® .(E) T® .num I7 T® (E .) E® E .+T I0 S’® .S
; I10 S I7 T® (E .) E® E .+T I0 S’® .S S® .E; E® .E+T E® .T T® .(E) T® .num I4 E® E+T. I8 F® (E). I5 T® num. I1 S® E .; E® E .+T I9 E®T. I6 T® (.E) E® .E+T E® .T T® .(E) T® .num I10 S’® S. I2 S® E;. IFT313 © Froduald Kabanza
11
AFD + simulation de l’analyseur LR(0) avec une entrée correcte
T® num. I0 S’® . S S® .E; E® .E+T E® .T T® .(E) T® .num I1 S® E .; E® E .+T I2 S® E;. I6 T® (.E) I3 E® E+.T I7 T® (E .) I4 E® E+T. I9 E®T. I8 F® (E). I10 S’® S. 1. (I0, num+num;$) Shift 2. (I0numI5, num;$) Reduce 3. (I0TI9, num;$) Reduce 4. (I0EI1, num;$) Shift 5. (I0EI1+I3, num;$) Shift 6. (I0EI1+I3numI5, ;$) Reduce 7. (I0EI1+I3TI4, ;$) Reduce 8. (I0EI1, ;$) Shift 9. (I0EI1;I2, $) Reduce 10. (I0SI10, $) Accept. Dérivation correspondante : num + num; <= num+ num; <= T + num; <= E + num <= E + num; <= E + num; <= E + T; <= E; <= E; <= E’ I0 I1 I6 I9 I2 I7 I8 I5 E T + num ( ) I4 I3 ; I10 S IFT313 © Froduald Kabanza
12
AFD + simulation de l’analyseur LR(0) avec une entrée erronée
T® num. I0 S’® . S S® .E; E® .E+T E® .T T® .(E) T® .num I1 S® E .; E® E .+T I2 S® E;. I6 T® (.E) I3 E® E+.T I7 T® (E .) I4 E® E+T. I9 E®T. I8 F® (E). I10 S’® S. 1. (I0, num++num;$) Shift 2. (I0numI5, num;$) Reduce 3. (I0TI9, num;$) Reduce 4. (I0EI1, num;$) Shift 5. (I0EI1+I3, num;$) Shift 6. (I0EI1+I3+, ;$) Error during reduction : goto(I3,+) is not defined. I0 I1 I6 I9 I2 I7 I8 I5 E T + num ( ) I4 I3 ; I10 S IFT313 © Froduald Kabanza
13
Vers un pilote pour Analyseur LR (1)
L’exemple précédent montre que lorsqu’on a une entrée erronée : L’analyseur LR(0) peut empiler (shift) le prochain token même s’il est erroné. Mais il va se rendre compte que le token est erroné plus tard, durant la réduction. En fait, en général, l’erreur peut être détectée après avoir empilé quelques tokens de plus au-delà du token fautif. Nous allons voir une variante de l’analyseur LR(0) qui fait shift uniquement si le prochain token a un élément shift correspondant dans l’état courant de l’AFD. Techniquement parlant, ceci n’est pas un analyseur LR(0), puisqu’il consulte le prochain token avant de décider de faire shift. C’est un anaylseur LR(1). Néanmoins, cette version est équivalente à l’analyseur LR(0), mis à part le fait qu’elle permet de détecter des erreurs plus tôt. Avec l’exemple précédent, l’erreur serait détectée à l’étape 5 lorsqu’on essaie d’empiler (shift) le ‘+’. Nous décrivons cette variante parce qu’elle permet une bonne transition vers l’analyseur LR(1) général qui nous intéresse le plus. IFT313 © Froduald Kabanza
14
Analyseur LR(1) équivalent à l’analyseur LR(0)
while (true) { // Version 2 if (la pile contient I0S’ et l’entrée est $ (vide)) return true; if (l’état au sommet de la pile contient un élément A ® a . ) { reduce with the production A ® a; // a est une poignée et A ® a la production correspondante c.-à-d. : Supprimer 2×|a| symboles de la pile (|a| états et |a| 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 ® a; continue; } if (l’état au sommet de la pile contient un élément A ® a . ab tel que a est le prochain 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. error(); IFT313 © Froduald Kabanza
15
Exemple revisité avec le nouvel algorithme
T® num. I0 S’® . S S® .E; E® .E+T E® .T T® .(E) T® .num I1 S® E .; E® E .+T I2 S® E;. I6 T® (.E) I3 E® E+.T I7 T® (E .) I4 E® E+T. I9 E®T. I8 F® (E). I10 S’® S. 1. (I0, num++num;$) Shift 2. (I0numI5, num;$) Reduce 3. (I0TI9, num;$) Reduce 4. (I0EI1, num;$) Shift 5. (I0EI1+I3, num;$) Error during reduction : cannot shift ‘+’ in state I3. I0 I1 I6 I9 I2 I7 I8 I5 E T + num ( ) I4 I3 ; I10 S IFT313 © Froduald Kabanza
16
Tables d’analyse LR(0) 1/2
On peut améliorer les deux ébauches d’analyseurs LR(0) précédents, en utilisant une table pour implémenter l’AFD pour les préfixes viables. L’idée est que l’action shift aussi bien que l’action reduce dépend seulement de l’état de l’AFD au sommet de la pile. Tout ce dont on a besoin de savoir pour cet état c’est s’il contient : (a) un élément de la forme A ® a . , et dans ce cas on fait reduce; (b) ou un élément de la forme A ® a . ab , et dans ce cas on fait shift; On peut mettre ces information dans une table annexée avec la fonction de transition de l’AFD, goto. De cette façon, on peut utiliser un algorithme d’analyse LR universel, piloté par la table d’analyse. IFT313 © Froduald Kabanza
17
Tables d’analyse LR(0) avec lookahead
Avec lookhead, la table est indexée par l’état de l’AFD et le prochain token. L’entrée dans la table est un symbole désignant l’action (shift ou reduce) et/ou l’état successeur pour la fonction goto. Nous utilisons les conventions suivantes pour la spécification des tables : si signifie ‘Fait shift ensuite empile l’état i’ (c.-à-d., action shif et goto état i); ri signifie ‘Fait reduce avec la production numéro i’; acc signifie accepte l’entrée; une entrée vide signifie que l’analyseur doit signaler une erreur. Comme expliqué précédement, en principe on n’a pas besoin de lookahead pour l’analyse LR(0). Je montre quand même l’algorithme d’analyse avec lookahead comme introduction à l’analyse LR(1). Je montrerai l’algorithme sans lookahead (optionnel) plus tard si j’ai le temps. IFT313 © Froduald Kabanza
18
Construire la table d’analyse LR(0) avec lookahead 1/2
Algorithm construire la table d’analyse LR(0) avec lookahead Entrée : Une grammaire augmentée G, avec le symbole de départ S’; Sortie : Table d’analyse LR(0) avec lookahead; Méthode : 1. Construire l’AFD pour les préfixes viables de G; 2. Nous notons i, l’état Ii. Les actions d’analyse pour l’état i sont déterminées comme suit : a. Si un élément A ® a . ab, tel que a est un terminal, est dans Ii, avec goto(Ii , a) = j, ajoute shift j dans action[i, a]; b. Si un élément A ® a . est dans Ii , avec A différent de S’, ajoute reduce A ® a dans action[i, a], pour chaque terminal a; c. Si l’élément S’ ® S . est dans Ii , ajoute ‘accept’ dans action[i, $]. IFT313 © Froduald Kabanza
19
Construire la table d’analyse LR(0) avec lookahead 2/2
3. Si goto(Ii, A) = Ij pour un non terminal A goto[i, A] devient j ; 4. Toutes les entrées vides sont considérées comme ayant la valeur “erreur”. 5. L’état initial, 0, est celui construit à partir de l’état de l’AFD contenant l’élément S’ ® . S Si la table générée par cette algorithme contient des conflits, c.-à-d., des entrées avec actions multiples, la grammaire correspondante n’est pas LR(0). Sinon, elle est LR(0). IFT313 © Froduald Kabanza
20
Exemple 1/2 IFT313 © Froduald Kabanza 1 2 3 4 5 I5 T® num. I0
S’® . S S® .E; E® .E+T E® .T T® .(E) T® .num I1 S® E .; E® E .+T I2 S® E;. I6 T® (.E) I3 E® E+.T I7 T® (E .) I4 E® E+T. I9 E®T. I8 T® (E). I10 S’® S. I0 I1 I6 I9 I2 I7 I8 I5 E T + num ( ) I4 I3 ; I10 S IFT313 © Froduald Kabanza
21
Exemple 2/2 State action/goto r2 acc r5 r4 r3 goto r1 + ) ( E T num s6
1 2 4 3 7 5 9 8 6 r2 s6 s3 s5 acc r5 r4 r3 ; s2 s8 $ goto 10 S r1 I0 I1 I6 I9 I2 I7 I8 I5 E T + num ( ) I4 I3 ; I10 S IFT313 © Froduald Kabanza
22
Algorithme d’analyse LR (1) 1/2
Algorithm LR1Parser Entrée : flux de tokens Sortie : dérivation de l’entrée si elle est dans L(G), sinon erreur. Variables : stack (pile), a (prochain token), in (entrée : flux de tokens) i (sommet de la pile) Table d’analyse LR(0) avec lookahead, ou SLR(1), ou LALR(1). Méthode : Initialement la pile contient l’état 0. Ensuite il exécute le code suivant. IFT313 © Froduald Kabanza
23
Algorithme d’analyse LR (1) 2/ 2
a = in.getNextToken(); while (true) { i = state on top of stack; if action[i,a] = shift j { push a on top of the stack; push j on top of the stack; a = get.NextToken(); continue; } if action[i,a] = reduce A®a { pop 2x|a| symbols off the stack; i = the state now on top of the stack; push A on top of stack; push goto[i,A] on top of the stack; printout the production A®a ; if action[i,a] = accept return true; error(); IFT313 © Froduald Kabanza
24
Exemple (Simulation de l’analyseur LR(1))
State action/goto + ) ( E T num 1 2 4 3 7 5 9 8 6 r2 s6 s3 s5 acc r5 r4 r3 ; s2 s8 $ goto 10 S r1 1. (0, num+num;$) Shift 2. (0 num 5, num;$) Reduce 5 3. (0 T 9, num;$) Reduce 3 4. (0 E 1, num;$) Shift 5. (0 E 1 + 3, num;$) Shift 6. (0 E num 5, ;$) Reduce 5 7. (0 E T 4, ;$) Reduce 2 8. (0 E 1, ;$) Shift 9. (0 E 1 ; 2, $) Reduce 1 10. (0 S 10, $) Accept. Corresponding derivation sequence: num + num; <= num+ num; <= T + num; <= E + num <= E + num; <= E + num; <= E + T; <= E; <= E; <= S Grammar S’® S 1. S ® E; 2. E ® E+T 3. E ® T 4. T ® (E) 5. T ® num IFT313 © Froduald Kabanza
25
Forces et limites de l’analyse LR(0)
On peut montrer que si un langage hors-contexte a un symbole spécifique qui termine tous les mots du langage (comme le point virgule dans l’exemple précédent), alors il existe une grammaire LR(0) équivalente. Remarquez que les langages de programmation sont en pratique des langages hors-contexte et terminent par une fin de fichier. Donc, théoriquement, on pourrait les analyser par un analyseur LR(0). Cependant, la grammaire LR(0) en question pourrait être très large, difficile à lire et peu efficace. Mais il en existe une. En pratique on préfère des parsers LR qui utilise un lookahead, parce qu’ils exigent des grammaires plus simples. IFT313 © Froduald Kabanza
26
Exemple de grammaire non LR(0)
Un grand nombre de grammaires intéressantes ne sont pas LR(0) même si elles ne sont pas ambiguës. Par exemple, la grammaire suivante pour les expressions arithmétiques n’est pas LR(0): E’ ® E (non numéroté parce que c’est une production interne) 1. E ® E+T 2. E ® T 3. T ® T*F 4. T ®F 5. F ® (E) 6. F® num Pour montrer que la grammaire n’est pas LR(0), on montre que l’AFD correspondant pour les préfixes viables a au moins un état contenant à la fois un élément shift et un élément reduce ou plus d’un élément reduce. Conséquemment la table d’analyse correspondante aurait des entrées multiples. IFT313 © Froduald Kabanza
27
AFD pour préfixes viables
T + F ( num * ) to I7 to I2 to I6 to I3 to I4 to I5 I4 I3 1 2 3 4 5 6 I0 E’® .E E® .E+T E® .T T®.T*F T® .F F® .(E) F®.num I1 E’® E. E® E.+T I2 E® T. T®T.*F I3 T® F. I4 F® (.E) F® .num I5 F® num. I6 E® E+.T T® .T*F I7 T®T*.F I8 F® (E.) I9 E® E+T. T®T*F. I11 F® (E). IFT313 © Froduald Kabanza
28
Table d’analyse LR(0) s5 s4 State actions / goto goto r6 r1 r3 s11 s7
+ * ) ( $ E T F s5 num 1 2 4 3 7 5 9 8 10 6 11 s4 State actions / goto goto r6 r1 r3 s11 s7 s6 r5 r4 r2 acc I0 I1 I6 I9 I2 I7 I10 I8 I11 I5 E T + F ( num * ) to I7 to I2 to I6 to I3 to I4 to I5 I4 I3 IFT313 © Froduald Kabanza
29
Analyse LR(1) Puisque les analyseurs LR(0) n’utilisent pas de lookahead, ils ne peuvent pas analyser efficacement les langages pratiques en programmation. Les analyseurs LR(1) généralisent les analyseurs LR(0) en introduisant un lookahead dans les tables d’analyse, un peu comme dans la version de l’analyseur LR(0) avec lookahead. La différence est que dans le cas d’un analyseur LR(1), le lookahead est non seulement impliqué dans la décision de faire l’action shift, mais aussi dans la décision de faire l’action reduce. IFT313 © Froduald Kabanza
30
Analyse LR(1) Les analyseurs LR(1) les plus populaires sont SLR(1) et LALR(1). SLR(1) signifie “simple” LR(1). Techniquement, c’est une simple modification de l’analyseur LR(0) avec lookahead. La modification est très simple mais significative : on obtient un analyseur presque aussi puissant qu’un analyseur LR(1) complet. LALR(1) signifie “Look Ahead LR(1)”. Il est légèrement plus puissant que SLR(1). L’appellation “LALR” peut paraître inappropriée vu que SLR(1), aussi bien que tout autre analyseur LR(1), utilise aussi un lookahead. En fait, en disant “Look Ahead LR(1),” le “Look Ahead” réfère à l’AFD pour les préfixes viables : dans un analyseur LALR(1), l’AFD est composé des éléments qui sont associés avec un lookahead, alors que ce n’est pas le cas ni dans l’analyse SLR(1) ni dans l’analyse LR(0) avec lookahead. IFT313 © Froduald Kabanza
31
Construire la table d’analyse SLR(1) 1/2
Algorithm construire la table d’analyse SLR(1) Entrée : Une grammaire augmentée G, avec le symbole de départ S’; Sortie : Table d’analyse SLR(1); Méthode : 1. Construire l’AFD pour les préfixes viables de G; 2. Nous notons i, l’état Ii. Les actions d’analyse pour l’état i sont déterminées comme suit : a. Si un élément A ® a . ab, tel que a est un terminal, est dans Ii et goto(Ii , a) est défini, ajoute shift dans action[i, a]; b. Si un élément A ® a . est dans Ii , avec A différent de S’, ajoute reduce A ® a dans action[i, a], pour chaque terminal a dans Follow(A); c. Si l’élément S’ ® S . est dans Ii , ajoute ‘accept’ dans action[i, $]. IFT313 © Froduald Kabanza
32
Construire la table d’analyse SLR(1) 2/2
3. Si goto(Ii, A) = Ij pour un non terminal A goto[i, A] devient j ; 4. Toutes les entrées vides sont considérées comme ayant la valeur “erreur”. 5. L’état initial, 0, est celui construit à partir de l’état de l’AFD contenant l’élément S’ ® . S Si la table générée par cette algorithme contient des conflits, c.-à-d., des entrées avec des actions multiples, la grammaire correspondante n’est pas SLR(1). L’algorithme d’analyse demeure le même que le précédent (seule la table change). Un analyseur SLR(1) est un analyseur qui utilise une table SLR(1). Dans ce cas on omet en général le suffixe (1) puisqu’on ne s’intéresse pratiquement pas à des analyseurs SLR(k) avec k>1. IFT313 © Froduald Kabanza
33
Exemple to I7 to I2 to I6 to I3 to I4 to I5 IFT313 © Froduald Kabanza
+ F ( num * ) to I7 to I2 to I6 to I3 to I4 to I5 I4 I3 1 2 3 4 5 6 I0 E’® .E E® .E+T E® .T T®.T*F T® .F F® .(E) F®.num I1 E’® E. E® E.+T I2 E® T. T®T.*F I3 T® F. I4 F® (.E) F® .num I5 F® num. I6 E® E+.T T® .T*F I7 T®T*.F I8 F® (E.) I9 E® E+T. T®T*F. I11 F® (E). IFT313 © Froduald Kabanza
34
Table d’analyse SLR(1) s5 s4 State actions / goto goto r6 r1 r3 s11 s7
+ F ( num * ) to I7 to I2 to I6 to I3 to I4 to I5 I4 I3 + * ) ( $ E T F s5 num 1 2 4 3 7 5 9 8 10 6 11 s4 State actions / goto goto r6 r1 r3 s11 s7 s6 r5 r4 r2 acc E’ -> E (non numéroté parce que c’est une production interne) 1. E -> E+T 2. E -> T 3. T -> T*F 4. T -> F 5. F -> (E) 6. F ->num IFT313 © Froduald Kabanza
35
Simulation s5 s4 actions / goto goto r6 r1 r3 s11 s7 s6 r5 r4 r2 acc
+ * ) ( $ E T F s5 num 1 2 4 3 7 5 9 8 10 6 11 s4 actions / goto goto r6 r1 r3 s11 s7 s6 r5 r4 r2 acc Exemple d’exécution : 1. (0, (num)$) s4 2. (0 ( 4, num)$) s5 3. (0 ( 4 num 5, )$) r6: F® num. 4. (0 ( 4 F 3, )$) r4: T® F. 5. (0 ( 4 T 2, )$) r2: E® T. 6. (0 ( 4 E 8, )$) s11 7. (0 ( 4 E 8 ) 11, $) r5: F® (E). 8. (0 F 3, $) r4: T® F. 9. (0 T 2, $) r2: E® T. 10. (0 E 1, $) accept Dérivation correspondante (num) <= (num) <= (num) <= (F) <= (T) <= (E) <= (E) <= F <= T <= E IFT313 © Froduald Kabanza
36
Algorithme d’analyse LR(0) sans lookahead
Optionnel Algorithme d’analyse LR(0) sans lookahead IFT313 © Froduald Kabanza
37
Tables d’analyse LR(0) sans Lookahead
En principle, pour l’analyse LR(0), on a pas besoin de lookahead. On aurait pu donc formule l’analyse LR(0) sans lookahead. Sans lookahead, la table d’analyse est indexée seulement par l’état de l’AFD. Nous utilisons les conventions suivantes pour la spécification des tables : s signifie ‘Fait shift’ (utilisé seulement dans les tables sans lookahead); On n’a plus besoin de si c.à`d. ‘Fait shift ensuite empile l’état i’ (c.-à-d., action shif et goto état i); ri signifie encore ‘Fait reduce avec la production numéro i’; acc signifie accepte l’entrée; une entrée vide signifie que l’analyseur doit signaler une erreur. IFT313 © Froduald Kabanza
38
Construire la table d’analyse LR(0) sans lookahead 1/2
Algorithm construire la table d’analyse LR(0) sans lookahead Entrée : Une grammaire augmentée G, avec le symbole de départ S’; Sortie : Table d’analyse LR(0) sans lookahead; Méthode : 1. Construire l’AFD pour les préfixes viables de G; 2. Nous notons i, l’état Ii. Les actions d’analyse pour l’état i sont déterminées comme suit : a. Si un élément A ® a . ab, tel que a est un terminal, est dans Ii et goto(Ii , a) est défini, ajoute shift dans action[i]; b. Si un élément A ® a . est dans Ii , avec A différent de S’, ajoute reduce A ® a dans action[i]; c. Si l’élément S’ ® S . est dans Ii , ajoute ‘accept’ dans action[i]. IFT313 © Froduald Kabanza
39
Construire la table d’analyse LR(0) sans lookahead) 2/2
3. Si goto(Ii, A) = Ij pour un non terminal A goto[i, A] devient j ; 4. Toutes les entrées vides sont considérées comme ayant la valeur “erreur”. 5. L’état initial, 0, est celui construit à partir de l’état de l’AFD contenant l’élément S’ ® . S Si la table générée par cette algorithme contient des conflits, c.-à-d., des entrées avec des actions multiples, la grammaire correspondante n’est pas LR(0). Sinon, elle est LR(0). IFT313 © Froduald Kabanza
40
Exemple 1/2 IFT313 © Froduald Kabanza 1 2 3 4 5 I5 T® num. I0
S’® . S S® .E; E® .E+T E® .T T® .(E) T® .num I1 S® E .; E® E .+T I2 S® E;. I6 T® (.E) I3 E® E+.T I7 T® (E .) I4 E® E+T. I9 E®T. I8 T® (E). I10 S’® S. I0 I1 I6 I9 I2 I7 I8 I5 E T + num ( ) I4 I3 ; I10 S IFT313 © Froduald Kabanza
41
Exemple 2/2 goto action s State r1 r2 r5 r4 r3 acc + ) ( E T num ; S
1 2 4 3 7 5 9 8 6 action r2 r1 r5 r4 r3 ; S 10 acc IFT313 © Froduald Kabanza
42
Algorithme d’analyse LR(0) avec table d’analyse sans lookahead (1/2)
Algorithm LR0ParserWithTable Entrée : flux de tokens Sortie : dérivation de l’entrée si elle est dans L(G), sinon erreur. Variables : stack (pile), a (prochain token), in (entrée : flux de tokens) i (sommet de la pile) Table d’analyse LR(0) sans lookahead. Méthode : Initialement la pile contient 0 (c-.à-d., état 0). Ensuite il exécute le code suivant. IFT313 © Froduald Kabanza
43
Algorithme d’analyse LR(0) avec table d’analyse sans lookahead (2/2)
while (true) { i = state on top of stack; if action[i] = shift { a = in.getNextToken(); // Ceci avance la tête de lecture. push a on top of the stack; push goto[i,a] on top of the stack; continue; } if action[I] = reduce A®a { pop 2x|a | symbols off the stack; i = the state now on top of the stack; push A on top of stack; push goto[i,A] on top of the stack; printout the production A®a ; if action[i] = accept and the input is empty return true; error(); IFT313 © Froduald Kabanza
44
Exemple (simulation de l’analyseur LR(0))
State + ) ( E T s num 1 2 4 3 7 5 9 8 6 action r2 r1 r5 r4 r3 ; S 10 acc 1. (0, num+num;$) Shift 2. (0 num 5, num;$) Reduce 5 3. (0 T 9, num;$) Reduce 3 4. (0 E 1, num;$) Shift 5. (0 E 1 + 3, num;$) Shift 6. (0 E num 5, ;$) Reduce 5 7. (0 E T 4, ;$) Reduce 2 8. (0 E 1, ;$) Shift 9. (0 E 1 ; 2, $) Reduce 1 10. (0 S 10, $) Accept. Dérivation correspondante : num + num; <= num+ num; <= T + num; <= E + num <= E + num; <= E + num; <= E + T; <= E; <= E; <= S Grammar S’® S 1. S ® E; 2. E ® E+T 3. E ® T 4. T ® (E) 5. T ® num IFT313 © Froduald Kabanza
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.