0% ont trouvé ce document utile (0 vote)
18 vues148 pages

Analyse Syntaxique

L'analyse syntaxique a pour rôle de vérifier si une séquence d'unités lexicales est générée par la grammaire d'un langage, en utilisant des méthodes d'analyse descendante et ascendante. L'analyse descendante, notamment par la méthode prédictive, construit un arbre de dérivation à partir de l'axiome de la grammaire, en utilisant des techniques comme l'élimination de la récursivité à gauche et de l'ambiguïté. La construction d'une table d'analyse syntaxique repose sur les ensembles PREMIER et SUIVANT, permettant de déterminer les règles de production à appliquer lors de l'analyse d'une chaîne.

Transféré par

rouaaessid2002
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
18 vues148 pages

Analyse Syntaxique

L'analyse syntaxique a pour rôle de vérifier si une séquence d'unités lexicales est générée par la grammaire d'un langage, en utilisant des méthodes d'analyse descendante et ascendante. L'analyse descendante, notamment par la méthode prédictive, construit un arbre de dérivation à partir de l'axiome de la grammaire, en utilisant des techniques comme l'élimination de la récursivité à gauche et de l'ambiguïté. La construction d'une table d'analyse syntaxique repose sur les ensembles PREMIER et SUIVANT, permettant de déterminer les règles de production à appliquer lors de l'analyse d'une chaîne.

Transféré par

rouaaessid2002
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
Vous êtes sur la page 1/ 148

Analyse Syntaxique

Chapitre 6
1. Rôle d’un analyseur syntaxique

Le rôle principal de l’analyse syntaxique est de vérifier si la


séquence d’unité lexicale retourné par l’analyseur lexical est
générée par la grammaire du langage.

Il existe plusieurs méthodes d’analyse appartenant à l’une des


deux catégories qui sont l’analyse descendante et l’analyse
ascendante.
Dans l’analyse descendante nous essayons de dériver à partir de
l’axiome de la grammaire le programme source.
D’une façon opposée, l’analyse ascendante établit des réductions
sur les chaînes à analyser pour aboutir à l’axiome de la
grammaire
2. Analyse descendante

a- Principe de l’Analyse descendante (méthode :Analyse


prédictive)
Le principe de l’analyse hiérarchique descendante d’un mot
consiste à construire l’arbre de dérivation du haut (l’axiome) vers
le bas (les unités lexicales).
A titre d’exemple, soit la grammaire G ayant S pour axiome et
pour règles de production, l’ensemble P = {S → aSbT |cT |d, T →
aT |bS|c} et le mot w = accbbadbc qu’on cherche à vérifier la
possibilité de sa génération par la grammaire G. Pour le faire, on
réalise la lecture successive des lettres du mot w tout en avançant
la construction descendante de l’arbre.
2. Analyse descendante
Avec cet exemple, c’est très facile de trouver l’arbre de dérivation
du mot w parce-que chaque règle commence par un terminal
différent, donc on sait immédiatement laquelle prendre.
Il est très fréquent de se trouver devant la situation où en lisant
un terminal, on ne sait pas quelle règle il faut prendre, vu
l’existence de plusieurs (au moins deux) règles qui commencent
par ce terminal. Pour le savoir, il faut lire aussi la lettre suivante,
ou bien, il faut se donner la possibilité de faire des retour en
arrière (backtracking).
Dans d’autres situations plus compliquées, pour savoir quelle
règle utiliser, il faut cette fois connaître aussi la dernière lettre du
mot, ce qui complique énormément le problème.
Analyse syntaxique prédictive non récursive

C’est une technique d’analyse descendante basée sur la construction de


l’arbre de dérivation à partir de ses sous-arbres en utilisant une pile.
▶ 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 pointe sur le premier symbole.
La racine de l’arbre
▶ A la fin de l’analyse, la pile contient le symbole $ et la tête de Lecture
pointe sur le symbole $ de fin de la chaı̂ ne d’entrée.
L’arbre est construit.
La grammaire doit être non récursive à gauche et non ambiguë.
▶ Élimination de la récursivité à gauche et de l’ambiguı̈ té si elles
existent.
L’évolution de l’analyse s’effectue en consultant une table d’analyse.
▶ Construite conformément à la grammaire du langage.
Élimination de la récursivité à gauche
Grammaire récursive à gauche
Une grammaire est dite récursive à gauche si elle admet une règle de
la forme : A → Aα
Transformation de cette grammaire en une équivalente non récursive
à gauche
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′ |β2 A′ | . . . |βm A′
A′ → α1 A′ |α2 A′ | . . . |αn A′ |ε
Élimination de la récursivité à gauche

Exemple
La grammaire dont les règles de production sont les suivantes est
récursive à gauche
Exp → Exp op Exp|(Exp)|id|nb

Elle est transformée en une grammaire équivalente non récursive


