Grammaires hors-contexte Une grammaire hors-contexte est un 4-uplet N,Σ,P,S o`u : ◮
terminaux, app ppeel´e l’alphabet N est un ensemble de symboles non terminaux, non terminal. terminal.
◮
◮
terminaux, ap appe pel´ l´e l’ l’al alph phab abet et Σ est un ensemble de symboles terminaux, terminal,, tel que N et Σ soient disjoints. terminal P est un sous ensemble fini de : N × (N ∪ Σ)∗
un ´el´ement (α, β) de P, que l’on note α estt ap app pel´e une r`egle β es de production ou r`egle de r´e´ e´ecriture. appel´ el´e par partie tie gau gauche che de la r`egle egl e α est app appel´ el´e par partie tie dro droite ite de la r`egle egl e β est app el´ement de N app ppeel´e l’axiome de la grammaire. S est un ´
→
◮
Automate `a pile
Un automate `a pile est un 6-uplet Q,Σ,Γ,δ,q0 , F ◮
l’ense nsemble mble des ´etats eta ts Q est l’e
◮
l’alph lphab abet et d’e d’entr´ ntr´ee ee Σ est l’a
◮
Γ est l’alphabet de symboles de pile
◮
δ est la fonction de transition : {ε δ : Q × (Σ ∪ { ε}) × Γ
→
℘(Q × Γ ∗ )
◮
estt l’´etat etat in init itia iall q0 ∈ Q es
◮
l’ensemble emble des ´etats etats d’acc d’acceptati eptation on F ⊆ Q est l’ens
Grammaires hors-contexte
⇔
Automate `a pile
Un langage est hors-contexte si et seulement si il existe un automate `a pilee qui le rec pil reconn onnaaˆıt. ◮
◮
Si un langage est hors-contexte alors il existe un automate `a pile quii le re qu reco connaˆ nnaˆıt. ıt . Si un langage est reconnu par un automate `a pile alors il est hors-contexte.
Grammaires hors-contexte
◮
◮
◮
⇒
Automate `a pile
Soit G = N,Σ,P,S une grammaire hors-contexte, on construit un automate `a pile A qui accepte un mot m s’il existe une + d´eriva er ivati tion on pou ourr m dans G (S m).
⇒
cu de telle sorte `a d´eter etermi mine nerr une d´erivat er ivatio ion n co condu nduis isant ant A est con¸cu de S `a m. Id´ee ee cle cleff : ´ecrir ecr iree dan danss la pil pilee de A les proto-phrases qui cons co nsti titue tuent nt la d´erivat er ivatio ion n re reche cherch´ rch´ee. ee.
Principe
1 2
Empiler l’axiome S Remplacer S par la partie droite d’une r`egle egle de la forme S α de telle sorte que le premier symbole x de α se trouve en sommet de pile.
→
◮
◮
Si x est un terminal alors on le compare avec le caract` ere se ere trouvant trou vant sous s ous la tˆete ete de lect lecture. ure. S’il S’ilss sont ´egaux egau x alor alorss on d´epile. epil e. Si x est un non terminal alors on le remplace par la partie droite d’une d’u ne r`egle egle de P de la forme x β.
→
Exemple Reconnaissance du mot : a+a∗a
avec la grammaire : E T F
→→ →
T + E | T F ∗ T | F (E) | a
T
F
a
+
+
+
+
E
E
E
E
E
E
a
a
a
a
+
a
F
a
*
*
*
T
T
T
T
a
a
a
*
T
a
a
a
Non d´eterminisme
◮
◮ ◮
Lorsqu’un non terminal X doit ˆetre remplac´e au sommet de la pile, il peut l’ˆetre par la partie droite d’une r`egle de la forme X β. Plusieurs r`egles de cette forme peuvent exister dans la grammaire. L’automate correspondant est g´en´eralement non d´eterministe.
→
Automate correspondant `a la grammaire G = N,Σ,P,S
ε, Ni
→
αi, pour toute regle Ni
0
→
1
ε, ε
→
S$
x, x
→
αi de P
2
ε, $ ε ∀x ∈ Σ
→
ε
Construction de l’automate Automate `a pile A correspondant `a la grammaire G = N,Σ,P,S : A = {0,1,2}, Σ , N ∪ Σ ∪ {$},δ,0, {2}
La fonction de transition δ est d´efinie de la fa¸con suivante : ◮ ◮
δ(0,ε, $) = {(1, S$)} On empile l’axiome. δ(1,ε,Ni ) = {(1, αi ) | avec Ni αi ∈ P} Si un symbole non terminal Ni occupe le sommet de la pile, on le remplace par la partie droite αi d’une r`egle Ni αi .
→
→
◮
δ(1,a,a) = {(1, ε) | avec a ∈ Σ}
◮
Si le mˆeme symbole terminal occupe le sommet de la pile et la case courante de la bande d’entr´ee, on d´epile. δ(1,ε, $) = {(2, $)} Si le mot en entr´ee a ´et´e reconnu et que la pile ne contient que le symbole de fond de pile, on passe `a l’´etat d’acceptation.
Exemple Grammaire : {E,T,F}, {a, +, −, ∗(, )},P,E avec : P = {E
Automate :
→
T + E | T , T
→
F ∗ T | F , F
→
(E) | a}
A1 = {0,1,2}, {a, +, ∗, (, )}, {a, +, ∗, (, ),E,T,F, $},δ,0, $, {2}
avec : δ(0, ε, $) δ(1,ε,E) δ(1,ε,T ) δ(1,ε,F) δ(1, ε, $)
= = = = =
{(1, E$, ε)} {(1, E + T ), {(1, T ∗ F), {(1, (E)), {(2, $)}
(1, T )} (1, F)} (1, a)}
δ(1, +, +) δ(1, ∗, ∗) δ(1, (, () δ(1,a,a)
= = = =
{(1, ε)} {(1, ε)} {(1, ε)} {(1, ε)}
Analyse syntaxique
Etant donn´e m ∈ Σ et G = Σ,N,P,A , analyser m consiste `a trouver pour m son (et ´eventuellement ses) arbre de d´erivation. ∗
E ¨ r ¨ r ¨ r ¨ r
E T F
→→ →
T + E|T F ∗ T |F (E)|a
T
+
E
F a
T ¨ r ¨ r
F a
*
T F a
Sens d’analyse
◮
◮
Analyse descendante L’arbre de d´erivation est construit depuis la racine vers les feuilles S´equence de d´erivations gauches `a partir de l’axiome E T + E F+E a+E a + T a + F ∗ T a + a ∗ T a+a∗F a+a∗a
⇒ ⇒⇒ ⇒
⇒
⇒
⇒
Analyse ascendante L’arbre de d´erivation est construit des feuilles vers la racine S´equence de d´erivation telle que la s´equence inverse soit une d´erivation droite de m. a+a∗a F+a∗a T + a ∗ a T + F ∗ a T + F ∗ F T + F ∗ T T + E E
⇐⇐ ⇐ ⇐
⇐
⇐
⇐
⇒
Transducteurs `a pile
BANDE D’ENTREE
TETE DE LECTURE
UNITE DE CONTROLE PILE
BANDE DE SORTIE
◮
◮
Un transducteur `a pile est un automate `a pile qui ´emet, `a chaque d´eplacement, un suite finie de symboles de sortie. Une configuration d’un transducteur `a pile est un quadruplet (q,w,α,y) o` u y est une s´equence de symboles de sortie.
Transducteur `a pile : d´efinition Un transducteur `a pile est un 8-uplet Q,Σ,Γ,∆,δ,q0 , F ◮
etats Q est l’ensemble des ´
◮
Σ est l’alphabet d’entr´ee
◮
Γ est l’alphabet de symboles de pile
◮
∆ est l’alphabet de sortie
◮
δ est la fonction de transition δ : Q × (Σ ∪ {ε}) × Γ
→
℘(Q × Γ ∗ × ∆∗ )
◮
q0 ∈ Q est l’´etat initial
◮
etats d’acceptation F ⊆ Q est l’ensemble des ´
Analyseur gauche
1E 3 T 5F ◮
2E 4 T 6F
T + E F ∗ T (E)
→→ → ⇒ ⇒
T F a
D´erivation gauche de a + a ∗ a : E
◮
→→ →
1
T + E
4
F+E
6
⇒ ⇒ ⇒
a+E
Analyse gauche : 14623646
2
a + T
∗
a+a∗a
Analyseur gauche
Soit une CFG G dont les r`egles ont ´et´e num´erot´ees de 1 `a p. On appelle un analyseur gauche de G, un transducteur `a pile non g d´eterministe T G qui produit pour un mot m ∈ L(G), une d´erivation gauche de m. Performances : ◮ Espace : O (|m|) ◮
Temps : O(c|m| )
Analyseur gauche : Exemple ε, E ε, E ε, T
→→ →
T, 2 T + E, 1 F ∗ T, 3
0
ε, T ε, F ε, F
→→ →
F, 4 (E), 5 a
1
ε, ε x, x
→
→
E$
2
ε, $
→
ε
ε, ε avec x ∈ {a, +, ∗, (, )}
⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢
(0, a + a ∗ a, $) (1, a + a ∗ a, E$) (1, a + a ∗ a, T + E$, 1) (1, a + a ∗ a, F + E$, 14) (1, a + a ∗ a, a + E$,146) (1, +a ∗ a, +E$,146) (1, a ∗ a, E$, 146) (1, a ∗ a, T $, 1462) (1, a ∗ a, F ∗ T $, 14623) (1, a ∗ a, a ∗ T $, 146236) (1, ∗a, ∗T $, 146236) (1,a,T $, 1462364) (1,a,F$, 14623646) (1,a,a$, 14623646) (1,ε, $, 14623646) (2, ε, ε, 14623646)
Analyse descendante pr´edictive : id´ee g´en´erale
◮
◮
◮
Rendre d´eterministe un analyseur gauche en s’autorisant `a regarder les k symboles suivant le caract`ere courant dans le mot `a analyser. Une grammaire dont l’analyseur gauche peut ˆetre rendu d´eterministe en regardant les k symboles suivant le caract`ere courant est dite LL(k). Certaines grammaires hors contexte ne sont pas LL(k), en particulier : ◮ ◮ ◮
les grammaires ambigu¨es. les grammaires r´ecursives a` gauche, certaines grammaires non factoris´ees a` gauche,
Probl`eme de la r´ecursivit´e a` gauche
Si la grammaire poss`ede une r`egle de la forme A a Aα, l’automate ` pile ou l’analyseur gauche correspondant bouclera !
→
A
⇒
A α
⇒
A α α
⇒
A α α α
⇒
A α α α α
R´ecursivit´e a` gauche
◮
Un symbole non terminal A est dit r´ecursif si A α, β ∈ (N ∪ Σ) . ∗
◮ ◮
◮
◮
Si α = ε, A est dit r´ecursif ` a gauche. Si β = ε, A est dit r´ecursif ` a droite.
∗
⇒
αAβ avec
Une grammaire comportant au moins un symbole r´ecursif `a gauche est dite grammaire r´ecursive a` gauche. Une grammaire comportant au moins un symbole r´ecursif `a droite est dite grammaire r´ecursive a` droite.
R´ecursivit´e a` gauche
◮
◮
r´ecursivit´e gauche directe : la r´ecursivit´e `a gauche apparaˆıt `a l’issue d’une seule d´erivation. Exemple : application de la r`egle A AB au symbole A : A
◮
◮
⇒
→
AB
r´ecursivit´e gauche indirecte : la r´ecursivit´e `a gauche apparaˆıt apr`es plusieurs d´erivations. Exemple : application sucessive des deux r`egles A aA: B AE `
→
A
BC
⇒ ⇒
AEC
→
BC et
Bonne nouvelle !
Tout langage hors-contexte peut ˆetre g´en´er´e par une grammaire hors-contexte non r´ecursive `a gauche. Id´ee g´en´erale :
A
→ ⇔ →→ Ab|a
A A′
a|aA ′ bA ′ |ε
Elimination de la r´ecursivit´e a` gauche directe Soit G = N,Σ,P,S une grammaire hors contexte, et soit A
→
Aα1 | Aα2 | . . . | Aαm | β1 | β2 | . . . | βn
toutes les r`egle de P ayant A pour partie gauche. eme langage que la grammaire G d´efinie de la fa¸con G g´en`ere le mˆ suivante : ′
G ′ = N ∪ {A ′ }, Σ , P ′ , S
o`u P est ´egale `a P avec les r`egles ayant A pour partie gauche remplac´ees par : ′
A A′
→ →
β1 | β2 | . . . | βn | β1 A ′ | β2 A ′ | . . . | βn A ′ α1 | α2 | . . . | αm | α1 A ′ | α2 A ′ | . . . | αm A ′
Exemple
E T F
→→ →
E + T | T T ∗ F | F (E) | a
⇒
E E′ T T ′ F
→→ →→ →
T | TE ′ +T | + TE ′ F | FT ′ ∗F | ∗ FT ′ (E) | a
Elimination de la r´ecursivit´e a` gauche
◮
◮
◮
Principe : On proc`ede de mani`ere incr´ementale en consid´erant des ensembles de r`egles de plus en plus important, jusqu’`a avoir trait´e toute les r`egles. On ordonne les non terminaux de la grammaire : A1 , . . . , An et on commence par ´eliminer la r´ecursivit´e directe des r`egles de la forme A1 α.
→
Puis on traite les r`egles de la forme A2 β et ainsi de suite, jusqu’`a avoir transform´e toute la grammaire.
→
Elimination de la r´ecursivit´e a` gauche une grammaire G = N,Σ,P,S une grammaire G non r´ecursive `a gauche
Entr´ ee : Sortie :
′
M´ ethode : ◮ ◮
◮
Num´eroter les non terminaux de G : N = {A1 , . . . , An } ´eliminer les r´ecursivit´es `a gauche directes des r`egles ayant A1 pour partie gauche. Pour i = 2 `a n faire ◮
pour j = 1 a ` i − 1 faire Ai Aj γ par les r` egles δ1 | .. . | δk sont toutes les r` egles
1 remplacer chaque r` egle de la forme
→
Ai δ1 γ | .. . | δk γ, o` u Aj ayant Aj pour partie gauche. eliminer les r´ ecursivit´ es ` a gauche directes des r` egles ayant Ai pour 2 ´ partie gauche.
→
→
Elimination de la r´ecursivit´e a` gauche
◮
◮
La raison pour laquelle l’algorithme ci-dessus produit l’effet voulu est qu’apr`es la (i − 1)`eme it´eration de la boucle la plus externe (en i), chaque r`egle de la forme Aj u j < i doit ˆetre telle Al α, o` que l > j.
→
Il en r´esulte qu’`a l’it´eration suivante dans la boucle interne (en j), les remplacements successifs de Aj dans les r`egles de la forme egles de la forme Ai Aj α va avoir pour cons´equence que les r` Ai Al α seront telles que l ≥ i et l’´elimination de la r´ecursivit´e directe sur Ai va faire que l > i.
→→
Exemple
A B C ◮ ◮
◮
◮
→→ →
BC | a CA | Ab AB | CC | a
On pose A1 = A, A2 = B et A3 = C. On commence par ´eliminer la r´ecursivit´e directe sur A puis on remplace, dans B elimine la CA | Ab, A par BC | a puis on ´ r´ecursivit´e directe sur B. On remplace alors, dans C AB | CC | a, A par BC | a, ce qui donne C BCB | aB | CC | a. Puis on remplace B par CA | ab | CAB | abB et on termine en ´eliminant la r´ecursivit´e directe sur C.
→
→
→
′
′
Exemple A B C ◮
→→ →
BC | a CA | Ab AB | CC | a
On pose A1 = A, A2 = B et A3 = C.
i=1 i=2 i=2 i=3 i=3 i=3
pas de changements j=1
j=1 j=2
B B B′ C C C C C′
CA | BCb | ab CA | ab | CAB ′ | abB ′ CbB ′ | Cb BCB | aB | CC | a CACB | abCB | CAB ′ CB | abB ′ B | aB | CC | a abCB | abB ′ CB | aB | a | abCBC ′ | abB ′ BC ′ | aBC ′ | aC ′ ACBC ′ | AB ′ CBC ′ | CC ′ | ACB | AB ′ B | C
→→ →→ →→ →→
Grammaire factoris´ee a` gauche
Une grammaire G est dite factoris´ee `a gauche si les parties droites de deux r`egles ayant la mˆeme partie gauche n’ont pas de pr´efixe commun propre : (A = ε). αβ1 | αβ2 avec α
→
Factorisation `a gauche une grammaire G Sortie : une grammaire ´ equivalente factoris´ee `a gauche M´ ethode : Pour chaque symbole non terminal A, trouver le plus long pr´efixe α = ε commun `a deux r`egles ou plus ayant A pour partie gauche. Remplacer toutes les r`egles ayant A pour partie gauche : Entr´ ee :
A
→
αβ1 | αβ2 | . . . | αβn | γ
o`u γ repr´esente toutes les parties droites qui ne commencent pas par α, par : A A′
→
→
αA ′ | γ
β1 | β2 | . . . | βn
Exemple
G = {E, S}, {i,t,e,a,b}, {S
→
iEtS | iEtSeS | a, E
→
b}, S
Factoris´ee `a gauche, cette grammaire devient :
G = {E,S,E ′ }, {i,t,e,a,b}, {S
→
iEtSS ′ | a, S ′
→
eS | ε, E
→
b}, S
Exemples
LL(2) LL(1) A A
→→
LL(1) aB bC
A A B D
→→ →→
BC DE a b
A A B D C E
→→ →→ →→
BC DE a a c e
Grammaires LL(1)
◮
◮
◮
◮
◮
Soit G = N,Σ,P,S une grammaire hors-contexte non ambigu¨e et m = a1 . . . an un mot de L(G). On sait qu’il existe une unique d´erivation gauche du mot m compos´ee des proto-phrases α1 . . . αk avec α1 = S et αk = m. Id´ee de l’analyse LL(1) : construire cette suite de proto-phrases en ne lisant m qu’une fois, de gauche `a droite. Principe : si αi = a1 . . . aj Aβ alors αi+1 doit pouvoir ˆetre d´etermin´ee de fa¸con unique en fonction du symbole non terminal A et du symbole aj+1 . Une grammaire poss´edant cette propri´et´e est dite grammaire LL(1).
Analyseurs LL(1)
BANDE D’ENTREE TETE DE LECTURE
TABLE D’ANALYSE PILE
BANDE DE SORTIE TETE D’ECRITURE
Configuration Une configuration d’un analyseur LL est un triplet (au, Xα, π ) o`u : ◮
◮
◮
au repr´esente la partie du mot d’entr´ee non encore lue, a est le
symbole terminal se trouvant sous la tˆete de lecture. Xα repr´esente le contenu de la pile (avec X au sommet de cette derni`ere) esente le mot produit sur la bande de sortie. π repr´
Si m ∈ Σ est le mot `a analyser, ∗
◮
◮
la configuration initiale de l’analyseur est : (m$, S$, ε) $ ´etant le symbole de fond de pile qui sert aussi `a marquer la fin de la chaˆıne `a analyser. Une configuration d’acceptation se pr´esente sous la forme : etant l’analyse gauche de m. ($, $, π ) π ´
Mouvements Trois cas possibles `a partir de la configuration (au,Xα,π ) : 1
Si X = a = $, l’analyseur s’arrˆete et annonce le succ`es de l’analyse.
2
= $, l’analyseur enl`eve X de la pile et avance la tˆ Si X = a ete de lecture : (au,aα,π ) ⊢ ( u,α,π )
3
Si X est un symbole non terminal, l’analyseur consulte l’entr´ee M(X, a) de la table d’analyse M. Deux cas sont possibles : 1
u i est le num´ero d’une r`egle ayant X pour partie M(X, a) = i o` gauche (X epil´e, β est empil´e et i est β). Dans ce cas, X est d´
→
´ecrit sur la bande de sortie. (au,Xα,π ) 2
M(X, a) =
l’analyse.
erreur
⊢
(au,βα,πi)
, l’analyse s’arrˆete et annonce l’´echec de
Exemple Grammaire 1 3 5 7
2 4 6 8
TE ′ ε ∗FT ′ (E)
E E′ T ′ F
→→ →→
E′ T T ′ F
+TE FT ε a
→→ →→
′
Table LL(1)
E E′ T T ′ F
a 1
( 1
×
×
4
4
∗ $ × × × × 3 2 × 3 × × × ×
×
×
6
8
7
× × × ×
)
+
6
5
6
′
⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢ ⊢
((a ∗ a), E$, ε) ((a ∗ a), TE $, 1) ((a ∗ a), FT E $, 14) ((a ∗ a), (E)T E $, 147) (a ∗ a), E)T E $, 147) (a ∗ a), TE )T E $, 1471) (a ∗ a), FT E )T E $, 14714) (a ∗ a), aT E )T E $, 147148) (∗a), T E )T E $, 147148) (∗a), ∗FT E )T E $, 1471485) (a), FT E )T E $, 1471485) (a), aT E )T E $, 14714858) (), T E )T E $, 14714858) (), E )T E $, 147148586) (), )T E $, 1471485863) (ε, T E $, 1471485863) (ε, E $, 14714858636) (ε, $, 147148586363) ′ ′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
′
Construction d’une table LL(1) `a partir d’une grammaire
La construction d’une table d’analyse LL(1) pour une grammaire ee par les deux fonctions premier et G = N,Σ,P,S est facilit´ suivant. Ces deux fonctions pemettent, quand c’est possible, de remplir les entr´ees de la table d’analyse LL(1) de G.
PREMIER
Si α est une proto-phrase de G, premier(α) est l’ensemble des terminaux qui commencent les chaˆınes se d´erivant de α. : premier
Si α
∗
⇒
(α) = {a ∈ Σ | α
a ε alors ε appartient aussi `
premier
∗
⇒
au}
(α).
PREMIER(X)
Pour calculer premier(X) avec X ∈ N ∪ Σ, on applique les r`egles suivantes jusqu’`a ce qu’aucun terminal ni ε ne puisse ˆetre ajout´e aux ensembles premier. 1 2 3
Si X ∈ Σ, premier(X) = {X}. Si X a premier(X). ε ∈ P, on ajoute ε `
→
Si X ∈ N et X Y 1 . . . Yk ∈ P, mettre a dans premier(X) s’il existe i tel que a est dans premier(Y i ) et que ε est dans tous les premier(Y 1 ) . . . premier(Y i−1 ). Si ε ∈ premier(Y j )∀j , 1 ≤ j ≤ k, on ajoute ε `a premier(X).
→
PREMIER(X1 . . . Xn)
On calcule 1
2
3
premier
(X1 . . . Xn ) de la fa¸con suivante :
Ajouter `a premier(X1 . . . Xn ) tous les symboles de premier(X1 ) diff´erents de ε. Si ε ∈ premier(X1 ), ajouter ´egalement les symboles de erents de ε. premier(X2 ) diff´ Si ε ∈ premier(X2 ), ajouter ´egalement les symboles de erents de ε, etc. premier(X3 ) diff´ Finalement, si ε appartient `a premier(Xj ) pour tous les a premier(X1 . . . Xn ). j = 1 , 2 , . . . n , on ajoute ε `
SUIVANT( X)
Si X ∈ N, suivant(X) est l’ensemble des symboles a ∈ Σ qui peuvent apparaˆıtre imm´ediatement `a droite de X dans une proto-phrase : suivant
(X) = {a ∈ Σ | S
∗
⇒
αXaβ}
Si X peut ˆetre le symbole le plus `a droite d’une proto-phrase alors $ est dans suivant(X).
SUIVANT( X)
Pour calculer suivant(X) pour tous symbole non terminal X, on applique les r`egles suivantes jusqu’`a ce qu’aucun symbole non terminal ne puisse ˆetre ajout´e aux ensembles suivant : 1 2
3
Mettre $ dans suivant(S). si X a αBβ, le contenu de premier(β), except´e ε, est ajout´e ` suivant (B). s’il existe une r`egle X αB ou une r`egle X αBβ telle que a dire β el´ements de suivant(X) ε ∈ premier(β) (c’est ` ε), les ´ sont ajout´es `a suivant(B).
→
→
∗
⇒
→
Exemple Soit la grammaire G = {E, E ,T,T , F}, {a, +, ∗, (, ), a},P,E non r´ecursive a` gauche o`u P est compos´e des r`egles suivantes : ′
1 3 5 7 Alors :
TE ′ ε ∗FT ′ (E)
E E′ T ′ F
→→ → →
′
2 4 6 8
E′ T T ′ F
+TE FT ε a
→→ →→
′
′
(E) = premier(T ) = premier(F) = {(, a} premier(E ) = {+, ε} premier(T ) = {∗, ε} suivant(E) = {), $} suivant(E ) = suivant (E) = {), $} suivant(T ) = {premier(E ) − {ε}} ∪ suivant (E) = {+, ), $} suivant(T ) = suivant (T ) = {+, ), $} suivant(F) = {premier(T ) − {ε}} ∪ suivant(T ) = {+, ∗, ), $} premier
′ ′
′
′
′
′
Construction de la table LL(1) Entr´ee : G = N,Σ,P,S Une grammaire dont les r`egles sont num´erot´ees. Sortie : M Une table d’analyse LL(1) pour G. M´ethode : 1
2
3
4
pour chaque regle i ∈ P de la forme A etapes α, proc´eder aux ´ 2 et 3. Pour chaque symbole terminal a ∈ premier(α), ajouter i `a M(A, a). Si ε ∈ premier(α), ajouter i `a M(A, b) pour chaque symbole terminal b ∈ suivant(A). Si ε ∈ premier(α) et $ ∈ suivant(A), ajouter i `a M(A, $). Mettre erreur dans toutes les entr´ees rest´ees vides.
→
Grammaires non LL(1)
Si G n’est pas LL(1), en particulier si elle est r´ecursive `a gauche, non factoris´ee `a gauche ou ambigu¨e, M peut avoir des entr´ees qui sont d´efinies de fa¸cons multiples. On peut montrer qu’une grammaire G est LL(1) si et seulement si, pour toute r`egle disctincte A α et A β de G, les conditions suivantes s’appliquent :
→
→
1
Pour aucun symbole terminal a, α et β ne se d´erivent toutes les deux en des mots commen¸cant par a.
2
Une des deux proto-phrases α et β peut se d´eriver en ε. Si β erive pas en un mot commen¸cant par un ε, α ne se d´ ´el´ement de suivant(A).
3
∗
⇒
R´ealisation simple d’un analyseur LL(1) en C
Principes g´en´eraux : ◮ ◮
◮
G est une grammaire LL(1).
Une fonction en langage C est associ´ee `a tout symbole non terminal de G. Le graphe des appels de fonctions repr´esente l’arbre de d´erivation.
Cas de base A
→
B avec
→
a
premier
(B) = {b}
void A(void){ if(cc == ’b’){ B(); return;} erreur();} A
void A(void){ if(cc == ’a’){ cc = yylex(); return;} erreur();}
Parties droites complexes A
→
BC avec
→
aB avec
premier
(B) = {b} et
premier
void A(void){ if(cc == ’b’){ B(); if(cc == ’c’){ C(); return;} erreur();} A
premier
(B) = {b}
void A(void){ if(cc == ’a’){ cc = yylex(); if(cc == ’b’){ B(); return;} erreur();}
(C) = {c}
Redondance Certains tests sont effectu´es plusieurs fois A B et B b avec premier(B) = {b}
→
→
void A(void){ if(cc == ’b’){ /* premiere fois */ B(); return;} erreur();} void B(void){ if(cc == ’b’){ /* deuxieme fois */ cc = yylex(); return;} erreur();}
Symboles ambigus
A
→
B|C avec
premier
(B) = {b} et
void A(void){ if(cc == ’b’){ B(); return;} if(cc == ’c’){ C(); return;} erreur();}
premier
(C) = {c}
R`egles non factoris´ees a` gauche BC|BD avec premier(B) = {b}, premier(D) = {d} A
→
void A(void){ if(cc == ’b’){ B(); if(cc == ’c’){ C(); return;} if(cc == ’d’){ D(); return;} } erreur();}
premier
(C) = {c} et
R`egles vides
A
→
B|ε avec
premier
(B) = {b} et
void A(void){if(cc == ’b’){ B(); return;} if(cc == ’c’){ return;} erreur();}
suivant
(A) = {c}
R`egles vides
De mani`ere plus g´en´erale A B avec premier(B) = {b, ε} et
→
void A(void){if(cc == ’b’){ B(); return;} if(cc == ’c’){ return;} erreur;}
suivant
(A) = {c}
Arbre de d´erivation
◮
◮
◮
◮
Il n’est pas n´ecessaire de construire explicitement l’arbre de d´erivation sous-jacent `a une analyse syntaxique. L’arbre abstrait sera constuit directement lors de l’analyse, par ajout d’actions s´emantiques. Il est cependant utile de pouvoir visualiser l’arbre de d´erivation pour des raisons de mise au point. On peut pour cela produire de mani`ere simple un fichier XML qui repr´esente la structure de l’arbre de d´erivation, qu’il suffira d’ouvrir `a l’aide d’un outil de visualisation de fichiers XML.
Production d’un arbre de d´erivation XML
void A(void){ fprintf(sortie_xml, ‘‘
\n’’); if(cc == ’b’){ B(); fprintf(sortie_xml, ‘‘\n’’); return;} if(cc == ’c’){ fprintf(sortie_xml, ‘‘\n’’); return;} erreur();}