Vous êtes sur la page 1sur 91

III.

Analyse Syntaxique
Plan

III.1. Présentation Générale


III.2. Analyse syntaxique par descente récursive
III.3. Analyse syntaxique prédictive récursive
III.4. Analyse syntaxique prédictive non récursive
III.5. Récupération sur erreur
III.6. Analyse syntaxique par décalage réduction
1
III.1. Présentation générale
L’analyse syntaxique consiste à vérifier que la séquence d’unités
lexicales retournées par l’analyseur lexical est générée par la grammaire
du langage.
Ceci revient à construire un arbre syntaxique dont les feuilles
concordent avec la séquence d’unités lexicales en les parcourant de
gauche à droite.

Nous distinguons:

• Analyse syntaxique descendante


• Analyse syntaxique ascendante

2
III.1. Présentation générale
Analyse syntaxique descendante :
• Elle s’effectue par la construction descendante d’un arbre syntaxique en
partant de la racine étiquetée par l’axiome de la grammaire et en
réalisant de manière répétitive les étapes suivantes:

• Étape 1: au nœud n étiqueté par le non terminal A, choisir une


production ayant A à gauche et construire les fils de n avec les
symboles en partie droite de la production.

• Étape 2: déterminer le prochain nœud où un sous arbre doit être


construit.

3
III.2. Analyse syntaxique descendante
récursive
Exemple: Le langage est formé par un ensemble de Types générés par la
grammaire non contextuelle suivante:
Type  array[Type_simple] of Type
| Type_simple
| ^Type
Type_simple  integer
|char
|nb 2points nb
Les étapes de construction descendante de l’arbre syntaxique pour le
mot:
array[nb 2points nb] of integer
sont les suivantes:

4
III.2. Analyse syntaxique descendante
récursive
(a) Type

(b) Type

array [ Type_simple ] of Type

(c) Type

array [ Type_simple ] of Type

nb 2points nb

5
III.2. Analyse syntaxique descendante
récursive

(d) Type

array [ Type_simple ] of Type

nb 2points nb Type_simple

(e) Type

array [ Type_simple ] of Type

nb 2points nb Type_simple

integer

6
III.2. Analyse syntaxique descendante
récursive

• C’est une méthode d’analyse dans laquelle on


exécute des procédures récursives.
• Une procédure est associée à chaque non
terminal.

7
III.2. Analyse syntaxique descendante
récursive
Exemple: Le langage est formé par un ensemble de
Types générés par la grammaire non contextuelle
suivante:
Type  array[Type_simple] of Type
| Type_simple
| ^Type
Type_simple  integer
|char
|nb 2points nb
8
III.2. Analyse syntaxique descendante
récursive
Procedure accepter(T) Procedure Type_simple()
Type  Si symbole = integerof alors
Si Symbole = T alors
array[Type_simple] Type
symbole := symbole_suivant();
AnalLex(); accepter(integer);
| Type_simple
Sinon erreur(); Sinon| ^TypeSi symboleType_simple
= char alors 
Fin Si integer accepter(char);
Procedure Type() Sinon
|char Si symbole = nb alors
Si symbole = array alors |nb 2points nb accepter(nb);
accepter(array); accepter([); Type_simple(); accepter(2points);
accepter(]); accepter(nb);
accepter(of); Type(); Sinon erreur();
Sinon si symbole  {integer, char, nb} alors Fin Si Fin Si Fin Si
type_simple(); Fin
Symbole_suivant est une fonction
Sinon si symbole = ^ alors accepter(^); qui retourne le nouveau symbole
Type();
trouvé par l’analyseur lexical et
sinon erreur ();
l’enregistre dans une variable
Fin Si FinSi FinSi globale symbole
Fin

9
III.3. Analyse syntaxique Prédictive
descendante récursive
• C’est une méthode d’analyse syntaxique par descente récursive
où un symbole de prévision permet de décider d’une manière
unique quelle règle peut être appliquée.
• La grammaire doit être non récursive à gauche et non ambiguë.
• Pour se faire, il faut éliminer la récursivité à gauche puis
enlever l’ambigüité.
• Ensuite, on associe une procédure à chaque non terminal.

Rq. Le pseudo-code précédent est associé à un analyseur


syntaxique prédictif récursif car la grammaire qui génère les
types est non ambiguë et non récursive à gauche

10
III.3.1. Elimination de la récursivité à gauche

• Une grammaire est dite récursive à gauche si


elle admet une règle de la forme : A  A 
• Une grammaire récursive à gauche avec les
règles de production
– A  A1|A2|…An |1|2 |… |m
Est transformée en une grammaire non récursive à
gauche ayant les règles de production :
– A  1 A’| 2A’|… mA’
– A’  1 A’|2A’|…nA’ |
11
III.3.1. Elimination de la récursivité à gauche

Exemple
• La grammaire suivante est récursive à gauche
Exp  Exp op Exp | (Exp) | id | nb
Elle est transformée en une grammaire non
récursive à gauche avec les règles suivantes:
Exp  (Exp) E’ | id E’ | nb E’
E’  op Exp E’ | 

12
III.3.2. Elimination de l’ambiguité
Une grammaire est dite ambiguë si elle admet des règles de la forme :
A   1 | 2
• Une grammaire ambiguë avec les règles de production
– A   1|2|…n |1|2 |… |m
Est transformée en une grammaire non ambiguë ayant les règles de production :
– A   A’|1 | 2 |…| n
A’  1|2|…n
• La grammaire suivante est ambigue
I  If (Expb) Then I | If (Expb) Then I else I
Elle est transformée en une grammaire non ambiguë avec les règles
suivantes:
I  If (Expb) Then I S
S   | else I

13
III.3.3. Exemple
Exemple: le langage est formé par une séquence non vide d’instructions d’affectation

L_I  I | I L_I
I  id := Exp;
Exp  id |nb| (Exp) | Exp op Exp
1) En éliminant la récursivité à gauche, on obtient:
L_I  I | I L_I
I  id := Exp;
Exp  id E’|nb E’| (Exp) E’
E’  op Exp E’ | 
2) En éliminant l’ambiguité, on obtient :
L_I  I S
S   | L_I
I  id := Exp;
Exp  id E’|nb E’| (Exp) E’
E’  op Exp E’ | 

14
III.3.3. Exemple
Un pseudo-code d’un analyseur syntaxique prédictif et récursif associé:

L_I  I S Procédure S()


