Licence d'Informatique d'Informatiqu e 2010-2011
Langages et Compilation
TD N° 9 : ANALYSE SYNTAXIQUE DESCENDANTE PREDICTIVE LL(1) Exercice 1 (Juin 06)
Soit la grammaire suivante, d’axiome S. S→ TU T → aTc | b U → cU | d 1) Quelle est la forme f orme générale des phrases engendrée par cette grammaire ? 2) Analyse LL(1). Calculer la fonction PREMIER et la table d’analyse. (Observez qu’il n’y a pas de ε-production). La grammaire est-elle LL(1) ? 3) Simulez l’analyse prédictive de : a) abccd ; b) aabcd. En cas de succès donner une dérivation et l’arbre d’analyse Exercice 2
On reprend la grammaire (G) d'expressions arithmétiques additives, avec un "-" unaire et un "-" binaire, associant à droite. EF+E|F-E|F F - F | ( E ) | id N.B. G est non ambiguë. - G est-elle récursive à gauche ? - G a-t-elle une chance d’être LL(1) ? Sinon, donner une grammaire G' équivalente qui le soit (peut-être). - Définir les fonctions PREMIER et SUIVANT et la table d'analyse pour G'- Simuler l'analyseur déterministe pour : - id - id et - id - + id Exercice 3
Soit la grammaire G2 (S-expressions Lisp) : S (L) | () | at LS|LS - G2 est-elle LL(1) ? Sinon la transformer pour qu'elle le soit (grammaire G’2). - Calculer la table d'analyse - Analyser : (at at) (at at () ) Exercice 4
Soit G3 (expressions conditionnelles) : I si B alors I sinon I | si B alors I | a Bb (a pour "autre", b pour "expressions booléennes", non analysées ici. On simule ainsi l’absence de conflits : les « autres » ne commencent pas par « si ». ) Peut-on mettre G3 sous forme LL(1) ? Peut-on néanmoins "déterminiser l'analyse" - par un dispositif "ad hoc" ? interprétation ? (analyser : si b alors si b alors a sinon a en produisant l’arbre d’analyse)
Exercice 5
Formulez un ensemble de conditions nécessaires et suffisantes pour qu'une grammaire soit LL(1). Indication : considérez les couples de règles A w1, A w2 et trouver une condition sur PREMIER et SUIVANT. Exercice 6 : analyse LL(k) et LL(*)
a. Soit la grammaire (expressions arithmétiques « simplifiée ») EF+E|F-E|F F id | nb Imaginez un automate capable de prédire quelle alternative choisir dans la première règle. b. On complète la grammaire. Même question. EF+E|F-E|F F - F | id | nb c. Peut-on appliquer le même procédé à ? EF+E|F-E|F F - F | ( E ) | id | nb Exercice 7
Éliminer les ε-productions de la grammaire G’2 de l’exercice 3
Licence d'Informatique 2010-2011
Langages et Applications
TD N° 9 : ANALYSE SYNTAXIQUE DESCENDANTE - CORRIGE Exercice 1
1) anbcqd avec q≥n. 2) PREM(U) = {c,d}. PREM(S) = PREM(T) = {a,b}. Table d’analyse a
b
S
S
T
T → aTc
→
TU
S
→
c
d
U → cU
U→ d
TU
T→ b
U 1 seule règle par case : grammaire LL(1) 3) Simulation abccd
abccd$ abccd$ abccd$ bccd$ bccd$ ccd$ cd$ cd$ d$ d$ $
S$ TU$ aTcU$ TcU$ bcU$ cU$ U$ cU$ U$ d$ $
S → TU T→ aTc Dépiler T→ b Dépiler Dépiler U → cU Dépiler U→ d Dépiler Succès
S$ TU$ aTcU$ TcU$ aTccU$ TccU$ bccU$ ccU$ cU$
S → TU T → aTc Dépiler T → aTc Dépiler T→ b Dépiler Dépiler Clash - Echec
Dérivation : S →TU → aTcU → abcU→ abccU→ abccd aabcd
aabcd$ aabcd$ aabcd$ abcd$ abcd$ bcd$ bcd$ cd$ d$
Exercice 2
- G n'est pas LL(1) : PREM(F+E) = PREM(F-E) = PREM(F) = { id, -, ( }. Donc on aura les trois règles pour E dans M(E,x), pour x égal à un de ces 3 terminaux. - Solution: factorisation -> G' : E F E' E' + E | - E | ε F - F | ( E ) | id (où l'on fait apparaître un ε production) - PREMIER : • Eff = {E'} (variables effaçables) • PREM(E) = PREM(F) • PREM(E') = {+,-} • PREM(F) = {-, (, id} - SUIVANT au départ : SUIV(E) = { $ } les autres sont vides Règle 2 : - SUIV(F) contient PREM(E')= {+,-} - SUIV(E) contient ), Au total : SUIV(F) = {+,-} et SUIV(E) ={), $} Règle 3 : - Règle E F E' (E’ effaçable) : SUIV(E’) et SUIV(F) contiennent SUIV(E) - Règles E’ + E et E’ - E : SUIV(E) contient SUIV(E’) Au total : - SUIV(E) = SUIV(E’) = SUIV(E) U SUIV(E’) de l’étape précédente = {), $} - SUIV(F) = SUIV(F) de l’étape précédente U SUIV(E’) = {+,-, ), $} • •
•
Au total : SUIV(E) = SUIV(E’) = { ), $ }, et SUIV(F) = {+,-, ), $} - TABLE D'ANALYSE +
-
E E' E' + E F
E F E' E' - E F-F
( E F E' F(E)
)
id
$
E F E' E' ε
F id
E' ε
- Analyse de : - id - id Entrée
Pile
- id - id $ - id - id $ - id - id $
E$ FE'$ -FE'$
Opération/règle
E F E' F-F dépiler -
id - id $ id - id $ - id $ - id $ id $ id $ id $ $ $
FE'$ idE'$ E'$ -E $ E$ FE'$ idE'$ E'$ $
F id dépiler id E' - E dépiler E F E' F id dépiler id E' ε SUCCES
- Analyse de : - id - + id Jusqu'à la dernière ligne, c'est la même chose. Entrée
Pile
- id - + id $ - id - + id $ id - + id $ id - + id $ id - + id $ - + id $ - + id $ + id $
E$ FE'$ -FE'$ FE'$ idE'$ E'$ -E $ E$
Opération/règle
E F E' F-F dépiler F id dépiler id E' - E dépiler ERREUR
Remarque : on peut imaginer un message d'erreur simple du type : attendu : - ou ( ou id [les éléments de PREM(E)] trouvé : + Ou encore : attendu : phrase de type E
Exercice 3
Soit G2 (S-expressions Lisp) : S (L) | () | at LS|LS Deux problèmes : 1) G2 est récursive à gauche (récursion directe sur L) et 2) PREM( (L) ) et PREM( () ) contiennent tous deux (. - Elimination de la récursivité gauche S (L) | () | at L S L' L' S L' | ε - Déterminisation : par factorisation (G’2) S ( S' | at S' L) | )
L S L' L' S L' | ε Eff = {L'} PREM(S) = {(,at} PREM(S') = PREM(L) U {)} = {(,),at} PREM(L) = PREM(L') = PREM(S) = {(,at} SUIVANT : Etape 1 : SUIV(S) = {$} Etape 2 : - SUIV(L) contient {)} - SUIV(S) contient PREM(L’) Au total : SUIV(L) = {)}, SUIV(S) = {$, (, at}, les autres toujours vide Etape 3 : - SUIV(S’) contient SUIV(S) (première règle) - SUIV(L’) contient SUIV(L) (règle pour L) - SUIV(S) contient SUIV(L) (règle pour L avec L’ effaçable) - SUIV(S) contient SUIV(L’) (règle pour L ‘ avec L’ effaçable) Au total : SUIV(L’) = SUIV(L) = {)}, SUIV(S’) = SUIV(S) = {$, (, at, )}, • •
•
S S' L L'
PREMIER
SUIVANT
( at ( ) at ( at ( at
( ) at $ ( ) at $ ) )
- Table d'analyse
( S S' L L'
S ( S' S' L) L S L' L' S L'
) S' ) L' ε
at S at S' L) L S L' L' S L'
$
Exercice 4
G4 : I si B alors I sinon I | si B alors I | a Bb On peut essayer de factoriser "si B alors I": G'4 : I si B alors I I' | a I' sinon I | ε Bb Eff = {I'} PREM(I) = {si,a} PREM(I') = {sinon} PREM(B) ={b} SUIV(I) = {$} U PREM(I') U SUIV(I') SUIV(I') = SUIV(I) SUIV(B) = {alors} a I
b
Ia
si
= {$, sinon}
alors
$
I' sinon I I' ε
I' ε
I si B alors I I'
I'
E
sinon
Bb
La grammaire n'est donc pas LL(1). Solution : décider que l’on préférera systématiquement la règle I'
sinon I, ce qui correspond à associer le sinon avec le alors le plus proche, comme déjà vu par une autre méthode dans le TD n° 4.
Entrée
Opération/règle
Pile
I si B alors I I’
si b alors si b alors a sinon a $
I$
si b alors si b alors a sinon a $
si B alors I I’$
dépiler
b alors si b alors a sinon a $
B alors I I’$
Bb
b alors si b alors a sinon a $
b alors I I’$
dépiler
alors si b alors a sinon a $
alors I I’$
dépiler
I si B alors I I’
si b alors a sinon a $
I I’$
si b alors a sinon a $
si B alors I I’I’$
Dépiler
b alors a sinon a $
B alors I I’I’$
Bb
b alors a sinon a $
b alors I I’I’$
Dépiler
a sinon a $
alors I I’I’$
Dépiler
a sinon a $
I I’I’$
I a
a sinon a $
a I’I’$
Dépiler
sinon a $
I’I’$
sinon a $
sinon I I’ $
a$
I I’ $
a$
a I’ $
Dépiler Ia Dépiler
$
I’ $
I’ ε
$
$
I’
sinon I
SUCCES
Exercice 5
(a) Pour tout couple de productions A w1 et Aw2, (w1 et w2 non vides) PREM(w1) et PREM(w2) sont disjoints (pas de conflit entre 2 règles non vides). (b) Si A est effaçable pour toute production A w (w non vide) PREM(w) et SUIV(A) sont disjoints (pas de conflit entre un effacement de A et une règle non vide). Exercice 6 : analyse LL(k) et LL(*) Préliminaire : même question pour :
AaB|aC B b X CcY
/ --- {b} - s2 => Règle 1 so ---- {a} -- s1 \ ---{c}-- s3 => Règle 2 a. Soit la grammaire (expressions arithmétiques « simplifiée ») EF+E|F-E|F F id | nb Imaginez un automate capable de prédire quelle alternative choisir dans la première règle. / --- {+} --> s2 (=> Règle 1) s0 --- {id,nb} ---> s1 --- {-} ---> s3 (=> Règle 2)
\ --- {$} --> s4 (=> Règle 3) b. On complète la grammaire. Même question. EF+E|F-E|F F - F | id | nb Même automate avec en outre une boucle {-} sur s0. c. Peut-on appliquer le même procédé à ? EF+E|F-E|F F - F | ( E ) | id | nb Impossible : le langage parenthésé induit par (E) ne peut être reconnu par un automate. Dans les 2 cas précédent, ce qui « marche » c’est que l’on peut reconnaître par un automate le langage qui « mène » à un jeton discriminant (+ ,- $)
NB. L’exemple en ANTLR. Notez la forme un peu différente de la F-règle : ANTLR exige la forme en EBNF pour reconnaître que le sous langage considéré est régulier et inférer l’automate. grammar LLetoile; exp
: somme '\n';
somme: facteur '+' somme | facteur '-' somme | facteur ; facteur : '-'* (ID | NB) ; ID
:
(('a'..'z')|('A'..'Z'))+ ;
NB
:
('0'..'9')+ ;
WS
: ( ' ' | '\t' ) {$channel=HIDDEN;} ;
Exercice 7
S ( S' | at S' L) | ) L S L' L' S L' | ε Eff = {L'} L’ apparaît dans la règle pour L. On la « duplique » et on supprime règle L’ ε Idem pour L’. S ( S' | at S' L) | ) L S L' | S L' S L' | S On peut évidemment simplifier les 2 dernières règles :
S ( S' | at S' L) | ) LSL|S Remarque : on a réintroduit le non-déterminisme !