TD 2 Top-down parsing LL(1) . Rappel cours: Objectif: - automatiser l’analyse d’une phrase à l’aide d’un analyseur construit à partir des règles de grammaire - faire une analyse « naturelle », descendante, en construisant l’arbre à partir de sa racine et en lisant la phrase à analyser de gauche à droite en considérant un seul terminal à la fois. Analyseur : a + b $ Automate (analyseur) Pile X Y Z $ sorties matrice Non terminaux Terminaux +$ - M[X,a] règle permettant d’obtenir le terminal à partir du non terminal X, de façon directe ou indirecte (plusieurs règles appliquées) Pile initialisée à $S Entrée : phrase à analyser, terminée par $ Algorithme de l’analyseur : (X sommet de pile, a : le terminal courant en entrée) 1- X=a=$ : terminé, phrase reconnue 2- X=a≠$ : dépiler X, avancer au terminal suivant en entrée 3- X≠a : - si x est non terminal, le remplacer par sa dérivation trouvée dans M[X,a], empilant par la fin - si M[X,a] est vide erreur, phrase non reconnue - si X est non terminale : idem H. Kassel 1 langages/compilation (2010/2011) Remarques : - L’analyseur ne peut fonctionner que s’il y a au plus une règle par entrée de M. Les grammaires qui satisfont cette condition sont dites LL(1). Les grammaires ambigües ou récursives à gauche ne sont pas LL(1) - S’agissant de la récursion à gauche, on peut l’éliminer de façon automatique A->Aα|β A-> βA’ A’-> αA’|ε Construire l’analyseur = construire la matrice M en fonction de la grammaire G La construction de M s’appuie sur les fonctions First() et Follow() Définition : α chaine de symboles de G(terminaux ou non) First(α) = {terminaux a tel que α=> aβ, plus ε si α=>ε} A non terminal de G Follow(A)= { terminaux a tel que S=>αAaβ, plus $ si S=>αA} Construction de la matrice M : Pour chaque règle A->α de G : 1. Ajouter A->α pour tous les M[A,a] où a appartient à First(α)-{ε} 2. Si ε appartient à First(α), ajouter A->α dans tous les M[A,a] où a appartient à Follow(A) Calcul pratique de First() et Follow() First(X), X symbole de G (on ne peut jamais avoir $ dans First(…) ) 1. Si X est terminal : First(X)={X} 2. Si X->ε : ajouter εà First(X) 3. Si X-> X1X2…Xn: ajouter tous les non-ε (non nul) de First(X1)à First(X) ; si ε appartient à First(X1), ajouter tous les non-ε de First(X2) à First(X) ; etc etc ; si ε appartient à First(X) 1≤1≤n, ajouter ε à First(X) Follow(X) est non terminal de G (on ne peut jamais avoir ε dans Follow(…) ) 1. Si X=S, initialiser Follow(X=S) à {$} 2. Si A->αXβ : ajouter les non-ε de First(β) à Follow(X) 3. Si A->αX ou A->αXβ et ε appartient à First(β) : ajouter Follow(A) à Follow(X) Exercise 1 a) Eliminate the left recursion from the following grammar : S (L) | a L L, S | S L->L… récursion à gauche ,S est α et S est β H. Kassel 2 langages/compilation (2010/2011) 1. 2. 3. 4. S-> (L) S-> a L-> SL’ (L’ c’est qq chose^^) L’->,SL’ (à partir de là on fait en sorte que ,S soit suivi de qq chose de nul pour garder G donnée) 5. L’->ε b) Construct a predictive parser for the grammar in (a). Pour construire M, il faut calculer les First() et les Follow() des non-terminaux de G First(S) (S non terminale donc pas la règle 1 et S ne donne pas ε donc pas la 2 non plus) Est-ce que l’on a S en parti gauche ? First(S)= First( ( )1 U First(a)2 U…. (en rouge les règles en haut de la page^^) -{ε} -{ε} = {(a} First(L)= First(S)3 U…. = First(S)={(a} First(L’)={ε}5 U First(,) U… = {ε,} -{ε} Follow(S) = {$} U First(L’)3+4 U Follow(L)3 U Follow(L’)4 (est ce que l’on a S en partie droite?) 1 -{ε}2 3 3 (règle de construction!!!) Follow(L) = First( ) )1 U … = {)} -{ε}2 Follow(L’)= Follow(L)3 U Follow(L’)4 3 3 ={)} On reprend Follow(S) car on avait pas toutes les données: Follow(S)= {$,)} a , S S->a 1 L L->SL’1 L’ L’->,SL’1 ( S->(L)1 L->SL’1 ) $ L’->ε2 c) Show the behavior of the parser on the following sentences : H. Kassel 3 langages/compilation (2010/2011) on fait du surplus avec (a): Pile $S Entrée (a)$ Sorties S->(L) cas 3 de l’automate :s? Cas 2 L->SL’ cas 3 S->a cas 3 Cas 2 L’->ε cas 3 Cas 2 Terminé, phrase reconnue $)L( (a)$ $)L a)$ $)L’S a)$ $)L’a a)$ $)L’ )$ $) )$ $ $ Quand on a une règle on reprend à l’envers Il faut impérativement le meme nombre d’étapes que la correction (il existe qu’une méthode !!!) ici il faut OBLIGATOIREMENT 8étapes (a,a) Pile $S $)L( $)L $)L’S $)L’a $)L’ $)L’S, $)L’S $)L’a $)L’ $) $ 12étapes!!! (a,(a,a)) 21étapes (a,((a,a),(a,a))) Entrée (a,a)$ (a,a)$ a,a)$ a,a)$ a,a)$ ,a)$ ,a)$ a)$ a)$ )$ )$ $ Sorties S->(L) L->SL’ S->a L’->,SL’ S->a L’->ε Fin reconnue Exercise 2 Construct a predictive parser for the following grammar : Exprb Exprb ou Termeb | Termeb Termeb Termeb et Facteurb | Facteurb Facteurb non Facteurb | (Exprb) | vrai | faux Exercise 3 Show that the following grammar : S AaAb | BbBa H. Kassel 4 langages/compilation (2010/2011) Aε Bε is LL(1) Exercise 4 Show that a grammar with no -productions in which each alternative begins with a distinct terminal is always LL(1). H. Kassel 5 langages/compilation (2010/2011)