Si symbole = id alors L_I();
S   | L_I Fin
I  id := Exp; Procédure I();
Exp  id E’|nb E’| (Exp) E’ Si symbole = id alors
accepter(id); accepter(:=);
E’  op Exp E’ |  Exp(); accepter(;);
Sinon erreur();
Fin Si
Fin
Procédure accepter(T) Procédure Exp();
Si symbole = T alors Symbole := symbole_ Si symbole = id alors accepter(id); E’();
suivant(); Sinon Si symbole = nb alors accepter(nb); E’();
Sinon erreur(); Sinon si symbole = ( alors accepter((); Exp(); accepter()); E’();
Sinon erreur();
FinSi
Fin Si Fin Si Fin Si
Fin Fin
Procédure L_I() Procédure E’()
I(); S(); Si symbole = op alors accepter(op); Exp(); E’();
Fin
Fin

15
III.4. Analyse syntaxique prédictive non
récursive
• C’est une méthode d’analyse où on remplace l’appel de
procédures récursives par la manipulation d’une pile
• La grammaire doit être non récursive à gauche et non ambiguë.
• Initialement la pile contient le symbole fond de pile $ et au
sommet l’axiome de la grammaire, le tampon d’entrée contient
le mot à analyser suivi du symbole $, la tête de lecture/écriture
pointe sur le premier symbole
• A la fin de l’analyse, la pile contient le symbole $ et la tête de L/E
pointe sur le symbole $ de fin de la chaine
• L’évolution de l’analyse s’effectue en consultant une table
d’analyse

16
III.4. Analyse syntaxique prédictive non
récursive
• Nous illustrons l’approche à travers l’exemple
suivant de grammaire :
• S  id:= E;
E  E + E | E – E | E * E | E/E | (E) | id | nb
Après l’élimination de la récursivité à gauche et de
l’ambiguité, nous obtenons:
• S  id:= E;
E  (E) E’ | id E’ | nb E’
E’  + E E’ | – E E’ | * E E’ | /E E’ |
17
III.4. Analyse syntaxique prédictive non
récursive

Id := id op nb ; $ Tampon
Configuration
initiale S
Tête de L/E
$
Pile

Id := id op nb ; $ Tampon
Configuration
finale
Tête de L/E
$
Pile
18
III.4. Analyse syntaxique prédictive non
récursive
• Table d’analyse M
Elle spécifie pour chaque non terminal, et
chaque terminal ou $ (cas de la fin de la
chaine), une règle de production pouvant
éventuellement être appliquée
Pour l’exemple la table est la suivante

19
III.4. Analyse syntaxique prédictive non
récursive
S  id:= E;
E  (E) E’ | id E’ | nb E’
E’  + E E’ | – E E’ | * E E’ | /E E’ |
Non Symbole d’entrée
terminal

id nb + - * / ( ) := $
S S  id:=
E;
E E  id E E
E’ nb E’ (E) E’
E’ E’  E’  E’  E’
+ E E’ - E E’ * E E’  /
E E’

20
III.4.1. Algorithme d’analyse syntaxique
prédictive non récursive

Positionner le pointeur (ps) sur le premier symbole de $;


Répéter
Soit X le symbole en sommet de pile et a le symbole en cours d’analyse
(repéré par ps) :
Si X es un terminal ou $ alors
Si X = a alors enlever X de la pile et avancer ps
Sinon erreur()
Sinon /* X est un non terminal*/
consulter M [X, a]
Si M[X, a] = X  Y1 Y2..YK =  alors dépiler X et empiler l’image
miroir de  c-a- d empiler Yk, yk-1, … Y1 et émettre en sortie la
règle X  Y1 Y2..YK
Sinon erreur ()
Jusqu’à X = $ /* la pile est vide*/

21
III.4.1. Analyse syntaxique prédictive non
récursive (Exemple)
Symbole d’entrée
NT id nb + - * / ( ) := ; $
S S
id:= E;
E E E  nb E
id E’ E’ (E) E’
E’ E’  E’  - E’  E’ E’
+ E E’ E E’ * E E’ /E 
E’

id := id + nb ; $

id + nb
:= := id E E E’ E’
E E E E’ E’ E’ E’ E’ E’ E’
S ; ; ; ; ; ; ; ; ; ; ;
$ $ $ $ $ $ $ $ $ $ $ $ $
22
III.4.1. Analyse syntaxique prédictive non
récursive (Exemple)
Pile Entrée Message
$S Id := id + nb ; $ L’algorithme se
contente d’informer
$ ; E := id Id := id + nb ; $ S  id := E ; l’utilisateur par la
$ ; E := := id + nb ; $ règle appliquée
$;E id + nb ; $ Ou bien par l’erreur
syntaxique détectée
$ ; E’ id id + nb ; $ E  id E’ Ces erreurs seront
$ ; E’ + nb ; $ vues plutard
$ ; E’ E + + nb ; $ E’  + E E’
$ ; E’ E nb ; $
$ ; E’ E’ nb nb ; $ E  nb E’
$ ; E’ E’ ;$
$ ; E’ ;$ E’  
$; ;$ E’  
$ $ 23
III.4.2. Calcul des premiers et suivants
La construction de la table d’analyse est facilitée par deux
fonctions associées à une grammaire G: Premier et suivant
Calcul du PREMIER(X) pour tout symbole X de la grammaire:
Appliquer les règles suivantes jusqu’à ce qu’aucun terminal ni  ne puisse être
ajouté aux ensembles PREMIER
1. Si X est un terminal, PREMIER(X) est {X}.
2. Si X   est une production, ajouter  à PREMIER(X).
3. Si X est un non-terminal et X  Y1 Y2..YK une production, mettre a dans
PREMIER(X) s’il existe i tel que a est dans PREMIER(Yi) et que  est dans
tous les PREMIER(Y1), …, PREMIER(Yi-1),
*
c-a-d Y1…Yi-1  .
Si  est dans PREMIER(Yj) pour tous les j = 1, 2, 3, …, k, ajouter  à
PREMIER(X). Si Y1 ne se dérive pas en , on n’ajoute rien de plus à
PREMIER(X), *
mais si Y1 , on ajoute PREMIER(Y2), etc.
24
III.4.2. Calcul des premiers et suivants

Calcul du SUIVANT(A) pour tous les non-terminaux A,


appliquer les règles suivantes jusqu’à ce qu’aucun terminal
ne puisse être ajouté aux ensembles SUIVANT.
1. Mettre $ dans SUIVANT(S), où S est l’axiome et $ est le
marqueur droit indiquant la fin du texte source.
2. S’il y a une production A  B, le contenu de
PREMIER(), excepté , est ajouté à SUIVANT(B).
3. S’il existe une production A B ou une production
A  B telle que PREMIER() contient 
*
(c-a-d   ), les éléments de SUIVANT(A) sont
ajoutés à SUIVANT(B).
25
III.4.3. Algorithme de construction d’une
table d’analyse prédictive
Donnée. Une grammaire G
Résultat. Une table d’analyse M pour G
Méthode.
1. Pour chaque production A  de G, procéder aux
étapes 2 et 3.
2. Pour chaque terminal a dans PREMIER(), ajouter
A  à M[A, a].
3. Si  est dans PREMIER(), ajouter A à M[A, b] pour
chaque b dans SUIVANT(A). Si  est dans PREMIER() et
$ est dans SUIVANT(A), ajouter A  à M[A, $]
4. Faire de chaque entrée non définie de M une erreur.

26
III.4.4. Exemple 1
Considérons la grammaire suivante:
E  TE’
E’  +TE’ | 
T  FT’
T’  *FT’ | 
F  id | (E)
PREMIER et SUIVANT
PREMIER(E) = PREMIER(T) = PREMIER(F) = {(, id}
PREMIER(E’) = {+, }
PREMIER(T’) = {*, }
SUIVANT(E) = SUIVANT(E’) = {), $}
SUIVANT(T) = SUIVANT(T’) = {+, ), $}
SUIVANT(F) = {+, *, ), $}
Rq. Si T   alors premier (E) = Premier(T)  Premier(E’)

