Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
Luc Brun
1 / 134
Plan
Introduction
Bibliographie
Analyse lexicale
Analyse Syntaxique
Analyse descendante
Analyse ascendante
2 / 134
Définition
I Synthèse
I Compilateurs
I Filtres
I Analyse lexicale :
vérifie/reconnait le vocabulaire
(identificateurs, mots clés,. . .)
I Analyse syntaxique :
vérifie/reconnait la grammaire
I Analyse sémantique : vérifie le
sens du programme (e.x. les
types)
I RI : Langage intermédiare
permettant de factoriser des
étapes pour plusieurs langages.
4 / 134
Bibliographie
5 / 134
Analyse lexicale
Objectifs :
I Transformation d’un ensemble de caractères en concepts (nombres,
identificateurs, mots clés,. . .)
I On distingue les concepts suivants :
6 / 134
Éléments de théorie des langages
Alphabet :
I Un alphabet Σ est un ensemble fini de symboles. L’alphabet binaire
{0, 1} et les codes ASCII sont des exemples d’alphabets, {A, G , C , T } est
l’alphabet des bases ADN.
I Une chaı̂ne, est une séquence finie de symboles. Le terme mot est
également utilisé.
7 / 134
Éléments de théorie des langages
Langages :
I Un langage est un ensemble a priori quelconques de chaı̂nes construites
sur un alphabet. L’ensemble des codes source C, des nombres binaires ou
des codes ADN sont des langages.
I ∅ désigne le langage vide. On désigne également par {} le langage
composé uniquement de la chaı̂ne vide.
I Si x et y sont deux chaı̂nes, la concaténation de x et y , xy représente la
chaı̂ne formée par la séquence des symboles de x suivie de celle de y . Ex :
x=anti, y=constitutionnellement, xy=anticonstitutionnellement.
I Un alphabet Σ munit de la concaténation et de son élément neutre a
une structure de monoı̈de (intuitivement un groupe sans l’inverse).
I Exponentiation : s 0 = , s 1 = s, s n = s n−1 s
8 / 134
Opérations sur les langages
Définitions :
I Union (L ∪ M) :
L ∪ M = {s | s ∈ L ou s ∈ M}
I Concaténation (LM) :
LM = {st | s ∈ L et s ∈ M}
Remarque : LL est dénoté L2 , L0 = {}, L1 = L.
I Fermeture de Kleene (L∗ ) :
+∞
[
L∗ = Li
i=0
9 / 134
Opérations sur les langages
Exemples :
I Si B = {0, 1},
B + est l’ensemble des nombres binaires d’au moins un chiffre.
I Si C = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
C 4 est l’ensemle des nombres de 4 chiffres.
I Si K = {a, . . . , z, A, . . . , Z },
K (K ∪ C )∗ est l’ensemble des mots commençant par une lettre puis
composés d’un nombre quelconque de lettres et chiffres.
10 / 134
Expressions régulières
11 / 134
Exemple
Soit Σ = {a, b}
I L(a|b) = {a, b},
I L((a|b)(a|b)) = {aa, ab, ba, bb},
I L(a∗ ) = {, a, a2 , . . .},
I {a, a2 , b, b 2 , ab, ab 2 , a2 b 2 , . . .} ⊂ L((a|b)∗ ),
I On évite des paranthèse inutiles en utilisant les conventions suivantes :
∗
a∗ (a|b|c)∗ de = ((a)∗ (((a)|(b))|(c)) )((d)(e))
12 / 134
Propriétés algébriques
Axiome Descriptif
r |s = s|r | est commutatif
r |(s|t) = (r |s)|t | est associatif
(rs)t = r (st) la concaténation est associa-
tive
r (s|t) = rs|rt
la concaténation est distribu-
(s|t)r = sr |tr
tive vis à vis de |
r = r = r est un élémement neutre
pour la concaténation
r ∗ = (r |)∗
r ∗∗ = r ∗ ∗ est idempotent
13 / 134
Définitions régulières
d1 → r1
d2 → r2
..
.
dn → rn
14 / 134
Exemple de définition régulière
I Identificateurs de variables
lettre → a|b|c . . . |z|A|B . . . |Z
chiffre → 0|1|2|3|4|5|6|7|8|9
id → lettre(lettre|chiffre)∗
I Nombres :
pm → (+|−)
chiffre → 0|1|2|3|4|5|6|7|8|9
frac → .chiffre+
exp → E (pm|) chiffre+
nb → (pm|) chiffre+ (frac|)|frac (exp|)
15 / 134
Notations abrégées et limites des expressions
régulières
Notations abrégées :
I L’expression (r |) se note également r ?. Ainsi exp → E (pm|) chiffre+ ,
se note également exp → E pm? chiffre+ ,
I (a|b|c) se note également [abc]. De même (a|b| . . . , |z) se note [a − z] et
[a − zA − Z 0 − 9] représente (a| . . . , |z|A| . . . |Z |0 . . . |9). Ainsi l’ensemble
des identificateurs se note : [a − zA − Z ][a − zA − Z 0 − 9]∗ .
Limites des expressions régulières :
Ayez bien conscience que les expressions régulières ne permettent de
coder qu’un nombre limité de languages. En particulier, les expressions
régulières ne permettent pas de compter. Ainsi le langage :
16 / 134
Unités lexicales et diagrammes de transition
Un diagramme de transition est une représentation graphique du
processus de reconnaissance d’une unité lexicale. Il représente les actions
réalisées par l’analyseur lexical sur le tampon d’entré lorsqu’il est appelé
par l’analyseur syntaxique.
I Un diagramme de transition est constitué d’états :
I Internes y
I Finaux : y
I Finaux avec recul de tampon y jCes états d’acceptation codent les cas où il est
nécessaire de reculer le tampon d’entré.
I Les arcs codent les transitions entre états. Ils ont des étiquettes indiquant
sur qu’elle entrée s’effectue chaque changement d’état. L’étiquette autre,
code tout caractère autre que ceux indiqués par les changements d’états
sur l’état courrant. On suppose les diagrammes déterministes (i.e. une
même étiquette ne peut envoyer sur deux états différents)
17 / 134
Diagramme de transition : Exemple
I id → lettre(lettre|chiffre)∗ .
18 / 134
Automates fini non déterministes (AFN)
19 / 134
AFN : Un premier exemple
I Soit l’unité lexicale (a|b)∗ abb. Celle ci est reconnue par l’AFN suivant :
Transiter
Etat Symbole d’entrée
a b
0 {0, 1} 0
1 − 2
2 − 3
20 / 134
AFN : Un second exemple
I Notez les transitions sur l’état de départ et les boucle sur les états
d’acceptation.
21 / 134
Construction d’un AFN à partir d’une expres-
sion régulière
Construction récursive :
1. Pour construire l’AFN :
22 / 134
Construction d’un AFN à partir d’une expres-
sion régulière
Construction récursive :
3. Soient N(s) et N(t) les AFN des expressions s et t. L’AFN N(s|t) est
défini par :
4. Soient N(s) et N(t) les AFN des expressions s et t. L’AFN N(st) est
défini par :
22 / 134
Construction d’un AFN à partir d’une expres-
sion régulière
Construction récursive :
4. Soit N(s) l’AFN de l’expression s. L’AFN N(s ∗ ) est défini par :
22 / 134
Propriétés de l’AFN construit
23 / 134
Exemple
I Évaluation de (a|b)∗ abb. Son arbre syntaxique associé est (cf évaluation
d’expressions cours 1A algo) :
r11
H
HH
r9 r10
H
H
r7 r8 b
H H
H
r5 r6 b
HH
* a
H
r4
H
HH
H
( r3 )
HH
r1 | r2
a b
24 / 134
Exemple de construction d’AFN
25 / 134
Exemple de construction d’AFN
25 / 134
Exemple de construction d’AFN
25 / 134
Reconnaissance d’une expression régulière
par un AFN
L’algorithme calcule itérativement un ensemble d’états E en utilisant les
fonctions :
I Transiter(E,a) : retourne l’ensemble des états accessibles via les états E
par une transition ’a’.
I -fermeture(E) : renvoie l’ensemble des états accessibles depuis E par une
transition.
fonction recAFN (e0 ,F) : Booléen
Déclaration E : Ensemble d’états,c : caractère
début
E ← -fermeture(e0 )
c ← carSuivant()
tant que c 6= fdf faire
E ← -fermeture(Transiter(E,c))
c ← carSuivant()
fintantque
retourner E ∩ F 6= ∅
fin
26 / 134
Déroulement de la reconnaissance d’une ex-
pression régulière par un AFN
3. Transiter(E,’a’)={3, 8} ;
-fermeture(Transiter(E,’a’)={1, 2, 3, 4, 6, 7, 8} ;c=’b’
4. Transiter(E,’b’)={5, 9} ;
-fermeture(Transiter(E,’a’)={1, 2, 4, 5, 6, 7, 9} ;c=’b’
5. Transiter(E,’b’)={5, 10} ;
-fermeture(Transiter(E,’a’)={1, 2, 4, 5, 6, 7, 10} ;c=’fdf’
27 / 134
Des AFN aux Automates finis déterministes
(AFD)
28 / 134
Reconnaissance d’un lexème par un AFD
29 / 134
Transformation d’un AFN en AFD
La reconnaissance d’un lexème par un AFD calcule une suite d’ensembles
d’états. L’idée de base est de pré calculer ces ensembles d’états et de les
stocker dans l’AFD avec leurs transitions (table Dtran).
fonction recAFD (AFN(e0 ,F)) : AFD
Déclaration Détat : ensemble d’états
début
D-état ← -fermeture({e0 })
tant que il existe T non marqué dans Détat faire
marquer T
Pour chaque a dans Σ faire
U ← -fermeture(Transiter(T,a))
si U 6∈ Détat alors
Détat ← Détat∪{U}
finsi
Dtran[T,a] ← U
finpour
fintantque
retourner AFD(Dtran,Détat)
fin 30 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
A
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(A,a))=-fermeture({3, 8})={1, 2, 3, 4, 6, 7, 8}=B
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B
B
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(A,b))=-fermeture({5})={1, 2, 4, 5, 6, 7}=C
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B
C
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(B,a))=-fermeture({3, 8})=B
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B B
C
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(B,b))= -fermeture({5, 9})={1, 2, 4, 5, 6, 7, 9}=D
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B B D D = {1, 2, 4, 5, 6, 7, 9}
C
D
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(C,a))= -fermeture({3, 8})=B
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B B D D = {1, 2, 4, 5, 6, 7, 9}
C B
D
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(C,b))= -fermeture({5})=C
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B B D D = {1, 2, 4, 5, 6, 7, 9}
C B C
D
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(D,a))= -fermeture({3, 8})=B
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B B D D = {1, 2, 4, 5, 6, 7, 9}
C B C
D B
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(D,b))=
-fermeture({5, 10})={1, 2, 4, 5, 6, 7, 10}=E
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B B D
D = {1, 2, 4, 5, 6, 7, 9}
C B C E = {1, 2, 4, 5, 6, 7, 10}
D B E
E
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(E,a))= -fermeture({3, 8})=B
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B B D D = {1, 2, 4, 5, 6, 7, 9}
C B C E = {1, 2, 4, 5, 6, 7, 10}
D B E
E B
31 / 134
Exemple de transformation
I -fermeture({0})={0, 1, 2, 4, 7}=A
I -fermeture(Transiter(E,b))= -fermeture({5})=C
Transiter
Etat Symbole d’entrée
a b A = {0, 1, 2, 4, 7}
B = {1, 2, 3, 4, 6, 7, 8}
A B C
C = {1, 2, 4, 5, 6, 7}
B B D D = {1, 2, 4, 5, 6, 7, 9}
C B C E = {1, 2, 4, 5, 6, 7, 10}
D B E
E B C
31 / 134
Exemple de transformation
Transiter
Etat Symbole d’entrée
a b
A B C
B B D
C B C
D B E
E B C
32 / 134
Discussion
I La reconnaissance d’un lexème par un AFD est plus rapide (une seule
transition par état),
I En revanche le nombre d’états d’un AFD peut être exponentiel par
rapport au nombres d’états de l’AFN.
33 / 134
Un outil d’analyse lexicale : Lex
34 / 134
Syntaxe des expressions régulières en Lex
x le caractère ”x”
. n’importe quel caractère sauf \n
[xyz] soit x, soit y, soit z
[ˆbz] tous les caractères, sauf b et z
[a-z] n’importe quel caractère entre a et z
[ˆa-z] tous les caractères, sauf ceux compris entre a et z
r* zéro r ou plus, où r est n’importe quelle expression régulière
r+ au moins un r
r? au plus un r (c’est-à-dire un r optionnel)
r{2,5} entre 2 et 5 r
r{2,} 2 r ou plus
r{2} exactement 2 r
rs r suivi de s
r|s r ou s
r/s r, seulement s’il est suivi par s
ˆr r, mais seulement en début de ligne
r$ r, mais seulement en fin de ligne
35 / 134
Syntaxe des expressions régulières en Lex
{r} l’expansion de r
”[xyz\”foo” la chaı̂ne ”[xyz”foo”
\X si X est un ”a”, ”b”, ”f”, ”n”, ”r”, ”t”, ou ”v”, représente
l’interprétation ANSI-C de \X.
\0 le caractère ASCII 0
\123 le caractère dont le code ASCII est 123, en octal
\x2A le caractère dont le code ASCII est 2A, en hexadécimal
<<EOF>> fin de fichier
35 / 134
Structure d’un fichier Lex
%{
Déclaration des variables C
%}
Déclaration des Unités lexicales
%%
Déclarations des actions associées à la reconnaissance d’unités lexicales
%%
Code C supplémentaire (déclarations de fonctions auxilières)
36 / 134
Exemple de fichier Lex
%{
int nb_numbers=0,nb_id=0;
%}
pm [+-]
chiffre [0-9]
frac \.{chiffre}+
exp E{pm}?{chiffre}+
nb {pm}?(({chiffre}+{frac}?)|{frac}){exp}?
lettre [a-zA-z]
id {lettre}({lettre}|{chiffre})*
%%
{nb} { nb_numbers++;printf("Nombre %s reconnu : %f\n",yytext,atof(yytex
{id} { nb_id++;printf("Id %s reconnu\n",yytext);}
{nb}{id} {printf("Lexical error\n");}
%%
int main()
{
yylex();
printf("Nb Numbers: %d, \nNb Id %d\n",nb_numbers,nb_id);
return 0;
} 37 / 134
Analyse syntaxique
Exemple :
Si (x < 0) alors Si Expr alors
x=-x Instr
−→
Finsi Finsi
38 / 134
Analyse Syntaxique et grammaires
39 / 134
Grammaire non contextuelle
41 / 134
Notations
42 / 134
Vérification et expressions régulières
43 / 134
Suppression des ambiguı̈tés
La grammaire suivante :
inst
H
H
HH
H
HH
H
HH
si expr alors inst
PP
PP
E1
PP
P
si expr alors inst sinon inst
44 / 134
Suppression des ambiguı̈tés
La grammaire suivante :
inst
X HX
HXXX
HH XXX
H XXX
HH XXX
si expr Alors inst Sinon inst
P PP
E1 PP
S2
si expr alors inst
44 / 134
Suppression des ambiguı̈tés
Solution : Affecter chaque sinon au alors sans correspondant le plus
proche. Réécrire la grammaire pour interdire les si alors sans
correspondant dans des si alors sinon.
inst → instFermee
instNonFerme
instFermee → si expr alors instFermee sinon instFermee
autre
instNonFermee → si expr alors inst
|si expr alors instFermee sinon instNonFermee
45 / 134
Suppression de la récursivité à gauche
Récusivité directe
Une grammaire récursive à gauche comporte productions telles que
+
A⇒Aα. Ce genre de dérivation ne peuvent pas être analysés par des
grammaires récursives gauches (celles que l’on étudie). On a donc
besoins de transformer les productions A → Aα|β en les productions
équivalentes :
A → βA0
A0 → αA0 |
Plus généralement si A → Aα1 | . . . Aαn |β1 | . . . |βm , où A n’est un préfixe
d’aucun βi on remplace cette production par :
A → β1 A0 |β2 A0 | . . . |βm A0
A0 → α1 A0 |α2 A0 | . . . |αn A0 |
46 / 134
Suppression de la récursivité à gauche
Exemple :
E → E + T |T
T → T ∗ F |F
F → (E )|id
se réécrit en :
E → TE 0
E0 → +TE 0 |
T → FT 0
T0 → ∗FT 0 |
F → (E )|id
47 / 134
Suppression de la récursivité à
gauche :Récusivité indirecte
S → Aa|b
A → Ac|Sd|
+
engendre la dérivation S ⇒Sda.
48 / 134
Suppression de la récursivité à
gauche :Récusivité indirecte
La récursivité à gauche peut être indirecte par exemple :
S → Aa|b
A → Ac|Sd|
+
engendre la dérivation S ⇒Sda.
procédure suprRecGauche (E/S Grammaire S)
Déclaration i,j : Entiers
début
Ordoner les non terminaux A1 , . . . , An
pour i ←1 à n faire
pour j ←1 à i-1 faire
Remplacer Ai → Aj γ par Ai → δ1 γ|δ2 γ| . . . |δk γ
où Aj → δ1 |δ2 | . . . |δk sont les Aj production courantes
finpour
supprimer les récursivités gauches immédiates des Ai productions
finpour
fin
48 / 134
Suppression de la récursivité à
gauche :Récusivité indirecte
S → Aa|b
A → Ac|Sd|
S → Aa|b
A → bdA0 |A0
A0 → cA0 |adA0 |
49 / 134
Factorisation à gauche
Sur rencontre de si expr alors inst laquelle des deux règles appliquer ?
On explicite ce choix par une factorisation gauche :
Cette dernière grammaire est plus efficace car le choix ne s’effectue que
quand il doit se faire.
50 / 134
Factorisation à gauche
A → αA0 |γ
A0 → β1 |β2 | . . . |βn
51 / 134
Le problème du rebroussement
Soit la grammaire :
S → cAd
A → ab|a
S (b)
H
H S (c)
S (a) c
A
H
d H H
HH c A d
H
c A d a b
a
52 / 134
Le problème du rebroussement
53 / 134
Grammaires et diagrammes de transitions
On associe un diagramme à chaque non terminal. Pour chaque
production A → X1 . . . Xn en crée une chemin de l’état initial à l’état
final avec les transitions X1 . . . . .Xn .
E → TE 0
E0 → +TE 0 |
T → FT 0
T0 → ∗FT 0 |
F → (E )|id
Exemple sur la grammaire
d’expressions régulières sim-
plifiées.
54 / 134
Schéma d’un analyseur syntaxtique prédictif
On doit donc lire le tampon d’entré et empiler au moins les règles dans
lequelles on rentre.
55 / 134
Analyse prédictive
Tampon d’entrée a = b + c $
6
X Programme
Y d’analyse -Flot de sortie
Z prédictive
$ ?
Table
d’analyse M
56 / 134
Analyse prédictive
57 / 134
Analyse prédictive : Algo
id + * ( ) $
E E → TE 0 E → TE 0
E’ E 0 → +TE 0 E0 → E0 →
0 0
T T → FT T → FT
T’ T0 → T 0 → ∗FT 0 T0 → T0 →
F F → id F → (E )
59 / 134
PREMIER et SUIVANT
60 / 134
Calcul de PREMIER
61 / 134
Calcul de SUIVANT
62 / 134
Calcul de PREMIER et SUIVANT : Exemple
E → TE 0
E0 → +TE 0 |
T → FT 0
T0 → ∗FT 0 |
F → (E )|id
63 / 134
Construction des tables
64 / 134
Grammaires LL(1)
65 / 134
Grammaires LL(1) : Conclusions
66 / 134
Analyse ascendante
I A l’inverse des méthodes descendantes qui sont basées sur une dérivation
de l’axiome les méthodes d’analyse par décalage-réduction sont des
méthodes ascendantes qui partent de la chaı̂ne (des feuilles) pour
remonter à l’axiome.
I A chaque étape la partie droite d’une production présente dans la chaı̂ne
est remplacée par sa partie gauche.
I Si on fait les bons choix (et si la chaı̂ne appartient au langage) on
remonte ainsi à l’axiome.
67 / 134
Analyse ascendante : exemple
Considérons la grammaire :
S → aABe
A → Abc|b
B → d
⇒ signifie que l’on applique une réduction sur le terminal le plus à droite
d
du mot.
Notez également que l’utilisation de la production A → b sur aAbcde
aurait donné aAAcde ce qui ne permettait pas de revenir à S.
68 / 134
Manche
69 / 134
Manche : Exemple
Considérons :
S → aABe
A → Abc|b
B → d
et :
S⇒aABe⇒aAde⇒aAbcde⇒abbcde
d d d d
70 / 134
Élagage du manche
71 / 134
Élagage du manche : Exemple
Soit la grammaire
E → E + E |E ∗ E |(E )
E → id
et w = id1 + id2 ∗ id3 . On obtient la séquence de réduction suivante :
72 / 134
Analyse par décalage-réduction avec une pile
73 / 134
Analyse par décalage-réduction : Exemple
74 / 134
Préfixes viables
75 / 134
Analyseurs LR
Left to right scanning of the input
LR(k) constructing a Rightmost derivation in reverse
using k symbols.
I Tous les langages que vous avez vu, peuvent être reconnus par un
analyseur LR.
I La méthode d’analyse LR est la méthode par décalage réduction sans
rebroussement la plus générale connue. Elle peut cependant être
implantée aussi efficacement que d’autre méthodes utilisant le même
principe.
I L’ensemble des grammaires reconnaissables par un analyseur LR est un
sur ensemble strict des grammaires pouvant être reconnue par un
analyseur prédictif.
I Les analyseurs LR peuvent détecter très tôt les erreurs de syntaxe.
I les tables d’analyse LR sont trop grandes pour être rédigées à la
main . Heureusement de très bon outils (Yacc, Bison) existent.
76 / 134
Analyse LR : Idée de base
E → TE 0
E0 → +TE 0 |
T → FT 0
T0 → ∗FT 0 |
F → (E )|id
77 / 134
Analyse LR : schéma
Tampon d’entrée a = b + c $
6
sm
Programme
-Flot de sortie
Xm d’analyse LR
sm−1
Xm−1
.. ? ?
. Action Successeur
s0
78 / 134
Analyse LR : schéma
79 / 134
Analyse LR : Algorithme
80 / 134
Analyse LR : Algorithme
(1) E → E +T
(2) E → T
(3) T → T ∗F
(4) T → F
(5) F → (E )
(6) F → id
avec les conventions suivantes :
I di : décaler et empiler i
I rj : réduire par la production j
I acc : accepter
I entré vide : erreur
82 / 134
Analyse LR : Exemple
83 / 134
Pile Entrée Action
(1) 0 id*id+id d5
y
i
0 i
1 i
6 i
9
i
5
i
2 i
7 i
10
i
3
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
i
0 i
1 i
6 i
9
id y
- 5i
i
2 i
7 i
10
i
3
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F 3 *id+id$ r par T → F
i
0 i
1 i
6 i
9
id - 5i
i
2 i
7 i
10
F - 3i
y
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F 3 *id+id$ r par T → F
i
0 i
1 i
6 i
9
(4) 0 T 2 *id+id$ d7
id - 5i
- 2i
T y i
7 i
10
F - 3i
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F3 *id+id$ r par T → F
i
0 i
1 i
6 i
9
(4) 0 T2 *id+id$ d7
id - 5i (5) 0 T2*7 id+id$ d5
- 2i -
T *
7i
y i
10
F - 3i
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F3 *id+id$ r par T → F
i
0 i
1 i
6 i
9
(4) 0 T2 *id+id$ d7
id y
- 5i (5) 0 T2*7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i -
T *
7i
6 i
10
F - 3i
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F3 *id+id$ r par T → F
i
0 i
1 6i i
9
(4) 0 T2 *id+id$ d7
id - 5i (5) 0 T2*7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i -
T *
7i - 10
6 F i
y (7) 0 T 2 * 7 F 10 +id$ r T →T ∗F
F - 3i
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F3 *id+id$ r par T → F
i
0 i
1 6i i
9
(4) 0 T2 *id+id$ d7
id - 5i (5) 0 T2*7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i
T y-*
7i - 10
6 F i (7) 0 T 2 * 7 F 10 +id$ r T →T ∗F
(8) 0 T2 +id$ rE →T
F - 3i
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F3 *id+id$ r par T → F
i
0
E y
- 1i 6i i
9
(4) 0 T2 *id+id$ d7
id - 5i (5) 0 T2*7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i -
T *
7i - 10
6 F i (7) 0 T 2 * 7 F 10 +id$ r T →T ∗F
(8) 0 T2 +id$ rE →T
F - 3i
(9) 0 E1 +id$ d6
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F 3 *id+id$ r par T → F
i
0
E - 1i + - 6i
y 9i
(4) 0 T 2 *id+id$ d7
id - 5i (5) 0 T 2 * 7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i -
T *
7i - 10
6 F i (7) 0 T 2 * 7 F 10 +id$ r T →T ∗F
(8) 0 T 2 +id$ rE →T
F - 3i
(9) 0 E 1 +id$ d6
(10) 0 E 1 + 6 id$ d5
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F 3 *id+id$ r par T → F
i
0
E - 1i + - 6i i
9
(4) 0 T 2 *id+id$ d7
id y
- 5i
id (5) 0 T 2 * 7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i -
T *
7i - 10
6 F i (7) 0 T 2 * 7 F 10 +id$ r T →T ∗F
(8) 0 T 2 +id$ rE →T
F - 3i
(9) 0 E 1 +id$ d6
(10) 0 E 1 + 6 id$ d5
(11) 0 E 1 + 6 id 5 $ r par F → id
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F 3 *id+id$ r par T → F
i
0
E - 1i + - 6i i
9
(4) 0 T 2 *id+id$ d7
id - 5i
id (5) 0 T 2 * 7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i -
T *
7i - 10
6 F i (7) 0 T 2 * 7 F 10 +id$ r T →T ∗F
(8) 0 T 2 +id$ rE →T
F - 3i
y
F
(9) 0 E 1 +id$ d6
(10) 0 E 1 + 6 id$ d5
(11) 0 E 1 + 6 id 5 $ r par F → id
(12) 0 E 1 + 6 F 3 $ r par T → F
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
(2) 0 id 5 *id+id$ r par F → id
(3) 0 F 3 *id+id$ r par T → F
i
0
E - 1i + - 6i
-T
9y
i
(4) 0 T 2 *id+id$ d7
id - 5i
id (5) 0 T 2 * 7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i -
T *
7i - 10
6 F i (7) 0 T 2 * 7 F 10 +id$ r T →T ∗F
(8) 0 T 2 +id$ rE →T
F - 3i
F
(9) 0 E 1 +id$ d6
(10) 0 E 1 + 6 id$ d5
(11) 0 E 1 + 6 id 5 $ r par F → id
(12) 0 E 1 + 6 F 3 $ r par T → F
(13) 0 E 1 + 6 T 9 $ r E →E +T
84 / 134
Pile Entrée Action
(1) 0 id*id+id d5
accepter (2) 0 id 5 *id+id$ r par F → id
(3) 0 F 3 *id+id$ r par T → F
i
0
E i
- 16 + - 6i
-T
9i
(4) 0 T 2 *id+id$ d7
id - 5i
id (5) 0 T 2 * 7 id+id$ d5
id (6) 0 T 2 * 7 id 5 +id$ r par F → id
- 2i -
T *
7i - 10
6 F i (7) 0 T 2 * 7 F 10 +id$ r T →T ∗F
(8) 0 T 2 +id$ rE →T
F - 3i
F
(9) 0 E 1 +id$ d6
(10) 0 E 1 + 6 id$ d5
(11) 0 E 1 + 6 id 5 $ r par F → id
(12) 0 E 1 + 6 F 3 $ r par T → F
(13) 0 E 1 + 6 T 9 $ r E →E +T
(14) 0 E 1 $ accepter
84 / 134
Grammaires SLR
SLR(k) : Simple-LR(k).
I Un item LR(0) (ou simplement item) d’une grammaire G est une
production de G avec un point repérant une position dans la partie
droite. Une règle A → XYZ peut donc donner :
A → .XYZ
A → X .YZ
A → XY .Z
A → XYZ .
85 / 134
Analyse SLR
86 / 134
Items valides
Un item A → β1 .β2 est valide pour un préfixe viable αβ1 si il existe une
dérivation telle que :
∗
S 0 ⇒ αAw ⇒αβ1 β2 w
d d
E 0 ⇒E ⇒E + T ⇒E + T ∗ F
d d d
87 / 134
Analyse SLR : Fermeture
88 / 134
Fermeture : Exemple
E0 → E
E → E + T |T
T → T ∗ F |F
F → (E )|id
et : 0
E → .E
E → .E + T |.T
Fermeture({E 0 → .E }) =
T → .T ∗ F |.F
F → .(E )|.id
89 / 134
Notion de Noyau
90 / 134
Transition
J = {A → αX .β | A → α.X β ∈ I }
et si J 6= ∅
Transition(I , X ) = Fermeture(J)
Intuitivement si I est l’ensemble des items valides pour un préfixes viable
γ, Transition(I,X) est l’ensemble des items valides pour le préfixe viable
γX .
Sur l’exemple précédent :
T → T ∗ .F
Transition({T → T .∗F }, ∗) = Fermeture({T → T ∗.F }) = F → .(E )
F → .id
91 / 134
Construction des ensembles d’items
92 / 134
Construction des ensembles d’items :
Exemple
I5 : F → id.
I0 : E 0 → .E
E → .E + T |.T
I6 : E → E + .T
T → .T ∗ F |.F
T → .T ∗ F |.F
F → .(E )|.id
F → .(E )|.id
I1 : E 0 → E.
I7 : T → T ∗ .F
E → E. + T
F → .(E )|.id
I2 : E → T.
I8 : F → (E .)
T → T. ∗ F
E → E. + T
I3 : T → F.
I9 : E → E + T.
I4 : F → (.E )|.(E )|.id
T → T. ∗ F
E → .E + T |.T
I10 : T → T ∗ F.
T → .T ∗ F |.F
I11 : F → (E ).
93 / 134
Exemple (suite) : l’AFD
vers 4
L’état i correspond à Ii . 6
(
0
m E
- 1m +
- 6m-
T
9
m *
-vers 7
6
id
- 5m id
id
6 +
T
- 2m *- 7m F
- m
10
(
-vers 4
F
- 3m F
F
6
(
- 4m - E
8
m )
- 11
m
T@
(
?@Rid
vers 2 vers 5
94 / 134
Construction des tables d’analyse SLR
96 / 134
Limites des grammaires SLR
S → G =D
S → D
G → ∗D
G → id
D → G
I2 : S → G. = D
D → G.
97 / 134
Limite des grammaires SLR : explications
98 / 134
Items LR valides
tel que :
1. γ = αβ
2. a est le premier symbole de w si w 6= sinon a=$.
99 / 134
Fermeture d’items LR(1)
∗
Pour toute réduction B → η on aura S ⇒δαBβaw ⇒δαηβaw .
d d
Par conséquent on doit s’attendre a voir (et donc ajouter à la fermeture)
les items de la forme [B → .η, b] avec b ∈ PREMIER(βaw ). Puisque a
est un terminal, on a PREMIER(βaw ) = PREMIER(βa).
100 / 134
Fermeture d’items LR(1) : Algorithme
101 / 134
Fermeture d’items LR(1) : exemple (1/2)
Considérons la grammaire augmentée simple suivante :
S0 → S
S → CC
C → cC |d
102 / 134
Fermeture d’items LR(1) : exemple (2/2)
I0 : S 0 → .S, $
S → .CC , $
C → .cC , c/d
C → .d, c/d
103 / 134
Transition d’items LR(1)
104 / 134
Transition d’items LR(1) : exemple
I2 : S → C .C , $
C → .cC , $
C → .d, $
I et ainsi de suite. . .
105 / 134
Collection d’items LR(1)
106 / 134
Collection d’items : Exemple
I0 : S 0 → .S ,$
I4 C → d. , c/d
S → .CC ,$
C → .cC , c/d
I5 : S → CC . ,$
C → .d , c/d
I6 : C → c.C ,$
I1 : S 0 → S. ,$
C → .cC ,$
C → .d ,$
I2 : S → C .C ,$
C → .cC ,$
I7 : C → d. ,$
C → .d ,$
I8 : C → cC . , c/d
I3 : C → c.C , c/d
C → .cC , c/d
I9 : C → cC . ,$
C → .d , c/d
107 / 134
Collection d’items : Exemple
i
-
0
S
1i
2i 5i
C
- -C
c
6i 9i
c
- ?-C
7i
d
-
c
3i 8i
c
- ?
-C
108 / 134
Construction des tables d’analyse LR(1)
110 / 134
Analyse LALR : Principes
I Toutes les liaisons entrantes vers deux états i et j sont donc fusionnées sur
l’état ij.
I La fonction de Transition dépendant du coeur et non pas des terminaux si
Transition(i,X)=k et Transition(j,X)= l alors k et l devront eux même être
fusionnés.
111 / 134
Items fusionnés : Exemple
I0 : S 0 → .S ,$ I47 C → d. , c/d/$
S → .CC ,$
C → .cC , c/d I5 : S → CC . ,$
C → .d , c/d
I89 : C → cC . , c/d/$
I1 : S 0 → S. ,$ 0i-S
1i
2i 5i
C C
I2 : S → C .C ,$ - -
C → .cC ,$ c
36i i
c
- ?
- C
89
C → .d ,$
47i
d
-
I36 : C → c.C , c/d/$
C → .cC , c/d/$
C → .d , c/d/$
112 / 134
Grammaires LALR(1) et conflits
décaler/réduire
Aucun conflit décaler/réduire ne peut être induit par la fusion des états
de même coeur.
I On a un conflit décaler réduire si dans un même état (fusionné) on a
deux productions [A → α., a] impliquant réduire et [B → β.aγ, b]
impliquant décaler.
I Soit I un état non fusionné contenant [A → α., a]. Tous les états
fusionnés ayant le même coeur, il existe un terminal c tel que
[B → β.aγ, c] ∈ I . On retrouve donc nos deux items antagonistes qui
continuent à produire un conflit décaler/réduire dans un état de
l’automate LR(1).
I Cela signifie que la grammaire n’est pas LR(1).
113 / 134
Construction triviale des tables d’analyse
LALR
Remarque : cette méthode est loin d’être optimale puisque l’on construit
tous les items LR(1) avant de les réduire.
114 / 134
Construction LALR : éviter le calcul de la fer-
meture
Comme on l’a vu, on peut ne stocker que le noyau I des états (i.e. l’item
de l’axiome [S 0 → S, $] et les items où le ’.’ n’est pas à gauche de la
partie droite de la production.
Actions réduire : A → α. impliquant une action réduire sera dans le
noyau à moins que α = . Réduire A → doit être appelé
sur une entrée a si il existe un item [B → γ.C δ, b] du
∗
noyau tel que C ⇒Aη avec a ∈ PREMIER(ηδb). Cet
d
ensemble de non terminaux A peut être pré-calculé.
Actions décaler : Nous décalons sur l’entré a, si il existe [B → γ.C δ, b]
∗
avec C ⇒aw . L’ensemble des terminaux a peut également
d
être pré-calculé.
Transitions : Si [B → γ.X δ, b] ∈ I alors
[B → γX .δ, b] ∈ Transition(I , X ). L’item [A → X .β, a] est
également dans Transition(I , X ) si [B → γ.C δ, b] ∈ I et
∗
C ⇒Aη.
d
115 / 134
Exemple
Soit la grammaire :
S → G = D|D
G → ∗D|id
D → G
Le noyau de sa grammaire LR(0) augmentée est :
I0 : S 0 → .S
I5 : G → id.
0
I1 : S → S.
I6 : S → G = .D
I2 : S → G. = D
I7 : G → ∗D.
D → G.
I8 : D → G.
I3 : S → D.
I9 : S → G = D.
I4 : G → ∗.D
116 / 134
Génération et propagation des symboles de
pré vision
∗
I Supposons à présent que l’item LR(1) [B → γ.C δ, b] ∈ I .Puisque C ⇒Aη,
d
l’item [A → X .β, a] ∈ Transition(I , X ) pour tout a ∈ PREMIER(ηδ). On
dit que a est engendré spontanément. Le terminal $ est engendré
spontanément pour [S 0 → .S].
∗
I Toutefois si ηδ ⇒, alors [A → X .β, b] ∈ Transition(I , X ). On dit dans ce
d
cas, que le symbole b se propage.
I l’algorithme suivant calcule les symboles de prévision en utilisant le
∗
symbole fictif # pour détecter les dérivations ηδ ⇒.
d
117 / 134
Détermination des symboles de pré vision :
Algorithme
procédure SymbolesPreVision (E I : un état,X un symbole, S PreVision)
début
J ← Transition(I,X)
K ← ensemble d’items LR(0) de I
Pour chaque B → γ.δ dans K faire
J’ ← Fermeture([B → γ.δ, #])
si [A → α.X β, a] ∈ J 0 et a 6= # alors
Remarque : Génération de a
PreVision[J,A → αX .β] ← PreVision[J,A → αX .β] ∪ {a}
finsi
si [A → α.X β, #] ∈ J 0 alors
Remarque : Propagation des b
PreVision[J,A → αX .β] ←
PreVision[J, A → αX .β] ∪ {b | [B → γ.δ, b] ∈ I }
finsi
finpour
fin
118 / 134
Symboles de prévision
S0 → .S, #
S → .G = D, #
S → .D, #
G → . ∗ D, #/ =
G → .id, #/ =
D → .G , #
119 / 134
Propagation des symboles de pré vision
120 / 134
Transmission des pré vision
De Vers
I0 : S 0 → .S I1 : S 0 → S.
I2 : S → G. = D
D → G.
I3 : S → D.
I4 : G → ∗.D
I5 : G → id.
I2 : S → G . = D I6 : S → G = .D
I4 : G → ∗.D I4 : G → ∗.D
I5 : G → id.
I7 : G → ∗D.
I8 : D → G.
I6 : S → G = .D I4 : G → ∗.D
I5 : G → id.
I8 : D → G.
I9 : S → G = D.
121 / 134
Transmission des pré vision : Le diagramme
122 / 134
Transmission des pré vision : Les différentes
passes
123 / 134
Un outil d’analyse grammaticale : Yacc
I Lex retourne des tokens qui sont combinés dans Yacc par une grammaire
pour reconnaitre un langage.
I Les cousins de Lex/Yacc pour le C++ se nomment Flex et Bisons.
I L’application de Yacc sur un fichier produit un fichier y.tab.c.
I Ci joint un exemple de Makefile :
$(OUTPUT) : $(OBJ)
CC = gcc $(CC) $(OBJ) -o $@ $(LIB)
LEX = lex
YACC = yacc y.tab.o : lex.yy.c y.tab.c
LEXFILE = monFichier.lex $(CC) -c y.tab.c
YACCFILE = monFichier.y
OBJ = y.tab.o lex.yy.c : $(LEXFILE)
OUTPUT = monFichier $(LEX) $(LEXFILE)
LIB = -ll y.tab.c : $(YACCFILE)
$(YACC) $(YACCFILE)
124 / 134
Combinaison de Lex et Yacc
125 / 134
Structure d’un fichier Yacc
%{
Déclaration des variables C
%}
Déclaration de tokens et d’associativité/priorité des opérateurs
%%
Déclaration des productions et de leurs actions associées
%%
Code C supplémentaire.
Par exemple :
#include "lex.yy.c"
main()
{
return yyparse();
}
126 / 134
Yacc : un exemple (fichier Lex)
%{
#include <stdio.h>
%}
blanc [ ]
pm [+-]
chiffre [0-9]
frac \.{chiffre}+
exp E{pm}?{chiffre}+
nb {pm}?({chiffre}+{frac}?|{frac}){exp}?
%%
{blanc} {}
{nb} {yylval=atof(yytext); return NB;}
- {return NEG;}
\n|. {return yytext[0];}
%%
127 / 134
Yacc : un exemple (fichier Yacc (1/3))
E → E + T |E − T |T
T → T ∗ F |T /F |F
F → (E )| − E |nombre
128 / 134
Yacc : un exemple (fichier Yacc (2/3))
%{
#include <stdio.h>
#define YYSTYPE double
%}
%token NB
%token NEG
%%
input:
/* ligne vide */
|input ligne
;
ligne : expr ’\n’ {printf("%f\n",$1);}
;
expr : expr ’+’ terme {$$=$1+$3;}
| expr NEG terme {$$=$1-$3;}
| terme
;
129 / 134
Yacc : un exemple (fichier Yacc (3/3))
main()
{
return yyparse();
}
130 / 134
Exemple Yacc : Explications
2. les différentes productions concernant ce membre gauche sont séparées par des
|.
131 / 134
Exemple Yacc : Explications
132 / 134
Yacc et les grammaires ambiguës
Yacc peut aussi considérer des grammaires ambiguë à condition que l’on
lève les ambiguı̈tés via la définition des règles d’associativité et de priorité
des opérateurs.
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token NOMBRE
%token PLUS MOINS FOIS DIVISE PUISSANCE
%token PARENTHESE_GAUCHE PARENTHESE_DROITE
%token FIN
Expression:
%left PLUS MOINS NOMBRE { $$=$1; }
%left FOIS DIVISE | Expression PLUS Expression { $$=$1+$3; }
%left NEG | Expression MOINS Expression { $$=$1-$3; }
%right PUISSANCE | Expression FOIS Expression { $$=$1*$3; }
| Expression DIVISE Expression { $$=$1/$3; }
% start Input | MOINS Expression %prec NEG { $$=-$2; }
%% | Expression PUISSANCE Expression { $$=pow($1,$3); }
Input: | PARENTHESE_GAUCHE Expression PARENTHESE_DROITE { $$=$2; }
/* Vide */ ;
| Input Ligne %%
;
Ligne:
FIN
| Expression FIN { printf("Resultat : %f\n",$1); }
;
133 / 134
Grammaires ambiguë : Explications
134 / 134