à gauche avec les règles suivantes :

Exp → (Exp) E′ |id E′ |nb E′


E′ → op Exp E′ |ε
Élimination de l’ambiguı̈ té

Grammaire ambiguë
Admet des règles de la forme : A → αβ1 |αβ2

Transformation d’une grammaire ambiguë en une non ambiguë


Une grammaire ambiguë avec les règles de production :

A → αβ1 |αβ2 | . . . |αβm |α1 |α2 | . . . |αn


Est transformée en une grammaire non ambiguë :

A → αA′ |α1 |α2 | . . . |αn


A′ → β1 |β2 | . . . |βm
Élimination de l’ambiguı̈ té

Exemple

La grammaire suivante est ambiguë


I → If (Expression) Then I|If (Expression) Then I else I
Elle est transformée en une grammaire non ambiguë :

I → If (Expression) Then I S
S → ε|else I
2. Analyse descendante

Conclusion: ce qui serait pratique, ça serait d'avoir une table


qui nous dit: quand je lis tel caractère et que j'en suis a dériver
tel symbole non-terminal, alors j'applique telle règle et je ne
me pose pas de questions. Heureusement ça existe, et ça
s'appelle une table d'analyse .

Pour construire une table d'analyse, on a besoin des


ensembles PREMIER et SUIVANT.
Calcul des premiers et suivants
Premier :
Pour toute chaı̂ ne composée de symboles terminaux et non-
terminaux, on cherche PREMIER(α) : l’ensemble de tous les
terminaux qui peuvent commencer une chaı̂ ne qui se dérive de α.
On cherche alors tous les terminaux a tel qu’il existe une
dérivation α ⇒* aβ (β étant une chaı̂ ne quelconque composée de
symboles terminaux et non-terminaux)

Suivant :
Pour tout non-terminal A, on cherche SUIVANT(A) : l’ensemble de
tous les symboles terminaux a qui peuvent apparaître
immédiatement à droite de A dans une dérivation : S→ αAaβ
Calcul des premiers et suivants
Calcul des premiers
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 Y1 ne dérive pas en ε,
on n’ajoute rien de plus à PREMIER(X), mais si Y1 ⇒ *ε, on ajoute
PREMIER(Y2 ), etc.
2. Analyse descendante
Algorithme de construction des ensembles PREMIER :
Exemple

S → AB | Da
A → aAb | ε
B → bB | ε
D → dD | e

ε-production { A, B, S}
Premier (S) = ? { a,b,d,e}
Premier (A) = ? {a,ε}
Premier (B) = ? {b,ε}
Premier (D) = ? {d,e}
Exemple suite

Premier (S) = Premier (A) ∪ Premier (B) ∪ Premier (D)


Premier (A) = {a, ε}
Premier (B) = {b, ε}
Premier (D) = {d, e} Premier (aAb) = {a}
D’où Premier (bB) = {b}
Premier (S) = {a, b, d, e} Premier (dD) = {d}
Premier (A) = {a, ε} Premier (e) = {e}
Premier (B) = {b, ε} Premier (ε) = ∅
Premier (D) = {d, e}
2. Analyse descendante

Exemple

E →TE’
E’→+TE’|-TE’|ε
T →FT’
T’→*FT’|/FT’|ε
PREMIER(E) = PREMIER(T )= PREMIER(F) = {(,nb}
F →(E)|nb PREMIER(E’) = {+,-,ε}
PREMIER(T) = PREMIER(F ) = {(,nb}
PREMIER(T’) = {*,/,ε}
PREMIER(F) = {(, nb}
2. Analyse descendante

Autre Exemple
2. Analyse descendante

Calcul de l’ensemble Suivant :

Pour tout non-terminal A, on cherche l’ensemble


SUIVANT(A), qui est l’ensemble de tous les terminaux a qui
peuvent apparaître juste après (à droite de) A dans une
dérivation S →* αAaβ, avec α et β sont deux chaînes
quelconques composées de symboles terminaux et non-
terminaux.

Pour l’ensemble des symboles non-terminaux, l’algorithme


permettant de définir les ensembles SUIVANT est le suivant :
2. Analyse descendante
2. Analyse descendante

Exemple Soit la grammaire G :


S → aSb| cd |SAe
A → aAdB | ε
B → bb

SUIVANT(S) = ? {$, b, a,e}


SUIVANT(A) = ? {d,e}
SUIVANT(B) = ? Suivant(A) = {d,e}
2. Analyse descendante

Exemple Soit la grammaire G :


S → aSb| cd |SAe
A → aAdB | ε
B → bb

SUIVANT(S) = SUIVANT(S) U PREMIER(A) { $,b,a,e} (e, car on a


la règle A→ ε)
SUIVANT(A) = {d,e}
SUIVANT(B) = SUIVANT(A) = {d,e} (Règle : A→ aAdB)
2. Analyse descendante

Autre Exemple Soit la grammaire G :


E → TE’
E’ → +TE’|-TE’|ε
T → FT’
T’ →*FT’|/FT’|ε
F → (E)|nb

SUIVANT(E) = {$,)}
SUIVANT(E’) = SUIVANT(E) = {$,)}
SUIVANT(T) = PREMIER(E’) U SUIVANT(E)
(cas E’ = ε) = {+,-, $,)}
SUIVANT(T’) = SUIVANT(T) = {+,-, $,)}
SUIVANT(F) = PREMIER(T’) U SUIVANT(T) (cas T’ =ε) = {*,/,+,-,$,)}
2. Analyse descendante

