L'analyse lexicale a pour but , à partir du programme source, suite de caractères, de former
des entités lexicales. L'analyse syntaxique a pour rôle la vérification de la forme ou encore de
l'écriture de la suite des entités lexicales, on parlera alors de la syntaxe du langage .
La vérification est faite à l'aide de la grammaire spécifique au langage appelée grammaire
syntaxique .
I. Définitions :
Remarques :
• L'entité entre < > est appelée NON TERMINAL.
• Chacune des règles de type .
Notion de dérivation :
Les opérations consistent à remplacer au fur et à mesure en partant de l'axiome des
non-terminaux par leurs MDP sont appelées Dérivations .
<Prg>
<Exp> #
<Exp> + <Term>
<Fact> <Fact> i
i i
Notion d'ambiguïté :
On dit qu'une grammaire est ambiguë s'il existe deux arbres syntaxiques correspondant à
une même chaine à analyser .
E E
E + E E * E
E * E i i E + E
i i i i
Remarque :
Dans notre cas , nous nous intéressons qu'aux grammaire non ambiguë .
• Une grammaire est dite récursive à gauche, de façon directe, si elle s'écrit de la manière
suivante :
A B 1 / 1
B A 2 / 2 Avec : A N et 1 , 1, 2, 2 (T N)*
Remarque :
Si la grammaire de la forme A A , on parlera de la récursivité droite .
∗
Avec : i et j ∈T ∪ N
Exemple :
{
S aS /b/ Ac
{S aS /b / Ac
A Aa/c
≡ A c /c A'
A' a/aA'
On a : {
A B 1 /1
B A 2 /2
On substitue B dans A , ce qui donne : A A 2 1 /1
On substitue A dans B , on aura : B B 1 2 /1
Et on aura, une grammaire récursive gauche directe, après transformation (vu juste
avant) , on obtient :
{
'
A 1 / 1 A
' '
A 2 1 / 2 1 A
'
B 2 / 2 B
' '
B 1 2 /1 1 B
devient :
{
G : S aS / bA
A aA/ab /c
G n' est pas factorisée.
{
S aS / bA
'
G : A aB / c
B A/ b
Grammaire − libre :
Une grammaire est − libre Ssi :
Il n'existe pas dans P des productions de la forme : A ou bien : S (axiome)
et il n'existe pas de MDP de la forme S et il n'existe pas une règle de la forme
A pour A≠S .
2. Si S et ∃ MDP de la forme S
'
Alors Introduire un non-terminal S' ; nouvel axiome de la grammaire S S /
Refaire l'étape 1 avec S
Exemple :
1)
{ {
S a / A S a/ A/
G: A AB/ ≡ G' : A AB / B Cette grammaire est −libre
B aAbB/ b B aAbB / abB/b
2)
{
S ' /S
{ {
S c/aSb / AB S c/ aSb/ab / A/ B/
' '' S c /aSb/ab /B / A
G : A a/ ≡ G : A a ≡ G :
A a
B b/ B b
B b
{
< Bloc début < LD; < LI fin
Exemple : Soit G : < LD d /d ; < LD
< LI i/i ; < LI
Chaine : début d ; d ; i ; i fin#
Remarque :
1. Cette technique n'est pas efficace car elle nécessite l'examen de plusieurs arbres en
parallèle, ce qui est couteux en temps et en espace mémoire.
2. Pour appliquer cette méthode, il faut que la grammaire soit non récursive gauche.
Exemple : G : {
S ca/b /cSA
Ac /b
et la chaine à analyser est ccab
S S S S
c a b c S A c S A
∥ ∤ ∤ ∥ ∥
c c c c c a c c c a b
∥ ∥ ∤ ∥ ∥ ∥
c a b c a b
Remarque :
1. Les dérivations se font de gauche à droite et de haut en bas, les retours arrières se font
dans le sens inverse.
2. Il faut que la grammaire soit non récursive gauche.
• Grammaire LL(1) :
Définition: Une grammaire est LL(1) Ssi pour chaque couple de productions
∗
A / avec : , ∈T ∪N et A∈ N , on a :
∗ ∗
1. Si ⇒ a 1 alors ¬⇒ a 2
TC = a : S S
∗ ∗
w 1 A1 w 1 A 1
ou bien :
∗ ∗
TC: a 1 TC : a 2
∗ ∗
2. Si ⇒ alors ¬⇒
∗ ∗ ∗
3. Si ⇒ et ⇒ a alors ¬∃ S wAa 1
Terminologie :
∗
Si ⇒ a 1 alors a est un symbole directeur de alpha.
Ensemble Début :
∗ ∗
Deb ={ a∈T / ⇒ a , ∈T ∪N } ∪ {t∈∪T / ⇒ t }
∈ T ∪N ∗
1. Si A 1 /2 /..../n Alors Deb A=deb 1 ∪deb 2 ....∪ Debn
2. Deb a={a }
3. Deb a ={a }
4. Deb ={ }
5. Deb Bx 1 ... x n ⊃Deb B−{ }
∗
x1 ∈T ∪ N
Si ∈Deb B alors Deb Bx 1 ... x n ⊃Deb x 1−{ }
Si ∈Deb x1 alors Deb Bx 1 ... x n ⊃Deb x 2−{ }
⋮
Si ∈Deb x n−1 alors Deb Bx 1 ... x n ⊃Deb x n−{ }
Si∈ Deb x n alors ∈ Deb Bx 1 ... x n
Fsi ;
Fsi ;
Fsi ;
{
S ABc /aSc
A / aAB
Exemple : G:
B bC /
C Bc /aC /
Début Suivant
S a b c # c
A a b c
B b c b
C a b c c b
Ensemble suivant :
∗
Suiv A={ a∈T ∪{ # }/ Z ⇒ wA avec a∈ Deb # et w , ∈T ∪ N ∗ }
A∈ N
Étapes de construction :
1. Si ∃ MDP Aa avec , ∈T ∪N ∗ a∈T et A∈N alors a∈Suiv A
2. Si ∃ MDP A B avec , ∈T ∪N ∗ et A , B∈ N Alors Deb B −{ }⊂suiv A
3. Si ∃ une production A x 1 ... x n B avec : x i ∈T ∪N alors Suiv A⊂Suiv B
Si ∈ Deb B alors Suiv A⊂Suiv x n
⋮
Si ∈ Deb x 2 alors Suiv A⊂Suiv x 1
Fsi
Fsi
Fsi
1. A a 2. A B 3. A x 1 x 2 B
S c A Bc A a A B
ABc a A B B b C
Bc CaC
aSc
Exemple :
{
ZS#
S aB/ Aa
G:
A BA/ b
B c
Procédure Z( )
Début
Tc := 1er terme de la chaine ;
Erreur := Faux ;
Si Tc∈Deb S Alors S ( ) ;
Si Tc≠# Alors Erreur := Vrai ; Fsi ;
Sinon Erreur := Faux ;
Fsi;
Si ¬ Erreur Alors '' Chaine correcte ''
Sinon ''Chaine incorrecte ''
Fsi;
Procedure A ( )
Début
Si Tc ∈ Deb BA alors B ;
Si Tc ∈ Deb Aet ¬ Erreur Alors A ;
Sinon Erreur :=Vrai ;
Fsi;
Fsi;
Fin.
Procédure B ( )
Début
Tc Tc1
Fin.
Tc Chaine Action
Z c cba# Appel S
ZS c cba# Appel A
ZSA c cba# Appel B
ZSAB c cba# Fin de B
ZSA b ba# Appel A
ZSAA b ba# Fin A et Tc := Tc+1
ZSA a a# Fin A et Tc := Tc+1
ZS a a# Fin S et Tc:=Tc+1
Z # # Chaine correcte
Remarques :
1. Si la grammaire est récursive gauche , il y a nécessité de la transformer .
2. Si on veut faire une analyse déterministe, il faut factoriser la grammaire.
3. Pour faire une analyse par la descente récursive, il faut que la grammaire soit
LL(1).
4. La méthode présente un inconvénient, car elle est liée à la grammaire.
5. Méthode simple à implémenter et efficace.
Remarque :
1. Chaque entrée de la table d'analyse LL(1) correspond à une erreur .
2. Une table d'analyse doit être monodéfinie (au plus une règle par entrée).
Définition N°02 :
Une condition nécessaire et suffisante pour qu'une grammaire soit LL(1) et
qu'elle soit :
• Non récursive gauche.
• Factorisée.
• Table d'analyse LL(1) monodéfinie.
Définition N°03 :
Une grammaire est LL(1) si :
• Non récursive gauche.
• Factorisée.
• Pour chaque production A 1 /2 /..../n
➢ Debi ∩Deb j =∅ ∀ i , j i≠ j
* *
➢ Sii ⇒ alors j ¬⇒ ∀ j j≠i
*
➢ Sii ⇒ alors Deb j ∩Suiv A=∅
Algorithme :
Début
Tc := 1er terme de la chaine ;
Empiler (#S) ;
Fin Analyse := Faux;
Tant que non fin analyse
Faire
Si sommetpile ∈ T
Alors Si Tc = sommetpile
Alors Tc := Tc+1 ;
Dépiler ;
Sinon 'Chaine incorrecte'
Fin Analyse := vrai ;
Fsi;
Sinon Si sommetpile ∈ N
Alors Si T[sommetpile,Tc] = ∅
Alors 'chaine incorrecte' ;
Finanalyse := Vrai ;
Sinon A:= Sommetpile ;
Dépiler ;
Empiler l'image miroir de la
règle T[A, Tc] ;
Fsi;
Sinon Si Tc = #
Alors 'Chaine correcte' ;
Finanalyse = vrai ;
Sinon 'Chaine incorrecte'
Finanalyse = vrai;
Fsi;
Fsi;
Fsi;
Fait;
Fin.
{
ZE#
E T E '
E ' TE ' /
G:
T FT '
T ' * FT ' /
F i/ E
Solution :
1. G est elle LL(1) ?
Début Suivant
E i ( # )
E' + # )
T i ( + # )
T' * + # )
F i ( * + )
• Table d'analyse :
+ * i ( ) #
E 1 1
E' 2 3 3
T 4 4
T' 6 5 6 6
F 7 8
• Grammaires LL(k) :
Une grammaire est LL(k) si k caractères du début de la chaine à analyser
suffisent pour faire une analyse déterministe.
De façon formelle si on a une règle : A / , il faut que :
Deb k . SUiv k A ∩ Debk . Suiv k A=∅
Ensemble Début k :
∗ ∗
Deb k ={ w∈T k / ⇒ w , ∈T ∪N ∗ }∪{ w∈T l , lk / ⇒ w }
∗
∈T ∪ N
3. Deb k w =
w ∈T
{
{ w } Si w∈T l et l≤k
{ w ' } Si w=w' w ' ' ∈T l et lk et w' ∈T k
+
Ensemble Suivant k :
∗
Suiv k A={ w /Z ⇒ A # k , w ∈ Deb # k et ∣w∣=k }
A∈ N
Étapes de construction :
∗
1. Si B A Alors Deb k bêta.Suiv k B⊂Suiv k A Avec : , ∈T ∪ N
2. Si A x 1 ... x n B Alors Idem L L 1
Exemple :
{
ZS #
G : S aAaa/bAba
A bA/
Remarques:
• Si une grammaire G est LL(k) alors G est LL(k+1).
• Si la table d'analyse LL(k) est monodéfinie alors la grammaire est LL(k) .
aa ab bb ba
S 1 1 2
A 4 3 3 4
Remarque :
Avant de construire le diagramme de transition d'un analyseur déterministe, il faut
vérifier les propriétés LL(1) .
Algorithme de construction :
• Pour chaque non-terminal A , créer un état initial et un état final (Pour le retour).
• Pour chaque production de tye A x 1 x 2 ... x n : créer un chemin de l'état initial
à l'état final, dont les arcs sont étiquetés par x 1 , x 2 ,... , x n. .
Remarque:
Pour simuler le fonctionnement du diagramme de transition, on utilisera une pile.
On empilera l'état i à chaque fois qu'un appel à un non-terminal est fait, on dépilera
lorsque l'état final est atteint.
Exemple:
{
E T E '
E ' TE ' /
G : T FT '
T ' * FT ' /
F id / E
T E'
E: 0 1 2
+ T E'
E': 3 4 5 6
T: 7 8 9
F T'
ℇ
Id
F: 14 17
( 16
15 )
F
Définition N°01 :
Soit une grammaire G =<T,N,S,P> , une chaine x est une forme sentencielle. Si
∗
x peut être obtenue par dérivation à partir de l'axiome. S ⇒ x x∈T ∪N
∗
Définition N°02 :
Soit une grammaire G =<T,N,S,P> et w= x y une forme sentencielle,
est une phrase simple de la forme sentencielle w, relativement au non -terminal
∗
U , si : S ⇒ x U y x y MDP de U :U
Définition N°03:
Une réduction consiste à remplacer une phrase simple dans une forme
sentencielle w= x y par U pour avoir x U y MDP de U .
Remarques :
1. La forme sentencielle initiale est la chaine d'entrée.
2. Les réductions sont de gauche à droite, ce sont les phrases les plus à gauche qui
sont réduites avant les autres.
3. À la réduction de par U, x ne doit pas contenir de phrase simple.
Exemple:
{
< Prog débutLD;LI fin .
< LDLD ; d /d
< LI LI ; i/ i
• Analyser la chaine : début d ; d ; i ; i fin.
• '' * '' plus prioritaire que '' + '' , on obtient la grammaire suivante :
{
E E T / T
T T ∗F / F
F i / E
• Soit U une expression i+i+i , on remarque que c'est le même opérateur, il faut
donc préciser si l'on effectue d'abord le premier '' + '' ou le second : Associativité
de gauche à droite ou associativité de droite à gauche.
{ {
E E T /T E T E /T
T T ∗F / F T F∗T / F
F i / E F i / E
Associativité Associativité
de gauche à droite. de droite à gauche.
{
∗
S ⇒
Si et avec ne peut être réduit avant.
∗
⇒ w
Avec : ∈T ∪N ∗ et w∈T ∗
:contenu de la pile à la réduction de en A
w : Reste de la chaine à la réduction de en A
A
w
Exemple :
{
Z#S#
S ABc
Aa
B b
Remarque :
#ab n'est pas un contexte gauche de la règle B b .
{
S Ab/ Bc
A As/
B bB /
Z S
Règles CG CD
S Ab #Ab #
S Bc #Bc #
A Aa #Aa a*b#
A # a*b#
B bB #b* b B c#
B #b+ c#
Définition N°01 :
Une grammaire est dite LR(0), si le contexte gauche (contenu de ma pile)
suffit pour décider de l'action à exécuter.
Définition N°02:
Une grammaire est LR(k), si on regardant k caractères du contexte droit
(ce qui reste à analyser), on décide de l'action à exécuter.
Définition N°03:
Le contexte LR(k) de la règle A est obtenue en concaténant le
contexte gauche et les k premiers du contexte droit de la règle A .
Suite exemple :
Construction du contexte LR(1) :
S Ab #Ab#
S Bc #Bc#
A Aa #Aaa , #Aab
A #a , #b
B bB #b* bBc
B #b* c
Z S #S#
Cette grammaire n'est pas LR(1) ⇒ Voir définition N°04 (à venir)
-Conséquence- : {
A ⇒ # b Avec # b≡ et c≡w d ' où : w≠
B ⇒ # bc
Exemple :
{
ZS
S CbBA
G : A Aab/ab
BCB /
C b
Questions :
1. G est-elle LR(k) ?
2. Construire la table d'analyse LR(k).
3. Analyser la chaine bbbabab# .
Règles CG CD
Z S #S #
S CbBA #CbBA #
A Aab #CbBAab (ab)* #
A ab #CbBab (ab)* #
B CB #CbC*CB (ab)+ #
B #CbC* (ab)+ #
Cb #b #CbC*b bb*(ab)+# b*(ab)+#
{ {
S CbBA # CbBA
Voir : A Aab ab
# CbBA
w
Z S #S#
S CbBA #CbBA#
A Aab #CbBAaba# #CbBAab#
A ab #CbBaba #CbBab#
B CB #CbC*CBa
B #CbC*a
Cb #bb #CbC*bb #CbC*ba
G est LR(1), car en examinant les contextes LR(1), il n'existe pas de contexte
LR(1) sous mot initial d'un autre mot contexte LR(1).
#
1 R4
S
0 C
b
2
b B
3 A #
b 4
5 R1
12 a
13 a a
C
b R4
6
b, a 8 b
a
b C b
R4 7
a, #
10
B 9
a, # R2
11
a
R3
R4
Table d'analyse LR(1) :
a b # S A B C
0 D,12 1 2
1 Acc
2 D,3
3 R,5 D,13 4 10
4 D,8 5
5 D,6 R1
6 D,7
7 R,2 R,2
8 D,9
9 R,3 R,3
10 R,5 D,13 11 10
11 R,4
12 R,6
13 R,6 R,6
Remarque :
• Une grammaire récursive gauche directe en S n'est pas LR(0).
• Une grammaire est LR (k) alors elle est LR(k+1).
• Une grammaire est LR(k) Ssi la table d'analyse LR(k) est monodéfinie.
Définition N°01 :
Un item LR(k) est de la forme [ A . , w ]
Avec : :constitue ce qui a été déjà réduit.
Où : A∈ N , , ∈T ∪N ∗ et w ∈ Debk T * . # k
A est une règle de la grammaire.
Pour la construction des ensembles des items d'une grammaire, nous avons besoin de
deux fonctions :
• La fermeture d'un ensemble d'items.
• La fonction GOTO.
Exemple:
G : S Sbc /a
Item LR(0):
I 0={[ Z . S ] }
I 0={[ Z . S ] ,[ S . Sbc ] ,[ S . a ] }
Item LR(1):
I 0={[ Z . S , # ] }
I 0={[ Z . S , # ] , [ S . Sbc , # ] , [ S . a , # ] ,[ s . Sbc , b ] , [ S . a ,b ] }
Focntion GOTO:
GOTO (I,X)
I: ensemble d'item.
X: symbole de la grammaire, X ∈T ∪N
Construction de l'ensemble C
(1) Si I j=Goto I i , A , A∈N alors T [ I i , A]=I j
(2) Si I j =Goto I i , a , a∈T
Alors Pour chaque item de Ii de la forme [ A . a , w ]
Faire
Pour chaque aw ' ∈ Debk a w
Faire
T [ I i , aw ' ] :=DI j ; ∣aw '∣=k
Fait;
Fait;
Fsi;
(3) Si dans Ii, , on a un item de la forme [ A . , w ]
Alors T [ I i , w ]:=R N ° A
Fsi;
Définition N°02 :
G est LR(k) ssi la table LR(k) déduite de l'ensemble canonique des items C est
monodéfinie.
Item LR(1):
I 0={[ Z . S , # ] , [ S . Sbc , # ] , [ S . a , # ] ,[ s . Sbc , b ] , [ S . a ,b ] }
I 1=Goto I 0, S ={ [ Z S. , # ] , [ S S.bc , # ] ,[ S S.bc , b ] }
I 2=Goto I 0, a={ [ S a. , # ] ,[ S a. , b ] }
I 3=Goto I 1, b={[ S Sb.c , # ] , [ S Sb.c , b ] }
I 4=Goto I 3, c ={[ S Sbc. , # ] , [ S Sbc. , b ] }
a b c # S
I0 D,I2 I1
I1 D,I3 Acc
I2 R1 R2
I3 D,I4
I4 R1 R1
Remarque :
Le cas Décalage/décalage ne peut pas se présenter :
• T [ I i , a ]=D , I j
• t [ I i , a]=D , I l ⇒ I j= I l
Conclusion:
Les analyseurs LR sont construits pour reconnaître tous les langages de
programmation, ils sont très performants, mais leurs tables d'analyse contiennent des
milliers d'états, de ce fait elles sont couteuses à implémenter. Pour cela, on a pensé
aux SLR et LALR qui permettent d'optimiser les grammaires LR.
Exemple:
{
G : S Sbc /a
Z S
CG CD Contexte SLR(1)
Z S #S # #S#
S Sbc #Sbc (bc)* # #Sbc# #Sbcb
Sa #a (bc)* # #a# #ab
Remarque:
G est SLR(1) car en examinant les contextes SLR(1), il n'existe pas de contexte
SLR(1) sous mot initial d'un autre contexte SLR(1).
# Acc
S 1
0 b c
2 #/b
3 R1
a
# /b R2
a b c # S
0 D,4 1
1 D,2 Acc
2 D,3
3 R1 R1
4 R2 R2
Remarques :
1. Si G est SLR(k) alors G est SLR(k+1).
2. Si G est SLR(k) ; la table SLR(k) et LR(k) sont équivalentes.
Exemple:
G: {S Z aSb/
S
Items LR(0):
I 0={[ Z . S ] ,[ S . aSb ] , [ S . ]}
I 1=Goto I 0, S ={ [ Z . S ] }
I 2=Goto I 0, a={ [ S a.Sb ] ,[ S . aSb ] , [ S .] }
I 3=Goto I 2, S ={[ S aS.b ] }
I 2=Goto I 2, a
I 4=Goto I 3, b={[ S aSb.]}
Table SLR(1):
a b # S
I0 D,I2 R2 R2 I1
I1 Acc
I2 D,I2 R2 R2 I3
I3 D,I4
I4 R1 R1
Grammaires LALR :
L'analyse SLR est une méthode optimale, facile à implémenter, mais cependant
peu de grammaires sont SLR.
C'est pour cela que la méthode LALR a été conçue, c'est une méthode intermédiaire
du point de vue puissance. Elle est souvent suffisante et produit des tables de même
importance que SLR.
I i =Z . S , # I j =Z . S , #
S . AB , a S . AB , d /a
A. a , # A. a , c /#
B. b , # B . b , b /#
Exemple:
{
ZS #
G= S CC
C cC /d
G est-elle LR(1) ??
C={ I 0, I 1, I 2, I 3, I 4, I 5, I 6, I 7, I 8, I 9 }
c d # S C
0 D,3 D,4 1 2
1 Acc
2 D,6 D,7 5
3 D,3 D,4 8
4 R3 R3
5 R1
6 D,6 D,7 9
7 R3
8 R2 R2
9 R2
G est-elle LALR(1) ?
Table LALR(1):
c d # S C
I0 D,3 D,4 1 2
I1 Acc
I2 D,6 D,7 5
I36 D,36 D,47 8,9
I47 R3 R3 R3
I5 R1
I89 R2 R2 R2