27
III.4.4. Exemple 1
Table d’analyse
Symbole d’entrée
Non id + * ( ) $
terminal
E ETE’ ETE’ Sync Sync
E’ E’ +TE’ E’ E’
T TFT’ Sync TFT’ Sync Sync
T’ T’  T’ *FT’ T’  T’ 
F F id Sync Sync F  (E) Sync Sync

28
Analyse du mot
III.4.4. Exemple 1Symbole d’entrée
id+id*id
Non id + * ( ) $
terminal
E ETE’ ETE’ Sync Sync
E’ E’ +TE’ E’ E’
T TFT’ Sync TFT’ Sync Sync
T’ T’  T’ *FT’ T’  T’ 
F F id Sync Sync F  (E) Sync Sync

PILE ENTREE SORTIE


$E Id+id*id$
$E’T Id+id*id$ ETE’
$E’T’F Id+id*id$ TFT’
$E’T’id Id+id*id$ Fid
$E’T’ +id*id$
$E’ +id*id$ T’ 
$E’T+ +id*id$ E’  +TE’ 29
Analyse du mot
III.4.4. Exemple 1 id+id*id

$E’T Id*id$
$E’T’F id*id$ TFT’
$E’T’id id*id$ Fid
$E’T’ *id$
$E’T’F* *id$ T’*FT’
$E’T’F id$
$E’T’id id$ F  id
$E’T’ $
$E’ $ T’ 
$ $ E’  

30
III.4.5. Exemple 2
Considérons la grammaire avec les règles de production suivantes:
E  E ou T E  E ou T |T
E T T  T et F|F
TF F  non F | (E)| id
T  T et F
TF
F  non F
F  (E)
F  id
Elle est transformée en la grammaire non récursive à gauche suivante:
E  TE’ Premier(E) = Premier(T) = Premier(F) = {non,(, id}
E’  ou T E’ | Premier(E’) = {ou, }
T  F T’ Premier(T’) = {et, }
T’  et F T’ |  Suivant(E) = {), $} = Suivant(E’)
F  (E) Suivant(T)= premier(E’) – {}  suivant(E) = {ou, ), $}
F  id = Suivant(T’)
Suivant(F) = premier(T’) – {}  suivant(T) = {et, ou, ), $}
31
III.4.5. Exemple 2
Table d’analyse
Symbole d’entrée
Non id et ou non ( ) $
terminal
E ETE’ ETE’ ETE’ Sync Sync
E’ E’ E’  E’ 
ouTE’
T T FT’ Sync T FT’ T FT’ Sync Sync
T’ T’etFT’ T’  T’  T’ 
F F id Sync Sync F F (E) Sync Sync
non F

32
III.4.5. Exemple 2
Table d’analyse
Symbole d’entrée
Non id nb Si Alors ( ) $
terminal
E ETE’ ETE’ ETE’ Sync Sync
E’ E’ E’  E’ 
ouTE’
T T FT’ Sync T FT’ T FT’ Sync Sync
T’ T’etFT’ T’  T’  T’ 
F F id Sync Sync F F (E) Sync Sync
non F

33
Analyse du mot
III.4.5. Exemple 2 (id et id) ou id

PILE ENTREE SORTIE


$E (Id et id) ou id $
$E’T (Id et id) ou id $ ETE’
$E’T’F (Id et id) ou id $ TFT’
$E’T’)E( (Id et id) ou id $ F(E)
$E’T’)E Id et id) ou id $
$E’T’)E’T Id et id) ou id $ E  TE’
$E’T’)E’T’F Id et id) ou id $ T  FT’
$E’T’)E’T’id Id et id) ou id $ F  id
$E’T’)E’T’ et id) ou id $
$E’T’)E’T’F et et id) ou id $ T  et FT’

34
Analyse du mot
III.4.5. Exemple 2 (id et id) ou id
PILE ENTREE SORTIE
$E’T’)E’T’F et et id) ou id $ T  et FT’
$E’T’)E’T’F id) ou id $
$E’T’)E’T’id id) ou id $ F  id
$E’T’)E’T’ ) ou id $
$E’T’)E’ ) ou id $ T’  
$E’T’) ) ou id $ E’  
$E’T’ ou id $
$E’ ou id $ T’  
$E’Tou ou id $ T’  ou T E’
$E’T id $
$E’T’F id $ T FT’

35
Analyse du mot
III.4.5. Exemple 2 (id et id) ou id

PILE ENTREE SORTIE


$E’T’F id $ T FT’
$E’T’F id $ F  id
$E’T’id id $
$E’T’ $
$E’ $ T’  
$ $ E’  

36
III.4.6. Grammaires LL(1)

Une grammaire dont la table d’analyse n’a aucune entrée


définie de façon multiple est appelée LL(1). Le premier L
signifie «parcours de l’entrée de gauche à droite » (Left to
right Scanning). Le deuxième L signifie « dérivation
gauche» (Left most derivation) et le 1 signifie qu’on utilise
un seul symbole de prévision.
Symbole d’entrée

Exemple. Non T a b e i t $
S  iEtSS’ | a S Sa S  iEtSS’
S’  eS |  S’ S’  S’ 
Eb S’ eS
E Eb

37
III.5. Récupération sur erreur

Une erreur provient dans une analyse syntaxique


prédictive non récursive lorsque :
 nous avons un symbole non terminal A en sommet de
pile et un symbole a en entrée et M[A, a] = 
 le symbole terminal sommet est différent du
symbole en entrée

