1 / 60

Compilation Analyses Lexicale, Syntaxique, et S mantique

Transparent 2. Sommaire. 1. Introduction

laszlo
Download Presentation

Compilation Analyses Lexicale, Syntaxique, et S mantique

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


    1. 1 Compilation Analyses Lexicale, Syntaxique, et Sémantique Introduction Les techniques d'analyse syntaxique utilisables dans la construction pratique des compilateurs sont principalement issues de deux grandes familles de grammaires, les LL(k) et les LR(k), pour lesquelles la théorie fournit des résultats quasi optimaux. Introduction Les techniques d'analyse syntaxique utilisables dans la construction pratique des compilateurs sont principalement issues de deux grandes familles de grammaires, les LL(k) et les LR(k), pour lesquelles la théorie fournit des résultats quasi optimaux.

    2. Transparent 2 Sommaire 1. Introduction à la compilation 2. Analyse lexicale 3. Rappels sur les langages formels 4. Analyse syntaxique non déterministe 5. Analyse syntaxique descendante méthodes LL() 6. Analyse syntaxique ascendante méthodes LR() 7. Traduction dirigée par la syntaxe 8. Générateurs LR() 9. Sémantique statique des L.P. 10. Traitements «source to source» Références bibliographiques Compilateurs: Principes, techniques et outils, A. Aho, R. Sethi, J. Ullman; InterEditions (1991) Lex & Yacc, JR Lewine, T. Mason, D. Brown; O’Reilly & Associates, Inc (1992) A first course using ANSI C, LEX and YACC, J. P. Bennett, 2nd edition, McGraw Hill (1996) Modern Compilation Implementation, A. Appel; Cambridge University Press (1998) The Essence of Compilers, R. Hunter, Prentice hall (1999) Compilateurs, D.Grune et all, Dunod (2002) Crafting a Compiler, C.Fischer, R.LeBlanc, Benjamin Cummings Series (1988) Autres Cours ESSI Petit Précis de Lex. J. Farré; Notes de TP ESSI-2 (1998) Petit Précis de Yacc. J. Farré; Notes de TP ESSI-2 (1998) Cours de Compilation du MIT (format .ppt en Anglais) lecture3: grammaires, arbres, langages, analyseurs lecture4: construction SLR lecture5: construction LR(1) lecture6: construction LALR(1) lecture7: sémantique statique. Références bibliographiques Compilateurs: Principes, techniques et outils, A. Aho, R. Sethi, J. Ullman; InterEditions (1991) Lex & Yacc, JR Lewine, T. Mason, D. Brown; O’Reilly & Associates, Inc (1992) A first course using ANSI C, LEX and YACC, J. P. Bennett, 2nd edition, McGraw Hill (1996) Modern Compilation Implementation, A. Appel; Cambridge University Press (1998) The Essence of Compilers, R. Hunter, Prentice hall (1999) Compilateurs, D.Grune et all, Dunod (2002) Crafting a Compiler, C.Fischer, R.LeBlanc, Benjamin Cummings Series (1988) Autres Cours ESSI Petit Précis de Lex. J. Farré; Notes de TP ESSI-2 (1998) Petit Précis de Yacc. J. Farré; Notes de TP ESSI-2 (1998) Cours de Compilation du MIT (format .ppt en Anglais) lecture3: grammaires, arbres, langages, analyseurs lecture4: construction SLR lecture5: construction LR(1) lecture6: construction LALR(1) lecture7: sémantique statique.

    3. 3 Chapitre 5 Analyse syntaxique descendante méthodes LL(k) Propriété LL(k) Déterminer si une grammaire est LL(1) ? Analyseur LL(1) Générateur syntaxique LL(1) Quelques Environnments de Compilation (compiler- compiler) Java Compiler Compiler [tm] (JavaCC [tm]) - The Java Parser Generator http://javacc.java.net/ SYNTAX http://syntax.gforge.inria.fr/ Free Compiler Construction Tools http://www.thefreecountry.com/programming/compilerconstruction.shtml ANTLR, ANother Tool for Language Recognition, http://www.antlr.org/ The Compiler Generator Coco/R http://www.ssw.uni-linz.ac.at/Coco/Quelques Environnments de Compilation (compiler- compiler) Java Compiler Compiler [tm] (JavaCC [tm]) - The Java Parser Generator http://javacc.java.net/ SYNTAX http://syntax.gforge.inria.fr/ Free Compiler Construction Tools http://www.thefreecountry.com/programming/compilerconstruction.shtml ANTLR, ANother Tool for Language Recognition, http://www.antlr.org/ The Compiler Generator Coco/R http://www.ssw.uni-linz.ac.at/Coco/

    4. Transparent 4 Propriété LL(k) il existe k? 0 dépendant uniquement de la grammaire tel que: pour tout mot X à analyser dans T* pour tout A dans N au plus une règle A?? de P dérive de S en: A?? *? y1 . . . yk T* LL(k) Lecture du mot de gauche à droite(Left to Right) Dérivations gauches (Leftmost) Propriété LL(k) des grammaires Notation: pour toute production {A??} d' une grammaire G, on note: Vuek(A??)={y[k], S ??g uAv ?u?v ?? uyw ?T*, avec v ?(N ? T)* } ? Interprétation: Vuek(A??) est l'ensemble des préfixes de longueur k que l'on peut réellement obtenir dans un arbre de dérivation, en dérivant A?? Définition: une grammaire est LL(k) si pour tout non terminal A et pour toute paire de production A?? et A?? : ? ? ? => Vuek(A??) ? Vuek(A??) = ? ? Propriété: une grammaire LL(k) est LL(k') pour k' > k ? Grammaire LL(1) Notation: pour k= 1, on note: Vue(A??) = Vuek(A??) ? Principe : Pour décider si une grammaire est LL(1), il suffit de savoir construire tous les ensembles Vue(A??) ? T , pour toutes les productions A?? vérifier la propriété de la définition ci-dessus.LL(k) Lecture du mot de gauche à droite(Left to Right) Dérivations gauches (Leftmost) Propriété LL(k) des grammaires Notation: pour toute production {A??} d' une grammaire G, on note: Vuek(A??)={y[k], S ??g uAv ?u?v ?? uyw ?T*, avec v ?(N ? T)* } ? Interprétation: Vuek(A??) est l'ensemble des préfixes de longueur k que l'on peut réellement obtenir dans un arbre de dérivation, en dérivant A?? Définition: une grammaire est LL(k) si pour tout non terminal A et pour toute paire de production A?? et A?? : ? ? ? => Vuek(A??) ? Vuek(A??) = ? ? Propriété: une grammaire LL(k) est LL(k') pour k' > k ? Grammaire LL(1) Notation: pour k= 1, on note: Vue(A??) = Vuek(A??) ? Principe : Pour décider si une grammaire est LL(1), il suffit de savoir construire tous les ensembles Vue(A??) ? T , pour toutes les productions A?? vérifier la propriété de la définition ci-dessus.

    5. Transparent 5 Grammaire non LL() Grammaire INST inst ::= var := exp (r1) inst ::= if exp then s_d_inst else s_d_inst endif (r2) s_d_inst ::= inst ; s_d_inst | inst (r3 r4) exp ::= var + exp | var = exp | var (r5 r6 r7) Analyse non LL(k) if v1= v2 then v3 := v4 + v5 ; if v3= v4 then v5 := v1 = v4 else v3 := v4 end if ; v7 := v8 else v3 := v4 endif Grammaires LL() Certaines propriétés permettent de décider facilement si une grammaire est ou n'est pas LL(k)? Grammaires Récursives Gauches Théorème: Une grammaire LL(k) n'est pas récursive gauche ? Preuve en TD3 Simples LL(k) Définition: Une grammaire est simple LL(k), noté SLL(k), si toutes les règles de P sont de la forme Si ? a1.. an ui avec a1.. an ? T+ et ui ? (N u T) * il existe k >= 0 tel que pour toute paire de règles Si ? a1.. an ui et Si ? b1.. bm vi les mots a1.. an et b1.. bm n'ont pas de préfixe commun de longueur k ? Théorème: Une grammaire SLL(k) est LL(k) ? Analyse de la grammaire INST La grammaire INST n'est pas RG; Les dérivations issues de INST sont SLL(1): se décident par "var" ou "if" Les dérivations issues de EXP sont LL(2) (pas SLL(2)) se décident par "var" "+" ou "var" "=" ou "var" suivi d'un lexème ? différent de "+" ou "=" Les dérivations issues de S_D_INST ne sont pas LL(k): pour tout k, il existe des INST plus longues que k Grammaires LL() Certaines propriétés permettent de décider facilement si une grammaire est ou n'est pas LL(k)? Grammaires Récursives Gauches Théorème: Une grammaire LL(k) n'est pas récursive gauche ? Preuve en TD3 Simples LL(k) Définition: Une grammaire est simple LL(k), noté SLL(k), si toutes les règles de P sont de la forme Si ? a1.. an ui avec a1.. an ? T+ et ui ? (N u T) * il existe k >= 0 tel que pour toute paire de règles Si ? a1.. an ui et Si ? b1.. bm vi les mots a1.. an et b1.. bm n'ont pas de préfixe commun de longueur k ? Théorème: Une grammaire SLL(k) est LL(k) ? Analyse de la grammaire INST La grammaire INST n'est pas RG; Les dérivations issues de INST sont SLL(1): se décident par "var" ou "if" Les dérivations issues de EXP sont LL(2) (pas SLL(2)) se décident par "var" "+" ou "var" "=" ou "var" suivi d'un lexème ? différent de "+" ou "=" Les dérivations issues de S_D_INST ne sont pas LL(k): pour tout k, il existe des INST plus longues que k

    6. Transparent 6 Grammaire LL(1) Grammaire INST' inst ::= var := exp (r1) inst ::= if exp then s_d_inst else s_d_inst endif (r2) s_d_inst ::= inst s_s_inst (r3) s_s_inst ::= ; s_d_inst | ? (r4 r5) exp ::= var s_d_exp (r6) s_d_exp ::= + exp | = exp | ? (r7 r8 r9) Analyse LL(1) if v1 = v2 then v3 := v4 + v5 ; if v3= v4 then v5 := v1 = v4 else v3 := v4 end if ; v7 := v8 else v3 := v4 endif Factorisation à gauche de la grammaire INST La grammaire INST' est obtenue par factorisation: de inst en s_s_inst dans r3 et r4 de var en s_d_exp dans r5, r6, r7 Remarque: Une "bonne" grammaire (factorisée à gauche et non récursive gauche) peut n'être ni SLL(k), ni même LL(k) pour aucun k ? Analyse de la grammaire INST ' La grammaire INST n' est pas RG; Les dérivations issues de INST sont SLL(1): se décident par "var" ou "if" Les dérivations issues de EXP sont SLL(0) Les dérivations issues de S_D_EXP sont LL(1) se décident par "+" ou "=" ou un lexème différent de "+" ou "=" ? Les dérivations issues de S_D_INST sont LL(0) Les dérivations issues de S_S_INST sont LL(1) se décident par ";" ou un lexème différent de ";" ? Factorisation à gauche de la grammaire INST La grammaire INST' est obtenue par factorisation: de inst en s_s_inst dans r3 et r4 de var en s_d_exp dans r5, r6, r7 Remarque: Une "bonne" grammaire (factorisée à gauche et non récursive gauche) peut n'être ni SLL(k), ni même LL(k) pour aucun k ? Analyse de la grammaire INST ' La grammaire INST n' est pas RG; Les dérivations issues de INST sont SLL(1): se décident par "var" ou "if" Les dérivations issues de EXP sont SLL(0) Les dérivations issues de S_D_EXP sont LL(1) se décident par "+" ou "=" ou un lexème différent de "+" ou "=" ? Les dérivations issues de S_D_INST sont LL(0) Les dérivations issues de S_S_INST sont LL(1) se décident par ";" ou un lexème différent de ";" ?

    7. Transparent 7 Code Ada pour un analyseur LL(1) Analyseur à pile pour INST' Lex(ul); while ul /= EOT() loop case ul of "var" => case Som() of end case; "if" => case Som() of end case; end case; end loop; Analyseur à pile pour une grammaire LL(1) procedure Analyseur { Lex(ul); while ul /= EOT() loop case ul of "var" => voir à coté "if" => voir à coté ";" => case Som() of ";" => S_S_INST => // r4 S_D_EXP => // r9 others => raise ERREUR_de_syntaxe; end case; "+" => case Som() of "+" => S_D_EXP => // r7 others => raise ERREUR_de_syntaxe; end case; "=" | "then" => comme "+" "else" | "endif" => comme ";" end case; end loop; } Analyseur à pile pour une grammaire LL(1) procedure Analyseur { Lex(ul); while ul /= EOT() loop case ul of "var" => voir à coté "if" => voir à coté ";" => case Som() of ";" => S_S_INST => // r4 S_D_EXP => // r9 others => raise ERREUR_de_syntaxe; end case; "+" => case Som() of "+" => S_D_EXP => // r7 others => raise ERREUR_de_syntaxe; end case; "=" | "then" => comme "+" "else" | "endif" => comme ";" end case; end loop; }

    8. Transparent 8 Code Ada pour un analyseur LL(1) Analyseur à pile pour INST' Lex(ul); while ul /= EOT() loop case ul of "var" => case Som() of "var" => Dep() ; Lex(ul) ; INST => Dep();Emp(EXP); Emp(":="); Emp("var"); // r1 S_D_INST => Dep(); Emp(S_S_INST); Emp(INST); // r3 EXP => Dep(); Emp(S_D_EXP); Emp("var"); // r6 others => raise ERREUR_de_syntaxe; end case; "if" => case Som() of "if" => Dep() ; Lex(ul) ; "INST" => Dep(); Emp( "endif"); Emp(S_D_INST); Emp("else"); Emp(S_D_INST); Emp("then"); Emp(EXP); Emp( "if" ); // r2 S_D_INST => Dep(); Emp(S_S_INST) ; Emp(INST); // r3 others => raise ERREUR_de_syntaxe; end case; - - - - - - - Analyseur à pile pour une grammaire LL(1) procedure Analyseur { Lex(ul); while ul /= EOT() loop case ul of "var" => voir à coté "if" => voir à coté ";" => case Som() of ";" => S_S_INST => // r4 S_D_EXP => // r9 others => raise ERREUR_de_syntaxe; end case; "+" => case Som() of "+" => S_D_EXP => // r7 others => raise ERREUR_de_syntaxe; end case; "=" | "then" => comme "+" "else" | "endif" => comme ";" end case; end loop; } Analyseur à pile pour une grammaire LL(1) procedure Analyseur { Lex(ul); while ul /= EOT() loop case ul of "var" => voir à coté "if" => voir à coté ";" => case Som() of ";" => S_S_INST => // r4 S_D_EXP => // r9 others => raise ERREUR_de_syntaxe; end case; "+" => case Som() of "+" => S_D_EXP => // r7 others => raise ERREUR_de_syntaxe; end case; "=" | "then" => comme "+" "else" | "endif" => comme ";" end case; end loop; }

    9. Transparent 9 Code Java pour un analyseur LL(1) Analyseur à pile pour INST' Lex(ul) ; while (ul != EOT() ) { switch (ul) { case "var": switch (Som() ) { } ; break; case "if" : switch (Som() ){ } ; break; } } Analyseur à pile pour une grammaire LL(1) procedure Analyseur() { Lex(ul); while ( ul != EOT() ) { switch (ul) { case "var" : voir à coté case "if" : voir à coté case ";" : switch (Som() ) { case ";" : case S_S_INST: // r4 case S_D_EXP : // r9 default: throw new ErreurSyntaxe(); } ; break ; case "+" : switch (Som() ) { case "+" : case S_D_EXP : // r7 default: throw new ErreurSyntaxe(); } ; break ; case "=" : case "then" : comme "+" case "else": case "endif" : comme ";" } } } Analyseur à pile pour une grammaire LL(1) procedure Analyseur() { Lex(ul); while ( ul != EOT() ) { switch (ul) { case "var" : voir à coté case "if" : voir à coté case ";" : switch (Som() ) { case ";" : case S_S_INST: // r4 case S_D_EXP : // r9 default: throw new ErreurSyntaxe(); } ; break ; case "+" : switch (Som() ) { case "+" : case S_D_EXP : // r7 default: throw new ErreurSyntaxe(); } ; break ; case "=" : case "then" : comme "+" case "else": case "endif" : comme ";" } } }

    10. Transparent 10 Code Java pour un analyseur LL(1) Lex(ul) ; while (ul != EOT() ) { switch (ul) { case "var": switch (Som() ) { case "var": Dep() ; Lex(ul) ; break ; case INST: Dep(); Emp(EXP); Emp(":="); Emp("var"); break ; // r1 case S_D_INST: Dep(); Emp(S_S_INST); Emp(INST); break; // r3 case EXP : Dep(); Emp(S_D_EXP); Emp("var"); break ; // r6 default : throw new ErreurSyntaxe(); } ; break; case "if" : switch (Som() ) { case "if" : Dep() ; Lex(ul) ; break ; case "INST": Dep(); Emp( "endif"); Emp(S_D_INST); Emp("else"); Emp(S_D_INST); Emp("then"); Emp(EXP); Emp( "if" ); break ; // r2 case S_D_INST : Dep(); Emp(S_S_INST) ; Emp(INST); break ; // r3 default : throw new ErreurSyntaxe(); } ; break; } } Analyseur à pile pour une grammaire LL(1) procedure Analyseur() { Lex(ul); while ( ul != EOT() ) { switch (ul) { case "var" : voir à coté case "if" : voir à coté case ";" : switch (Som() ) { case ";" : case S_S_INST: // r4 case S_D_EXP : // r9 default: throw new ErreurSyntaxe(); } ; break ; case "+" : switch (Som() ) { case "+" : case S_D_EXP : // r7 default: throw new ErreurSyntaxe(); } ; break ; case "=" : case "then" : comme "+" case "else": case "endif" : comme ";" } } } Analyseur à pile pour une grammaire LL(1) procedure Analyseur() { Lex(ul); while ( ul != EOT() ) { switch (ul) { case "var" : voir à coté case "if" : voir à coté case ";" : switch (Som() ) { case ";" : case S_S_INST: // r4 case S_D_EXP : // r9 default: throw new ErreurSyntaxe(); } ; break ; case "+" : switch (Som() ) { case "+" : case S_D_EXP : // r7 default: throw new ErreurSyntaxe(); } ; break ; case "=" : case "then" : comme "+" case "else": case "endif" : comme ";" } } }

    11. Transparent 11 Analyseur récursif LL(1) proc INST(ul) { switch( ul ) { case "var" : break; case "if" : break; default : throw new ErreurSyntaxe(); } } proc EXP(ul) { switch( ul ) { case "var" : break; default : throw new ErreurSyntaxe(); } } proc S_D_INST(ul) { switch( ul ) { case "var" : case"if" : break; default : throw new ErreurSyntaxe(); } } Analyseur pour une grammaire LL(1) proc scan(ul, term) { if (ul = term) Lex(ul) ; else throw new ErreurSyntaxe();} proc INST(ul); voir à coté proc EXP(ul) ; voir à coté proc S_D_INST(ul) voir à coté proc S_S_INST(ul) { switch ( ul) { case ";": scan(ul, ";" ); S_D_INST(ul) ; break ; // r4 case"else": case "endif": case ";" : break; // r5 default: throw new ErreurSyntaxe(); } } proc S_D_EXP(ul) { switch ( ul) { case "+": scan(ul, "+" ); EXP(ul) ; break; // r7 case "=" : scan(ul, "=" ); EXP(ul) ; break; // r8 cas "then": case"else": case"endif": case";": break; // r9 default: throw new ErreurSyntaxe(); } } Analyseur pour une grammaire LL(1) proc scan(ul, term) { if (ul = term) Lex(ul) ; else throw new ErreurSyntaxe();} proc INST(ul); voir à coté proc EXP(ul) ; voir à coté proc S_D_INST(ul) voir à coté proc S_S_INST(ul) { switch ( ul) { case ";": scan(ul, ";" ); S_D_INST(ul) ; break ; // r4 case"else": case "endif": case ";" : break; // r5 default: throw new ErreurSyntaxe(); } } proc S_D_EXP(ul) { switch ( ul) { case "+": scan(ul, "+" ); EXP(ul) ; break; // r7 case "=" : scan(ul, "=" ); EXP(ul) ; break; // r8 cas "then": case"else": case"endif": case";": break; // r9 default: throw new ErreurSyntaxe(); } }

    12. Transparent 12 Analyseur récursif LL(1) proc INST(ul) { switch( ul ) { case "var" : scan(ul, "var" ); scan(ul, ":=" ); EXP(ul) ; break; // r1 case "if" : scan(ul, "if" ); EXP(ul) ; scan(ul, "then" ); S_D_INST(ul); scan(ul, "else" ); S_D_INST(ul); scan(ul, "endif" ); break; // r2 default : throw new ErreurSyntaxe(); } } proc EXP(ul) { switch( ul ) { case "var": scan(ul, "var" ); S_D_EXP(ul) ; break; // r6 default : throw new ErreurSyntaxe(); } } proc S_D_INST(ul) { switch( ul ) { case "var": case"if": INST (ul); S_S_INST (ul); break; // r3 default : throw new ErreurSyntaxe(); } } Analyseur pour une grammaire LL(1) proc scan(ul, term) { if (ul = term) Lex(ul) ; else throw new ErreurSyntaxe();} proc INST(ul); voir à coté proc EXP(ul) ; voir à coté proc S_D_INST(ul) voir à coté proc S_S_INST(ul) { switch ( ul) { case ";": scan(ul, ";" ); S_D_INST(ul) ; break ; // r4 case"else": case "endif": case ";" : break; // r5 default: throw new ErreurSyntaxe(); } } proc S_D_EXP(ul) { switch ( ul) { case "+": scan(ul, "+" ); EXP(ul) ; break; // r7 case "=" : scan(ul, "=" ); EXP(ul) ; break; // r8 case"then": case"else": cas "endif": case";": break; // r9 default: throw new ErreurSyntaxe(); } } Analyseur pour une grammaire LL(1) proc scan(ul, term) { if (ul = term) Lex(ul) ; else throw new ErreurSyntaxe();} proc INST(ul); voir à coté proc EXP(ul) ; voir à coté proc S_D_INST(ul) voir à coté proc S_S_INST(ul) { switch ( ul) { case ";": scan(ul, ";" ); S_D_INST(ul) ; break ; // r4 case"else": case "endif": case ";" : break; // r5 default: throw new ErreurSyntaxe(); } } proc S_D_EXP(ul) { switch ( ul) { case "+": scan(ul, "+" ); EXP(ul) ; break; // r7 case "=" : scan(ul, "=" ); EXP(ul) ; break; // r8 case"then": case"else": cas "endif": case";": break; // r9 default: throw new ErreurSyntaxe(); } }

    13. Transparent 13 PREMIER() Calcul de Prem(X) si x ? T alors Prem(x) = {x} si {X ? ?} ? P alors ? ? Prem(X) si X ? N et {X ? Y1 ..Yi..Yn } ? P alors calculer la clôture des règles suivantes: Prem(Y1) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1.. i-1 alors Prem(Yi) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1 .. n alors ? ? Prem(X) Calcul de Prem(X1… Xj…Xn): Prem(X1) - ? ? Prem(X1… Xj…Xn) si ? ? Prem(Xj) pour j = 1 .. i-1 alors Prem(Xj) - ? ? Prem(X1… Xj…Xn) si ? ? Prem(Xj) pour j = 1 .. n alors ? ? Prem(X1… Xj…Xn) Les Premiers dans une grammaire (ici de longueur 1) Notation: pour tout ? ?(N ?T)+, on note: Prem(? ) = { a ?T si ? ?? a w avec w ? (N ?T)?, et ? si ? ?? ? } ? Interprétation: Prem(?) est l'ensemble des premiers symboles terminaux de tous les mots que l'on peut dériver à partir de ? (à partir de l'axiome ou non !) Propriété: si une grammaire G ne contient pas de ?-production (règle A? ?): Vue(A? ?) = Prem(?[1]) ? Exemple: si ? = RSw et R?? ? P : alors Vue(A? ? ) ? Prem(R) et Prem(S) Généralisation: Premiers de longueur k Premk(? ) = { a ?Tk si ? ?? a w avec w ? (N ?T)?, et ? si ? ?? ? } ? Les Premiers dans une grammaire (ici de longueur 1) Notation: pour tout ? ?(N ?T)+, on note: Prem(? ) = { a ?T si ? ?? a w avec w ? (N ?T)?, et ? si ? ?? ? } ? Interprétation: Prem(?) est l'ensemble des premiers symboles terminaux de tous les mots que l'on peut dériver à partir de ? (à partir de l'axiome ou non !) Propriété: si une grammaire G ne contient pas de ?-production (règle A? ?): Vue(A? ?) = Prem(?[1]) ? Exemple: si ? = RSw et R?? ? P : alors Vue(A? ? ) ? Prem(R) et Prem(S) Généralisation: Premiers de longueur k Premk(? ) = { a ?Tk si ? ?? a w avec w ? (N ?T)?, et ? si ? ?? ? } ?

    14. Transparent 14 PREMIERs de EE'TT'F Cloture Les premiers dans une grammaire si {X ? Y1 ..Yi..Yn } ? P Prem(Y1) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1.. i-1 alors Prem(Yi) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1 .. n alors ? ? Prem(X) Les Premiers pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | id Les premiers dans une grammaire si {X ? Y1 ..Yi..Yn } ? P Prem(Y1) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1.. i-1 alors Prem(Yi) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1 .. n alors ? ? Prem(X) Les Premiers pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | id

    15. Transparent 15 PREMIERs de EE'TT'F Cloture T ? FT' E ? TE' {X ? ?Y?} et ??Prem(?) Les premiers dans une grammaire si {X ? Y1 ..Yi..Yn } ? P Prem(Y1) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1.. i-1 alors Prem(Yi) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1 .. n alors ? ? Prem(X) Les Premiers pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | var Prem(F) = { ( ,var } Prem(E') = { + , ? } Prem(T') = { * , ? } Prem(E, T, F) = { ( ,var } Les premiers dans une grammaire si {X ? Y1 ..Yi..Yn } ? P Prem(Y1) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1.. i-1 alors Prem(Yi) - ? ? Prem(X) si ? ? Prem(Yj) pour j = 1 .. n alors ? ? Prem(X) Les Premiers pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | var Prem(F) = { ( ,var } Prem(E') = { + , ? } Prem(T') = { * , ? } Prem(E, T, F) = { ( ,var }

    16. Transparent 16 SUIVANT() Calcul de Suiv(X) si S est l'axiome alors # ? Suiv(S) si A et B ? N et x ? T et {A ? ?Bx} ? P alors x ? Suiv(B) si {A ? ?B?} ? P alors Prem(?) - ? ? Suiv(B) calculer la clôture des règles suivantes: si {A ? ?B} ? P alors Suiv(A) ? Suiv(B) si {A ? ?B?} ? P et ? ? Prem(?) alors Suiv(A) ? Suiv(B) Les suivants dans une grammaire (ici de longueur 1) Notation: pour tout A ?N, on note: Suiv(A) = {a?T? #, S#??uAav avec uv?(N ? T)? } ? Interprétation: Suiv(A) est l'ensemble des symboles terminaux qui peuvent suivre immédiatement A dans une dérivation à partir de l'axiome. Propriété: soit A? ? une production d'une grammaire G: Vue(A? ? ) =Prem(?) ? Suiv(A) si ? ?? ? Vue(A? ? ) =Prem(?) sinon ? Calcul des suivants dans une grammaire Notation: pour tout ? ?(N ?T)+, on note: Fin(? ) = {X ? N, ? ?? ? X avec ? ? (N ? T)? } ? Interprétation: Fin(? ) est l'ensemble des non terminaux qui peuvent terminer une dérivation issue de ? Propriété: x ? T, x ? Suiv(A) <=> il existe X? ?? ? P tel que A ? Fin(?) et x ? Prem(? ) ? Décidabilité de la propriété LL(1) Théorème: Pour décider si une grammaire est LL(1) il suffit de calculer les ensembles Prem() et Suiv() et de tester la propriété sur Vue sur l'ensemble des règles de production : pour toute paire de production A? ? et A? ? , ? ? ? si ? ?? ? => ( Prem(?) ? Suiv(A) ) ? Prem(?) = ? si ? ?? ? => Prem(?) ? ( Prem(?) ? Suiv(A) ) = ? si ni ?, ni ? ?? ? => Prem(?) ? Prem(?) = ? sinon ?, et ? ?? ? => pas LL(1) ?Les suivants dans une grammaire (ici de longueur 1) Notation: pour tout A ?N, on note: Suiv(A) = {a?T? #, S#??uAav avec uv?(N ? T)? } ? Interprétation: Suiv(A) est l'ensemble des symboles terminaux qui peuvent suivre immédiatement A dans une dérivation à partir de l'axiome. Propriété: soit A? ? une production d'une grammaire G: Vue(A? ? ) =Prem(?) ? Suiv(A) si ? ?? ? Vue(A? ? ) =Prem(?) sinon ? Calcul des suivants dans une grammaire Notation: pour tout ? ?(N ?T)+, on note: Fin(? ) = {X ? N, ? ?? ? X avec ? ? (N ? T)? } ? Interprétation: Fin(? ) est l'ensemble des non terminaux qui peuvent terminer une dérivation issue de ? Propriété: x ? T, x ? Suiv(A) <=> il existe X? ?? ? P tel que A ? Fin(?) et x ? Prem(? ) ? Décidabilité de la propriété LL(1) Théorème: Pour décider si une grammaire est LL(1) il suffit de calculer les ensembles Prem() et Suiv() et de tester la propriété sur Vue sur l'ensemble des règles de production : pour toute paire de production A? ? et A? ? , ? ? ? si ? ?? ? => ( Prem(?) ? Suiv(A) ) ? Prem(?) = ? si ? ?? ? => Prem(?) ? ( Prem(?) ? Suiv(A) ) = ? si ni ?, ni ? ?? ? => Prem(?) ? Prem(?) = ? sinon ?, et ? ?? ? => pas LL(1) ?

    17. Transparent 17 SUIVANTs de EE'TT'F Cloture E ? TE' T ? FT' E ? TE' ??Prem(E') T ? FT' ??Prem(T') Suivant() calculer la clôture des règles suivantes: si {A ? ?B?} ? P alors Prem(?) - ? ? Suiv(B) si {A ? ?B} ? P alors Suiv(A) ? Suiv(B) si {A ? ?B?} ? P et ? ? Prem(?) alors Suiv(A) ? Suiv(B) Calcul de Suiv() pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | id Prem(F) = { ( ,var } Prem(E') = { + , ? } Prem(T') = { * , ? } Prem(E, T, F) = { ( ,var } Suivant() calculer la clôture des règles suivantes: si {A ? ?B?} ? P alors Prem(?) - ? ? Suiv(B) si {A ? ?B} ? P alors Suiv(A) ? Suiv(B) si {A ? ?B?} ? P et ? ? Prem(?) alors Suiv(A) ? Suiv(B) Calcul de Suiv() pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | id Prem(F) = { ( ,var } Prem(E') = { + , ? } Prem(T') = { * , ? } Prem(E, T, F) = { ( ,var }

    18. Transparent 18 SUIVANTs de EE'TT'F Cloture E ? TE' T ? FT' E ? TE' ??Prem(E') T ? FT' ??Prem(T') Suivant() calculer la clôture des règles suivantes: si {A ? ?B?} ? P alors Prem(?) - ? ? Suiv(B) si {A ? ?B} ? P alors Suiv(A) ? Suiv(B) si {A ? ?B?} ? P et ? ? Prem(?) alors Suiv(A) ? Suiv(B) Calcul de Suiv() pour EE'TT'F: (r0) E0 ? E # (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | id Prem(F) = { ( ,var } Prem(E') = { + , ? } Prem(T') = { * , ? } Prem(E, T, F) = { ( ,var } Suiv(E) = Suiv(E') = { ) , # } Suiv(T) = Suiv(T') = {+ ,) , # } Suiv(F) = { *, + ,) , # } Suivant() calculer la clôture des règles suivantes: si {A ? ?B?} ? P alors Prem(?) - ? ? Suiv(B) si {A ? ?B} ? P alors Suiv(A) ? Suiv(B) si {A ? ?B?} ? P et ? ? Prem(?) alors Suiv(A) ? Suiv(B) Calcul de Suiv() pour EE'TT'F: (r0) E0 ? E # (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | id Prem(F) = { ( ,var } Prem(E') = { + , ? } Prem(T') = { * , ? } Prem(E, T, F) = { ( ,var } Suiv(E) = Suiv(E') = { ) , # } Suiv(T) = Suiv(T') = {+ ,) , # } Suiv(F) = { *, + ,) , # }

    19. Transparent 19 Génération des Tables LL(1) pour chaque {A ? ?} ? P { pour chaque a ? T, a ? Prem(?) { M[A, a] += {A ? ?} } si ? ? Prem(?) alors { pour chaque b ? T, b ? Suiv(A) { M[A, b] += {A ? ?} } si # ? Suiv(A) alors M[A, #] += {A ? ?} } } toute entrée non définie dans M est une "erreur" M[$, #] = "accepter" Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a?

    20. Transparent 20 Table LL(1) pour EE'TT'F PREMIERS SUIVANTS Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Table LL(1) pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | var Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Table LL(1) pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | var

    21. Transparent 21 Table LL(1) pour EE'TT'F PREMIERS Prem(E) = Prem(T) = Prem(F) = { var , ( } Prem(E') = { +, ? } Prem(T') = { *, ? } SUIVANTS Suiv(E) = Suiv(E') = { ) , # } Suiv(T) = Suiv(T') = {+ ,) ,# } Suiv(F) = { *, + ,) , #} Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Table LL(1) pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | var Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Table LL(1) pour EE'TT'F: (r1) E ? T E' (r2, r3) E' ? + T E' | ? (r4) T ? F T' (r5, r6) T' ? * F T' | ? (r7, r8) F ? ( E ) | var

    22. Transparent 22 Table LL(1) pour INST' Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Table LL(1) pour INST' inst ::= var := exp (r1) inst ::= if exp then s_d_inst else s_d_inst endif (r2) s_d_inst ::= inst s_s_inst (r3) s_s_inst ::= ; s_d_inst | ? (r4 r5) exp ::= var s_d_exp (r6) s_d_exp ::= + exp | = exp | ? (r7 r8 r9) Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Table LL(1) pour INST' inst ::= var := exp (r1) inst ::= if exp then s_d_inst else s_d_inst endif (r2) s_d_inst ::= inst s_s_inst (r3) s_s_inst ::= ; s_d_inst | ? (r4 r5) exp ::= var s_d_exp (r6) s_d_exp ::= + exp | = exp | ? (r7 r8 r9)

    23. Transparent 23 Table LL(1) pour INST' Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Table LL(1) pour INST' inst ::= var := exp (r1) inst ::= if exp then s_d_inst else s_d_inst endif (r2) s_d_inst ::= inst s_s_inst (r3) s_s_inst ::= ; s_d_inst | ? (r4 r5) exp ::= var s_d_exp (r6) s_d_exp ::= + exp | = exp | ? (r7 r8 r9) Construction des Tables LL(1) Données: une grammaire G, supposée LL(1). La construction permet de vérifier la propriété Résultat: une table d'analyse LL(1) pour un analyseur prédictif Méthode: Prem() et Suiv() permettent de construire une table d'analyse M pour un analyseur prédictif M : (N ? {$}) x (T ? {#}) ? P ? {erreur, accepter} Propriété: La grammaire est LL(1) ssi M[A, a] contient au plus une action pour tout A et a? Table LL(1) pour INST' inst ::= var := exp (r1) inst ::= if exp then s_d_inst else s_d_inst endif (r2) s_d_inst ::= inst s_s_inst (r3) s_s_inst ::= ; s_d_inst | ? (r4 r5) exp ::= var s_d_exp (r6) s_d_exp ::= + exp | = exp | ? (r7 r8 r9)

    24. Transparent 24 Analyse descendante LL(1) Source ? if v1= v2 then v3 := v4 + v5 ; if v3= v4 then v5 := v1= v4 else v3 := v4 endif ; v7 := v8 else v3 := v4 endif # Grammaire INST après factorisation à gauche inst ::= var := exp (r1) inst ::= if exp then s_d_inst else s_d_inst endif (r2) s_d_inst ::= inst s_s_inst (r3) s_s_inst ::= ; s_d_inst | ? (r4 r5) exp ::= var s_d_exp (r6) s_d_ exp ::= + exp | = exp | ? (r7 r8 r9) Analyse LL(1) du source if v1= v2 then v3 := v4 + v5 ; if v3= v4 then v5 := v1= v4 else v3 := v4 endif ; v7 := v8 else v3 := v4 endif #Grammaire INST après factorisation à gauche inst ::= var := exp (r1) inst ::= if exp then s_d_inst else s_d_inst endif (r2) s_d_inst ::= inst s_s_inst (r3) s_s_inst ::= ; s_d_inst | ? (r4 r5) exp ::= var s_d_exp (r6) s_d_ exp ::= + exp | = exp | ? (r7 r8 r9) Analyse LL(1) du source if v1= v2 then v3 := v4 + v5 ; if v3= v4 then v5 := v1= v4 else v3 := v4 endif ; v7 := v8 else v3 := v4 endif #

    25. Transparent 25 Analyseur générique LL(1) Actions procedure Action(u: LEX; X: N_ou_T) { if (X = u ) { Dep(X) ; Lex(u) ; } else switch (M(u, X)) { case "A ? ? " : Dep(X) ; Emp(miroir(? )) ; break ; case "A ? ?" : Dep(X) ; break ; case "succès" : break ; case "erreur" : throw new Erreur() ; } } Analyseur function Analyse() { Lex(ul); Emp(Axiome); while (ul != "#") { Action(ul, Som()) ; } return succes ; } Décidabilité sur les grammaires LL() Théorème: La propriété LL(k) d'une grammaire est indécidable (pour k non fixé) ? Corollaire: Il n'existe pas d'algorithme permettant de transformer une grammaire quelconque en une grammaire équivalente LL(k) ; mais on peut toujours essayer sur une grammaire donnée! Théorème: Une grammaire LL(1) est non ambiguë preuve: d'après la propriété LL(1) il ne peut exister deux dérivations distinctes pour deux mots identiques ? généralisation: ce résultat est vrai pour les grammaires LL(k) ? Complexité de l'analyse LL() Théorème: Le test LL(1) et la construction de la table d'analyse est en O( |P|*|T|*|N| ) preuve: d'après le calcul de Prem() et Suiv() et la construction précédente ? généralisation: ce résultat est vrai pour l'analyse LL(k) ? Théorème: L'analyse LL(1) d'un mot m est en O(|m|) preuve: directement d'après le code ci-contre ? généralisation: ce résultat est vrai pour l'analyse LL(k) ? Langages LL() Théorème: La propriété LL(k) d'un langage est indécidable (pour k non fixé) ? Théorème: LL(1) ?... ? LL(k) ? ALG DETERMINISTE ? Décidabilité sur les grammaires LL() Théorème: La propriété LL(k) d'une grammaire est indécidable (pour k non fixé) ? Corollaire: Il n'existe pas d'algorithme permettant de transformer une grammaire quelconque en une grammaire équivalente LL(k) ; mais on peut toujours essayer sur une grammaire donnée! Théorème: Une grammaire LL(1) est non ambiguë preuve: d'après la propriété LL(1) il ne peut exister deux dérivations distinctes pour deux mots identiques ? généralisation: ce résultat est vrai pour les grammaires LL(k) ? Complexité de l'analyse LL() Théorème: Le test LL(1) et la construction de la table d'analyse est en O( |P|*|T|*|N| ) preuve: d'après le calcul de Prem() et Suiv() et la construction précédente ? généralisation: ce résultat est vrai pour l'analyse LL(k) ? Théorème: L'analyse LL(1) d'un mot m est en O(|m|) preuve: directement d'après le code ci-contre ? généralisation: ce résultat est vrai pour l'analyse LL(k) ? Langages LL() Théorème: La propriété LL(k) d'un langage est indécidable (pour k non fixé) ? Théorème: LL(1) ?... ? LL(k) ? ALG DETERMINISTE ?

    26. 26 Chapitre 6 Analyse syntaxique ascendante méthodes LR(k) Analyse Ascendante Propriété LR(k) Grammaire SLR, LR(1), LALR(1) Analyseur LR(1) Générateur syntaxique LR(1)

    27. Transparent 27 Analyse Ascendante Principe le mot x à analyser dans T* est lu une seule fois de gauche à droite on construit un arbre de dérivation en montant des feuilles (= x ) vers la racine = axiome Méthode par décalage ou réduction réduire par une dérivation droite inverse se décaler sur X Principe de l'Analyse Ascendante le mot X à analyser dans T* est lu une seule fois de gauche à droite on construit un arbre de dérivation en montant des feuilles (mot des feuilles = X) vers la racine=axiome en assemblant des sous arbres d'analyse on "remonte" les dérivations en utilisant les règles A?? de P de la droite vers la gauche (Pile), cad ? (au Sommet) est réduit en A: on dit que l'on réduit ? Méthode décalage-réduction on gère un mot w dans (N ? T)+ comme le mot des racines des sous arbres d'analyse déjà construits pris de gauche à droite lorsque w = u où u ? (N ? T)* et P ne contient pas de règle A?u , l'analyseur avance dans la lecture de X à la lettre suivante x et donc w = u x lorsque w = u? où u ? (N ? T)* et ? est une partie droite de règles A?? dans P (plusieurs ? possibles, car décomposition de w = u? non unique) , l'analyseur doit pouvoir décider: s'il y a lieu de réduire w en uA et par quelle règle de P ? s'il y a lieu d'avancer dans la lecture du mot X à la lettre suivante x et donc w = u? x Propriété: la suite de dérivations utilisées pour réduire un mot X correspond à la suite inverse des dérivations les +à droites (Rightmost) pour produire XPrincipe de l'Analyse Ascendante le mot X à analyser dans T* est lu une seule fois de gauche à droite on construit un arbre de dérivation en montant des feuilles (mot des feuilles = X) vers la racine=axiome en assemblant des sous arbres d'analyse on "remonte" les dérivations en utilisant les règles A?? de P de la droite vers la gauche (Pile), cad ? (au Sommet) est réduit en A: on dit que l'on réduit ? Méthode décalage-réduction on gère un mot w dans (N ? T)+ comme le mot des racines des sous arbres d'analyse déjà construits pris de gauche à droite lorsque w = u où u ? (N ? T)* et P ne contient pas de règle A?u , l'analyseur avance dans la lecture de X à la lettre suivante x et donc w = u x lorsque w = u? où u ? (N ? T)* et ? est une partie droite de règles A?? dans P (plusieurs ? possibles, car décomposition de w = u? non unique) , l'analyseur doit pouvoir décider: s'il y a lieu de réduire w en uA et par quelle règle de P ? s'il y a lieu d'avancer dans la lecture du mot X à la lettre suivante x et donc w = u? x Propriété: la suite de dérivations utilisées pour réduire un mot X correspond à la suite inverse des dérivations les +à droites (Rightmost) pour produire X

    28. Transparent 28 Analyse Ascendante Déterministe Grammaire ETF E ::= E + T | T (r1 r2) T ::= T * F | F (r3 r4) F ::= var | ( E ) (r5 r6) Analyse déterministe? v1 + v2 * v3 v1 + v2 * v3 v1 + v2 * v3 Suite de dérivations et Analyse Dérivations gauches: E ?g E + T ?g T + T ?g F + T ?g v1 + T ?g v1 + T * F ?g v1 + F * F ?g v1 + v2 * F ?g v1 + v2 * v3 Dérivations droites: E ?d E + T ?d E + T * F ?d E + T * v3 ?d E + F * v3 ?d E + v2 * v3 ?d T + v2 * v3 ?d F + v2 * v3 ?d v1 + v2 * v3 Manche (traduction pour "handle") Définition: ? ? (N ? T)* est une forme sententielle droite (fsd) dans une grammaire G si S *?d ? ? Définition: ? ? (N ? T)* est appelé manche dans une fsd ? si ? = g ? x où x ? T* et g A x est une fsd avec A?? ? P Les Manches (des fsg et fsd) sont soulignés dans les dérivations ci-dessus ? Génération ou Analyse "descendante" d'un mot: on "descend" les dérivations gauches; v1 est le premier manche ?T* produit et v3 le dernier ; en symétrisant la définition de manche pour d'une fsg: le manche est précédé d'un mot terminal ?T* et provient d'une fsg Analyse "ascendante" d'un mot: on "remonte" les dérivations droites où v3 est le premier manche ?T* réduit et v1 le dernier; le manche est suivi d'un mot terminal ?T* et provient d'une fsdSuite de dérivations et Analyse Dérivations gauches: E ?g E + T ?g T + T ?g F + T ?g v1 + T ?g v1 + T * F ?g v1 + F * F ?g v1 + v2 * F ?g v1 + v2 * v3 Dérivations droites: E ?d E + T ?d E + T * F ?d E + T * v3 ?d E + F * v3 ?d E + v2 * v3 ?d T + v2 * v3 ?d F + v2 * v3 ?d v1 + v2 * v3 Manche (traduction pour "handle") Définition: ? ? (N ? T)* est une forme sententielle droite (fsd) dans une grammaire G si S *?d ? ? Définition: ? ? (N ? T)* est appelé manche dans une fsd ? si ? = g ? x où x ? T* et g A x est une fsd avec A?? ? P Les Manches (des fsg et fsd) sont soulignés dans les dérivations ci-dessus ? Génération ou Analyse "descendante" d'un mot: on "descend" les dérivations gauches; v1 est le premier manche ?T* produit et v3 le dernier ; en symétrisant la définition de manche pour d'une fsg: le manche est précédé d'un mot terminal ?T* et provient d'une fsg Analyse "ascendante" d'un mot: on "remonte" les dérivations droites où v3 est le premier manche ?T* réduit et v1 le dernier; le manche est suivi d'un mot terminal ?T* et provient d'une fsd

    29. Transparent 29 Un manche ou LE manche ? Grammaire ambiguë des expressions E ::= E + E | E * E (r1 r2) E ::= var | ( E ) (r3 r4) Des Manches différents v1 + v2 * v3 v1 + v2 * v3 Un Manche ou LE Manche ? Propriété: si une grammaire est non ambiguë, toute fsd a exactement un manche ? Exemple d'ambiguïté: Deux Dérivations droites distinctes: E ?d E + E ?d E + E * E ?d E + E * v3 ?d E + v2 * v3 ?d v1 + v2 * v3 E ?d E * E ?d E * v3 ?d E + E * v3 ?d E + v2 * v3 ?d v1 + v2 * v3 Un Manche ou LE Manche ? Propriété: si une grammaire est non ambiguë, toute fsd a exactement un manche ? Exemple d'ambiguïté: Deux Dérivations droites distinctes: E ?d E + E ?d E + E * E ?d E + E * v3 ?d E + v2 * v3 ?d v1 + v2 * v3 E ?d E * E ?d E * v3 ?d E + E * v3 ?d E + v2 * v3 ?d v1 + v2 * v3

    30. Transparent 30 Analyseur par Décalage-Réduction Schéma simplifié Analyseur par Décalage - Réduction Définition: un ADR pour une grammaire G se compose de : un tampon d'entrée pour les lexèmes dans T*, terminé par # une pile M de symboles dans (N ? T)*, initialement vide. une sortie pour produire la dérivation (ou l'arbre de) une table A générée pour G, avec 4 actions {M} ? { D, R, ac, er} Décaler "shift": empile dans M le symbole courant de l'entrée avancer d'un symbole en entrée Réduire "reduce": dépiler le manche dans M (p symboles en sommet de pile) empile dans M le non terminal de la réduction du manche Accepter: si M contient l'axiome et que l'entrée contient # Erreur: si pas d'action prévue dans A un analyseur indépendant de la grammaire G exécutant A en boucle, jusqu'à Accepter ou Erreur ? Conflits pour un ADR L'implémentation d'un ADR consiste à régler deux sortes de choix : conflit décaler ou réduire ("shift/reduce" terminologie Yacc) conflit réduire r1 ou réduire r2 ("reduce/reduce" sous Yacc) Divers ADRs: analyseurs LR(k), LALR(k) , SLR(k) analyseurs par précédence d'opérateurs Analyseur par Décalage - Réduction Définition: un ADR pour une grammaire G se compose de : un tampon d'entrée pour les lexèmes dans T*, terminé par # une pile M de symboles dans (N ? T)*, initialement vide. une sortie pour produire la dérivation (ou l'arbre de) une table A générée pour G, avec 4 actions {M} ? { D, R, ac, er} Décaler "shift": empile dans M le symbole courant de l'entrée avancer d'un symbole en entrée Réduire "reduce": dépiler le manche dans M (p symboles en sommet de pile) empile dans M le non terminal de la réduction du manche Accepter: si M contient l'axiome et que l'entrée contient # Erreur: si pas d'action prévue dans A un analyseur indépendant de la grammaire G exécutant A en boucle, jusqu'à Accepter ou Erreur ? Conflits pour un ADR L'implémentation d'un ADR consiste à régler deux sortes de choix : conflit décaler ou réduire ("shift/reduce" terminologie Yacc) conflit réduire r1 ou réduire r2 ("reduce/reduce" sous Yacc) Divers ADRs: analyseurs LR(k), LALR(k) , SLR(k) analyseurs par précédence d'opérateurs

    31. Transparent 31 Analyse par décalage-réduction dans ETF Source dans ETF v1 + v2 * v3 # Analyse ADR Grammaire ETF récursive gauche (r1, r2) E ? E + T | T (r3, r4) T ? T * F | F (r5, r6) F ? var | ( E ) Analyse ADR "remonter" la dérivation droite: E ?d E + T ?d E + T * F ?d E + T * v3 ?d E + F * v3 ?d E + v2 * v3 ?d T + v2 * v3 ?d F + v2 * v3 ?d v1 + v2 * v3 Les conflits se résolvent comme suit: réduire v1 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var + réduire F par r4 (au lieu de décaler), car il n'existe pas de manche contenant F + réduire T par r2 (au lieu de décaler), car il n'existe pas de manche contenant T + réduire v2 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var * réduire F par r4 (au lieu de décaler), car il n'existe pas de manche contenant F * réduire v3 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var # réduire T*F par r3 (au lieu de décaler), car il n'existe pas de manche contenant T*F # réduire E+T par r1 (au lieu de décaler), car il n'existe pas de manche contenant E+T # Grammaire ETF récursive gauche (r1, r2) E ? E + T | T (r3, r4) T ? T * F | F (r5, r6) F ? var | ( E ) Analyse ADR "remonter" la dérivation droite: E ?d E + T ?d E + T * F ?d E + T * v3 ?d E + F * v3 ?d E + v2 * v3 ?d T + v2 * v3 ?d F + v2 * v3 ?d v1 + v2 * v3 Les conflits se résolvent comme suit: réduire v1 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var + réduire F par r4 (au lieu de décaler), car il n'existe pas de manche contenant F + réduire T par r2 (au lieu de décaler), car il n'existe pas de manche contenant T + réduire v2 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var * réduire F par r4 (au lieu de décaler), car il n'existe pas de manche contenant F * réduire v3 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var # réduire T*F par r3 (au lieu de décaler), car il n'existe pas de manche contenant T*F # réduire E+T par r1 (au lieu de décaler), car il n'existe pas de manche contenant E+T #

    32. Transparent 32 Analyse par décalage-réduction dans ETF Source dans ETF v1 + v2 * v3 # Analyse ADR Grammaire ETF récursive gauche (r1, r2) E ? E + T | T (r3, r4) T ? T * F | F (r5, r6) F ? var | ( E ) Analyse ADR Le tableau ci-contre donne les états successifs d'un analyseur ADR pour le mot : v1 + v2 * v3 # . On "remonte" la dérivation droite: E ?d E + T ?d E + T * F ?d E + T * v3 ?d E + F * v3 ?d E + v2 * v3 ?d T + v2 * v3 ?d F + v2 * v3 ?d v1 + v2 * v3 Les conflits ont été résolus comme suit: réduire v1 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var + réduire F par r4 (au lieu de décaler), car il n'existe pas de manche contenant F + réduire T par r2 (au lieu de décaler), car il n'existe pas de manche contenant T + réduire v2 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var * réduire F par r4 (au lieu de décaler), car il n'existe pas de manche contenant F * réduire v3 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var # réduire T*F par r3 (au lieu de décaler), car il n'existe pas de manche contenant T*F # réduire E+T par r1 (au lieu de décaler), car il n'existe pas de manche contenant E+T # Grammaire ETF récursive gauche (r1, r2) E ? E + T | T (r3, r4) T ? T * F | F (r5, r6) F ? var | ( E ) Analyse ADR Le tableau ci-contre donne les états successifs d'un analyseur ADR pour le mot : v1 + v2 * v3 # . On "remonte" la dérivation droite: E ?d E + T ?d E + T * F ?d E + T * v3 ?d E + F * v3 ?d E + v2 * v3 ?d T + v2 * v3 ?d F + v2 * v3 ?d v1 + v2 * v3 Les conflits ont été résolus comme suit: réduire v1 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var + réduire F par r4 (au lieu de décaler), car il n'existe pas de manche contenant F + réduire T par r2 (au lieu de décaler), car il n'existe pas de manche contenant T + réduire v2 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var * réduire F par r4 (au lieu de décaler), car il n'existe pas de manche contenant F * réduire v3 par r5 (au lieu de décaler), car il n'existe pas de manche contenant var # réduire T*F par r3 (au lieu de décaler), car il n'existe pas de manche contenant T*F # réduire E+T par r1 (au lieu de décaler), car il n'existe pas de manche contenant E+T #

    33. Transparent 33 Propriété LR(k) il existe k? 0 dépendant uniquement de la grammaire tel que: pour tout mot X à analyser dans T* pour toute fsd F= ? ? a w dans (N ? T)* et tout manche ? il existe au plus une règle A? ? dans P telle que ? A a w est une fsd Intitulé LR(k) Lecture du mot de gauche à droite("Left to Right") Dérivations (les + à) droites ("Rightmost") Propriété LR(k) des grammaires Définition: une grammaire est LR(k) ssi pour ?, ?, ?, ? ?(N ? T)*; A, B ?N ; a ?Tk ; w, w'? T* si S *?d ? A aw ?d ? ? a w et si S *?d ? B w' ?d ? ?' w' = ? ? a ? alors A=B , ? =?' , ? = ? et w'=a ? Note: ? est un manche des deux fsd ? ? aw et ? ?' w' ? Propriété: une grammaire LR(k) est LR(k') pour k' > k ? Grammaire LR(1) La définition précédente donne celle des: LR(0) en prenant a = ? LR(1) en prenant a ?T ? Intitulé LR(k) Lecture du mot de gauche à droite("Left to Right") Dérivations (les + à) droites ("Rightmost") Propriété LR(k) des grammaires Définition: une grammaire est LR(k) ssi pour ?, ?, ?, ? ?(N ? T)*; A, B ?N ; a ?Tk ; w, w'? T* si S *?d ? A aw ?d ? ? a w et si S *?d ? B w' ?d ? ?' w' = ? ? a ? alors A=B , ? =?' , ? = ? et w'=a ? Note: ? est un manche des deux fsd ? ? aw et ? ?' w' ? Propriété: une grammaire LR(k) est LR(k') pour k' > k ? Grammaire LR(1) La définition précédente donne celle des: LR(0) en prenant a = ? LR(1) en prenant a ?T ?

    34. Transparent 34 ETF est elle LR(0) ? Grammaire ETF E ::= E + T | T (r1 r2) T ::= T * F | F (r3 r4) F ::= var | ( E ) (r5 r6) pas LR(0) , mais LR(1) ? La décision peut dépendre du prochain terminal à lire (look ahead) v1 + v2 + v3 v1 + v2 * v3 Une grammaire est elle LR(k) ? En pratique on considère les grammaires LR(0) ou LR(1) Intuitivement, la propriété est vraie si la connaissance de k terminaux après le caractère courant (look-ahead) permet de décider de manière unique comment traiter le manche. La définition précédente est difficile à utiliser pour prouver la propriété; par contre, on peut exhiber un contre-exemple de dérivations pour prouver l'absence de cette propriété. La construction de l'analyseur LR(k) donnée ci après permet de répondre à la même question. ETF est elle LR(0) ? Intuitivement, la réponse est NON Formellement: on considère deux dérivations droites: E ?d E + T ?d E + F ?d E + v3 ?d E + T + v3 avec ? =a= ? , A = E , ? = E+T, w = + v3 E ?d E + T ?dE + T * F avec ? = E+, B = T, ?' = T*F, w'= ? et ? ?' w' = ? ? a ? = E+T*F avec ? = *F voir aussi l'analyse des items canoniques de l'analyseur SLR Une grammaire est elle LR(k) ? En pratique on considère les grammaires LR(0) ou LR(1) Intuitivement, la propriété est vraie si la connaissance de k terminaux après le caractère courant (look-ahead) permet de décider de manière unique comment traiter le manche. La définition précédente est difficile à utiliser pour prouver la propriété; par contre, on peut exhiber un contre-exemple de dérivations pour prouver l'absence de cette propriété. La construction de l'analyseur LR(k) donnée ci après permet de répondre à la même question. ETF est elle LR(0) ? Intuitivement, la réponse est NON Formellement: on considère deux dérivations droites: E ?d E + T ?d E + F ?d E + v3 ?d E + T + v3 avec ? =a= ? , A = E , ? = E+T, w = + v3 E ?d E + T ?dE + T * F avec ? = E+, B = T, ?' = T*F, w'= ? et ? ?' w' = ? ? a ? = E+T*F avec ? = *F voir aussi l'analyse des items canoniques de l'analyseur SLR

    35. Transparent 35 Les langages de mots de pile Grammaire Dyck des () D ::= D D (r1) | a D b (r2) | a b (r3) Langage des Contextes Gauches CG = {?, ? D est un préfixe viable de Dyck} CG ::= CG D ( par r1) | CG a ( par r2) | ? ( par r3) => CG = (D | a)* Langage des Préfixes Viables PV est le langage des mots de pile ADR PV ::= CG D + CG D D | CG a + CG a D + CG a D b | CG a + CG a b => PV ? RAT Comment trouver le Manche ? Les analyseurs ADR utilisent pour repérer les manches une propriété fondamentale des grammaires algébriques: le langage des préfixes des fsd , cad les mots de pile d'un ADR, est rationnel. Définition: Tout préfixe p= ? u de ? ? dans une fsd F= ? ? w où ? est le manche est dit préfixe viable de F Remarque: p déborde le début du manche ?, mais pas la fin Propriété: Les préfixes viables forment l'ensemble des mots qui peuvent apparaître dans la pile lors d'une ADR ? Théorème: Le langage des préfixes viables d'une grammaire algébrique est un langage rationnel Preuve: voir la construction de l'automate des préfixes viables SLR ? Résolution ADR: l'analyseur ADR utilise un automate d'état fini pour repérer les manches. Comment trouver le Manche ? Les analyseurs ADR utilisent pour repérer les manches une propriété fondamentale des grammaires algébriques: le langage des préfixes des fsd , cad les mots de pile d'un ADR, est rationnel. Définition: Tout préfixe p= ? u de ? ? dans une fsd F= ? ? w où ? est le manche est dit préfixe viable de F Remarque: p déborde le début du manche ?, mais pas la fin Propriété: Les préfixes viables forment l'ensemble des mots qui peuvent apparaître dans la pile lors d'une ADR ? Théorème: Le langage des préfixes viables d'une grammaire algébrique est un langage rationnel Preuve: voir la construction de l'automate des préfixes viables SLR ? Résolution ADR: l'analyseur ADR utilise un automate d'état fini pour repérer les manches.

    36. Transparent 36 Analyseur LR Schéma conceptuel Analyseur LR Définition: un ALR pour une grammaire G se compose de : un tampon d'entrée pour les lexèmes à analyser dans T*, terminé par # une pile M de symboles dans (N ? T)*, initialement vide. une pile E d'états de l'automate fini PV , initialement avec un état initial une sortie pour produire la dérivation (ou l'arbre de) une table de transition T[{e}, N ? T] ? {e} pour les états de PV une table A générée pour G, avec 4 actions {M} ? { D, R, A, E} Décaler: empile dans M le symbole courant de l'entrée empile dans E l'état atteint = T[etat_courant, som(M)] avancer d'un symbole en entrée Réduire: dépiler le manche dans M (p symboles en sommet de pile) dépiler p états dans E empile dans M le non terminal de la réduction du manche empile dans E l'état atteint = T[etat_courant, som(M)] Accepter: si M = {l'axiome} et que l'entrée = {#} Erreur: si pas d'action prévue dans A un analyseur indépendant de la grammaire G exécutant A en boucle, jusqu'à pile ou entrée vide ?Analyseur LR Définition: un ALR pour une grammaire G se compose de : un tampon d'entrée pour les lexèmes à analyser dans T*, terminé par # une pile M de symboles dans (N ? T)*, initialement vide. une pile E d'états de l'automate fini PV , initialement avec un état initial une sortie pour produire la dérivation (ou l'arbre de) une table de transition T[{e}, N ? T] ? {e} pour les états de PV une table A générée pour G, avec 4 actions {M} ? { D, R, A, E} Décaler: empile dans M le symbole courant de l'entrée empile dans E l'état atteint = T[etat_courant, som(M)] avancer d'un symbole en entrée Réduire: dépiler le manche dans M (p symboles en sommet de pile) dépiler p états dans E empile dans M le non terminal de la réduction du manche empile dans E l'état atteint = T[etat_courant, som(M)] Accepter: si M = {l'axiome} et que l'entrée = {#} Erreur: si pas d'action prévue dans A un analyseur indépendant de la grammaire G exécutant A en boucle, jusqu'à pile ou entrée vide ?

    37. Transparent 37 Analyseur générique LR(1) Actions boolean Action(LEX u) { Etat e = som().etat() ; switch (A[e, u] ){ "décaler " => e' = T[e, u] ; emp(u, e') ; lex(u) ; break; " réduire A? m" => e = som().etat() ; dep(e, m) ; emp("A", T[e, "A"] ) ; "succès" => return true; "erreur" => return false ; } } Analyseur function Analyse() { lex(ul); emp(Fond, Etat_Initial); while ul /= "#" { succes=Action(ul) } return succes ; } Grammaires LR() Propriété (rappel): pour k' > k >= 0, LR(k) => LR(k') ? Théorème: La propriété LR(k) d'une grammaire est indécidable (pour k non fixé) ? Corollaire: Il n'existe pas d'algorithme permettant de transformer une grammaire quelconque en une grammaire équivalente LR(k) ; mais on peut toujours essayer sur une grammaire donnée! Théorème: Une grammaire LR(1) est non ambiguë preuve: d'après la propriété LR(1) il ne peut exister deux dérivations distinctes pour deux mots identiques ? généralisation: ce résultat est vrai pour les grammaires LR(k) ? Complexité de l'analyse LR() Théorème: L'analyse LR(1) d'un mot m est en O(|m|) preuve: d'après le code ci-contre ? généralisation: ce résultat est vrai pour l'analyse LR(k) ? Langages LR() Théorème: LR(0) = LR(1) = LR(k) = ALG DETERMINISTE ? Remarque: En pratique, pour un langage donné, on peut être amené à préférer une grammaire LR(1), voire LR(2), à une grammaire LR(0) qui peut être beaucoup plus difficile à lire et volumineuse en nombre de règles de production. Théorème: La propriété LR(k) d'un langage est indécidable (pour k non fixé) ? Grammaires LR() Propriété (rappel): pour k' > k >= 0, LR(k) => LR(k') ? Théorème: La propriété LR(k) d'une grammaire est indécidable (pour k non fixé) ? Corollaire: Il n'existe pas d'algorithme permettant de transformer une grammaire quelconque en une grammaire équivalente LR(k) ; mais on peut toujours essayer sur une grammaire donnée! Théorème: Une grammaire LR(1) est non ambiguë preuve: d'après la propriété LR(1) il ne peut exister deux dérivations distinctes pour deux mots identiques ? généralisation: ce résultat est vrai pour les grammaires LR(k) ? Complexité de l'analyse LR() Théorème: L'analyse LR(1) d'un mot m est en O(|m|) preuve: d'après le code ci-contre ? généralisation: ce résultat est vrai pour l'analyse LR(k) ? Langages LR() Théorème: LR(0) = LR(1) = LR(k) = ALG DETERMINISTE ? Remarque: En pratique, pour un langage donné, on peut être amené à préférer une grammaire LR(1), voire LR(2), à une grammaire LR(0) qui peut être beaucoup plus difficile à lire et volumineuse en nombre de règles de production. Théorème: La propriété LR(k) d'un langage est indécidable (pour k non fixé) ?

    38. Transparent 38 Grammaires SLR() items LR(0) pour E ::= E + T Grammaire ETF enracinée E ' ::= E # (r0) E ::= E + T | T (r1 r2) T ::= T * F | F (r3 r4) F ::= var | ( E ) (r5 r6) Construction des analyseurs LR() La construction des analyseurs LR() pour une grammaire donnée est fastidieuse: on utilise donc de préférence un générateur syntaxique LR comme YACC ou BISON. Cette construction repose sur le calcul de la table d'Actions et de la Table de Transition pour les états de l'automate des Préfixes Viables. Trois classes de grammaires, avec une inclusion stricte: SLR ? LALR ? LR permettent de réaliser cette construction en utilisant l'analyseur générique LR présenté précédemment. Construction des analyseurs SLR On présente une construction générale qui permet d'obtenir le découpage des manches par un Automate d'état fini. Dans le cas des grammaires, dites SLR, cette construction permet d'obtenir directement les tables d'analyse LR(). Dans la suite, on "enracine" les grammaires utilisées par une règle de production ajoutée à P: { S'?S# } ; ceci afin de ne pas devoir traiter la dernière "remontée" vers S comme un cas particulier. Définition: On appelle item LR(0) une production de P marquée en partie droite par "?" Interprétation: le marqueur matérialise la position courante de la reconnaissance ascendante de la règle ?Construction des analyseurs LR() La construction des analyseurs LR() pour une grammaire donnée est fastidieuse: on utilise donc de préférence un générateur syntaxique LR comme YACC ou BISON. Cette construction repose sur le calcul de la table d'Actions et de la Table de Transition pour les états de l'automate des Préfixes Viables. Trois classes de grammaires, avec une inclusion stricte: SLR ? LALR ? LR permettent de réaliser cette construction en utilisant l'analyseur générique LR présenté précédemment. Construction des analyseurs SLR On présente une construction générale qui permet d'obtenir le découpage des manches par un Automate d'état fini. Dans le cas des grammaires, dites SLR, cette construction permet d'obtenir directement les tables d'analyse LR(). Dans la suite, on "enracine" les grammaires utilisées par une règle de production ajoutée à P: { S'?S# } ; ceci afin de ne pas devoir traiter la dernière "remontée" vers S comme un cas particulier. Définition: On appelle item LR(0) une production de P marquée en partie droite par "?" Interprétation: le marqueur matérialise la position courante de la reconnaissance ascendante de la règle ?

    39. Transparent 39 Automates SLR() La fermeture ? ( { E'? ? E } ) E'? ?E E? ?E + T E? ?T T? ?T * F T? ?F F? ?var F? ?( E ) Les transitions LR(0) Fermeture d'un item LR(0) Définition: Soit I un ensemble d'items, on note ? (I) la fermeture de I définie par: I ? ? si A?? ? B? ? ? alors B? ? g ? ? pour B? g ? P Interprétation: le marqueur indique que dans l'état I (ensemble I): on espère réduire ?B? en A ? a déjà été "remonté" il faut "remonter" B on ajoute donc à cet état I, toutes les possibilités pour "remonter" B ? Construction de l'Automate de Transition LR(0) Théorème: Le langage des préfixes viables d'une grammaire algébrique est reconnu par l'automate TRANS de Transition LR(0) défini comme suit: les états de TRANS sont des fermetures ? les transitions sont définies par : TRANS[I, X] = ? ( {A?? X??} pour {A?? ?X? } ? I) où I est un ensemble d'items et X ? N ? T l'état initial est ? ( {S'? ? S } ) tous les états sont terminaux Interprétation : les états de l'automate codent l'ensemble des parties droites possibles pour compléter le préfixe empilé en cours d'analyse ? Fermeture d'un item LR(0) Définition: Soit I un ensemble d'items, on note ? (I) la fermeture de I définie par: I ? ? si A?? ? B? ? ? alors B? ? g ? ? pour B? g ? P Interprétation: le marqueur indique que dans l'état I (ensemble I): on espère réduire ?B? en A ? a déjà été "remonté" il faut "remonter" B on ajoute donc à cet état I, toutes les possibilités pour "remonter" B ? Construction de l'Automate de Transition LR(0) Théorème: Le langage des préfixes viables d'une grammaire algébrique est reconnu par l'automate TRANS de Transition LR(0) défini comme suit: les états de TRANS sont des fermetures ? les transitions sont définies par : TRANS[I, X] = ? ( {A?? X??} pour {A?? ?X? } ? I) où I est un ensemble d'items et X ? N ? T l'état initial est ? ( {S'? ? S } ) tous les états sont terminaux Interprétation : les états de l'automate codent l'ensemble des parties droites possibles pour compléter le préfixe empilé en cours d'analyse ?

    40. Transparent 40 Items LR(0) Canoniques ? I ensemble d'items LR(0) ? X ? (N ? T) FERMETURE ? ( I ): ? I? ? ( I ) ? si [A? ??B ? ] ? ? ( I ) et [B? ? ] ? P, alors [B? ? ? ] ? ? ( I ) TRANSITIONS TRANS( I, X ) : ? TRANS( I, X ) = ? ( { [A? ?X? ? ] } , pour [A? ??X ? ] ? I ) C: Ensemble d'items canoniques ? ? ( { [E'? ? E] } ) ? C ? ? I ? C, TRANS(I, X) ? C Définition: On appelle Items LR(0) canoniques les états atteignables dans TRANS à partir de l'état initial ? ( {S'? ? S } ) Construction des items LR(0) canoniques Items pour ETF Définition: On appelle Items LR(0) canoniques les états atteignables dans TRANS à partir de l'état initial ? ( {S'? ? S } ) Construction des items LR(0) canoniques Items pour ETF

    41. Transparent 41 Automates SLR() L'Automate des Préfixes Viables dans ETF Construction des items LR(0) canoniques Items pour ETF Construction des items LR(0) canoniques Items pour ETF

    42. Transparent 42 Tables SLR pour ETF ETF est SLR Construction de la Table ACTION SLR On construit la table A d'analyse en appliquant les règles suivantes où A?N, a?T ? {#} et Ip l'item LR(0) associé à l'état p de l'Automate des préfixes viables. si A???a? ? Ip alors A[p, a] = "décaler" si A??? ? Ip alors pour tout a ? Suivant(A): A[p, a] = "réduire par A ? ? " si S'?S? ? Ip alors A[p, #] = "accepter" sinon A[p, a] = "erreur" Conflits pendant la construction de la table ACTION décalage/réduction: il existe Ip contenant les items: A???a? => A[p, a] = "décaler" B??'? avec a ? Suite(B) =>A[p, a] = "réduire " réduction/réduction: il existe Ip contenant les items: A??? et a ? Suiv(A) => A[p, a] = "réd par A" B??'? et a ? Suiv(B) =>A[p, a] = "réd par B" Construction de la Table ACTION SLR On construit la table A d'analyse en appliquant les règles suivantes où A?N, a?T ? {#} et Ip l'item LR(0) associé à l'état p de l'Automate des préfixes viables. si A???a? ? Ip alors A[p, a] = "décaler" si A??? ? Ip alors pour tout a ? Suivant(A): A[p, a] = "réduire par A ? ? " si S'?S? ? Ip alors A[p, #] = "accepter" sinon A[p, a] = "erreur" Conflits pendant la construction de la table ACTION décalage/réduction: il existe Ip contenant les items: A???a? => A[p, a] = "décaler" B??'? avec a ? Suite(B) =>A[p, a] = "réduire " réduction/réduction: il existe Ip contenant les items: A??? et a ? Suiv(A) => A[p, a] = "réd par A" B??'? et a ? Suiv(B) =>A[p, a] = "réd par B"

    43. Transparent 43 Tables SLR pour ETF ETF est SLR, mais pas LR(0) Propriété LR() des grammaires Définition: une grammaire est SLR(1) ou SLR, si la construction précédente de la table Action se termine sans conflit. ? Propriété: une grammaire est LR(0) ? SLR, si la construction précédente de la table Action se termine sans conflit et que pour chaque état, les actions (D, Ri ou Rj) ne dépendent pas des Terminaux ? Grammaire ETF récursive gauche (r1, r2) E ? E + T | T (r3, r4) T ? T * F | F (r5, r6) F ? var | ( E ) Suivants pour ETF (r0) E : # (r1) E : + (r6) E : ) (r3) T : * (r2) T : + ) # (r4) F : * + ) # F = { * + ) # } => T = { * + ) # } => E = { + ) # } Propriété LR() des grammaires Définition: une grammaire est SLR(1) ou SLR, si la construction précédente de la table Action se termine sans conflit. ? Propriété: une grammaire est LR(0) ? SLR, si la construction précédente de la table Action se termine sans conflit et que pour chaque état, les actions (D, Ri ou Rj) ne dépendent pas des Terminaux ? Grammaire ETF récursive gauche (r1, r2) E ? E + T | T (r3, r4) T ? T * F | F (r5, r6) F ? var | ( E ) Suivants pour ETF (r0) E : # (r1) E : + (r6) E : ) (r3) T : * (r2) T : + ) # (r4) F : * + ) # F = { * + ) # } => T = { * + ) # } => E = { + ) # }

    44. Transparent 44 Analyse LR(1) dans ETF Source v1 + v2 * v3 # Analyse SLR Grammaire ETF récursive gauche (r1, r2) E ? E + T | T (r3, r4) T ? T * F | F (r5, r6) F ? var | ( E ) Analyse ADR Le tableau ci_contre donne les états successifs d'un analyseur ADR pour le mot : v1 + v2 * v3. Réssultat La suite des Réductions exécutées par l'Automate: R6 R4 R2 R6 R4 R6 R3 R1 est la suite des dérivations inverses les + à droite pour le mot en entrée Grammaire ETF récursive gauche (r1, r2) E ? E + T | T (r3, r4) T ? T * F | F (r5, r6) F ? var | ( E ) Analyse ADR Le tableau ci_contre donne les états successifs d'un analyseur ADR pour le mot : v1 + v2 * v3. Réssultat La suite des Réductions exécutées par l'Automate: R6 R4 R2 R6 R4 R6 R3 R1 est la suite des dérivations inverses les + à droite pour le mot en entrée

    45. Transparent 45 Un conflit dans la construction SLR Grammaire des affectations sur valeurs références A ::= G = D | D (r1, r2) G ::= * D | var (r3, r4) D ::= G (r5) Items LR(0) canoniques Conflit dans la table Action[2, "="] = "décaler" Action[2, "="] = "réduire D ? G" Conflits pendant la construction de la table ACTION décalage/réduction: il existe un état I2 contenant les items: A?G?=D => A[2, "="] = "décaler" D?G? => A[2, "="] = "réduire par D?G " car A ? G=D ?*D=D => "=" ? Suivants(D) Exemple: le mot *v1= v2# se réduit en *G avec = v2# en entrée deux possibilités: réduire G en D => *D = v2 ?G=v2 ?G=G ?G=D ? A => accepter décaler =v2 => *G = v2 ?* G = G ?* G = D ?* A => erreur Interprétation: la grammaire présentée ici n'est pas ambiguë; le conflit provient de la technique SLR qui n'est pas assez puissante pour mémoriser suffisamment de contexte gauche; Après avoir remonter une entrée vers G, l'analyseur ne dispose pas d'assez d'information pour décider qu'il faut réduire G car décaler ne peut conduire à une bonne solution ! Conflits pendant la construction de la table ACTION décalage/réduction: il existe un état I2 contenant les items: A?G?=D => A[2, "="] = "décaler" D?G? => A[2, "="] = "réduire par D?G " car A ? G=D ?*D=D => "=" ? Suivants(D) Exemple: le mot *v1= v2# se réduit en *G avec = v2# en entrée deux possibilités: réduire G en D => *D = v2 ?G=v2 ?G=G ?G=D ? A => accepter décaler =v2 => *G = v2 ?* G = G ?* G = D ?* A => erreur Interprétation: la grammaire présentée ici n'est pas ambiguë; le conflit provient de la technique SLR qui n'est pas assez puissante pour mémoriser suffisamment de contexte gauche; Après avoir remonter une entrée vers G, l'analyseur ne dispose pas d'assez d'information pour décider qu'il faut réduire G car décaler ne peut conduire à une bonne solution !

    46. Transparent 46 Grammaires LR() Grammaire SCC enracinée S' ::= S # (r0) S ::= CC (r1) C ::= c C | d (r2 r3) items LR(1) SUIVANTS SUIV(S)= {#} SUIV(C) = {c d #} Extension des analyseurs SLR() aux LR() Dans l'analyse SLR on exécute l'action réduire { A? ? } dans l'état Ip pour tout a?T ? {#} si A?? ? ? Ip et a ? Suivant(A) Or il se peut que ?? soit un préfixe viable mais pas ?Aa Un analyseur LR peut s'obtenir à partir de la construction SLR où l'on ne réduit ?? en ?A que si ?Aa est un préfixe viable Définition: On appelle item LR(1) un couple [A? ? ?? , a], composé d'un item LR(0) et d'un terminal a (de prévision ou d'anticipation) . Définition:un item LR(1) [A? ? ? ? , a] est dit valide pour un préfixe viable ?? si: S *?d ?Aaw avec ?Aaw ?d ???aw Interprétation: si on a déjà remonté ?? si ce qui suit en entrée commence par ?a alors ???aw est une fsd dont la dernière dérivation est ?Aaw ?d ???aw la prévision a n'a aucun effet dans les items sans réduction, de la forme A? ? ??, avec ? non vide. Extension des analyseurs SLR() aux LR() Dans l'analyse SLR on exécute l'action réduire { A? ? } dans l'état Ip pour tout a?T ? {#} si A?? ? ? Ip et a ? Suivant(A) Or il se peut que ?? soit un préfixe viable mais pas ?Aa Un analyseur LR peut s'obtenir à partir de la construction SLR où l'on ne réduit ?? en ?A que si ?Aa est un préfixe viable Définition: On appelle item LR(1) un couple [A? ? ?? , a], composé d'un item LR(0) et d'un terminal a (de prévision ou d'anticipation) . Définition:un item LR(1) [A? ? ? ? , a] est dit valide pour un préfixe viable ?? si: S *?d ?Aaw avec ?Aaw ?d ???aw Interprétation: si on a déjà remonté ?? si ce qui suit en entrée commence par ?a alors ???aw est une fsd dont la dernière dérivation est ?Aaw ?d ???aw la prévision a n'a aucun effet dans les items sans réduction, de la forme A? ? ??, avec ? non vide.

    47. Transparent 47 Automates LR() Grammaire SCC {S'? S # ; S? CC ; C? cC | d } ? ( [ S'? ? S, # ] ) S'? ?S, # S? ?CC , # C? ?cC, c|d C? ? d , c|d Les transitions LR(1) Fermeture d'un item LR(1) Définition: Soit I un ensemble d'items LR(1) , on appelle ? (I) la fermeture de I définie par: I ? ? si [A?? ? B?, a]? ? alors [B? ? g, b]? ? pour [B? g ] ?P et b?Prem(?a) ? Construction de l'Automate de Transition LR(1) Théorème: Le langage des "préfixes viables suivis d'un terminal d'anticipation " d'une grammaire algébrique est reconnu par l'automate T de Transition LR(1) défini comme suit: les états de T sont des fermetures ? les transitions sont définies par : T(I, X) = ?( [A?? X??, b] pour [A?? ?X?, b] ? I ) où I est un ensemble d'items LR(1) et X ? N ? T l'état initial est ? ( [S'? ? S, #] ) tous les états sont terminaux ? Fermeture d'un item LR(1) Définition: Soit I un ensemble d'items LR(1) , on appelle ? (I) la fermeture de I définie par: I ? ? si [A?? ? B?, a]? ? alors [B? ? g, b]? ? pour [B? g ] ?P et b?Prem(?a) ? Construction de l'Automate de Transition LR(1) Théorème: Le langage des "préfixes viables suivis d'un terminal d'anticipation " d'une grammaire algébrique est reconnu par l'automate T de Transition LR(1) défini comme suit: les états de T sont des fermetures ? les transitions sont définies par : T(I, X) = ?( [A?? X??, b] pour [A?? ?X?, b] ? I ) où I est un ensemble d'items LR(1) et X ? N ? T l'état initial est ? ( [S'? ? S, #] ) tous les états sont terminaux ?

    48. Transparent 48 Construction des items LR(1) canoniques Items LR(1) pour SCC état I4: on reconnaît le premier "d" : on doit donc réduire ssi le lookahead = "c" | "d" et erreur sinon état I7: on reconnaît le second "d" : on doit donc réduire ssi le lookahead = "#" et erreur sinon état I3: on reconnaît les premiers "c" état I6: on reconnaît les seconds "c" Construction des items LR(1) canoniques Items LR(1) pour SCC état I4: on reconnaît le premier "d" : on doit donc réduire ssi le lookahead = "c" | "d" et erreur sinon état I7: on reconnaît le second "d" : on doit donc réduire ssi le lookahead = "#" et erreur sinon état I3: on reconnaît les premiers "c" état I6: on reconnaît les seconds "c"

    49. Transparent 49 Automates LR(1) L'Automate des Transitions LR(1) dans SCC Construction des items LR(1) canoniques Items LR(1) pour SCC état I4: on reconnaît le premier "d" : on doit donc réduire ssi le lookahead = "c" | "d" et erreur sinon état I7: on reconnaît le second "d" : on doit donc réduire ssi le lookahead = "#" et erreur sinon état I3: on reconnaît les premiers "c" état I6: on reconnaît les seconds "c" Construction des items LR(1) canoniques Items LR(1) pour SCC état I4: on reconnaît le premier "d" : on doit donc réduire ssi le lookahead = "c" | "d" et erreur sinon état I7: on reconnaît le second "d" : on doit donc réduire ssi le lookahead = "#" et erreur sinon état I3: on reconnaît les premiers "c" état I6: on reconnaît les seconds "c"

    50. Transparent 50 Tables LR(1) pour SCC Construction de la Table ACTION LR(1) On construit la table comme dans le cas SLR soit A?N, a?T ? {#} et Ip l'item LR(1) associé à l'état p de l'Automate des préfixes viables. si [A???a?, b]? Ip alors A[p, a] = "décaler" si [A???, a] ? Ip alors A[p, a] = "réduire par A ? ? " si [S'?S?, #] ? Ip alors A[p, #] = "accepter" sinon A[p, a] = "erreur" état initial = [S'??S, #] transitions comme dans le cas SLR Etats et items LR(1) canoniques de SCC C? c?C , c|d C? c?C , # I3= C? ?cC , c|d I6= C? ?cC , # C? ?d , c|d C? ?d , # I4= C? d? , c|d I7= C? d? , # I8= C? cC? , c|d I9= C? cC? , # Propriété des grammaires LR(1) Théorème: La construction donnée ci dessus est sans conflit pour toute grammaire LR(1) ? Construction de la Table ACTION LR(1) On construit la table comme dans le cas SLR soit A?N, a?T ? {#} et Ip l'item LR(1) associé à l'état p de l'Automate des préfixes viables. si [A???a?, b]? Ip alors A[p, a] = "décaler" si [A???, a] ? Ip alors A[p, a] = "réduire par A ? ? " si [S'?S?, #] ? Ip alors A[p, #] = "accepter" sinon A[p, a] = "erreur" état initial = [S'??S, #] transitions comme dans le cas SLR Etats et items LR(1) canoniques de SCC C? c?C , c|d C? c?C , # I3= C? ?cC , c|d I6= C? ?cC , # C? ?d , c|d C? ?d , # I4= C? d? , c|d I7= C? d? , # I8= C? cC? , c|d I9= C? cC? , # Propriété des grammaires LR(1) Théorème: La construction donnée ci dessus est sans conflit pour toute grammaire LR(1) ?

    51. Transparent 51 Construction LR(1) vs SLR L'Automate des Transitions SLR dans SCC Construction SLR pour SCC Items LR(0) pour SCC les Items LR(0) regroupent des items LR(1) La construction SLR pour SCC est plus économique On fusionne I4 et I7 sans conflit de réduction en I4: on doit réduire (r3) ssi le lookahead = "c" | "d" en I7: on doit réduire (r3) ssi le lookahead = "#" en I74: on réduit dans tous les cas, et l'erreur (éventuelle) sera détectée plus tard les états I3 et I6 peuvent être fusionnés sans conflit car les actions sont "shift". Idem pour I8 et I9 Construction SLR pour SCC Items LR(0) pour SCC les Items LR(0) regroupent des items LR(1) La construction SLR pour SCC est plus économique On fusionne I4 et I7 sans conflit de réduction en I4: on doit réduire (r3) ssi le lookahead = "c" | "d" en I7: on doit réduire (r3) ssi le lookahead = "#" en I74: on réduit dans tous les cas, et l'erreur (éventuelle) sera détectée plus tard les états I3 et I6 peuvent être fusionnés sans conflit car les actions sont "shift". Idem pour I8 et I9

    52. Transparent 52 Tables SLR pour SCC Construction pratique des analyseurs LR() La construction des analyseurs LR() repose sur le calcul de la table d'Actions et de la Table de Transitions pour les états de l'automate des Préfixes Viables. Quatre classes de grammaires, avec une inclusion stricte: LR(0) ? SLR ? LALR(1) ? LR(1) permettent de réaliser cette construction en utilisant l'analyseur générique LR présenté précédemment. La construction SLR est efficace, mais la classe des langages atteints est insuffisante en pratique pour les LP. La construction LR(1) est plus coûteuse en mémoire, mais la classe des langages atteints couvre en pratique tous les LP. A titre d'exemple, on peut avoir pour la même grammaire: N états dans l'automate des transitions SLR N3 états dans l'automate des transitions LR les grammaires LALR(1) réalisent un bon compromis complexité/puissance d'expression; c'est la famille qui est supportée par les générateurs syntaxiques LR comme YACC ou BISON. Construction pratique des analyseurs LR() La construction des analyseurs LR() repose sur le calcul de la table d'Actions et de la Table de Transitions pour les états de l'automate des Préfixes Viables. Quatre classes de grammaires, avec une inclusion stricte: LR(0) ? SLR ? LALR(1) ? LR(1) permettent de réaliser cette construction en utilisant l'analyseur générique LR présenté précédemment. La construction SLR est efficace, mais la classe des langages atteints est insuffisante en pratique pour les LP. La construction LR(1) est plus coûteuse en mémoire, mais la classe des langages atteints couvre en pratique tous les LP. A titre d'exemple, on peut avoir pour la même grammaire: N états dans l'automate des transitions SLR N3 états dans l'automate des transitions LR les grammaires LALR(1) réalisent un bon compromis complexité/puissance d'expression; c'est la famille qui est supportée par les générateurs syntaxiques LR comme YACC ou BISON.

    53. Transparent 53 Grammaires LALR(1) Grammaire SCC {S'? S# ; S? CC ; C? cC | d } Fusion des items LR(1) I3= { [ C? c?C , c|d ], [ C? ?cC , 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|# ] } Construction des transitions LALR(1) Principe: On fusionne les états issus d'ensembles d'items LR(1) dont les ensembles d'items LR(0) ( "cœur") sont identiques. Définition: On appelle coeur d'un ensemble I d'items LR(1) l'ensemble d'items LR(0) [ A????] pour lesquels I contient un item LR(1) [A? ? ??, ak] (les ak peuvent être différents) Pour tout cœur C d’items LR(1) [A? ? ??, ak] , PREVISION( C )= {ak} ? SUIVANT(A) Construction LALR(1) "méthode gourmande": Etant donnée une table Action LR(1): la fusion d'états ayant le même coeur n'engendre aucun conflit "décaler/réduire". Définition: une grammaire est LALR(1) si la fusion précédente n'engendre pas de conflit "réduire/réduire". Les conflits "réduire/réduire" créés par cette fusion sont rares en pratique (grammaires LR, non LALR). Remarque: la méthode "gourmande" a peu d'intérêt en pratique, puisqu'elle implique la construction des items LR(1). Construction des transitions LALR(1) Principe: On fusionne les états issus d'ensembles d'items LR(1) dont les ensembles d'items LR(0) ( "cœur") sont identiques. Définition: On appelle coeur d'un ensemble I d'items LR(1) l'ensemble d'items LR(0) [ A????] pour lesquels I contient un item LR(1) [A? ? ??, ak] (les ak peuvent être différents) Pour tout cœur C d’items LR(1) [A? ? ??, ak] , PREVISION( C )= {ak} ? SUIVANT(A) Construction LALR(1) "méthode gourmande": Etant donnée une table Action LR(1): la fusion d'états ayant le même coeur n'engendre aucun conflit "décaler/réduire". Définition: une grammaire est LALR(1) si la fusion précédente n'engendre pas de conflit "réduire/réduire". Les conflits "réduire/réduire" créés par cette fusion sont rares en pratique (grammaires LR, non LALR). Remarque: la méthode "gourmande" a peu d'intérêt en pratique, puisqu'elle implique la construction des items LR(1).

    54. Transparent 54 Construction LALR(1) Grammaire SCC {S'? S# ; S? CC ; C? cC | d } Noyaux LR(0) + prévision initiale I0= [ S'? ?S , # ] I1= [ S'? S? , # ] I2= [ S? C?C , # ] I3= [ C? c?C , c|d ] I4= [ C? d? , c|d ] I5= [ S? CC? , # ] I6= [ C? c?C , # ] I7= [ C? d? , # ] etc Construction LALR(1) "méthode économique": On ne construit pas les Items LR(1): On construit seulement les "noyaux" des Items LR(0) On calcule itérativement les symboles de prévision pour chaque noyau LR(0) Définition: le noyau d'un ensemble d'items I est le sous-ensemble des items de I qui n'ont pas leur point ?en début de partie droite plus l'item initial [S' ? ? S, #] (il s'agit des items obtenus directement par transition et non pas par fermeture) Construction LALR(1) "méthode économique": On ne construit pas les Items LR(1): On construit seulement les "noyaux" des Items LR(0) On calcule itérativement les symboles de prévision pour chaque noyau LR(0) Définition: le noyau d'un ensemble d'items I est le sous-ensemble des items de I qui n'ont pas leur point ?en début de partie droite plus l'item initial [S' ? ? S, #] (il s'agit des items obtenus directement par transition et non pas par fermeture)

    55. Transparent 55 Construction LALR(1) Grammaire SGD {S'? S ; S? G = D | D ; G? * D | id ; D? G } Noyaux LR(0) + Passes Prévision I0= [S'? ?S] I1= [S'? S?] I2= [S? G?=D] [D? G?] I3= [S? D?] I4= [G? *?D] I5= [G? id?] I6= [S? G=?D] I7= [G? *D?] I8= [D? G?] I9= [S? G=D?] Détermination des symboles de prévision à partir des noyaux: Soit K le noyau d'un ensemble d'items I X ? (N ? T) # est un symbole de prévision factice pour représenter les symboles de prévision pour chaque item [B ? ??? ] ? K, si [A ? ??X?, a] ? ? ({[B ? ??? , #]}) et a ? # alors [A ? ?X??, a] ? TRANS(I,X) (génération spontanée d'un symbole de prévision) si [A ? ??X?, #] ? ? ({[B ? ???, # ]}) alors [A ? ?X??, #] ? TRANS(I,X) (propagation des symboles de prévision) Exemple grammaire SGD ? ({[S' ? ?S, # ]}) = { [S' ? ?S, # ], [S ? ?G=D, # ], [S ? ?D, # ], [G ? ?*D, #/= ], [G ? ?id, # /= ], [D ? ?G, # ] }Détermination des symboles de prévision à partir des noyaux: Soit K le noyau d'un ensemble d'items I X ? (N ? T) # est un symbole de prévision factice pour représenter les symboles de prévision pour chaque item [B ? ??? ] ? K, si [A ? ??X?, a] ? ? ({[B ? ??? , #]}) et a ? # alors [A ? ?X??, a] ? TRANS(I,X) (génération spontanée d'un symbole de prévision) si [A ? ??X?, #] ? ? ({[B ? ???, # ]}) alors [A ? ?X??, #] ? TRANS(I,X) (propagation des symboles de prévision) Exemple grammaire SGD ? ({[S' ? ?S, # ]}) = { [S' ? ?S, # ], [S ? ?G=D, # ], [S ? ?D, # ], [G ? ?*D, #/= ], [G ? ?id, # /= ], [D ? ?G, # ] }

    56. Transparent 56 Construction LALR(1) Grammaire SGD {S'? S ; S? G = D | D ; G? * D | id ; D? G } Noyaux LR(0) + Passes Prévision I0= [S'? ?S] I1= [S'? S?] I2= [S? G?=D] [D? G?] I3= [S? D?] I4= [G? *?D] I5= [G? id?] I6= [S? G=?D] I7= [G? *D?] I8= [D? G?] I9= [S? G=D?] Détermination des symboles de prévision à partir des noyaux: Soit K le noyau d'un ensemble d'items I X ? (N ? T) # est un symbole de prévision factice pour représenter les symboles de prévision pour chaque item [B ? ??? ] ? K, si [A ? ??X?, a] ? ? ({[B ? ??? , #]}) et a ? # alors [A ? ?X??, a] ? TRANS(I,X) (génération spontanée d'un symbole de prévision) si [A ? ??X?, #] ? ? ({[B ? ???, # ]}) alors [A ? ?X??, #] ? TRANS(I,X) (propagation des symboles de prévision) Exemple grammaire SGD ? ({[S' ? ?S, # ]}) = { [S' ? ?S, # ], [S ? ?G=D, # ], [S ? ?D, # ], [G ? ?*D, #/= ], [G ? ?id, # /= ], [D ? ?G, # ] }Détermination des symboles de prévision à partir des noyaux: Soit K le noyau d'un ensemble d'items I X ? (N ? T) # est un symbole de prévision factice pour représenter les symboles de prévision pour chaque item [B ? ??? ] ? K, si [A ? ??X?, a] ? ? ({[B ? ??? , #]}) et a ? # alors [A ? ?X??, a] ? TRANS(I,X) (génération spontanée d'un symbole de prévision) si [A ? ??X?, #] ? ? ({[B ? ???, # ]}) alors [A ? ?X??, #] ? TRANS(I,X) (propagation des symboles de prévision) Exemple grammaire SGD ? ({[S' ? ?S, # ]}) = { [S' ? ?S, # ], [S ? ?G=D, # ], [S ? ?D, # ], [G ? ?*D, #/= ], [G ? ?id, # /= ], [D ? ?G, # ] }

    57. Transparent 57 Classification des Grammaires Algébriques

    58. Transparent 58 Classification des Langages Algébriques

    59. Transparent 59 Quelques Environnements de Compilation (compiler-compiler) Java Compiler Compiler [tm] (JavaCC [tm]) - The Java Parser Generator http://javacc.java.net/ SYNTAX http://syntax.gforge.inria.fr/ Free Compiler Construction Tools http://www.thefreecountry.com/programming/compilerconstruction.shtml ANTLR, ANother Tool for Language Recognition, http://www.antlr.org/ The Compiler Generator Coco/R http://www.ssw.uni-linz.ac.at/Coco/

    60. La Compilation sur le Web http://toutprogrammer.com/ Attribute Grammar Systems Code Generator Kits Sociétés Compiler Construction Kits Cross Compilers Functional GNU Compiler Collection Lexer and Parser Generators Object-Oriented Procedural Theory Transformation Tools

More Related