c. Construction de la table d’analyse syntaxique

Une table d'analyse est un tableau M à deux dimensions qui


indique pour chaque symbole non-terminal A et chaque
symbole terminal a ou symbole $ la règle de production a
appliquer. Ceci revient à appliquer l’algorithme suivant :
1 Pour chaque production A → α faire :
- pour tout a ∈ PREMIER(α) (avec, α ≠ ε), rajouter la
production A → α dans la case M [A, a] ;
- si ε ∈ PREMIER(α) , alors pour chaque b ∈
SUIVANT(A)
ajouter A → α dans M [A, b].
2 - chaque case M [A, a] vide est une erreur syntaxique.
2. Analyse descendante
Exemple :

Soit la grammaire G ayant E pour axiome et pour règles de


productions l’ensemble :

E → TE’
E’→ +TE’ | −TE’| ε
T → FT’
T’→ ∗FT’ | /FT’| ε
F → (E) | nb
La construction de la table d’analyse du grammaire G revient à
l’application des 3 étapes suivantes :
2. Analyse descendante


1. Calcul du PREMIER
PREMIER(E) = {(,nb}
PREMIER(E’) = {+,-,ε}
PREMIER(T) = {(,nb}
PREMIER(T’) = {*,/,ε}
PREMIER(F) = {(, nb}

2. Calcul du SUIVANT
SUIVANT(E) = {$,)}
SUIVANT(E’) = {$,)}
SUIVANT(T) = {+,-, $,)}
SUIVANT(T’) = {+,-, $,)}
SUIVANT(F) = {*,/,+,-,$,)}
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E
E’
T
T’
F
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’
E’
T
T’
F
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’ E→TE’
E’
T
T’
F
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’ E→TE’
E’ E’→+TE E’→-TE
T
T’
F
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’ E→TE’
E’ E’→+TE E’→-TE E’→ε E’→ε
T
T’
F
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’ E→TE’
E’ E’→+TE E’→-TE E’→ε E’→ε
T T→FT’ T→FT’
T’
F
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’ E→TE’
E’ E’→+TE E’→-TE E’→ε E’→ε
T T→FT’ T→FT’
T’ T’→*FT’ T’→/FT’
F
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’ E→TE’
E’ E’→+TE E’→-TE E’→ε E’→ε
T T→FT’ T→FT’
T’ T’→ε T’→ε T’→*FT’ T→/FT’ T’→ε T’→ε
F
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’ E→TE’
E’ E’→+TE E’→-TE E’→ε E’→ε
T T→FT’ T→FT’
T’ T’→ε T’→ε T’→*FT’ T→/FT’ T’→ε T’→ε
F F→nb
2. Analyse descendante
3. Construction de la table d’analyse

nb + - * / ( ) $
E E→TE’ E→TE’
E’ E’→+TE E’→-TE E’→ε E’→ε
T T→FT’ T→FT’
T’ T’→ε T’→ε T’→*FT’ T→/FT’ T’→ε T’→ε
F F→nb F→(E)
2. Analyse descendante

Analyse Syntaxique

Nous allons voir maintenant, comment utiliser la table


d’analyse et plus particulièrement le tableau M , relative à
une grammaire G, pour décider si un mot m peut être
généré par la grammaire G. Pour ce faire, on a besoin
d’une pile pour empiler les symboles. En fait, ayant une
pile contenant initialement les symboles $ et S (en
sommet de pile) et un pointeur ps sur la première lettre de
m, l’analyse syntaxique revient à l’application de la boucle
répéter suivante :
Ainsi, le mot m = id + id ∗id peut être généré par la grammaire G,
puisque l’analyse syntaxique a réussie. Ceci correspond à la génération
descendante de l’arbre suivant :
Récupération sur erreur
Quand on distingue une erreur ?
Une erreur provient dans une analyse syntaxique prédictive non
récursive lorsque :
1- nous avons un symbole non terminal A en sommet de pile et un
symbole a en entrée et M[A, a] = ∅
2 - le symbole terminal sommet est différent du symbole en entrée.
Récupération sur erreur
Une erreur peut être récupérée :
1 - en mode panique : l’analyseur saute les symboles en entrée
jusqu’à ce qu’apparaisse une unité lexicale appartenant à un
ensemble sélectionné d’unités lexicales de synchronisation
2 - au niveau du syntagme : l’analyseur exécute des routines
d’erreurs qui remplacent, insèrent ou suppriment des symboles
d’entrée et émettre des messages d’erreur.
Récupération sur erreur en mode panique