38
III.5. Récupération sur erreur
Table d’analyse
Symbole d’entrée
Non id + * ( ) $
terminal
E ETE’ ETE’
E’ E’ +TE’ E’ E’
T TFT’ TFT’
T’ T’  T’ *FT’ T’  T’ 
F F id F  (E)

39
III.5. Récupération sur erreur
Une erreur provient dans une analyse syntaxique
prédictive non récursive lorsque :
 nous avons un symbole non terminal A en sommet de
pile et un symbole a en entrée et M[A, a] = 
alors sauter jusqu’à suivant(A) et dépiler A dans l’espoir
de continuer avec les suivants de A
) id * + id $ ) id * + id $ ) id * + id $
Sauter jusqu’à
suivant(F) et
F + dépiler F
+ T
T
T E’ E’
E’ … …
… $ $
$ 40
III.5. Récupération sur erreur
 nous avons un symbole non terminal A en sommet de
pile et un symbole a en entrée et M[A, a] = 
On est au début de l’analyse alors sauter jusqu’à
premier(A) dans l’espoir de continuer avec A

) * id + id $ ) * id + id $ ) * id + id $
Sauter jusqu’à
Premier(E)

Sauter jusqu’à
suivant(A) et
dépiler A
T M[A, a] =  
E E E’ Sauter jusqu’à
premier(A)
$ $ $
41
III.5. Récupération sur erreur
 nous avons un symbole terminal a en sommet de pile
et un symbole b en entrée et a  b
On dépile le sommet a et on informe l’utilisateur
par a manquant

id id + nb $ id id + nb $ id id + nb $
Dépiler ‘:=‘

:=
id id …
… … $
$ $
42
III.5. Récupération sur erreur
Analyse du mot
Analyse du mot )id*+id (id et id) ou id
PILE ENTREE SORTIE
$E )Id *+ id$
$E Id *+id $ Sauter jusqu’à premier(E) ‘)’mal inséré
$E’T Id *+id $ TTE’
$E’T’F Id *+id $ FFT’
$E’T’id Id *+id $ Fid
$E’T’ *+id $
$E’T’F* *+id $ T’  *FT’
$E’T’F +id $
$E’T’ +id $ Dépiler F ‘ F’ mal formé
$E’ +id$ T’  
$E’T+ + id$ E’  +TE’
$E’T id$
43
III.5. Récupération sur erreur
Analyse du mot
Analyse du mot )id*+id (id et id) ou id
PILE ENTREE SORTIE
$E’T id$
$E’T’F id$ T  FT’
$E’T’id id$ F  id
$E’T’ $
$E’ $ T’  
$ $ E’  

44
III.5. Récupération sur erreur
III.4.4. Exemple
Symbole d’entrée
Non id + * ( ) $
terminal
E ETE’ ETE’ Sync Sync
E’ E’ +TE’ E’ E’
T TFT’ Sync TFT’ Sync Sync
T’ T’  T’ *FT’ T’  T’ 
F F id Sync Sync F  (E) Sync Sync

Cas général de traitement des erreurs On se synchronise avec les


