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 Z i 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 ::= Z 1 Z 2 Z k est une production, et que tous les nonterminaux Z i 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 ::= Z 1 Z 2 Z k 'a' γ est une production et que les Z i sont annulables alors 'a' Premier(X) (et Premier(X) contient tous les terminaux des Premier(Z i )) 4)Si X ::= Z 1 Z 2 Z k Y γ est une production et que les Z i sont annulables alors Premier(X) contient tous les terminaux de Premier(Y) (et des Premier(Z i ))
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 Terminaux : 'a' 'c' 'd' Productions : S ::= X Y S 'd' Y ::= 'c' ε X ::= Y 'a' Annulable = {X,Y} Premier(S) : P(X),P(Y),'d' Premier(Y) : 'c' Premier(X) : P(Y),'a' Premier(X) : 'c','a' Premier(S) : 'c','a','d'
Exemple Non-terminaux : S Y Terminaux : 'c' 'd' Productions : S ::= Y 'd' ε Y ::= S 'c' ε Annulable = {S,Y} Premier(S) : P(Y),'d' Premier(Y) : P(S),'c' 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 Z 1 Z 2 Z n 'a' δ et que tous les Z i sont annulables alors 'a' est dans Suivant(X) (ainsi que les Premier(Z i )) 5)Si A ::= γ X Z 1 Z 2 Z n Y δ et que tous les Z i sont annulables alors Premier(Y) est dans Suivant(X) (ainsi que les Premier(Z i )) 6)Si Y ::= γ X Z 1 Z 2 Z n et que tous les Z i sont annulables alors Suivant(X) contient Suivant(Y) (ainsi que les Premier(Z i ))
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 Terminaux : 'a' 'c' 'd' Productions : S ::= X Y S 'd' Y ::= 'c' ε X ::= Y 'a' Annulable = {X,Y} Premier(Y) : 'c' Premier(X) : 'c','a' Premier(S) : 'c','a','d' Suivant(S) : vide Suivant(Y) : P(S),S(S),S(X) Suivant(X) : P(Y),P(S),S(S) Suivant(X) : 'c','a','d' Suivant(Y) : 'c','a','d'
Exemple Non-terminaux : S E O F Terminaux : '+' '-' 'n' '(' ')' Productions : S ::= E '$' E ::= E O E F O ::= '+' '-' ε F ::= 'n' '(' E ')' Annulable={O} Premier(O)={+,-} Premier(E)={n,(} Suivant(S) : vide Suivant(E) : P(O),P(E),')' Suivant(O) : P(E) Suivant(F) : S(E) Suivant(O) : 'id','n','(' Suivant(E) : '+','-','n','(',')' Suivant(F) : '+','-','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')' Annulable Premier Suivant S P(E) E P(T) ) $ E2 oui + - S(E) T P(F) P(E2),S(E2),S(E) T2 oui S(T) F ( 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 Suivant S ( id n E ( id n ) $ E2 oui + - ) $ T ( id n ) + - $ T2 oui ) + - $ F ( id n ) + - $
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 : Premier(OE) : '+','-','n','(' S ::= E '$' E ::= E O E F O ::= '+' '-' ε F ::= 'n' '(' E ')'
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 Start : S Terminaux : 'a' 'c' 'd' Productions : S ::= X Y S 'd' Y ::= 'c' ε X ::= Y 'a' Non-terminaux : R S X Y Start : R Terminaux : 'a' 'c' 'd' '$' Productions : R ::= S '$' S ::= X Y S 'd' Y ::= 'c' ε X ::= Y 'a'