1 Nous avons un symbole non terminal A en sommet de pile et un


symbole a en entrée et M[A, a] = ∅ :

a - On est au début de l’analyse alors sauter jusqu’à premier(A) dans


l’espoir de continuer avec A
b - On n’est pas au début de l’analyse alors sauter jusqu’à suivant(A)
et dépiler A dans l’espoir de continuer avec les suivants de A

2 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


Grammaires LL(1)

Si la table prédictive est multi définie c à d que si une case


occupée par plus d’une règle on dit que la grammaire n’est pas
LL(1) Left-to-right scanning, Leftmost derivation, use 1 symbol
lookahead

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)
le 1 signifie qu’on utilise un seul symbole de prévision.
Exemple

soit p= { S→ aAb , A→ cd |c }

Nous avons Premier (S)= {a} , Premier (A)= {c} , Suivant (S)= {$} ,
Suivant (A)= {b} , ce qui donne la table d’analyse :

Cette grammaire
n’est pas LL(1)
Il y a deux réductions pour la case M[A, c], donc ce n’est
pas une grammaire LL(1) On ne peut pas utiliser cette
méthode d‘analyse, pour pouvoir choisir entre la
production A →cd et la production A →c, il faut lire la lettre
qui suit celle que l’on pointe (donc deux symboles de
prévision sont nécessaires).
Grammaires LL(1)

Conditions nécessaires pour q’une Grammaire Soit LL(1) :

Théorème :
Une grammaire ambiguë ou récursive à gauche n‘est pas
LL(1)
Définition d’une grammaire LL(1)

Une grammaire est dite LL(1) si et seulement si elle vérifie


les conditions suivantes :
Pour toutes paire de règles de production A→α|β

Premier(α) ∩ Premier(β) = ∅

α→*ε ou bien β→*ε mais pas les deux.

Si α→*ε alors Premier(β)∩ Suivant(A) = ∅
3. Limites de l’analyse descendante

Cela dit certaines grammaires ne pourront pas s’analyser de


manière descendante quel que soit le nombre d’unités
lexicales lues en avance.
4. Approche ascendante pour l’analyse syntaxique

Principe

Construire l’arbre de dérivation en démarrant des unités
lexicales (feuilles) d’une chaîne jusqu’à arriver à la racine
(axiome de départ)

Des réductions successives jusqu’à retrouver l’axiome de
départ de la grammaire.

On procède à la réduction des symboles on allant de
gauche à droite.

Parfois plusieurs règles peuvent être utilisées pour réduire
une suite de symboles.
Réduction

Une réduction est une dérivation prise dans le sens inverse :



On remplace une séquence de terminaux et/ou non-
terminaux par un non-terminal.

La séquence doit être reconnue par la partie droite d’une
production.
Exemple

m = abbaab On va commencer par les


S→AB|SAB feuilles et essayer de remonter
A→a|aab jusqu’à trouver l’axiome de
départ
B→b|bba
Exemple

m = abbaab On va commencer par les


S→AB|SAB feuilles et essayer de remonter
A→a|aab jusqu’à trouver l’axiome de
départ
B→b|bba
Exemple

m = abbaab On va commencer par les


S→AB|SAB feuilles et essayer de remonter
A→a|aab jusqu’à trouver l’axiome de
On réduit départ
B→b|bba aàA
Exemple

m = abbaab On va commencer par les


S→AB|SAB feuilles et essayer de remonter
A→a|aab jusqu’à trouver l’axiome de
On réduit départ
B→b|bba bba à B
Exemple

On a réussi à retrouver la racine après une série de


réductions. Donc l’expression ‘’abbaab’’ est reconnue par la
grammaire.
Analyse par décalage-réduction
Manche
Informellement, un manche d’une chaı̂ ne est une sous-chaı̂ ne 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 chaı̂ ne β peut être
trouvée et remplacée par A pour produire la proto-phrase droite
précédente dans une dérivation droite de γ. Autrement :
Si S ⇒d α A ω ⇒d αβω
Alors, A → β dans la position qui suit α est un manche de αβω
On dit aussi que β est un manche pour αβω
Analyse par décalage-réduction
Illustration d’un Manche
Considérons la grammaire suivante :
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.