suivants des non terminaux en
M[A, a] =   Sauter a
replissant les cases [A, suivant(A)]
par Sync si la case est vide
M[A, a] = Sync  Dépiler A si au milieu d’analyse
Sauter si début d’analyse
45
Exemple (Version récursive)
E  TE’ Proc F()
E’  +TE’ |  Si symbole.UL = id
T  FT’ alors accepter (id);
Sinon Si Symbole.UL = (
T’  *FT’ | 
alors acceptr((); E();
F  id | (E) accepter());
Proc E() Sinon
T(); E’(); Si i = 1 Alors
Proc E’() Repeter Symbole =
Si symbole.UL = + Symbole_suivant();
alors accepter(+); T(); E’(); Jusqu’à symbole.Ul  {id, (} ou EOF
Proc T() Si symbole.UL  {id, (} alors F();
F(); i = 0; T’(); Sinon
Répéter Symbole =
Proc T’()
Symbole_suivant();
Si symbole.UL = * jusqu’à symbole.UL  {+, *, ), EOF}
alors accepter(*); F(); T’(); Message(F mal formé);
Fin Fin Fin
46
Exemple
Acceptet(T)
Si Symbole.UL = T
alors Symbole := Symbole_suivant();
Sinon Message(T manquant)

Programme AnalSyn()
Début
Ouvrir Fichie
Symbole := symbole_suivant;
I = 1;
E();
Fermer Fihier
Fin

47
III.6. Analyse syntaxique par décalage
réduction (shift/Reduce) (Ascendante)
• L’analyse par décalage-réduction a pour but de construire un
arbre d’analyse pour une chaine source en commençant par
les feuilles et en remontant vers la racine.
• C’est un processus de « réduction » d’une chaine w vers
l’axiome de la grammaire.
• A chaque étape de réduction, une sous-chaine particulière
correspondant à la partie droite d’une production est
remplacée par le symbole de la partie gauche de cette
production.
• Si la sous-chaine est choisie correctement à chaque étape,
alors une dérivation droite est ainsi élaborée en sens inverse.

48
III.6. Analyse syntaxique par décalage
réduction
Considérons la grammaire avec les règles de production suivantes:
S  aABe
A  Abc | b
Bd

La phrase abbcde peut être réduite vers S par les étapes suivantes:

abbcde abbcde
aAbcde aAbcde
aAde aAde
aABe aABe
S S
Ces réductions élaborent en sens inverse la dérivation droite suivante:

S  aABe  aAde  aAbcde  abbcde


d d d d

49
III.6. Analyse syntaxique par décalage
réduction
Manches
Informellement, un « manche » d’une chaine est une sous-chaine qui correspond à la
partie droite d’une production et dont la réduction vers le non terminal de la
partie gauche de cette production représente une étape le long de la dérivation
droite inverse.

Formellement, un manche d’une proto-phrase droite  est une production


A  et une position dans  où la chaine  peut être trouvée et remplacée par A
pour produire la proto-phrase droite précédente dans une dérivation droite de .
C-a-d si
S *  A  *   
d d
Alors, A   dans la position qui suit  est un manche de   
On dit aussi que «  est un manche pour    »

50
III.6. Analyse syntaxique par décalage
réduction
Exemple
Considérons la grammaire suivante:
EE+E
EE*E
E  (E)
E  id

Une dérivation droite est :


E  E+E
E+E*E
 E + E * id3
 E + id2 * id3
 id1 + id2 * id3
Id1 est un manche de la proto-phrase droite id1+id2*id3 car id est la partie droite de la production
E  id et le remplacement de id1 par E produit la proto-phrase droite précédente E + id2 * id3.

51
III.6. Analyse syntaxique par décalage
réduction
La grammaire est ambiguë car il y a une autre dérivation droite pour la même chaine:
EE+E
EE*E
E  (E)
E  id

Une dérivation droite est :


E  E+E E  E*E
E+E*E  E * id3
 E + E * id3  E + E * id3
 E + id2 * id3  E + id2 * id3
 id1 + id2 * id3  id1 + id2 * id3
Id1 est un manche de la proto-phrase droite id1+id2*id3 car id est la partie droite de la
production E  id et le remplacement de id1 par E produit la proto-phrase droite
précédente E + id2 * id3.

52
III.6. Analyse syntaxique par décalage
réduction

Proto-phrase droite Manche Production de


réduction
id1 + id2 * id3 Id1 Eid
E + id2 * id3 id2 Eid
E + E * id3 id3 Eid
E+E*E E*E EE*E
E+E E+E E E+ E
E

53
III.6. Analyse syntaxique par décalage
réduction
Implantation à l’aide d’une pile de l’analyse par
décalage-réduction

Nous utilisons une pile pour conserver les


symboles grammaticaux et un tampon d’entrée
qui contient la chaine  à analyser.
Le symbole $ est utilisé pour marquer le fond de
la pile et l’extrémité droite du tampon d’entrée.

54
III.6. Analyse syntaxique par décalage
réduction

Id + id * id $ Tampon
Configuration
initiale
Tête de L/E
$
Pile

Id + id * id $ Tampon
Configuration
finale
S
Tête de L/E
$
Pile 55
III.6. Analyse syntaxique par décalage
réduction
PILE ENTREE SORTIE
$ Id1 + id2 * id3 $ Décaler
$id1 + id2 * id3 $ Réduire par Eid
$E + id2 * id3 $ Décaler
$E+ id2 * id3 $ Décaler
$E+ id2 * id3 $ Réduire par E  id
$E + E * Id3 $ Décaler
$E + E * id3 $ Décaler
$E + E * id3 $ Réduire par E  id
$E + E * E $ Réduire par E  E*E
$E + E $ Réduire par E  E+E
$E $ Accepter

56
III.6. Analyse syntaxique par décalage
réduction
Les opérations de base l’analyseur:
(1) décaler, (2) réduire, (3) accepter et (4) erreur.

1. Dans une action décaler, le prochain symbole du tampon d’entrée est


enlevé du tampon et placé en sommet de la pile.
2. Dans une action réduire, l’analyseur sait que l’extrémité de la partie
droite du manche est dans la pile et décide par quel non-terminal
remplacer le manche
3. Dans une action accepter, l’analyseur s’arrête et annonce la réussite
finale de l’analyse.
4. Dans une action erreur, l’analyseur découvre qu’une erreur de syntaxe
s‘est produite et appelle une routine de récupération sur erreur.

57
III.6. Analyse syntaxique par décalage
réduction
Algorithme par Décalage/Réduction
(Shift/Reduce)
(1) décaler, (2) réduire, (3) accepter et (4) erreur.

- Initialement, la pile contient $ et l’entrée contient $


- A chaque étape, l’analyseur décale un ou plusieurs
symboles (action décaler) jusqu’à ce qu’un manche
apparaît au sommet de la pile. Une action réduire est
alors réalisée en remplaçant le manche par la partie
gauche de la règle de production associée.
58
III.7. Analyseurs LR
C’est une méthode d’analyse syntaxique ascendante
qui peut être utilisée pour analyser une large classe
de grammaires non contextuelles.
Cette technique est appelée analyse LR(k); « L » signifie
le « parcours de l’entrée de gauche vers la droite »
(Left to right scanning of the input), « R » signifie «
en construisant une dérivation droite inverse »
(constructing a Rightmost derivation in reverse) et k
indique le nombre de symboles de prévision utilisés
pour prendre une décision d’analyse.
59
III.7. Analyseurs LR
Modèle d’un analyseur LR
a1 … ai … an $

Sm Programme Flot de Sortie

Xm d’analyse
Sm-1
LR
Xm-1
Action Successeur

S0

60
III.7. Analyseurs LR
Les tables d’analyse contiennent deux parties, une fonction
d’actions d’analyse Action et une fonction de transfert Successeur.
Le programme dirigeant l’analyseur LR se comporte de la façon
suivante. Il détermine sm, l’état en sommet de pile, et ai, le
symbole terminal d’entrée courant. Il consulte alors Action[sm, ai],
l’entrée de la table des actions pour l’état sm et le terminal ai qui
peut avoir l’une des quatre valeurs:

1. Décaler s où s est un état


2. Réduire par une production de la grammaire A
3. Accepter et
4. Erreur

61
III.7. Analyseurs LR
Une configuration d’un analyseur LR est un couple dont le premier
composant est le contenu de la pile et dont le second composant est
la chaine d’entrée restant à analyser:

(s0 X1 s1 X2 … Xm Sm, ai ai+1… an$)

Cette configuration représente la proto-phrase droite :

X1 X2 … Xm ai ai+1 … am

- Analogue à l’analyse par décalage/ Réduction; seule la présence


d’états en pile est nouvelle

62
III.7. Analyseurs LR
(s0 X1 s1 X2 … Xm Sm, ai ai+1… an$)

L’action suivante de l’analyseur est déterminée par la lecture de ai, le symbole


d’entrée courant, sm, l’état en sommet de pile, et la consultation de l’entrée
Action [sm, ai] de la table des actions d’analyse.
La configuration suivante après chacune des quatre types d’action, sont les
suivantes :
1. Si Action[sm, ai] = décaler s, l’analyseur exécute une action décaler atteignant la
configuration :
(s0 X1 s1 X2 … Xm Sm ai s, ai+1… an$)

Ici, l’analyseur a à la fois empilé le symbole d’entrée courant ai et le prochain


état s, qui est donné par Action[sm, ai]; ai+1 devient le symbole d’entrée courant.

63
III.7. Analyseurs LR
(s0 X1 s1 X2 … Xm Sm, ai ai+1… an$)

2. Si Action[sm, ai] = réduire par A  alors l’analyseur exécute une action réduire,
atteignant la configuration :

(s0 X1 s1 X2 s2 … Xm-r Sm-r A s, ai ai+1 … an$)

Où s = Successeur[sm-r , A] et r est la longueur de , partie droite de la production.


Ici l’analyseur commence par dépiler 2r symboles (r symboles d’états et r
symboles grammaticaux), exposant ainsi l’état sm-r au sommet.
L’analyseur empile alors à la fois A, partie gauche de la production et s, l’entrée
pour Successeur [sm-r, A]. Le symbole d’entrée n’a pas changé.
La séquence de symboles dépilés Xm-r+1 … Xm correspond toujours à 

64
III.7. Analyseurs LR
(s0 X1 s1 X2 … Xm Sm, ai ai+1… an$)

3. Si Action[sm, ai] = accepter, l’analyse est


terminée
4. Si Action[sm, ai] = erreur, l’analyseur a
découvert une erreur et appelle une
routine de récupération sur erreur .
65
III.7. Analyseurs LR
Exemple :
Soit la grammaire des expressions suivantes :
(1) EE+T
(2) ET
(3) TT*F
(4) TF
(5) F  (E)
(6) F  id

Le codage des actions est :


1. di signifie décaler et empiler l’état i,
2. rj signifie réduire par la production (j),
3. Acc signifie accepter et
4. Une entrée vide signifie erreur

66
III.7. Analyseurs LR
Etat Action Successeur
Table Id + * ( ) $ E T F
d’analyse
pour la 0 d5 d4 1 2 3
grammaire 1 d6 acc
des 2 r2 d7 r2 r2
expressions: 3 r4 r4 r4 r4
4 d5 d4 8 2 3
5 r6 r6 r6 r6
6 d5 d4 9 3
7 d5 d4 10
8 d6 d11
9 r1 d7 r1 r1
10 r3 r3 r3 r3
11 r5 r5 r5 r5

67
III.7. Analyseurs LR
Entrée : Table d’analyseur et le mot w
Initialiser le pointeur source ps sur le premier symbole de $; La pile contient s0
Répéter indéfiniment
Début Soit s l’état en sommet de pile et a le symbole pointé par ps;
si Action[s, a] = décaler s’ alors
début empiler a puis s’;
avancer ps sur le prochain symbole en entrée fin
sinon si Action[s, a] = réduire par A alors
début dépiler 2 x || symboles;
soit s’ le nouvel état sommet de pile;
empiler A puis Successeur [s’, A];
émettre en sortie une identification de la production
A
fin
sinon si Action [s, a] = accepter alors
retourner
sinon erreur()
68
Fin
PILE ENTREE ACTION
(1) 0 Id*id+id$ Décaler

III.7. Analyseurs
(3) 0 F 3
LR(2) 0 id 5
*id+id$
*id+id$ Réduire par Fid
Réduire par TF
Et Action Successeur
at (4) 0 T 2 *id+id$ Décaler
Id + * ( ) $ E T F (5) 0 T 2 * 7 id+id$ Décaler
0 d5 d4 1 2 3 (6) 0 T 2 *7 id 5 +id$ Réduire par Fid
1 d6 acc (7) 0 T 2 * 7 F 10 +id$ Réduire par
2 r2 d7 r2 r2 TT*F
3 r4 r4 r4 r4 (8) 0 T 2 +id$ Réduire par ET
4 d5 d4 8 2 3 (9) 0 E 1 +id$ Décaler
5 r6 r6 r6 r6 (10) 0 E 1 + 6 id$ Décaler
6 d5 d4 9 3 (11) 0 E 1 + 6 id 5 $ Réduire par Fid
7 d5 d4 10 (12) 0 E 1 + 6 F 3 $ Réduire par TF
8 d6 d11
(13) 0 E 1 + 6 T 9 $ Réduire par E
9 r1 d7 r1 r1 E+T
10 r3 r3 r3 r3 (14) 0 E 1 $ Accepter
11 r5 r5 r5 r5

69
III.7. Analyseurs LR
Construction de la table d’analyse SLR(1):
Pour la construction des Tables d’analyse LR à partir d’une grammaire, nous
distinguons trois méthodes qui diffèrent par leur puissance et leur facilité
d’implantation. La première est appelée « Simple LR » ou SLR. Elle est la plus
simple à implanter mais la moins puissante en terme de nombre de grammaires
pour lesquelles elle réussit.

Une grammaire pour laquelle il est possible de construire une table d’analyse SLR
est une grammaire SLR.

Les deux autres méthodes augmentent la méthode SLR avec une information de
prévision.

70
III.7. Analyseurs LR
Construction de la table d’analyse SLR(1):
Définition : préfixe variable est tout préfixe d’une forme grammaticale pouvant
apparaître sur la pile d’un analyseur décalage/réduction. Un préfixe variable ne
dépasse jamais un manche.
Définition : un item est une règle de production avec un point repérant une
position de la partie droite.
A  x . Yz
Ce qu’on a déjà Ce qu’on espère voir
Rencontré
La production A  XYZ X, Y, Z  (VT) fournit les 4 items:
A  . XYZ
A  X . YZ
A  XY . Z
A  XYZ .
La production A   fournit uniquement l’item A  . 71
III.7. Analyseurs LR
item

- Un item peut être codé par un couple d’entiers, le premier donnant le numéro de
la production et le second, la position du point.
- Un item indique la « quantité » de partie droite qui a été reconnue, à un moment
donné au cours du processus d’analyse.

L’item A  . XYZ indique qu’on espère voir en entrée une chaine dérivable
depuis XYZ.
L’item suivant A  X . YZ indique que nous venons de voir en entrée une chaine
dérivée de X et que nous espérons maintenant voir une chaine dérivée de YZ.

- L’idée de la méthode SLR est de construire tout d’abord, à partir de la grammaire,


un automate fini déterministe pour reconnaître les préfixes variables. Les items
sont regroupés en ensembles qui constituent les états de l’analyseur LR.

72
III.7. Analyseurs LR
On espère atteindre un mot du langage c-a-d on espère reconnaître un mot dérivé
à partir de S

S’  S
S’  .S
S’  S.

La technique SLR se base sur la construction d’un automate permettant la


reconnaissance des préfixes variables.
Les items sont regroupés en des ensembles qui constituent les états de l’analyseur
SLR.
Une collection d’ensembles d’items LR(0), que nous appelons collection LR(0)
canonique, fournit la base de la construction des analyseurs SLR.
Pour construire la collection LR(0), nous définissons une grammaire augmentée et
deux fonctions, Fermeture et Transition.

73
III.7. Analyseurs LR
L’opération Fermeture
-Si I est un ensemble d’items pour une grammaire G, Fermeture (I) est l’ensemble
d’items construit à partir de I par les deux règles:
1. Initialement, placer chaque item de I dans Fermeture(I)
2. Si A  .B est dans Fermeture(I) et B   est une production, ajouter l’item
B  . à Fermeture(I), s’il ne s’y trouve pas déjà. Nous appliquons cette règle
jusqu’à ce qu’aucun nouvel item ne puisse plus être ajouté à Fermeture(I).

Exemple Si I est l’ensemble formé par l’unique item {[E’ .E]},


alors Fermeture(I) contient les items:
E’  E E’  .E (par r1) ici = et = , B = E,  = E+T
EE+T|T E  .E+T E  .T (par r2)
TT*F|F T  .T*F T  .F (par r2)
F  (E) | id F  .(E) F  .id (par r2)
74
III.7. Analyseurs LR
L’opération Fermeture
Fonction Fermeture(I)
Début
J := I;
répéter
pour chaque item A .B de J et chaque production
B   de G telle que B  . n’est pas dans J faire
ajouter B  . à J
Jusqu’à ce qu’aucun autre item ne puisse être ajouté à J;
Retourner J
Fin

75
III.7. Analyseurs LR
L’opération Transition
Transition(I, X) où I est un ensemble d’items et X est un symbole de la grammaire.
Transition(I, X) est définie comme la fermeture de l’ensemble de tous les items
[A X.] tels que [A .X] appartienne à I.
Intuitivement, si I est l’ensemble des items qui sont valides par un préfixe variable
donné , alors Transition(I, X) est l’ensemble des items qui sont valides pour le
préfixe variable X.

Exemple :
Si I est l’ensemble des deux items {[E’  E.], E E.+T]}, alors Transition(I, +)
consiste en :
E E+.T Nous calculons Transition(I, +) en cherchant dans I les items
T .T*F ayant + immédiatement à droite du point. E’ E. ne convient
T .F pas mais E E.+T répond au critère. Nous franchissons le +
F .(E) afin d’obtenir {E E+.T} puis nous calculons fermeture de cet
F .id ensemble.
76
III.7. Analyseurs LR
Construction des ensemble d’items
La collection canonique d’ensemble d’items LR(0) pour une grammaire augmentée
G’ est calculée par la procédure suivante: (1) EE+T
(2) ET
Procedure Items(G’) (3) TT*F
Début (4) TF
C:= {Fermeture({[S’ .S]})} (5) F  (E)
(6) F  id
répéter
pour chaque ensemble d’items I de C et pour chaque symbole de la
grammaire X tel que Transition(I, X) soit non vide et non encore dans C
faire
ajouter Transition (I, X) à C
Jusqu’à ce qu’aucun nouvel ensemble d’items ne puisse plus être ajouté
àC
Fin

77
III.7. Analyseurs LR
Construction des ensemble d’items
La collection canonique d’ensemble d’items LR(0) pour une grammaire augmentée
G’ est calculée par la procédure suivante:

Procedure Items(G’)
Début
C:= {Fermeture({[S’ .S]})}
répéter
pour chaque ensemble d’items I de C et pour chaque symbole de la
grammaire X tel que Transition(I, X) soit non vide et non encore dans C
faire
ajouter Transition (I, X) à C
Jusqu’à ce qu’aucun nouvel ensemble d’items ne puisse plus être ajouté
àC
Fin

78
III.7. Analyseurs LR
Exemple (1) EE+T
E’  E (2) ET
EE+T|T (3) TT*F
TT*F|F (4) TF
F  (E) | id (5) F  (E)
(6) F  id
La collection canonique d’ensembles d’items LR(0) pour cette grammaire est:
I0: E’ .E I3: T F. I6: E E+.T I9: E E+T.
E  .E + T T .T*F T T.*F
E  .T I4: F (.E) T .F I10: T T*F.
T  .T * F E .E+T F .(E) I11: F (E).
T  .F E .T F .id
F  .(E) T .T*F I7: T  T*.F
F  .id T .F F .(E)
I1: E’ E. F .(E) F .id
E  E. + T F .id I8: F (E.)
I2: E  T. E E.+T
T  T.*F I5: F id. 79
III.7. Analyseurs LR
E + T * Vers I7
I0 I1 I6 I9
F
( Vers I3
id Vers I4
Vers I5
T *
F
I2 I7 I10
(
F Vers I4
I3 id
Vers I5
(
( E )
I4 I8 I11

id +
T Vers I6
F Vers I2
id
I5 Vers I3
80
(2) ET
(3) TT*F
III.7. Analyseurs LR (4)
(5)
TF
F  (E)
Algorithme de construction de la table d’analyse SLR (6) F  id
Entrée: Une grammaire augmentée G’
Sortie: les tables d’analyse SLR des fonctions Action et Successeur pour G’.
1) Construire C = {I0, I1, …, In}, la collection des ensembles d’items LR(0) pour G’.
2) L’état i est construit à partir de Ii. Les actions d’analyse pour l’état i sont
déterminées comme suit:
a) Si [A  .a] est dans Ii et Transition(Ii, a) = Ij, remplir Action[i, a] avec
« décaler j ». Ici a doit être un terminal
b) Si [A  .] est dans Ii, remplir Action[i, a] avec « réduire par A   »
pour tous les a dans Suivant(A); ici A ne doit pas être S’.
c) Si [S’  S.] est dans Ii, remplir Action[i, $] avec « accepter ».
Si les règles précédentes engendrent des actions conflictuelles, nous disons
que la grammaire n’est pas SLR(1). Dans ce cas, l’algorithme ne produit
pas l’analyseur.
3) On construit les transitions Successeur pour l’état i pour tout non terminal A
en utilisant la règle: Si Transition(Ii, A) = Ij, alors Successeur[i, A] = j
4) Toutes les entrées non définies par les règles (2) et (3) sont positionnées à
« erreur » T  T * F | F 81
III.7. Analyseurs LR
Exemple:
Construisons les tables SLR pour la grammaire des expressions.
Considérons tout d’abord l’ensemble d’items I0 de la collection canonique de
l’ensemble des items LR(0):
E’ .E
E  .E + T E  .T
T  .T * F T  .F
F  .(E) F  .id
L’item F  .(E) produit l’entrée Action[0, (]= décaler 4 et l’item F  .id l’entrée
Action[0, id] = décaler 5. Les autres items de I0 ne produisent aucune action.
Considérons maintenant I1
E’  E.
E  E.+T
Le premier item produit Action[1, $] = accepter, le second item produit
Action[1, +] = décaler 6.

82
III.7. Analyseurs LR
Exemple:
Considérons ensuite I2
E  T.
T  T.*F
Comme SUIVANT(E) = {$, +, )},
le premier item produit Action[2, $] = Action[2, +]= Action[2, )]= réduire par ET
Le second item produit Action[2, *] = décaler 7. En continuant ainsi, nous
obtenons les tables Action et Successeur présentées précédemment. L’ordre des
numéros de production dans les actions réduire est le même que l’ordre
d’apparition de ces productions dans la grammaire initiale. C-a-d E  E+T est
numéroté 1, E  T est numéroté 2 et ainsi de suite.

