Compilation Algorithmes d'analyse syntaxique Préliminaires ● Si A est un non-terminal et γ une suite de terminaux et de non-terminaux, on note : A ―›› γ si en partant de A on peut arriver à γ par dérivations successives (y compris aucune donc A ―›› A). Préliminaires ● Non-terminaux : E ● Terminaux : '+' 'n' 'id' ● E ::= E '+' E | 'id' | 'n' E ―› E '+' E ―› 'id' '+' E ―› 'id' '+' E '+' E ―› 'id' '+' E '+' 'n' E ―›› E E ―›› 'id' '+' E '+' E E ―›› 'id' '+' E '+' 'n' 'id' '+' E ―›› 'id' '+' E '+' 'n' Algorithmes d'analyse syntaxique ● Il existe deux principaux types algorithmes d'analyse syntaxique : – prédictifs ou descendants ou LL ● – Left-to-right Leftmost ascendants ou LR ● Left-to-right Rightmost Algorithmes d'analyse syntaxique ● Ces deux algorithmes nécessitent de calculer, à partir de la grammaire algébrique : – l'ensemble Annulable (nullable) – la fonction Premier (first) – la fonction Suivant (follow) Annulable, premier et suivant ● Les algorithmes pour calculer ces trois objets ont tous le même déroulement : – On dispose de propriétés caractéristiques sur ces objets – On applique les propriétés pour obtenir des équations ensemblistes entre ces objets – On résoud le système d'équations ensemblistes Annulable, premier et suivant ● Dans les propriétés qui suivent : – On apprend quelque chose sur X – [à l'aide de Y] – [quand les Zi sont annulables] L'ensemble Annulable ● L'ensemble Annulable contient l'ensemble des non terminaux annulables, c'est-à-dire ceux qui peuvent se dériver en ε, éventuellement en appliquant plusieurs productions : X ∈ Annulable si X ―›› ε L'ensemble Annulable ● Non-terminaux : S X Y ● Terminaux : 'a' 'c' 'd' ● Productions : – S ::= X Y S | 'd' – Y ::= 'c' | ε – X ::= Y | 'a' Annulable = {X,Y} Propriétés de Annulable ● Propriétés : 1)Si X ::= ε est une productions, alors X est annulable 2)Si X ::= Z1 Z2 … Zk est une production, et que tous les nonterminaux Zi sont annulables, alors X est annulable. ● Remarques : ● ● ● S'il n'y a aucune production de type X ::= ε, aucun nonterminal n'est annulable Seules les production dont le membre droit est ε ou ne contient que des non-terminaux sont à considérer Les productions qui donnent des informations sur X sont celles dont le membre gauche est X Calcul de Annulable ● ● ● On commence par déclarer annulable les non-terminaux X pour lesquels il y a une production X ::= ε À l'aide des productions dont le membre droit ne contient que des non-terminaux, ajouter à l'ensemble Annulable les non-terminaux rendus annulables par la propriété 2) Remarques – Une fois que l'on sait un non-terminal annulable, on n'a plus besoin de considérer les productions associées Exemple ● Non-terminaux : S X Y ● Terminaux : 'a' 'c' 'd' ● Productions : – S ::= X Y S | 'd' – Y ::= 'c' | ε – X ::= Y | 'a' 1)Y est annulable avec Y ::= ε 2)Les productions potentiellement utiles sont X ::= Y et S ::= X Y S 3)X est annulable avec X ::= Y 4)On n'apprend plus rien donc seuls X et Y sont annulables La fonction Premier ● La fonction Premier associe à un non-terminal l'ensemble des terminaux qui peuvent apparaître en premier une fois appliquées une ou plusieurs dérivations à partir de ce non-terminal : a ∈ Premier(X) si X ―›› aγ γ est une suite de terminaux et non-terminaux, éventuellement vide La fonction Premier ● ● ● Non-terminaux : S E T F Terminaux : '+' '-' '×' '*' '(' ')' 'id' 'n' '$' Productions : – S ::= E '$' – E ::= E '+' T | '-' T | T – T ::= T '×' F | '*' F | F – F ::= 'id' | 'n' | '(' E ')' Premier(E) = {'(','id','n','*','-'} Premier(T) = {'(','id','n','*'} Premier(F) = {'(','id','n'} Propriétés de Premier ● Propriétés : 1)Si X ::= 'a' γ est une production alors 'a' ∈ Premier(X) 2)Si X ::= Y γ est une production alors Premier(X) contient tous les terminaux de Premier(Y) 3)Si X ::= Z1 Z2 … Zk 'a' γ est une production et que les Zi sont annulables alors 'a' ∈ Premier(X) (et Premier(X) contient tous les terminaux des Premier(Zi)) 4)Si X ::= Z1 Z2 … Zk Y γ est une production et que les Zi sont annulables alors Premier(X) contient tous les terminaux de Premier(Y) (et des Premier(Zi)) Propriétés de Premier ● Remarques 1)Les productions qui donnent des informations sur X sont celles dont le membre gauche est X 2)La production E ::= E γ enseigne que Premier(E) contient Premier(E), ce que l'on savait déjà, mais attention si E est annulable Calcul de Premier ● ● ● Calculer l'ensemble Annulable Pour chaque non-terminal E, appliquer les propriétés aux productions dont le membre gauche est E pour trouver Premier(E) en fonction des autres ensembles Premier — on abrégera Premier(X) en P(X) Résoudre les équations ensemblistes pour trouver ces ensembles – en remplaçant les ensembles connus dans les équations – si cela ne suffit pas, réfléchir ! Exemple ● ● ● Non-terminaux : S E T F Terminaux : '+' '-' '×' '*' '(' ')' 'id' 'n' '$' Productions : – S ::= E '$' – E ::= E '+' T | '-' T | T – – T ::= T '×' F | '*' F | F F ::= 'id' | 'n' | '(' E ')' ● Premier(S) : P(E) ● Premier(E) : '-',P(T) ● Premier(T) : '*',P(F) ● Premier(F) : 'id','n','(' ● Premier(T) : '*','id','n','(' ● Premier(E) : '-','*','id','n','(' ● Premier(S) : '-','*','id','n','(' Exemple ● Non-terminaux : S X Y ● Premier(S) : P(X),P(Y),'d' ● Terminaux : 'a' 'c' 'd' ● Premier(Y) : 'c' ● Productions : ● Premier(X) : P(Y),'a' ● – S ::= X Y S | 'd' ● Premier(X) : 'c','a' – Y ::= 'c' | ε ● – X ::= Y | 'a' Premier(S) : 'c','a','d' Annulable = {X,Y} Exemple ● Non-terminaux : S Y ● Premier(S) : P(Y),'d' ● Terminaux : 'c' 'd' ● Premier(Y) : P(S),'c' ● Productions : ● ● – S ::= Y 'd' | ε – Y ::= S 'c' | ε Annulable = {S,Y} En réfléchissant : Premier(S)={'c','d'} Premier(Y)={'c','d'} La fonction Suivant ● La fonction Suivant associe à un non-terminal, les terminaux qui peuvent apparaître après ce non-terminal dans une suite de dérivations issues du start : b ∈ Suivant(X) si S ―›› γXbδ γ et δ sont des suites de non-terminaux et de terminaux, éventuellement vides La fonction Suivant ● ● ● Non-terminaux : S E T F Terminaux : '+' '-' '×' '÷' '(' ')' 'id' 'n' '$' Productions : – S ::= E '$' – E ::= E '+' T | E '-' T | T – T ::= T '×' F | T '÷' F | F – F ::= 'n' | 'id' | '(' E ')' ● Suivant(E)={+,-,),$} ● Suivant(T)={×,÷,+,-,),$} ● Suivant(F)={×,÷,+,-,),$} Propriétés de Suivant ● Propriétés : 1)Si A ::= γ X 'a' δ alors 'a' est dans Suivant(X) 2)Si A ::= γ X Y δ alors Premier(Y) est dans Suivant(X) 3)Si Y ::= γ X alors Suivant(X) contient Suivant(Y) 4)Si A ::= γ X Z1 Z2 … Zn 'a' δ et que tous les Zi sont annulables alors 'a' est dans Suivant(X) (ainsi que les Premier(Zi)) 5)Si A ::= γ X Z1 Z2 … Zn Y δ et que tous les Zi sont annulables alors Premier(Y) est dans Suivant(X) (ainsi que les Premier(Zi)) 6)Si Y ::= γ X Z1 Z2 … Zn et que tous les Zi sont annulables alors Suivant(X) contient Suivant(Y) (ainsi que les Premier(Zi)) Propriétés de Suivant ● Remarques 1)Les productions qui donnent des informations sur X sont celles dont le membre droit contient X, pour chaque occurrence de X 2)La production E ::= γ E enseigne que Suivant(E) contient Suivant(E), ce que l'on savait déjà Calcul de Suivant ● ● Calculer Annulable et Premier Pour chaque non-terminal E, appliquer les propriétés à chaque occurrence de E dans les membres droits des productions — on abrégera Suivant(X) en S(X) : – regarder ce qui suit : ● ● si c'est un terminal 'x', ajouter 'x' à Suivant(E) si c'est un non-terminal Y, ajouter P(Y) à Suivant(E) – ● ● si Y est annulable, reprendre à partir de ce qui suit Y là si rien ne suit, ajouter S(A) à Suivant(E), où A est le membre gauche de la production Résoudre les inéquations ensemblistes. Exemple ● ● ● Non-terminaux : S E T F Terminaux : '+' '-' '×' '÷' '(' ')' 'id' 'n' '$' Productions : – S ::= E '$' – E ::= E '+' T | E '-' T | T – T ::= T '×' F | T '÷' F | F – F ::= 'n' | 'id' | '(' E ')' ● Suivant(E) : '$','+','-',')' ● Suivant(T) : S(E),'×','÷' ● Suivant(F) : S(T) ● Suivant(T)='+','-',')','$','×','÷' ● Suivant(F)='+','-',')','$','×','÷' Exemple ● Non-terminaux : S X Y ● Suivant(S) : vide ● Terminaux : 'a' 'c' 'd' ● Suivant(Y) : P(S),S(S),S(X) ● Productions : ● Suivant(X) : P(Y),P(S),S(S) ● – S ::= X Y S | 'd' ● Suivant(X) : 'c','a','d' – Y ::= 'c' | ε ● – X ::= Y | 'a' Suivant(Y) : 'c','a','d' Annulable = {X,Y} Premier(Y) : 'c' Premier(X) : 'c','a' Premier(S) : 'c','a','d' Exemple ● Non-terminaux : S E O F ● Suivant(S) : vide ● Terminaux : '+' '-' 'n' '(' ')' ● Suivant(E) : P(O),P(E),')' ● Productions : ● Suivant(O) : P(E) – S ::= E '$' ● Suivant(F) : S(E) – E ::= E O E | F ● – O ::= '+' | '-' | ε Suivant(O) : 'id','n','(' ● – F ::= 'n' | '(' E ')' Suivant(E) : '+','-','n','(',')' ● Suivant(F) : '+','-','n','(',')' ● Annulable={O} Premier(O)={+,-} Premier(E)={n,(} Exercice ● Non-terminaux : S E E2 T T2 F ● Terminaux : '$' '+' '-' '×' '÷' '(' ')' 'id' 'n' ● Productions : – S ::= E '$' – E ::= T E2 – E2 ::= '+' T E2 | '-' T E2 | ε – T ::= F T2 – T2 ::= '×' F T2 | '÷' F T2 | ε – F ::= 'n' | 'id' | '('E')' S E E2 T T2 F Annulable Premier Suivant P(E) P(T) )$ oui +S(E) P(F) P(E2),S(E2),S(E) oui ÷× S(T) ( id n P(T2),S(T2),S(T) Exercice ● Non-terminaux : S E E2 T T2 F ● Terminaux : '$' '+' '-' '×' '÷' '(' ')' 'id' 'n' ● Productions : – S ::= E '$' – E ::= T E2 – E2 ::= '+' T E2 | '-' T E2 | ε – T ::= F T2 – T2 ::= '×' F T2 | '÷' F T2 | ε – F ::= 'n' | 'id' | '('E')' Annulable Premier S ( id n E ( id n E2 oui +T ( id n T2 oui ÷× F ( id n Suivant )$ )$ )+-$ )+-$ )+-÷×$ Extensions ● ● On peut étendre Premier et Annulable (pas Suivant) aux suite de terminaux et non-terminaux : γ est annulable si elle ne contient que des non terminaux annulables ● Premier('a'γ) = { a } ● Si Z est annulable, Premier(Zγ) = P(Z) + Premier(γ) ● Si A n'est pas annulable, Premier(Aγ) = P(A) Exemple ● Non-terminaux : S E O F ● Terminaux : '+' '-' 'n' '(' ')' ● Productions : – S ::= E '$' – E ::= E O E | F – O ::= '+' | '-' | ε – F ::= 'n' | '(' E ')' ● Premier(OE) : '+','-','n','(' Notion de lookahead ● ● ● Lors de l’analyse du code, on lira un certain nombre de lexèmes (en général un) à l’avance, par rapport à ce que l’on a déjà analysé Ces lexèmes constituent le lookahead Les algorithmes agissent en fonction des valeurs de ces lookahead Grammaire augmentée ● ● Pour effectuer le parsing, il faut spécifier aux algorithmes quand arrive la fin du fichier : – on ajoute un terminal spécial (en général '$') qui sera envoyé par le lexer un fois la fin du fichier atteinte – en plus des actions usuelles, ce terminal est utilisé par les algorithmes pour savoir quand le parsing est terminé Pour cela, on augmente les grammaires : – On ajoute un nouveau start, et un nouvel terminal '$' – On ajoute la production nouveauStart ::= ancienStart '$' Exemple ● Non-terminaux : S X Y ● Non-terminaux : R S X Y ● Start : S ● Start : R ● Terminaux : 'a' 'c' 'd' ● Terminaux : 'a' 'c' 'd' '$' ● Productions : ● Productions : – S ::= X Y S | 'd' – R ::= S '$' – Y ::= 'c' | ε – S ::= X Y S | 'd' – X ::= Y | 'a' – Y ::= 'c' | ε – X ::= Y | 'a'