La séquence de réductions réduit id1 + id2 * id3 vers l’axiome E
Analyse ascendante par décalage-réduction
Les opérations de base de 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.
Analyse ascendante par décalage-réduction
Implantation de l’analyse à l’aide d’une pile
Nous utilisons une pile pour conserver les symboles grammaticaux
et un tampon d’entrée qui contient la chaı̂ ne β à analyse.
Le symbole $ est utilisé pour marquer le fond de la pile et
l’extrémité droite du tampon d’entrée.
Algorithme par Décalage/Réduction (Shift/Reduce)
1 - Initialement, la pile contient $ et l’entrée contient ω$
2 - 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.
3 - 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.
Analyse ascendante par décalage-réduction

Exemple : on utilisant une pile, vérifier que la séquence aabbac est
valide par rapport à la grammaire
S→aaSSac| b
Pile Entrée Action
$ aabbac$
Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
$a abbac$ Décalage
Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
$a abbac$ Décalage
$aa bbac$ Décalage
Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
$a abbac$ Décalage
$aa bbac$ Décalage

$aab bac$ Réduction S→b


Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
$a abbac$ Décalage
$aa bbac$ Décalage

$aab bac$ Réduction S→b

$aaS bac$ Décalage


Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
$a abbac$ Décalage
$aa bbac$ Décalage

$aab bac$ Réduction S→b

$aaS bac$ Décalage


$aaSb ac$ Réduction S→b
Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
$a abbac$ Décalage
$aa bbac$ Décalage

$aab bac$ Réduction S→b

$aaS bac$ Décalage


$aaSb ac$ Réduction S→b

$aaSS ac$ Décalage


Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
$a abbac$ Décalage
$aa bbac$ Décalage

$aab bac$ Réduction S→b

$aaS bac$ Décalage


$aaSb ac$ Réduction S→b

$aaSS ac$ Décalage


$aaSSa c$ Décalage
Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ aabbac$ Décalage
$a abbac$ Décalage
$aa bbac$ Décalage

$aab bac$ Réduction S→b

$aaS bac$ Décalage


$aaSb ac$ Réduction S→b

$aaSS ac$ Décalage


$aaSSa c$ Décalage
$aaSSac $ Réduction
S→aaSSac
Analyse ascendante par décalage-réduction

S→aaSSac| b
Pile Entrée Action
$ε aabbac$ Décalage
$a abbac$ Décalage
$aa bbac$ Décalage

$aab bac$ Réduction S→b

$aaS bac$ Décalage


$aaSb ac$ Réduction S→b

$aaSS ac$ Décalage


$aaSSa c$ Décalage
$aaSSac $ Réduction
S→aaSSac

$S $ sucées
Méthode d’Analyseur 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)
k indique le nombre de symboles de prévision utilisés pour
prendre une décision d’analyse. Quand k est omis, k est supposé
être égal à 1.
Méthode d’Analyseur LR
Avantages
Les analyseurs LR reconnaissent virtuellement toutes les
constructions des langages de programmation qui peuvent être
décrits par des un grammaire non contextuelle La méthode
d’analyse LR peut être implantée aussi efficacement que les autres
méthodes par décalage-réduction Un analyseur LR peut détecter
une erreur de syntaxe aussitôt que possible au cours d’un parcours
de gauche à droite de l’entrée.
Inconvénient
La méthode d’analyse LR exige de fournir un outil spécialiser pour
construire les analyseurs (Bison/yacc)
Une quantité de travail trop importante pour construire à la main
un analyseur
Techniques de construction des tables d’analyse LR
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 :
1 - 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.
2 - la seconde méthode, appelée LR canonique est la plus puissante mais la plus
coûteuse.
3 - La troisième méthode, appelée LookAhead LR (LALR) a une puissance et un
coût intermédiaire entre les deux. elle est applicable à la plupart des grammaires
de langages de programmation.
Les deux dernières méthodes augmentent la méthode SLR avec une information
de prévision.
Construction de la table d’analyse SLR

L’analyse SLR commence par la construction d’un automate à pile


fini non déterministe.
Soit la grammaire G =(A, V, S, R) tel que :

A : Alphabet (terminaux)

V : Non-terminaux

S : Axiome de départ

R : Règle de production

On augmente la grammaire G par :


1- L’ajout d’un nouveau symbole terminal ($ par exemple)
Toute entrée (chaîne) à analyser m est transformée en m$ (le
$ pour savoir qu’on est arrivé en fin du mot)
2- L’ajout d’un nouvel axiome S’
Construction d’un automate à pile fini non
déterministe : transformation

Le but d’ajouter S’ c’est qu’on peut avoir plusieurs dérivations de S


et on ne peux pas savoir quand est ce que c’est la réduction finale.
Avec l’ajout de S’ on a une seule dérivation vers l’axiome de
départ.

3- L’ajout d’une nouvelle règle : S’→S$


La réduction finale en S’ est le seul cas d’acceptation.
Construction d’un automate à pile fini non
déterministe : transformation

Exemple de grammaire Grammaire transformée