83
III.7. Analyseurs LR
Grammaire LR
C’est toute grammaire pour laquelle on peut construire les tables d’analyse LR.
Considérons ensuite I2
E  T.
T  T.*F
Comme SUIVANT(E) = {$, +, )},
le premier item produit Action[2, $] = Action[2, +]= Action[2, )]= réduire par ET
Le second item produit Action[2, *] = décaler 7. En continuant ainsi, nous
obtenons les tables Action et Successeur présentées précédemment. L’ordre des
numéros de production dans les actions réduire est le même que l’ordre
d’apparition de ces productions dans la grammaire initiale. C-a-d E  E+T est
numéroté 1, E  T est numéroté 2 et ainsi de suite.

84
III.7. Analyseurs LR
Exemple de grammaire non SLR(1)
Toute grammaire SLR(1) est non ambiguë, mais beaucoup de grammaires non
ambigües ne sont pas SLR(1). Considérons la grammaire avec les productions
suivantes:
SG=D
SD
G  *D
G  id
DG
G et D représentent respectivement une valeur-g et une valeur-d et *un opérateur
signifiant « contenu de ». La collection canonique des ensembles d’items
LR(0) est la suivante:
I0: S’  .S I1: S’  S. I4: G  *.D I6: S  G = .D
S  .G = D D  .G D  .G I9: S  G=D.
S  .D I2: S  G.=D G .*D G  .*D
G  .*D D  G. G  .id G  .id
G  .id I7: G  *D.
D  .G I3: S  D. I5: G  id. I8: D  G. 85
III.7. Analyseurs LR
Considérons l’ensemble d’items I2. Le premier item de cet ensemble positionne
Action[2, =] à « décaler 6 ». Comme SUIVANT(D) contient =
(S  G=D *D=D), le second item positionne Action [2, =] à « réduire par
D  G ». Par conséquent, l’entrée Action[2, =] est définie de façon multiple.
Comme il y a à la fois une action décaler et une action réduire dans Action[2,
=], l’état 2 présente un conflit décaler/réduire sur le symbole d’entrée =.
La grammaire n’est pas ambiguë. Ce conflit décaler/réduire provient du fait
que la méthode de construction de l’analyseur SLR n’est pas suffisamment
puissante pour se rappeler assez de contexte gauche pour décider de
l’action que doit effectuer l’analyseur sur l’ensemble = après avoir vu une
chaine réductible vers G. La méthode canonique et la méthode LALR,
réussissent leur construction sur une collection plus importante de
grammaires, incluant la grammaire précédente.
Il existe des grammaires non ambigües pour lesquelles une méthode de
construction d’analyseur LR produit des tables d’analyse présentant des
conflits. De telles grammaires peuvent être évitées pour les langages de
programmation.
86
III.7. Analyseurs LR
Exercice:
Construire la table d’analyse SLR(1) pour la grammaire avec les règles de
production suivantes:
E  E div E E  E sup E E  (E) E  id
I0 = f(E’ .E) = {E’ .E, E .E div E, E .E sup E, E .(E), E  .id}
I1 = tr(I0, E) = {E’ E., E E. div E, E E. sup E}
I2 = tr(I0, () = {E (.E)}, E .E div E, E .E sup E, E .(E), E  .id}
I3 = tr(I0, id) = {E  id.}
I4 = tr(I1, div) = {E E div. E, E .E div E, E .E sup E, E .(E), E  .id}
I5 = tr(I1, sup) = {E E sup. E, E .E div E, E .E sup E, E .(E), E  .id}
I6 = tr(I2, E) = {E (E.), E E. div E, E E. sup E}
tr(I2, ()= f(E (.E)) = I2 tr(I2, id) = I3 tr(I4, E) = {E E. div E, E E. sup E} = I7
Tr(I4, id) = I3 Tr(I4, () = f(E (.E)) = I2
Tr(I5, E) = {E  E sup E., E  E. div E, E  E. sup E} = I8
Tr(I5, () = f(E (.E)) = I2 tr(I5, id) = I3
Tr(I6, )) = {E (E).} = I9 Tr(I6, div) = f(E  E div. E) = I4
Tr(I6, sup) = f(E  E sup. E) = I5 Tr(I7, div) = f(E  E div. E) = I4
87
Tr(I7, sup) = I5 Tr(I8, sup) = I4 Tr(I8, div) = I5
III.7. Analyseurs LR
Table Etat Action Successeur
d’analyse Id div sup ( ) $ E
SLR(1)
0 d3 d2 1
1 d4 d5 acc
2 d3 d2 6
3
4 d7 d2 7
5 d3 d2 8
6 d4 d5 d9
7
8

88
III.7. Analyseurs LR
Exercice:
Construire la table d’analyse SLR(1) pour la grammaire avec les règles de
production suivantes:
(1) S  L = R (2) S  R (3) L  *R (4)L  id (5)R  L
I0 = f(S’ .S) = {S’ .S, S .L=R, S .R, L .*R, L  .id, R  .L}
I1 = tr(I0, S) = {S’ S.} I2 = tr(I0, L) = {S L.=R, R L.}
I3 = tr(I0, R) = {S R.} I4 = tr(I0, id) = {L id.}
I5 = tr(I0, *) = {L *.R, R .L, L .*R, L  .id}
tr(I0, =) =  tr(I1, X) =  = tr(I3, X) = tr(I4, X)
tr(I2, =)= f(S L=.R) = {S L=.R, R .L, L .*R, L .id) = I6
tr(I5, R) = {L *R.} = I7 tr(I5, L) = {R L.} = I8
tr(I5, id) = {L  id.} = I4 tr(I5, *) = {L  *.R, R .L, L .*R, L .id} = I5
tr(I5, S) = tr(I5, =) =  tr(I6, R) = {S L = R.} = I9
tr(I6, L) = R  L.} = I8 tr(I6, *) = f(L  *.R) = I5 Tr(I6, id) = I4
Tr(I6, =) = tr(I6, S) =  tr(I7, X) = tr(I9, X) = 
SUIVANT(S) = {$}
SUIVANT(R) = SUIVANT(L) = {=, $}
89
III.7. Analyseurs LR
S
I0 I1

L = R
I2 I6 I9

id
R
I3 L

*
id
I4
I9
id
* I8
R
* L
I5
90
III.7. Analyseurs LR
Etat Action Successeur
G n’est pas = * id $ S L R
SLR(1) car la
0 d5 d4 1 2 3
table n’est pas
déterministe. 1 acc
2 d6 RL
RL
3 SR
4 Lid Lid
5 d5 d4 8 7
6 d5 d4 8 9
7 L*R L*R
8 RL RL
9 SL=R

91

Vous aimerez peut-être aussi