600 likes | 1.01k Views
Transparent 2. Sommaire. 1. Introduction
E N D
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 5Analyse syntaxique descendantemé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 6Analyse syntaxique ascendantemé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 Webhttp://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