S→AA S’→S$
A→aA|b S→AA
A→aA|b

L’axiome de la grammaire était S.


On a ajouté la règle S’→S$ est maintenant l’axiome est S’

La rencontre de cet axiome indique à l’analyseur syntaxique de


terminer l’analyse.
Table d’analyse LR
Pour une grammaire G, on cherche à construire une table
semblable à celle dessus :
Construire un automate à pile fini non
déterministe les items


Chaque état de cet automate est défini par un ou
plusieurs items

Un item appelé aussi item de G est une règle contenant
un point (•) obtenue par la transformation d’une règle de
G:
 La première règle de G (S’→S$) est transformée en
une règle : S’→•S$
Le but d’ajouter un • est de savoir ce qui est déjà reconnu et ce qui
n’est pas encore reconnu. Tout ce qui est à gauche du • est
reconnu tout ce qui est à droite du • on doit le reconnaître.
On s’apprête de reconnaître un mot qui dérive de S (axiome)
Construire un automate à pile fini non
déterministe les items

 Chaque règle restante de G de la forme :


A →αβ est transformée en une règle : A →.αβ ensuite en A →α • β

On a reconnu une séquence qui dérive α, il ne reste qu’à reconnaître


une séquence dérivée de β pour pouvoir affirmer qu’on a reconnu un
mot qui dérive de A (matérialisé par la réduction αβ en A)

 Une règle A→ε est transformée en A→• (il y a plus rien à


reconnaître)


Les transitions de l’automate sont étiquetées par des symboles
terminaux (mots vide inclus) ou non terminaux.
Construire un automate à pile fini non
déterministe États de l’automate


Exemple de génération des états de l’automate

Règle originale Règle transformée Déjà rencontré S’attendre à

E →•E+T Retrouver E+T

E →E•+T E Retrouver +T

E →E+T
E →E+•T E+ Retrouver T

E →E+T• E+T Réduire E+T par E


Construire un automate à pile fini non
déterministe États de l’automate


État initiale de l’automate c’est l’état qui contient la règle :
S’→•S$

États finaux de l’automate sont les états qui contiennent
au moins un item de la forme : A→α• (c’est à dire il y a
plus à reconnaître)
Construire un automate à pile fini non
déterministe États de l’automate

Les items , répartis en sous ensembles, forment les états de
l’automate, et sont données par des fermetures de sous
ensembles d’items.

On applique
fermetures
Calcul de la fermeture de l’ensemble
d’items I

Soit FERMETURE(I), la fermeture de I à calculer par


rapport à une grammaire G. FERMETURE(I) se calcule on
appliquant les règles suivantes :
1) Ajouter tout item de I à FERMETURE(I) :
FERMETURE(I) ←I

2) Si A→α•Bβ (B non terminal) est dans FERMETURE(I) et


que la production B→Ɣ appartient à G, alors ajouter B→•Ɣ
à FERMETURE(I) :
FERMETURE(I)←FERMETURE(I) U {B→•Ɣ}
Calcul de la fermeture de l’ensemble
d’items I

Si vous avez le • avant un non-terminal, donc ajouter toutes les


dérivations de ce non-terminal avec un point à gauche de la
dérivation.

3) Appliquer la deuxième règle jusqu’à ce qu’aucun nouvel item


ne peut être ajouté à FERMETURE(I).
L’analyse SLR

Etapes :


1 - Augmentation de la grammaire S’→S

2 - On pose l’item I = {S’→•S}
 3 - Calcul de l’item I0 : I0 = fermeture (I)
 4 - Calcul de la transition dans I0 : Δ(I0,X) pour construire de
nouvelles items. (Δ() ou ALLER_A() ou tr() : fonction de transition)

5 - Arrêt lorsque aucun nouveau item ne peut être trouvé.
L’analyse SLR

Exemple

Soit la grammaire suivante :

E →E + T Premier Suivant
E →T
T→T*F E {(,id} {$,+,)}
T→F
F → (E) T {(,id} {$,+,),*}
F → id
F {(,id} {$,+,),*}
L’analyse SLR

Étape 1
Augmentation de la grammaire
E’→E
E →E + T
E →T
T→T*F
T→F
F → (E)
F → id
L’analyse SLR
E’→E
E →E + T
Étape 2 E →T
Calcul de l’item I T→T*F
I = {E’→•E} T→F
F → (E)
F → id
Étape 3
Calcul item I0 : I0 =Fermeture (I)
I0 =Fermeture {E’→•E}
I0 =Fermeture {E’→•E, E →•E + T, E →•T, T → •T * F, T → •F, F → •(E),F → •id}
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
T→F
F → (E)
F → id
Étape 4
Calcul de la transition I0 : Δ(I0,X) :
I0 = {E’→•E, E →•E + T, E →•T, T → •T * F, T → •F, F → •(E),F →
•id}
Avec X = {E, T, F, (, id}
Δ(I0,E) = {E’→E•, E →E• + T} = I1
Δ(I0,T) = {E →T•, T → T• * F} = I2
Δ(I0,F) = {T → F•} = I3
Δ(I0,() = {F → (•E), E →•E + T, E →•T, T → •T * F, T → •F, F →
•(E),F → •id} = I4
Δ(I0,id) = {F → id•} = I5
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
Calcul de la transition dans I1 : Δ(I1,X) T→F
F → (E)
On a trouvé I1 ={E’→E•, E →E• + T} F → id
Avec X = {+}
Δ(I1,+) = {E →E +• T, T → •T * F, T → •F, F → •(E),F → •id} =I6

Calcul de la transition dans I2 : Δ(I2,X)


On a trouvé I2 = {E →T•, T → T• * F}
Avec X = {*}
Δ(I2,*) = {T → T*• F, F → •(E),F → •id} = I7
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
Calcul de la transition dans I3 : Δ(I3,X) T→F
F → (E)
On a trouvé I3 ={T → F•} F → id
Avec X = Ø
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
Calcul de la transition dans I4 : Δ(I4,X) T→F
F → (E)
F → id

On a trouvé I4 ={F → (•E), E →•E + T, E →•T, T → •T * F, T → •F, F


→ •(E),F → •id}
Avec X = {E, T, F, (, id}
Δ(I4,E) = {F → (E•), E →E• + T} = I8
Δ(I4,T) = {E →T•, T → T• * F} = I2 (Déjà trouvé)
Δ(I4,F) = {T → F•} = I3
Δ(I4,() = {F → (•E), E →•E + T, E →•T, T → •T * F, T → •F, F →
•(E),F → •id} = I4
Δ(I4,id) = {F → id•} = I5
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
Calcul de la transition dans I5 : Δ(I5,X) T→F
F → (E)
On a trouvé I5 = {F → id•} F → id
Avec X = Ø

Calcul de la transition dans I6 : Δ(I6,X)


On a trouvé I6 = {E →E +• T, T → •T * F, T → •F, F → •(E),F → •id}
Avec X ={T, F, (, id}
Δ(I6,T) = {E →E +T•, T → T• * F} = I9
Δ(I6,F) = {T → F•} = I3
Δ(I6,() = {F → (•E),E →•E + T, E →•T, T → •T * F, T → •F, F →
•(E),F → •id} = I4
Δ(I6,id) = {F → id•} = I5
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
T→F
Calcul de la transition dans I7 : Δ(I7,X) F → (E)
On a trouvé I7 ={T → T*• F, F → •(E),F → •id} F → id
Avec X ={F, (, id}
Δ(I7,F) = {T → T*F• } = i10
Δ(I7,() = {F → (•E), E →•E + T, E →•T, T → •T * F, T → •F, F →
•(E),F → •id} = I4
Δ(I7,id) = {F → id•} = I5
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
T→F
Calcul de la transition dans I8 : Δ(I8,X) F → (E)
On a trouvé I8 = {F → (E•), E →E• + T} F → id
Avec X ={), +}
Δ(I8,)) = {F → (E)• } = i11
Δ(I8,+) = {E →E +• T, T → •T * F, T → •F, F → •(E),F → •id} =I6
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
T→F
Calcul de la transition dans I9 : Δ(I9,X) F → (E)
On a trouvé I9 = {E →E +T•, T → T• * F} F → id
Avec X ={T, *}
Δ(I9,T) = Ø
Δ(I9,*) = {T → T * •F, F → •(E), F → •id} =I7
E’→E
E →E + T
L’analyse SLR E →T
T→T*F
T→F
Calcul de la transition dans I10 : Δ(I10,X) F → (E)
On a trouvé I10 = {T → T*F• } F → id
Avec X = Ø

Calcul de la transition dans I11 : Δ(I11,X)


On a trouvé I11 ={F → (E)• }
Avec X = Ø

Fin de calcul des items


L’analyse SLR :

Transitions
Δ(I0,E) = I1 Δ(I4,id) = I5
Δ(I0,T) = I2 Δ(I6,T) = I9
Δ(I0,F) = I3 Δ(I6,F) = I3
Δ(I0,() = I4 Δ(I6,() = I4
Δ(I0,id) = I5 Δ(I6,id) = I5
Δ(I1,+) = I6 Δ(I7,F) = I10
Δ(I2,*) = I7 Δ(I7,() = I4
Δ(I4,E) = I8 Δ(I7,id) = I5
Δ(I4,T) = I2 Δ(I8,)) = I11
Δ(I4,F) = I3 Δ(I8,+) = I6
Δ(I4,() = I4
Automate
(1) E’→E Premier Suivant
(2) E →E + T
(3) E →T E {(,id} {$,+,)}
(4) T→T*F
T {(,id} {$,+,),*}
(5) T→F
(6) F → (E) F {(,id} {$,+,),*}
(7) F → id

126 / 148
127 / 148
Actions Successeurs
Terminaux Non-Terminaux
Items + * ( ) id $ E T F
I0 d4 d5 1 2 3
I1 d6 Acc
I2 r3 d7 r3 r3
I3 r5 r5 r5 r5
I4 d4 d5 8 2 3
I5 r7 r7 r7 r7
I6 d4 d5 9 3
I7 d4 d5 10
I8 d6 d11
I9 r2 r2 r2
I10 r4 r4 r4 r4
128 / 148
I11 r6 r6 r6 r6
Exercice d’application

Énoncé :
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
Solution : Calcul des items et des SUIVANT

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 ) = ∅
I6 = tr (I2 , =) = f (S → L = .R) = {S → L = .R, R → .L, L → . ∗ R, L → .id}
I7 = tr (I5 , R) = {L → ∗R.} I8 = tr (I5 , L) = {R → L.}
tr (I5 , id) = {L → id.} = I4 tr (I5 , ∗) = {L → ∗.R, R → .L, L → . ∗ R, L → .id} =
I5
tr (I5 , S) = tr (I5 , =) = ∅ I9 = tr (I6 , R) = {S → L = R.}
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) = {=, $}
Solution : Construction de l’automate
Solution : Construction de la table SLR(1)
Modèle d’un analyseur LR
Table d’analyse
Les tables d’analyse contiennent deux parties :

une fonction d’actions d’analyse Action

une fonction de transfert Successeur.


prend comme arguments un état et un symbole non-
terminal et retourne un état
Table d’analyse
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
4 Erreur
Configuration d’un analyseur 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 chaı̂ ne d’entrée restant à analyser : (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.
Configuration d’un analyseur LR

Les configurations résultantes après chacun 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.
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 . . . 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.
Configuration d’un analyseur LR

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 à β
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.
Algorithme de Analyse LR

Entrée : Table d’analyseur et le mot ω


Initialiser le pointeur source ps sur le premier symbole de ω$ ; La pile
contient s0
Algorithme de Analyse LR
Algorithme de Analyse LR
Construction de la table canonique LR

Motivation :
L’analyse LR canonique est plus performante que la technique SLR car elle
permet d’analyser avec succès un nombre plus important de grammaires.
Dans la méthode SLR, l’état i indique une action réduire par A → α à la vue
d’un terminal a appartenant à SUIVANT(A).
Cependant, dans certains cas, quand l’état i apparaı̂ t en sommet de pile, le
préfixe viable βα de la pile est tel que βA ne peut être suivi par a dans
aucune proto-phrase. Par conséquent, réduire par A → α est invalide à la
vue de a.
Il faut attacher plus d’information à un état : information qui permet
d’éviter les réductions invalides comme A → α
Information supplémentaire dans l’état : ajouter un symbole terminal
comme second composant d’un item ([A → α . β, a])

→ L’item est appelé alors item LR(1)


Construction des tables canoniques d’analyse LR

Algorithme :
Entrée : Une grammaire augmentée G’
Sortie : Les fonctions Action et Successeur des tables canoniques
d’analyse LR associées à G’.
Méthode :
1- Construire C = {I0 , I1 ,. . ., In }, la collection des ensembles d’items
LR(1) 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 :
1 Si [A → α.aβ ,b] est dans Ii et Transition(Ii , a) = Ij , remplir Action[i, a]
avec décaler j . Ici a doit être un terminal
2 Si [A → α. ,a] est dans Ii , A ̸= S ′ , remplir Action[i, a] avec réduire par
A → α.
Construction des tables canoniques d’analyse LR

3 Si [S’ → S.,$] est dans Ii , remplir Action[i, $] avec accepter.


Si un conflit résulte de l’application des règles précédentes, la
grammaire n’est pas LR(1) et l’algorithme échoue.

3 - Les transitions Successeur pour l’état i sont déterminées comme


suit : 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
remplies avec erreur.
5 - L’état initial de l’analyseur est celui qui a été construit à partir de
l’ensemble contenant l’item [S’ → .S,$].
Construction des tables canoniques d’analyse LR
Construction des ensembles d’items LR(1)

Donnée : une grammaire augmentée G’


Résultat : les ensembles d’items LR(1) qui sont les ensembles
d’items valides pour un ou plusieurs préfixes viables de G’.
Méthode : Les procédures Fermeture et Transition et la procédure
principale Items sont les suivantes :
Construction des tables canoniques d’analyse LR
Construction des ensembles d’items LR(1)
Construction des tables canoniques d’analyse LR
Construction des ensembles d’items LR(1)
Construction des tables canoniques d’analyse LR
Construction des ensembles d’items LR(1)

Vous aimerez peut-être aussi