La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

IHDC 2105 Syntaxe et sémantique des langages de programmation Pierre-Yves Schobbens Bureau 409 081/72 49 90 rue Grandgagnage 21 5000 Namur

Présentations similaires


Présentation au sujet: "IHDC 2105 Syntaxe et sémantique des langages de programmation Pierre-Yves Schobbens Bureau 409 081/72 49 90 rue Grandgagnage 21 5000 Namur"— Transcription de la présentation:

1 IHDC 2105 Syntaxe et sémantique des langages de programmation Pierre-Yves Schobbens Bureau / rue Grandgagnage Namur

2 Plan 0. Introduction 1. Analyse lexicale : Langages réguliers 2. Analyse syntaxique : Langages non contextuels 3. Analyse statique (p.ex. typage): Grammaires attribuées 4. Eléments de génération de code 5. Introduction à la sémantique

3 Références Grune, Bal, Jacobs, Langendoen « Compilateurs », Dunod, Aho, Sethi, Ullman : « Compilateurs : principes, techniques et outils », InterEditions, 1998, BUMP # 1 412/037 R. Wilhem, D. Maurer : « Les compilateurs : théorie, construction, génération », Masson, 1994, BUMP # 1 412/030

4 Chapitre 0. Introduction

5 Types de langages Les techniques de ce cours sappliquent à: –des langages de programmation :Pascal, Ada, … –des langages de commande : JCL, Sh, Csh, … – des langages de description de données: SQL (DDL), XML,... – des langages de spécification : VDM, Z, Albert,... – des langages de formulaires : EDIFACT, CGI (WWW),... – des formats de messages (réseaux) –des langages de documents : EQN, HTML,

6 Paradigmes de langages de programmation 1. impératifs : Algol, Pascal, Ada, Fortran, Cobol, Modula, C axés sur laffectation 2. fonctionnels : Lisp, ML, Hope, Miranda, Haskell, FP basés sur lévaluation des expressions 3. logiques : Prolog, Gödel basés sur la preuve de formules 4. orientés objet : Simula, Smalltalk, C++, Eiffel, CLOS, Java basés sur lhéritage N.B. :Les paradigmes ne sont pas mutuellement exclusifs.

7 Exécution des langages 2 extrêmes 1. Les interpréteurs - lisent le programme au fur et à mesure les programmes peuvent être créés dynamiquement 2. Les compilateurs - traduisent lensemble du programme soit- en langage dune machine concrète 486, P6, Power ou- en langage dune machine abstraite SECD, WAM, JVM, P-MACHINE

8 Rôle dun compilateur compilateur Code source Code cible Code machine du compilateur compilateur dimplémentation Générateur de compilateur (Flex, Bison) Code dimplémentation du compilateur Spécification

9 Structure dun compilateur 1. analyse lexicale 2. crible 3. analyse syntaxique 4. analyse sémantique 5. optimisations 6. allocation mémoire 7. génération de code 8. optimisations propres à la cible avant arrière reconnaître les « mots » reconnaître les « phrases » vérifier les types, etc. élimination de code inutile, etc. choisir la place des variables instructions machine séquence plus efficaces D25

10 Ex. compilateurs GNU C ANSI 68000Pentium Power Ada 95 C++ Pascal Front-ends (1-4) partie avant Middle-end (5) Back-ends (6-9) partie arrière

11 Outils pour les langages Editeurs structurels : édition intelligente Analyseurs : p.ex. pour la rétro-ingénierie, Y2K Paragrapheurs : mettent en page D17

12 Chapitre 1 : Analyse Lexicale Rôle : retrouver les mots qui composent le texte

13 Place de lanalyse lexicale Analyseur lexical Texte source = caractères « mots » = lexèmes générateur danalyseur lexical Expressions régulières Automate fini D

14 Plan 1. Langages et expressions régulières 2. automates finis : Kleene 2.1 non-déterministe 2.2 déterministe 2.3 minimal 3. Régulier ou pas?

15 Définitions : alphabet, ensemble de caractères (donné, fini) ex. : ASCII, EBCDIC, ISO-Latin-1, UniCode,... texte, mot, phrase : suite de caractères Langage : ensemble de phrases Note : convient pour les langages séquentiels (parlé, écrit) mais pas pour des langages graphiques : phrase vide. : concaténation (parfois le. est omis) D112

16 Propriétés x. = x =. xneutre x. (y. z) = (x. y). zassociativité Ces propriétés sont complètes D113

17 Ordres X est un préfixe de Y : Y commence par X –« 12 » est un préfixe de « 1234 » X est un suffixe de Y : Y finit par X –« 34 » est un suffixe de « 1234 » X est une sous-chaîne de Y : X sobtient par suppression dun suffixe et dun préfixe –« 23 » est une sous-chaîne de « 1234 » D113

18 Opérations sur les langages D114

19 Propriétés D117

20 Expressions régulières = les expressions écrites avec souvent omis aussi noté ou + Langage régulier = langage décrit par une expression régulière D115

21 Exemples dexpressions régulières 1. = 0 | (1| 2 | 3 | 4 | 6 | 7 | 8 | 9). (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9)* une constante décimale de C est, soit un 0 seul, soit un chiffre significatif suivi dautant 0 1 nest pas une constante décimale en C, mais octale. 1 0 est une constante décimale. 2. = (0 | 1)* = (a | b |... | z). (a | b |... | z | 0 |... | 1)*

22 Abréviations } L n =L. L.... L où n est un naturel n n fois L + =L L* [a - z]=tous les caractères entre a et z dans le code ASCII = les lettres = a b... z L ? =L L [n-m] =L n L n+1... L m

23 2. Automates finis b a eb a e caractère courant mot à reconnaître état final ou accepteur q4q4 q3q3 q2q2 q1q1 q0q0 état initial état courant a c b a b D135

24 Définition Un automate fini (non-déterministe avec transitions vides) se compose de : D136

25 Fonctionnement Un automate accepte un mot m si on peut trouver un chemin c: –Qui commence dans létat initial –Qui finit dans un état final –Qui suit des transitions –La concaténation des étiquettes des transitions donne m Les mots acceptés forment le langage de lautomate L(A) D137

26 Exemple: constante naturelle décimale de C [1-9] 0 [0-9]

27 Exemple : multiples de 2 en notation binaire Multiples de 2 en notation binaire : Ils se terminent toujours par 0. Ceci est facile à représenter par un automate non-déterministe

28 Exemple : identificateurs de Pascal a a z z 0 9 notation : [a-z] [a-z 0-9]

29 Exemple : Multiples de 7 rs a Principe: r est le reste par 7 du nombre lu (n) m = n * 10 + a donc s = (r * 10 + a) mod 7

30 Exemple : Multiples de 7

31 Théorème de Kleene Un langage est régulier ssi cest le langage dun automate fini Preuve : La preuve est donnée par 2 algorithmes 1. qui construit un automate pour chaque expression régulière 2. qui construit une expression régulière pour chaque automate fini en gardant le même langage.

32 Expression automate cas de base début (a) Automate pour (b) Automate pour. début (c) Automate pour le caractère "a". début a

33 Expression automate: union Pour R 1 Pour R 2 début (a) Construction de lautomate dunion pour deux expressions régulières

34 Expression automate: concaténation Pour R 1 Pour R 2 début (b) Construction de lautomate de concaténation pour deux expressions régulières

35 Expression automate: répétition Pour R 1 début (c) Construction de lautomate de fermeture pour deux expressions régulières

36 Exemple : constante décimale de C F

37 Problèmes 1. Lautomate contient des -transitions 2. Il nest pas déterministe: moins efficace 3. Il y a beaucoup trop détats (80 dans lexemple)

38 Automate déterministe Un automate fini est déterministe, intuitivement sil ne peut se comporter que dune façon pour un mot donné : –Il na pas de transition- –Étant donné un état de départ et un caractère lu, il y a au plus 1 état darrivée Il est complet si, étant donné un état de départ et un caractère lu, il y a au moins un état darrivée D138

39 Idée de la déterminisation début k S 1, S 2,..., S k Dans lautomate déterministe: Un seul chemin vers un état qui représente tous ceux où une copie peut être. début k S1S1 S2S2 SnSn... Dans lautomate non déterministe: Plusieurs chemins étiquetés

40 Déterminisation On construit un nouvel automate A Note : on peut diminuer le nombre détats en ne considérant que les états accessibles. Notation : puisque est fonctionnelle pour les automates déterministes, on emploie une notation fonctionnelle - De même alphabet - nouvel état = ensemble danciens états - état initial = états accessibles de q 0 par des transitions vides - état final = état contenant un ancien état final - transition = ensemble des états où une copie peut arriver S,a) = succs( {p | p q, q S} ) D140 a

41 Exemple : constantes décimales de C Quelques ensembles fermés par F État initial 0

42 Constantes décimales de C déterminisé

43 Exemple Reconnaître une suite de 1, 2, 3 où le dernier chiffre est apparu précédemment. Expression régulière : * (1 * 1 | 2 * 2 | 3 * 3), où Automate : ,2,3

44 Exemple : déterminisation ,1 1/2 0,2 0,3 0,1,4 0,1,2 0,1,3 0,2,4 0,2,3 0,3, / /3 1 1/ ,1 2,4 0,1 2,3 0,1 3,4 0,2 3,4 1/3 2/3 1/2/ ,1 2,3,4 Intuition : Les états marqués 1 (ou 2, 3) signifient «on a rencontré un 1 (ou 2,3)». Létat 4 signifie : on a rencontré un 2° caractère identique, donc on peut terminer.

45 Algorithme de minimisation retirer les états non accessibles compléter lautomate Idée : On met les états dans des classes différentes quand on voit quils ont un comportement différent. répéter pour chaque K, K := ( \ {K}) {{K i }} où {K i } est la partition de K la plus grosse tous les états de K i arrivent dans la même classe pour chaque caractère jusquà ce que ne change pas : partition couranteles états sont groupés en classes := {F, Q \ F}au départ, on crée deux classes: les finaux et les non-finaux Fusionner les états d une même classe Retirer létat mort

46 Exemple de minimisation « Constante décimale de C » Non finaux Finaux Minimisation du nombre détats : partition des états

47 9 0 Exemple de minimisation « Constante décimale de C » Fusion détats : partition des états

48 Kleene (2) automate fini expression régulière (1) 1° étape : automate fini jeu déquations pour chaque état on crée une équation : S 3 = a. S 4 b. S 5 S 3 représente lensemble des chaînes quon peut lire en partant de S 3. Note: ces équations ont plusieurs solutions, c'est la plus petite qui nous intéresse. S3S3 S4S4 S5S5 a b si S 3 est final

49 automate fini expression régulière (2) 2° étape : résolution des équations où S 3 napparaît pas dans les expressions x, y. S 3 = x y. S 3 ~> S 3 = y* x

50 Exemple S0S0 S1S1 S2S2 1° étape: l automate est équivalent aux équations S 0 = 0. S 1 | (1 | 2 | … | 9). S 2 S 1 = S 2 = | (0 | 1 |... | 9). S 2

51 Exemple (2) 2° étape : résolution par triangulation 1) éliminer S 1 : S 0 = 0 | [1-9]. S 2 S 2 = | [0-9]. S 2 2) résoudre S 2 : S 2 = [0-9]*. 3) éliminer S 2 : S 0 = 0 | [1- 9]. [0-9]*

52 Complémentation On calcule un automate qui accepte le complément de A. Algorithme: 1.Déterminiser A; 2.Le compléter: 1.Ajouter un état mort; 2.Ajouter des transitions vers cet état (si car. manque). 3.Propriété: chaque chaîne amène dans un seul état. 3.Inverser les états finaux et non-finaux.

53 Exemple de complémentation Automate déterministe complété : il y a une flèche pour chaque caractère de = [0-9] [0-9] [1-9] 0 S0S0 [0-9] Négation : on intervertit les états finaux [0-9] [1-9] 0 S0S0 [0-9] S3S3 S1S1 S2S2 S1S1 S2S2

54 Langages non réguliers Un langage est régulier ssi un programme peut le lire (de gauche à droite) en ne mémorisant quune information finie. Lemme de pompage: Une chaîne plus longue que le nombre détats de lautomate contient une boucle quon peut répéter. si k est le nombre détats une chaîne plus longue doit faire une boucle. y z x D119

55 Exemple Le langage {0 n 1 n } nest pas régulier : –Il faut retenir le nombre de 0, qui peut être grand : linformation nest pas finie. –Sil était régulier, on aurait un automate; Soit k son nombre détats. 0 k 1 k doit passer par une boucle : Si la boucle ne contient que des 0, on accepte des chaînes avec plus de 0 que de 1. Si la boucle ne contient que des 1, on accepte des chaînes avec plus de 1 que de 0. Si la boucle contient des 0 et 1, alors on accepte des chaînes où 0 suit 1.

56 Chapitre 2 : Analyse Syntaxique Rôle :Lanalyseur syntaxique retrouve la structure (arbre) grammaticale du programme.

57 Place de lanalyse syntaxique Analyseur syntaxique mots Arbre générateur danalyseur syntaxique Grammaire non contextuelle (BNF) Automate à pile Analyseur lexical

58 2.1 Grammaire non contextuelle (BNF) règle, production déf : une production non-contextuelle se compose de: un non-terminal une suite de symboles Ex. : : : = if then else La règle pour un non-terminal A regroupe toutes les productions de A: Ex. : : : = if then else | while do | := | … non terminal terminal

59 Grammaire non contextuelle une grammaire a 4 éléments: lensemble des symboles terminaux V T lensemble des non-terminaux V N lensemble des productions P le symbole de départ S (non-terminal) finis

60 BNF : Exemple : Pascal Exemple Pour Pascal, on reprend : V T = les symboles reconnus lors de lanalyse lexicale : mots-clés. Ex. if, identificateurs. Ex. x,... V N = les catégories syntaxiques : Ex. :,, P = les productions de la grammaire Ex. : : : = if then else S = la catégorie des textes complets : Pour le langage C la catégorie nexiste pas, le symbole de départ (ce quon peut compiler) est.

61 Notations Terminaux: les minuscules, chiffres, symboles dopérateurs, symboles en gras Non-terminaux: majuscules: A,B,C,S ; entre Symboles: X, Y, Z Chaînes de terminaux: u,v,w Chaînes de symboles: D192 W254

62 Historique - Pourquoi « non contextuel » ? (context-free) Chomsky (en 1956) a choisi ce nom par contraste avec ses « grammaires contextuelles » (type 1) où on peut mettre des conditions pour lapplication dune règle. - BNF signifie « Backus Naur form », du nom de ses inventeurs (utilisé pour la définition d Algol 60, vers 1958).

63 Emploi dune grammaire Partir du symbole de départ (ou axiome) S; répéter : –employer une règle : remplacer le côté gauche par le côté droit jusquà ce quil ny ait plus que des symboles terminaux dans le texte.

64 Langage Chaque chaîne quon peut obtenir ainsi est une phrase de G. Lensemble des phrases est le langage de G noté L(G). Les étapes intermédiaires sont des proto-phrases de G.

65 Dérivations Une dérivation est une suite de pas de l algorithme précédent: S w Si l algorithme peut passer de à en zéro, une ou plusieurs étapes, on dit que produit, noté *

66 Exemple : program tutu. : program tutu begin end. Comp : : : = begin end produit directement Comp * produit program tutu begin end.

67 Simplifications Un non-terminal est inaccessible sil ne fait partie daucune proto-phrase. Il est improductif sil ne produit aucune chaîne de terminaux. On peut retirer ces non-terminaux de la grammaire sans changer le langage : ils ne servent à rien.

68 Algorithme: Productif Algorithme qui donne les non-terminaux productifs. Au départ: aucun non-terminal nest marqué productif tous les terminaux sont productifs répéter parcourir les productions A ::= si tous les symboles du côté droit sont marqués productifs alors marquer le côté gauche A comme productif jusquà ce quun parcours ne marque rien de plus On enlève les non-terminaux improductifs et les productions où ils apparaissent.

69 Algorithme: Accessible Algorithme qui donne les non-terminaux accessibles. Au départ: seul le symbole de départ S est marqué accessible répéter parcourir les productions A ::= si le côté gauche A est marqué accessible alors marquer tous les non-terminaux du côté droit comme accessibles jusquà ce quun parcours ne marque rien de plus On enlève les non-terminaux inaccessibles et leurs règles. Exercice: Réécrivez ces deux algorithmes avec un temps d'exécution optimal (linéaire plutôt que quadratique).

70 Arbre de dérivation Idée : pour une phrase, il y a beaucoup de dérivations essentiellement identiques Déf. : Un arbre de dérivation pour u dans G est un arbre ordonné : –Dont les nœuds sont étiquetés par des non-terminaux – Dont les feuilles sont étiquetées par des terminaux (ou ) – Dont la racine est étiquetées par le symbole de départ – Chaque nœud correspond à une règle de production

71 Exemple darbre S : : = p id R ; D C.(1) D : : = (2) R : : = (F) | (3 | 4) F ::= id | id, F(5 | 6) C ::= b I e(7) I ::= (8) Dérivations gauche: S p id R ; D C. p id ; D C. p id ; C. p id ; b I e. p id ; b e. droite: S p id R ; D C. p id R ; D b I e. p id R ; D b e. p id R ; b e. p id ; b e. Arbre de dérivation : S p id R ; D C b I e Grammaire S: programme R: paramètres du programme D: déclarations C: instruction composée (1)(1)(4)(4)(2)(2)(7)(7)(8)(8) (1)(1)(7)(7)(8)(8)(2)(2)(4)(4)

72 Ambiguité Déf. : une grammaire est ambiguë sil y a une phrase qui a plusieurs arbres de dérivation. A éviter quand on veut générer un analyseur. Peut être utile comme grammaire abstraite. Exemple dambiguïté : les « else pendants » du Pascal : : = if then else | if then if b then if c then x : = 5 else x : = 3 Autre exemple: la grammaire précédente est ambigüe

73 Ambiguité : exemple : expressions La grammaire suivante des expressions de Pascal avec +,* : E ::= E+E | E*E | (E) | id est ambiguë: par exemple, x+y+z a deux arbres d'analyse: E E E E E E x + y + z x + y + z On notera ces arbres (x+y)+z et x+(y+z).

74 Résolution des ambigüités Une ambigüité (x+y)+z vs. x+(y+z) est appellée une ambigüité d'associativité: on la résoud en choisissant le coté récursif (coté gauche en Pascal) E ::= E+F | F F ::= id | (E)

75 Résolution des ambigüités Une ambigüité (x+y)*z vs. x+(y*z) est appellée une ambigüité de précédence: on la résoud en ajoutant un nouveau non-terminal par niveau de précédence. Ici, terme T et facteur F: E ::= E+T | T T ::= T*F | F F ::= id | (E)

76 Résolution des ambigüités L'ambigüité du if then else peut aussi se résoudre en introduisant des non-terminaux: : qui a tous ses else : sinon. ::= | ::= if then else ::= if then | if then else

77 Automate à pile a caractère courant fenêtre de lecture (avance dun caractère) sommet = état courant pile a létat définit le sommet de la pile

78 Automates à pile Définition Un automate à pile se compose de : V T lalphabet dentrée (fini) Q les états (fini) q 0 létat initial Fles états finaux ou accepteurs caractère à trouver dans la fenêtre états à trouver au sommet de la pile états à pousser sur la pile

79 Fonctionnement Lautomate démarre avec une pile vide, dans létat initial. Il suit les transitions : –lire un caractère. –empiler/dépiler les éléments indiqués de la pile. Il accepte le texte sil arrive dans un état accepteur (final).

80 Déterminisme Un automate à pile est déterministe si : –il na pas de transitions. –si deux transitions lisent le même caractère, elle ne peuvent pas sappliquer sur la même pile : la pile consultée de lune ne peut pas être un préfixe de la pile consultée de lautre.

81 BNF Automates à piles Les états sont des items, càd des règles avec un « point de lecture » inséré. On utilise 3 type de transitions : –Expansions (expand) : si létat a le point devant un non- terminal: A::= … B … on empile une règle pour celui-ci: B ::= … avec le point au début. –Réductions (reduce): si létat a le point en fin: B ::= …, on le dépile et on avance le point: A::= … B … –Lectures ou décalages (shift): si létat a le point devant un terminal: A::= … a …, on le lit et on avance le point A::= …a ….

82 BNF: état initial/final On ajoute un nouveau symbole de départ S létat de départ est S ::= S létat final est S ::= S

83 BNF = Automates à pile Il y a aussi une transformation des automates à pile vers les BNF. Un langage est donc non-contextuel ssi cest le langage dun automate à pile non-déterministe.

84 Non-déterminisme Lautomate obtenu est non-déterministe : plusieurs expansions sont possibles, laquelle choisir ? –Regarder les k symboles en entrée pour choisir la bonne production: analyseur descendants gauche LL(k) – Postposer la décision (comme pour les automates finis) analyseur ascendant droit (ex. yacc) LR(k)

85 Analyse descendante LL(k) Grammaire LL(k) : Le choix de la bonne expansion doit pouvoir se faire sur base des k prochains symboles à lire.

86 Cas simple Si pour chaque non-terminal chacune des productions commence par un symbole terminal différent alors la grammaire est simplement LL(1) Exemple : : = if then else fi while do od begin end le premier symbole lexical permet de faire le bon choix.

87 LL(k): définition Pour chaque choix d'une production pour A, on peut faire ce choix sur base des k premiers caractères non encore lus: G est LL(k) ssi pour tout choix A ::=, A::= de G ( ), PREMIER( ) PREMIER( ) = pour tout qui peut suivre A dans une dérivation gauche: S g * wA

88 Algorithme : PREMIER PREMIER(A) donne les possibilités de début de A, tronqués à k caractères. Pour chaque non-terminal A, le tableau P[A] contient un sous-ensemble de PREMIER(A), initialement vide. tant que P change: pour chaque règle A ::= ajouter PREMIER( ) à P[A] PREMIER(X1…Xn) est la concaténation tronquée à k de PREMIER(X1) … PREMIER(Xn) PREMIER(X) = {X} si X est terminal PREMIER(X) = P[X] si X est non-terminal

89 Exemple : sommes Une somme est une expression Pascal du genre : x+y+z+w en Pascal, les opérations se regroupent de gauche à droite : ((x+y)+z)+w La grammaire des sommes est donc: S ::= S+id | id | (S)où id est le terminal pour les identificateurs P[S] = après la 1ère production = {id} après la 2ème production = {id, ( } après la 3ème production, qui est la valeur finale. Donc cette grammaire nest pas LL(1).

90 Comment rendre une grammaire LL(1) ? éliminer la récursivité gauche factoriser les parties communes

91 Éliminer la récursivité gauche Une grammaire est récursive à gauche si un non-terminal A se dérive strictement en une proto-phrase commençant par A: A + A Une grammaire récursive à gauche nest jamais LL(k). A ::= A devient A, A ::= A| D201

92 Algorithme pre : G sans cycle A A, sans vide A post : G sans récursivité à gauche invariant : (A k ::= A l ), si k k : les règles déjà traitées commencent par des grands terminaux pour i := 1..n pour j := 1..i-1 remplacer Aj par sa définition dans Ai ::= Aj remplacer Ai ::= Ai par Ai ::= Ai, Ai ::= Ai|

93 Exemple Élimination de la récursivité gauche Grammaire dexpressions: E ::= E + T | T T ::= T * F | F F ::= ( E ) | id D202 Ordre: 1: E, 2: T, 3: F i=1 Ai::=Ai | E ::= T E E ::= +T E | i=2 Ai::=Ai | T ::= F T T ::= * F T | F ::= ( E ) | id Résultat

94 Exemple 2 Élimination de la récursivité gauche Grammaire : A ::= B b | C e B ::= A a | d C ::= A c | d D203 Ordre: 1: A, 2: B, 3: C i=2 Ai::=Aj B ::= B b a | C e a | d B::= CeaB|dB B::=baB| Ai::=Ai | C ::= B b c | C e c | d C ::= CeaBbc|dBbc|Cec|d C ::= dBbcC|dC C::=eaB bcC|ecC| calcul :Résultat A ::= B b | C e

95 Factorisation Idée : postposer le choix en regroupant les parties communes (facteurs) Exemple: I ::= if E then I | if E then I else I devient I ::= if E then I C C::= | else I

96 Exemple : PREMIER Pour la grammaire des expressions sans récursivité gauche: 0 : S ::= E3 : E ::= + E6 : T ::= * T 1 : E ::= T E4 : T ::= F T7 : F ::= (E) 2 : E ::= 5 : T ::= 8 : F ::= id k vaut 1. Les itérations de PREMIER sont listées en colonnes. On visite les productions en commençant par le fin (de 8 à 1). Par exemple, on peut lire dans la deuxième entrée de la première colonne, quaprès la visite des productions 8 puis 7, lensemble P du non- terminal F contient les symboles id et (. 8 : P[F] = {id}5 : P[T] = {*, }2 : P[E] = {+, } 7 : P[F] = {id, ( }4 : P[T] = {id, ( }1 : P[E] = {id, ( } 6 : P[T] = {*}3 : P[E] = {+}0 : P[S] = {id, ( } P ne donne pas le début des productions 5 et 2: il faut connaître le début de ce qui est derrière E et T, calculé par SUIVANT.

97 Suivant Quand PREMIER( ) est trop court, on regarde derrière avec SUIVANT(A) : ce qui peut suivre A. Algorithme : Le tableau des suivants est initialisé à vide SUIVANT[S] := {$} /* le marqueur de fin */ tant que SUIVANT change pour chaque règle A ::= B ajouter PREMIER( ). SUIVANT[A] à SUIVANT[B]

98 Exemple : SUIVANT Pour la grammaire des expressions sans récursivité gauche: 0 : S ::= E3 : E ::= + E6 : T ::= * T 1 : E ::= T E4 : T ::= F T7 : F ::= (E) 2 : E ::= 5 : T ::= 8 : F ::= id PREMIER ne suffit pas pour E, T On calcule SUIVANT: S: {$} 0: E: {$} 1: T: {+,$} E:{$} 4: F: {*,+,$} T:{+,$} 7: E: { ),$} 1: T: {+,),$} E:{ ),$} 4: F: {*,+,),$} T:{+,),$}

99 Analyseur descendant à pile Si la grammaire est LL(k) : à partir du non-terminal à développer (derrière le en sommet de pile) et des k caractères dentrée, on sait quelle règle appliquer. On le met dans une table. Lanalyseur fait : –une lecture si le est devant un terminal: On avance la fenêtre et le point dans l'item. –une réduction si le est en fin de d'item: On dépile l'item. –une expansion si le est devant un non-terminal: On empile l'item daprès la table.

100 Exemple table LL(1) pour expressions D215

101 Trace de lanalyse LL(1) dune expression Contenu de la pileChaîne d'entrée $ [S E] id * id $ $ [S E] [E TE'] id * id $ $ [S E] [E TE'] [T FT'] id * id $ $ [S E] [E TE'] [T FT'] [F id] id * id $ $ [S E] [E TE'] [T FT'] [F id] * id $ $ [S E] [E TE'] [T FT'] * id $ $ [S E] [E TE'] [T FT'] [T' *T] * id $ $ [S E] [E TE'] [T FT'] [T' *T] id $ $ [S E] [E TE'] [T FT'] [T' *T] [T FT'] id $ $ [S E] [E TE'] [T FT'] [T' *T] [T FT'] [F id] id $ $ [S E] [E TE'] [T FT'] [T' *T] [T FT'] [F id] $ $ [S E] [E TE'] [T FT'] [T' *T] [T FT'] $ $ [S E] [E TE'] [T FT'] [T' *T] [T FT'] [T' ] $ $ [S E] [E TE'] [T FT'] [T' *T] [T FT'] $ $ [S E] [E TE'] [T FT'] [T' *T] $ $ [S E] [E TE'] [T FT'] $ $ [S E] [E TE'] $ $ [S E] [E TE'] [E' ] $ $ [S E] [E TE'] $ $ [S E] $ $$ D216

102 Gestion de la pile On peut représenter les items en mettant les non- terminaux non encore lus en ordre inverse sur la pile. Lanalyseur fait : –une lecture si le sommet est un terminal: On avance la fenêtre et on dépile. –une expansion si le sommet est un non-terminal: On empile en ordre inverse la partie droite de la règle trouvée daprès la table. –les réductions deviennent implicites. D215

103 Analyseur récursif prédictif On peut employer la pile implicite de récursion : –le non-terminal de gauche = procédure appelée –règles = corps de la procédure –prédiction = test du fichier dentrée –point = adresse de retour

104 Exemple : expression procedure expr; begin if input^ in [ (, id ] then begin term; exprend; end else erreur end; E ::= T E choix par table LL(1) T E

105 Exemple: suite procedure exprend; begin if input^ = + then begin get; term; exprend; end else if eof or input^ = ) then else erreur end E ::= +TE | E + T E

106 Actions On peut insérer du code dans les règles de syntaxe, appelé « action » Ce code est exécuté lorsque l'analyseur exécute cette partie de la règle Souvent ces actions construisent un arbre danalyse abstrait

107 Arbre abstrait : exemple E T E F T id + E T E F T Arbre syntaxique concret de x + y, pour la grammaire des expressions sans récursion à gauche. + x y Arbre abstrait pour la grammaire ambiguë de départ x + y

108 2.3 Analyse syntaxique ascendante Idée : On choisit la règle à appliquer après avoir lu le texte correspondant –larbre danalyse est construit de bas (feuilles) en haut (racine) –la dérivation correspondante est droite : le non-terminal le plus à droite est actif. –Le programme remonte dans la dérivation. Problème : comment garder trace des possibilités ? D222

109 Exemple : Texte Ada if x + 1 > y then x := 1 else x := 2 end if ; > + x 1 y := x1 x2 * if then else := end if manche if then else end if...

110 Automate fini caractéristique Décrit le comportement du sommet de pile Sa déterminisation donne des ensembles de règles possibles Ses états finaux sont les réductions

111 Automate fini caractéristique Déf. : Lautomate fini caractéristique est donné par états = items (G) alphabet = état initial = états finaux = transitions = les états où on réduit lecture dun symbole : expansions : pas de réductions : elles sont représentées par des états terminaux.

112 Automate fini caractéristique Déf. : Lautomate fini caractéristique est donné par états = items(G) alphabet = les symboles (terminaux ou non) état initial = litem de départ: [S ::= S] états finaux = les états où on réduit: [A ::= ] transitions = lecture : on déplace le point après le symbole lu expansion: si le point est devant un non-terminal, on choisit une production pour ce non terminal

113 Déterminisation de lautomate fini caractéristique En appliquant la déterminisation, on obtient un automate déterministe où létat atteint en suivant un préfixe viable est lensemble de ses items valides. Cet état peut être impropre ou conflictuel, s'il contient: –Une lecture (shift), càd un item où le point est devant un terminal –Et une réduction, càd un item où le point est en fin ou - deux réductions (conflit R/R) Dans ce cas, lautomate à pile associé est non déterministe, et la grammaire n'est pas LR(0).

114 Exemple : expression S0S0 S1S1 S2S2 S5S5 S3S3

115 Préfixe viable = la partie déjà analysée du texte = létat de la pile dun analyseur ascendant (avant le point) def: un préfixe dune proto-phrase droite qui ne sétend pas au-delà du manche le plus à droite

116 Item valide Intuitivement, litem valide donne un état possible de lanalyseur quand il a lu un préfixe. Def. : A::= est valide pour le préfixe viable ssi il y a une dérivation droite S d * A w d * w

117 Construction directe On peut spécialiser la déterminisation pour lautomate caractéristique de façon à ne pas le construire: on fait les deux étapes ensemble. D252 W342

118 Fermeture fonction Fermeture (s : ensemble ditems) : ensemble ditems ; (* fermeture par les successeurs, ici les expansions *) var q : ensemble ditems ; début q := s ; tant que [X Y ] q et Y P et [Y ] q /* il y a une expansion qui n'est pas encore dans q */ ajouter [Y ] à q retourne (q) fin ; s est appelé le noyau de q; il détermine q. D252 W342

119 Successeurs fonction Transition(s : ensemble ditems, Y : V N V N ) : ensemble ditems; (* donne le noyau de létat atteint par la lecture de Y *) retourne ( { [X Y ] | [X Y ] s } ) Le noyau du successeur par une transition étiquetée Y contient les items qui avaient le point devant Y, où on a avancé le point. D253 W343

120 Construction des états Q := { Fermeture({[S' ::= S]})}/* l'ensemble des états part de l'item initial */ := /* les transitions sont initialement vides */ pour chaque état q de Q, symbole X apparaissant derrière le point dans q faire q := Fermeture(Transition(q,X)) ; si q' non vide alors si q n'est pas dans Q alors on l'ajoute à Q on ajoute la transition de q vers q' lisant X dans D253 W343

121 Exemple : expressions S4S4 S 11 S5S5 S3S3 S2S2 S0S0 S1S1 S8S8 S9S9 +T E T F id ( ( T F F ( S6S6 E + ) S7S7 S 10 * * id F ( Lautomate LR(0) donne : D254 W339 Les états S 1, S 2, S 9 sont impropres : ils contiennent des conflits LR(0) : cette grammaire nest pas LR(0).

122 Exemple : expressions : états LR(0) Les états S 1, S 2, S 9 sont impropres : ils contiennent des conflits LR(0) : cette grammaire nest pas LR(0).

123 Exemple La grammaire: S ::= C | D C ::= a C | b D ::= a D | e nest pas LL(k) : on ne peut pas choisir entre C et D car il peut y avoir des a dabord dans les deux cas. Elle est LR(0) car on peut choisir après lecture. Son automate déterministe caractéristique ne contient pas de conflits LR(0). q 0 = {[S ::= S], [S::= C], [C::= aC], [C::= b], [S::= D], [D::= aC], [D::= e]} q 1 = {[C::= aC], [C::= aC], [C::= b], [D::= aC], [D::= aC], [D::= e]} q 2 = {[C::= b]} q 3 = {[D::= e]} q 4 = {[S::= C]} q 5 = {[C::= aC]} q 6 = {[S::= D]} q 7 = {[D::= aD]} q 7 = {[S::= S]} q0q0 q7q7 q6q6 q4q4 q5q5 q8q8 q3q3 q2q2 q1q1 a e b C D S C b e D

124 SLR Pour résoudre les conflits LR(0), on regarde SUIVANT(A), où A est le côté gauche de la règle à réduire. D256 W352

125 Exemple : expressions SLR(1) Les états conflictuels LR(0) S 1 : le conflit entre réduire S, SUIVANT(S) = { $ } et lire +, est résolu. S 2 : le conflit entre réduire E, SUIVANT(E) = { $, +, ) } et lire *, est résolu. S 9 : idem. Cette grammaire est donc SLR(1). D237 W353

126 Exemple : Affectations en C S : : = L = R | R L : : = *R | id R : : = L L = partie gauche (donne ladresse) R : expression ; une expression est une instruction en C * : déréférenciation (prendre le contenu de ladresse) D257

127 Exemple : Affectations en C : automate SLR(1) [S S] [S L = R] [S R] [L * R] [L id] [R L] S3S3 S R [S S ] [S R ] S2S2 L [S L = R] [R L ] [S L = R] [R L] [L * = R] [L id] = S6S6 R S9S9 [S L = R ] [L id ] id S5S5 S4S4 * * L L R S7S7 S8S8 * [R L ] [L *R ] [L * R] [R L] [L *R] [L id] S 2 est conflictuel : SUIVANT(R) contient =. Cette grammaire nest pas SLR(1). id D258

128 Items LR(k) canonique On ajoute aux items une chaîne de longueur k (la prévision de litem), qui indique le texte qui peut suivre cet item: [A, u] La prévision est propagée par les transitions. Une nouvelle prévision est calculée avec PREMIER pour les expansions. On crée plus détats quavec les autres techniques (LR(0), SLR(1), LALR(1) ). D260 W350

129 Fermeture fonction Fermeture(I); répéter pour chaque item LR(k) [A B, u] de I et chaque chaîne v de PREMIER( u) pour chaque règle B ajouter [B, v] à I jusquà stabilisation D261 W350

130 Exemple : expressions : états LR(1) S4S4 S 11 S5S5 S3S3 S2S2 S0S0 S1S1 S8S8 S9S9 +T E T F id ( F ( S6S6 E ) S7S7 S 10 * * id F ( S 15 S 19 S 12 S 18 S 17 S 13 ( T F F E id ) S 16 S 21 * * id F ( S 20 +T id ( S 14 T F + Lautomate LR(0) est doublé : prévision avec $ (fin) ou avec )

131 Exemple : expressions : états LR(1) S 0 = Fermeture(Début) S 6 = Fermeture( S 1, +)) ={[S E,{$}]{[E E + T, {$, +} ], [E E+T,{$, +}],[T T * F, {$, +, *}], [E T, {$, +}],[T F, {$, +, *} ], [T T * F, {$, +, *}],[F (E), {$, +, *}], [T F, {$, +, *}],[F id, {$, +, *}] } [F (E), {$, +, *}], [F id, {$, +, *}] }S 9 = Fermeture(Succ( S 6, T)) {[E E + T, {$, +}], S 1 = Fermeture(Succ(S 0,E)) [T T * F, {$, +, *}] } {[S E, {$}], [E E + T, {$, +}] } S 2 = Fermeture(Succ(S 1,T)) {[E T, {$, +}], [T T * F, {$, +, *}] } = = S 4 = [E E+T,{), +}], [E T, {), +}], [T T * F, {), +, *} [T F, {), +, *}], [F (E), {), +, *}], [F id, {), +, *}] } { [F ( E), {$, +, *}], Notation: lensemble des prévisions des items LR(1) qui ont la même production sont regroupés.

132 LALR on garde les états LR(0) les prévisions sont la fusion des prévisions LR ayant le même cœur (état LR(0) ) Pour calculer les prévisions de [B ] : –trouver les origines de la règle : expansions [B ] –trouver les sources de lexpansion [A B, u] –calculer ce qui se trouve derrière B: PREMIER( u) –faire lunion –en cas de boucle: répéter jusquà stabilisation D270 W

133 Exemple : affectations en C [S S, {$} ] [S L = R] [S R, {$} ] [L * R] [L id] [R L, {$} ] S3S3 S R [S S ] [S R ] S2S2 L [S L = R] [R L, {$} ] [S L = R] [R L] [L * = R] [L id] = S6S6 R S9S9 [S L = R ] [L id ] id S5S5 S4S4 * * L L R S7S7 S8S8 * [R L ] [L *R ] [L * R] [R L] [L *R] [L id] id S0S0 Le conflit en S 2 est résolu Cette grammaire est LALR(1).

134 Exemple : expressions Etats impropres (conflit décaler/réduire) ( ( ( Derrière, en mauve: les ensembles de prévision LALR(1)

135 Grammaires ambiguës Une grammaire ambiguë peut être plus naturelle Elle provoque toujours des conflits Les conflits peuvent être résolus par des règles de précédence et dassociativité, sans augmenter le nombre détats D277 W368

136 Exemple : expressions La grammaire la plus naturelle est : E ::= E + E | E * E | ( E ) | id qui est ambiguë, mais peut servir de grammaire abstraite. En donnant des règles d associativité: %left + %left * et de précédence données par lordre décriture, on résout les conflits Shift/Reduce: Si le dernier terminal de la règle à réduire est plus fort que celui la fenêtre, on réduit; sinon on lit. Si cest le même, on emploie lassociativité. Enfin, Yacc et Bison décalent de préférence. Pour les conflits réduire/réduire, ils préfèrent la règle écrite en premier.

137 Exemple : if then else En Pascal, on a : ::= if E then I else I | if E then I cette grammaire est ambiguë, mais sera analysée correctement grâce à la préférence au décalage.

138 Langages contextuels Certains langages ne peuvent pas être traités avec les grammaires non-contextuelles. Méthodes: –1. un langage est non-contextuel ssi il peut être reconnu par un programme dont la seule structure de données infinie est une pile.

139 Lemme de pompage –2. Si un langage est non-contextuel, alors il a une longueur k : toute chaîne plus longue que k se décompose en 5 parties u v w x y, et les parties v et x peuvent être répétées le même nombre de fois: u v n w x n y fait aussi partie du langage. Les parties v w x ensemble ont une longueur de k au plus. En pratique on lemploie dans lautre sens : on trouve une série de phrases (une pour chaque k) dans le langage et, quelle que soit la décomposition, le lemme nous obligerait à inclure aussi des phrases incorrectes : on sait alors que le langage ne peut être décrit par une grammaire BNF.

140 Exemple {a n b n c n } nest pas non-contextuel: on peut empiler pour chaque a, puis dépiler pour chaque b mais alors on ne sait plus compter les c.

141 Exemple {a n b n c n } nest pas non-contextuel: si l'était, a k b k c k se décomposerait en u v w x y v w x est de longueur k au plus donc il ne peut contenir à la fois des a, des b, et des c donc en répétant v et x, on n'a plus assez du caractère manquant: impossible.

142 Sémantique statique Rôle : Vérifier les propriétés contextuelles statiques, principalement la cohérence des types D Ch.5-6 W Ch. 9

143 Syntaxe abstraite La sémantique statique travaille sur les arbres de syntaxe abstraite. if2 grt plusassign id (x) iconst (1) id (y) id (z) iconst (1) id (z) iconst (2) Exemple : Arbre de syntaxe abstraite

144 CondStat Ifstat E T F id (x) E F iconst (1) +if E compop (>) ETFETF id (y) then E id (z) E T F iconst (1) := Ass else Stat E id (z) E T F iconst (2) := Ass fi Arbre de syntaxe concrète pour le même exemple

145 Sémantique statique 1. un exemple : le typage 2. une technique de spécification : les grammaires attribuées

146 1. Typage Portée Systèmes de types –équivalence –coercition –polymorphisme –surcharge D Ch. 6 W388

147 Portée Les types se déduisent des déclarations Les déclarations sont valides dans leur portée Elles peuvent être cachées par dautres déclarations Chaque langage a ses règles de portée / visibilité.

148 Portée : exemple de Pascal En Pascal, la portée dune déclaration est le bloc dans lequel elle se trouve Il ne peut y avoir quune déclaration de ce nom dans un bloc Une nouvelle déclaration du même nom dans un bloc imbriqué cache la déclaration extérieure Les paramètres sont traités comme des variables locales

149 Portée : exemple dAda La portée dune déclaration commence à la déclaration et se termine à la fin du bloc Si le bloc est un package, elle comprend de plus les packages qui importent celui-ci Une nouvelle déclaration ne cache un nom que si le type est le même

150 Portée : implémentation Pour chaque bloc on crée une table de symboles Chaque table a un lien vers le bloc englobant Chaque déclaration ajoute une entrée dans le bloc (souvent avec des infos: type, taille, déplacement dans le bloc dactivation, etc.) Chaque occurrence didentificateur est recherchée dans la liste des blocs en appliquant les règles du langage.

151 Expressions de types expressions de type : typiquement : –des types de base : booléen, entier, réel, … –des noms de types –des constructeurs de type : tableaux records (structures, enregistrement) fonctions pointeurs D381

152 Règles de typage Chaque langage a ses règles Parfois les règles demandent une vérification dynamique (à lexécution) Un système de typage est sain si toutes les valeurs utilisées à lexécution sont du type calculé statiquement Un langage est typé si le typage impose des conditions sur les programmes. D383

153 Exemple : Pascal le typage de Pascal nest pas sain : –on nest pas obligé de vérifier que les indices de tableaux restent dans les bornes prévues –les variants peuvent être modifiés sans contrôle –les valeurs initiales ne sont pas nécessairement du bon type

154 Exemple de règles Si a est un tableau, alors dans indexation sur a, les expressions des indices doivent avoir le même type de base que le type dindices apparaissant dans la déclaration de a. –exemple: vara : array[1..10] of integer; i : ; i := a[i] (* correct car le type de base est integer, mais pas recommandé *)

155 Equivalence des types Quand 2 types sont ils égaux ? 2 grandes familles : équivalence par nom : ils doivent avoir la même déclaration (Pascal, Ada) équivalence structurelle : on calcule sils se ramènent à la même structure (C, Algol68, ML) D389

156 Equivalence par nom ex. : Pascal, Ada 1) varx : record a, b : integer end y : record a, b : integer end les types de x, y sont différents (dépend de limplémentation en Pascal74) 2) typer = record a, b : integer end varx : r ; y : r ; les types de x, y sont équivalents 3) varx, y : record a, b : integer end les types de x, y sont équivalents en Pascal, mais différents en Ada

157 Equivalence structurelle deux types sont équivalents si leur structure est la même (intuitivement, sils admettent les mêmes valeurs) vérification en parcourant la structure des types si cycles possibles, attention à la terminaison D390

158 Algorithme structure globale : partition des nœuds du graphe, notée t1 == t2 (les types déjà prouvés équivalents) equiv(t1, t2) si t1 == t2 alors renvoyer vrai sinon si constructeur(t1) <> constructeur(t2) alors renvoyer faux sinon si pour tout i, equiv (fils(i,t1),fils(i,t2))) alors union(t1, t2); renvoyer vrai

159 Particularités de typage surcharge coercition polymorphisme

160 Surcharge (ou « polymorphisme ad hoc ») Un identificateur est surchargé sil peut avoir des significations différentes suivant son type. Exemple en Pascal, en ML, … + : real x real real + : int x int int en Ada : lutilisateur peut surcharger lui-même, par exemple : function "*" (x, y : Matrix) return Matrix ;

161 Résolution de la surcharge + 3 f p int int x int int real x real real real int char char real int A la fin de lalgorithme, chaque fonction doit avoir un seul type sinon : ambiguïté de type Soit vis(k) lensemble des définitions de k visibles, avec leurs types Ex. : vis(« + ») = { int x int int, real x real real } Lalgorithme élimine les types dabord en montant dans larbre puis en descendant. La contrainte est que les arguments doivent avoir le type attendu par la fonction. Ex. : vis(« p ») = { int, real} vis(« f ») = { real real, int int, char char} 3 + f(p) D400 W390

162 Coercition Def : Conversion implicite entre types (insérée par le compilateur) Exemple : En Pascal, un entier peut être employé à la place dun réel dans une expression mais PAS à gauche de := ex. : var r : real ; i : integer ; begin r := i i := r x interdit Notation : typedestnote une coercition vers typedest (notation Ada) Exemple : Dans tous les langages à objets : une variable peut être « coercée » vers tous les types dont son type statique hérite. D396

163 Les coercitions introduisent de nombreuses ambiguïtés, surtout combinées aux surcharges : Exemple : coercition integer real notée real / : integer x integer integer ; / : real x real real ; r := 3/2 peut se comprendre : r := real (3/2) valeur 1. ou r := real (3) / real (2) valeur 1.5 en Pascal : on utilise 2 noms pour la division: / et div. Les langages non-O.O. modernes interdisent les coercitions.

164 Résolution de la coercition Pour résoudre les ambiguïtés de coercition, on se donne des règles de préférence, p.ex.: –préférer une coercition unique à une suite de coercitions –préférer les coercitions le plus haut dans larbre Sil ny a pas de surcharge: insérer des coercitions lorsque nécessaire Avec surcharge : on étend lensemble des typages avec un ordre partiel de préférence Pour Pascal, une passe ascendante suffit.

165 Exemple : Pascal si les 2 opérandes sont entiers : résultat entier si les 2 opérandes sont réels : résultat réel si un opérande est entier, le coercer en réel. exemple: 3+2+5*4.1 = real(3+2) +( real(5) * 4.1 )

166 Polymorphisme (paramétrique) Une définition est polymorphique si elle peut sappliquer de la même façon à tout type. Exemple en ML head : a list a renvoie le 1er élément dune liste où a est une variable qui représente n'importe quel type en Pascal : nil : a Différence par rapport à la surcharge lopérateur a une seule définition : son comportement est uniforme lensemble des types est potentiellement infini. D402 W391

167 Résolution du polymorphisme Pour chaque occurrence dune fonction polymorphe, on introduit une copie de son type avec de nouvelles variables de type Pour chaque variable (de type inconnu), on introduit une nouvelle variable de type. La portée des variables est locale à une ligne. Les variables de type peuvent recevoir des valeurs particulières dans une substitution On résout les contraintes par unification, en calculant la substitution qui permet de les satisfaire. Il y a un résultat le plus général, le type principal. D409 W394

168 Exemple 1 (en ML) On peut écrire une fonction « longueur » qui marche sur des listes de nimporte quel type (impossible en Pascal) fun longueur( [] )= 0 | longueur (x :: l) = longueur(l) +1 où: [] est la liste vide, de type a list : liste de nimporte quel type. : : est le constructeur de liste: (x :: l) est la liste obtenue en mettant x devant l. Il est de type b x b list b list, càd que x doit avoir le même type que les éléments de l. Les types de longueur, x, l sont inconnus a priori. On introduit donc de nouvelles variables to, tx, tl pour leur type. Les contraintes sont: to = (a list) int pour la 1ère ligne to = (b list) int pour la 2ème ligne. On en déduit a = b par unification. D412

169 Exemple 2 (ML) fun append ( [ ] ) (l2) = l2 append (x :: r) (l2) = x :: (append r l2) Contraintes : ta= a list (tl2 e1) tl2= e1 :: : b x b list b list tr= b list tx= b ta= b list (tl3 e2 ) tx= c ta= tr (tl3 c list) e2= c list ta =a list (a list a list) taa listtl2 txtrtl3 ! tx list W395

170 2. Grammaires attribuées basées sur une grammaire BNF on ajoute à chaque nœud de larbre des attributs (p.ex. : type, table de symboles, code, valeur). Ce sont des champs supplémentaires les attributs sont calculés par des règles dattribution associées aux règles de la grammaire

171 Attributs synthétisés et hérités Attribut synthétisé : remonte dans larbre (calculé daprès les attributs de ses fils) Attribut hérité : descend dans larbre (calculé daprès les attributs de son père et/ou de ses frères) Attributs lexicaux (synthétisés) : pour les terminaux, calculés par lanalyseur lexical (p.ex. la valeur dune constante)

172 Exemple : calculatrice Règle de grammaireRègle dattribution S ::= E val : attribut synthétisé de E, T, F, nombre E ::= E 1 +TE.val = E 1.val + T.val E ::= TE.val = T.val T ::= T 1 *FT.val = T 1.val * F.val T ::= FT.val = F.val F ::= ( E ) F.val = E.val F ::= nombreF.val = nombre.val

173 Pour l exemple suivant, il nous faut un type abstrait « table de symboles » : ajout (table, id, def) : table - crée une erreur si id est déjà dans table - dans cet exemple, def est le type de la variable ; on peut mettre d autres infos dans la table (le déplacement, etc.) t 1 + t 2 : tableles défs de t 2 écrasent les défs de t 1 vide : table rech(table, id) : defretrouve la déf courante de id. La table sera synthétisée par les déclarations et héritées par les instructions.

174 Exemple : types dans les déclarations typeh: attribut hérité de L tab: attribut synthétisé de L: table de symboles (nom, type) Règles de grammaireRègles d'attribution D ::= L : TypeL.typeh = Type L ::= id, L 1 L 1.typeh = L.typeh L.tab = ajout(L 1.tab, id.entrée, L.typeh) | idL.tab = ajout(vide, id.entrée, L.typeh) D316

175 Graphe de dépendances Sur un arbre attribué, on ajoute une flèche si un attribut est employé pour calculer un autre Les flèches changent au max. d1 niveau Lordre du calcul doit suivre les flèches Sil y a un cycle, le calcul nest pas possible

176 Exemple : Graphe de dépendances x, y, z : bool; D typeh L tab : T id, typeh L tab bool id, typeh L tab id

177 Exemple : typage Pascal E 0.type = if E 1.type = int and E 2.type = int then int else real | (E 1 ) E 0. type = E 1. type Calcul du type dune expression numérique en Pascal (avec surcharge à la place de coercition) dans la grammaire abstraite type : attribut synthétisé de E : {int, real} Règles de grammaireRègles dattribution E 0 ::= E 1 op E 2 op peut être +, -, *

178 Exemple : arbre abstrait Les grammaires attribuées peuvent aussi servir à calculer larbre abstrait comme attribut de larbre concret. cons(e,g,d) construit un nœud darbre à 2 fils, g et d. a est un attribut synthétisé représentant l'arbre abstrait Règles de grammaireRègles dattribution E ::= E 1 +T E.a = cons(+, E 1.a, T.a) E ::= TE.a = T.a T ::= ( E )T.a = E.a T ::= idT.a = id Pour un DAG, cons renvoie le nœud (si) existant

179 Ordres dévaluation des attributs ordre fixe : donné a priori (p.ex. suit la méthode danalyse syntaxique : LL ou LR) ordre statique : daprès la grammaire attribuée, on précalcule un ordre ordre dynamique : le graphe de dépendance est construit avec larbre; les attributs sont évalués dans un ordre compatible avec le graphe

180 Ordre fixe : grammaire S-attribuées Une grammaire est S-attribuée si elle ne contient que des attributs synthétisés Implémenté dans les analyseurs ascendants (Yacc, Bison, …) Syntaxe: ex: E : E '+' E { $$ = $1 + $3 } ; –lévaluation de lattribut synthétisé $$ se fait dans laction de réduction –$i désigne lattribut du ième symbole D326

181 Grammaires S-attribuées : Implémentation Lanalyseur LR conserve une pile des non- terminaux déjà réduits Il leur associe leur attribut synthétisé Lors de la réduction, les $i sont trouvés en sommet de pile, utilisés pour calculer $$, et remplacés par $$. D328

182 Exemple : calculatrice Règle de grammaireAction dattribution(Yacc) S : E ; E : E + E{ $$ = $1+$3 } | E * E{ $$ = $1*$3 } | ( E ) { $$ = $2} ; F : nombre { $$ = $1} ;

183 Exemple : calculatrice - pile Dans cet exemple, la pile des attributs se comporte comme une pile dévaluation postfixe. D329

184 Ordre fixe : grammaires L-attribuées Une grammaire est L-attribuée si on peut évaluer les attributs lors d'un parcours en profondeur de gauche à droite de larbre danalyse càd: un attribut hérité ne dépend que dattribut hérités plus à gauche ou du père peut simplémenter dans LL(1), LALR(1), etc. D330 W434

185 Exemple : expression LL(1) val : attribut synthétisé h : attribut hérité de E': valeur de l'expression à gauche Règles BNFAttribution E ::= T E'E'.h = T.val E.val = E'.val E' ::= - T E' 1 E' 1.h = E'.h - T.val E'.val = E' 1.val | E'.val = E'.h T ::= nbT.val = nb.val

186 Ex dévaluation dune expression arbre attribué pour lexpression E.val=1 T.val = 9 nb.val = 9 E.h = 9 T.val = 5 nb.val = 5 E.h = 4 T.val = 3 nb.val = 3 E.h = 1 val =1

187 L-Attributs dans LL(1) récursif On ajoute les attributs hérités comme paramètres d'entrée de la procédure du non- terminal, les attributs synthétisés comme paramètres de sortie On ajoute des variables locales pour les attributs apparaissant dans une règle du non-terminal D340

188 Exemple : expressions LL(1) Règle LL(1)attribution E' ::= E'.val = E'.h | - T E' 1 E' 1.h = E'.h - T.val E'.val = E' 1.val procedure reste(h: integer; var val: integer); var tval, e1val : integer; begin if eof then val := h else if input^ = - then begin get; (* lit - *) terme(h, tval); reste(h-tval, e1val); val := e1val end else error end

189 L-attributs dans LR On ajoute des actions à lendroit où les attributs doivent être calculés les actions dans un règle (mais pas à la fin) seront traduites par des marqueurs : des non- terminaux à définition vide, avec une action en fin. On accède aux attributs des non-terminaux précédents en remontant la pile ($0, $-1, etc.) D342

190 Exemple : marqueur Une règle S : {$$ = 5} B ; est traduite par S : M B; M : {$$ = 5}; Dans B la valeur de M est accessible comme $0 (cest lélément précédent sur la pile).

191 Ex: table de symboles pour C BNFAttribution insérée dans la règle BNF D ::= T { L.typeh = T.type } L T ::= int { T.type = entier } L ::= {L 1.typeh = L.typeh } L 1, id {L.tab = Ajout(id.nom, L.typeh, L 1.tab) } | id {L.tab = Ajout(id.nom, L.typeh, L 1.tab) } D : déclaration L : liste didentificateurs T : type (se place avant en C) D344

192 Ex: Table de symboles (Bison) D: T {$$=$1} L{$$ = $3 }; T : int{$$ = integer() }; L: L ',' id{$$ = add($3, $ 0, $1)} | id{$$ = add($1, $ 0, empty() ) }; Dans cet exemple laction {$$=$1}nest pas nécessaire: On peut utiliser lattribut synthétisé type pour lattribut hérité typeh

193 Ex: mise en page de formule EQN est un programme de mise en page de formules mathématiques (dites "boîtes") les indices doivent être plus bas et dans une fonte plus petite. P.ex. le texte dentrée E sub 1.a est mis en page comme E 1.a. Les boîtes servent à l'espacement. sub s'associe à droite: E sub i sub j = E sub (i sub j) D23, D333, D347

194 Ex: mise en page de formule tc: attribut hérité: taille des caractères ht: attribut synthétisé: hauteur totale de la boîte D334 S ::= B B ::= B 1 B 2 B ::= B 1 sub B 2 B ::= texte B.tc = 10au départ, taille 10 points S.ht = B.ht B 1.tc = B.tc B 2.tc = B.tc B.ht = max(B 1.ht, B 2.ht) B 1.tc = B.tc B 2.tc = Rétrécir(B.tc)plus petit pour l'indice B.ht = Déplacer(B 1.ht, B 2.ht)p.ex B 1.ht + B 2.ht/2 B.ht = texte.htn B.tchtn: hauteur des lettres

195 Même exemple en Bison %left ' ' %right sub % S : {$$ = 10 } B {$$ = $2}; B : B ' '{$$ = $0} B {$$ = max($1, $4)} | B sub {$$ = Rétrécir($0)} B {$$ = Déplacer($1,$4)} | texte {$$ = $1 * $0}; Avant chaque B, une action met tc dans $$ pour qu'il soit disponible dans B comme $0. On peut omettre {$$=$0} avant le premier B d'une règle pour B. S.ht B.ht B.tc

196 Utiliser les attributs synthétisés Ex: types dans les déclarations (Pascal) La règle D ::= L : T fait que le type nest pas disponible dans L ::= id, L Solution (peu naturelle): mettre le type dans la liste: D ::= id R R ::=, id R | : T T ::= integer |... D350 D id, id : integer R R T

197 Ex: types dans les déclarations (Pascal) D ::= id L D.tab = Ajout(id.nom, L.type, L.tab) L ::=, id L 1 L.type = L 1.type L.tab = Ajout(id.nom, L 1.type, L 1.tab) L::= : T L.type = T.type L.tab = vide Tous les attributs sont synthétisés.

198 Ordre statique Pour certaines grammaires attribuées (l- ordonnées, fortement non-circulaires) on peut calculer un ordre de visite de larbre à partir de la grammaire. Utilisé dans les systèmes FNC-2, GAG, etc.

199 Ordre dynamique Si les conditions précédentes ne sont pas vérifiées, on peut toujours construire larbre danalyse, son graphe de dépendances, et le trier pour faire le parcours. En pratique, cette technique est coûteuse. Utilisé p.ex. dans le système Elegant

200 Génération de Code pour langages impératifs D, Chap. 2 et 7 à 10 W, Chap. 2 : P-Code Chap. 12 : code optimisé

201 Plan 1.Machines abstraites: ex. P-machine 1.Expressions 2.Instructions 3.Données 2.Machines concrètes: ex. MIPS 1.Expressions 2.Instructions 3.Allocation mémoire

202 1. Machines abstraites Ont des instructions proches d'un langages: –P-machine pour Pascal –JVM pour Java –WAM pour Prolog –CAM pour CAML Simplifient les détails des machines concrètes –Registres, alignement, … Code portable

203 Pile dexpressions Les expressions peuvent se calculer avec une pile en notation postfixe (appelée aussi Polonaise inversée) (p. ex. calculette Hewlett-Packard) Exemple : ((3 * 5) + (7 * 4)) / (3 + 5) Postfixe : 3 5 * 7 4 * / Parenthèses inutiles nombres empiler opération prendre les données sur la pile les remplacer par le résultat Ce principe est employé dans les langages à pile PostScript et FORTH, et dans les machines abstraites: P-machine (Pascal), JVM (Java) 5 3 * } 4 7 * 15 } 5 3 * 43 } 8 43 / } + } 5 W8

204 P-instructions pour expressions STORE : tableau représentant la mémoire une partie (jusque SP) est utilisée pour la pile. Les deux valeurs en sommet de pile doivent avoir le même type numérique (entier, réel, ou adresse) W8

205 Variables globales de type simple Les variables ont deux emplois différents : à gauche de :=on emploie ladressecode G à droite de := on emploie la valeur. code D code G (var) = ldc a addr(var) code D ajoute la valeur en sommet de pile code D (var) = code G (var) ; ind type(var) code D (e 1 op e 2 ) = code D (e 1 ) ; code D (e 2 ) ; P(op) code(v := e) = code G (v) ; code D (e 2 ) ; sto type(v) P(op) est la P-instruction correspondante, p.ex. P(+) = add i Les variables globales ont une adresse fixe ; on les met en début de la pile. L'adresse est stockée dans la table de symboles. Les variables locales des procédures non récursives peuvent aussi recevoir une adresse fixe (cas du COBOL, du FORTRAN IV) W9

206 P-instructions pour variables P-instrSignificationConditionRésultat ldo T qSP := SP + 1 ; STORE [SP] := STORE [q] q : adresse(T) ldc T qSP := SP + 1 ; STORE [SP] := q Type(q) = T(T) ind TSTORE [SP] := STORE [STORE [SP]](a)(T) sro T qSTORE [q] := STORE [SP] ; SP := SP - 1 (T) q : adresse sto TSTORE [STORE [SP - 1]] := STORE[SP] ; SP := SP - 2 (a,T) W9

207 1.2 Instructions Instructions de branchement Ces instructions modifient le Program Counter (PC) goto absoluujp q :goto q goto conditionnelfjp q :if top = false then goto q goto calculéixj q :goto top + q W11

208 Conditionnelles code D (e) fjp code(st 1 ) ujp code(st 2 ) if e then st 1 else st 2 code D (e) fjp code(st) if e then st (a) deux branches(b) une seule branche W12

209 Boucles code D (e) fjp code(st) ujp code(st) while e do st repeat st until e (a) boucle while(b) boucle repeat code D (e) fjp W12

210 Exemples ldca 5 indi ldca 6 indi grti fjp ldca 7 ldca 5 indi stoi ujp ldca 7 ldca 6 indi stoi else c b := if a b > then c a := while a b > do c 1 + := a b - := W13

211 Case case e of 0 : st 0 ;. k : st k end code D e neg i ixj q code D st 0 ujp code D st 1 ujp code D st k ujp Laisse la valeur du sélecteur en sommet de la pile Branchement indexé vers la fin de la table des branchements Branchement vers la fin de linstruction Table des branchements q Code du cas 0 W14

212 1.3 Données Tableaux En Pascal les types d'indice dun tableau sont statiques et font partie de son type Les extensions de Pascal ont des tableaux de taille dynamique La plupart des compilateurs rangent les tableaux en mémoire par ligne: le dernier indice varie d'abord Les compilateurs Fortran rangent les tableaux par colonne Appelons l i la borne inférieure du ième indice u i sa borne supérieure d i sa dimension = u i - l i + 1 (si u i > l i ) W16

213 Indexation de tableaux Ladresse de a [ i 1,..., i k ] est : addr(a)+ [i k - l k + (i k-1 - l k-1 ) * d k. + (i 1 - l 1 ) * d 2 *... * d k ] * sizeof (type) Dans la P-machine, on précalcule les parties constantes. Autre optimisation: schéma de Horner W17

214 P-code pour l'indexation code G c[i 1,..., i k ] =ldc a (c) code I [i 1,..., i k ] c code I [i 1,..., i k ] n =code D i 1 ; ixa n* d 2 *... * d k code D i 2 ; ixa n* d 3 *... * d k. code D i k ; ixa n dec a n * (l k + l k-1 * d k +...) ixa q : sp i ixa q s s+i*q W20

215 1.3.2 Records En Pascal les types ont une taille statique pour chaque champ on a un déplacement relatif : On le stocke dans la table des symboles Ex.recordtailledéplacement a : array [1.. 5, 1.. 5] of boolean25x1 octets0 x : integer4 octets25 y : real4 octets29 end Traduction code G (v.c i ) =code G (v); inc a dépl(c i ) W24

216 Pointeurs Les cases créées par new ne peuvent pas être allouées sur la pile car elles vivent plus longtemps que la procédure qui les a créées. On réserve une zone de mémoire spéciale, le TAS. La gestion du tas - récupérer la place lors dun dispose - risque de fragmenter la mémoire p.ex. : organisation en pools où toutes les cases ont la même taille. PILETAS SP W25

217 Procédures imbriquées Distinguer limbrication statique du texte des procédures dynamique des appels de procédure Une occurrence de variable a une différence dimbrication statique : procédure p var x : integer procedure q... x... end 1 niveau dimbrication statique L imbrication de procédures n existe pas en C, FORTRAN, Java,... W28

218 proc p(a) var b; var c proc q var a var q proc r var b b a c. a b q proc s var a. a q a q Les flèches montrent pour chaque utilisation de variable, la définition associée Les nombres indiquent la différence dimbrication des occurrences de variables. W31

219 Prédécesseurs statiques Le lien daccès (ou prédécesseur statique) pointe vers lactivation la plus récente de la procédure englobante program h ; var i : integer ; proc p var a proc r var i : real i := i/2 ; a := 5 if i > 0 then i := i - 1 ; p else r fi i := 2 ; p ; p end. h p p p r p r Liens daccès Figure : Un programme et son arbre d activation (ou dappels). Les crochets donnent l imbrication des procédures. W29

220 Accès non local Chaque occurrence de variable est identifiée par sa différence dimbrication d et son déplacement o Pour trouver son adresse, on suit d liens daccès (donne le bloc dactivation de sa déclaration) et on ajoute o. D461 W36

221 P-instructions pour variables lod (load) charge une variable sur la pile lda (load address) charge ladresse d une variable str (store) remet un résultat dans une variable. base(p,a) = if p = 0 then a else base(p - 1, STORE[a + 1]) fi W37

222 Mise à jour Lors dun appel, le nouveau lien daccès est obtenu en suivant d liens daccès de lappelant, où d est la différence d'imbrication de l'appel.

223 Exemples proc p proc q q proc r proc p q proc q p proc r proc q proc p q p q * p q d = 0 (a) d = 1 (b) d = 2 (c) * p q MP SP r * q q MP SP r * p *

224 Bloc d'activation Les appels de sous-programme sont gérés sur la pile Chaque appel a son bloc d'activation avec ses données: PILE Val de fonction Préd. statique Préd. dynamique Val de EP Adresse de retour RET param ètres Vars. locales Pile locale TAS EP SP MP p s pp W33

225 Protocole d'appel 1.Mettre le prédécesseur statique à la dernière instance de la procédure englobant q. 2.Mettre le prédecesseur dynamique à l'appelant p. 3.Préserver EP, le registre bornant la pile 4.Calculer les arguments dans l'appelant 5.Mettre MP sur le bloc 6.Sauver l'adresse de retour 7.Sauter à q 8.Mettre EP à jour W42

226 P-Instructions pour lappel dun sous-programme base(p,a) = if p = 0 then a else base(p - 1, STORE[a + 1]) fi W43

227 Protocole de retour Remettre les registres à jour: SP PC EP MP W44

228 P-instructions de retour de sous-programme W44

229 2. Machines concrètes Les machines concrètes = processeurs ex. Pentium, MIPS, G4, ARM Contraintes: –de registres –d'alignement –de parallélisme (pipeline, unités parallèles)

230 1. Expressions sans partage : Pile –Réordonnancement –Allocation de registres avec partage : DAG –utilisation avec pipelines

231 Registres Types de registres courants: universels spécialisés: réels flottants données adresses base index PC: program counter (prochaine instruction) CC: codes de conditions Les processeurs RISC ont de nombreux registres universels W553

232 Allocation de registres D613 W565 Technique simplifiée pour les arbres : 1. réorganisation des calculs 2. allocation des registres par simulation de pile

233 Réordonnancement Idée : on évalue dabord lexpression qui emploie le plus de registres car 1 registre sert pour le résultat. Exemple : + t 1 t 2 4 reg 3 reg } + calcul de t1 ; calcul de t2 ; addition D613 W566

234 Calcul du meilleur ordre calculer récursivement le nombre de registres optimal : r (t 1 op t 2 ) =max (r 1, r 2 )si r 1 r 2 r 1 + 1si r 1 = r 2 oùr 1 = r(t 1 ) r 2 = r(t 2 ) Le cas de base dépend du type dinstructions de la machine. Pour une architecture load/store, il faut 1 registre. { D614 W567

235 Exemple abc de _ + + _ (a + b) - (c - (d + e)) requiert 3 registres sur une machine load/store D614 W568

236 type abstrait Pile empiler(P, E)ajoute E sur P dépiler(P)enlève le sommet de P et le renvoie échanger(P)échange le sommet et celui en dessous sommet(P)renvoie le sommet sans changer la pile sommet2(P) renvoie lélément en dessous du sommet

237 Algorithme dallocation pilereg : pile statique de registres libres pilereg nest jamais vide Le sommet de pilereg contiendra le résultat pilereg doit être remis dans létat initial Une pile de temporaires est employée lorsqu il n y a plus assez de registres (> r) D615

238 Algorithme : cas de base la variable est chargée dans le registre : ProdCode(n) : si n est une feuille (une variable dadresse var): émettre( lw sommet(pilereg), 0(var) ) Note: diffère de D617 car prévu pour une machine load/store (p.ex. MIPS) D617

239 Algorithme : cas 3 sil est plus avantageux de respecter lordre : r1 r2, r>r2 ProdCode(n1); R := dépiler(pilereg); ProdCode(n2); émettre(op, R, R, sommet(pilereg)) ; empiler(pilereg, R);

240 Algorithme : cas 2 sil est plus avantageux dinverser lordre càd si r2 r1, r>r1: ProdCode(n2); R := dépiler(pilereg); ProdCode(n1); émettre( op, R, sommet(pilereg), R); empiler(pilereg, R);

241 Algorithme : cas 4 si les deux sous-termes utilisent plus de registres quil ny en a: r1, r2 r ProdCode(n1); T := dépiler(piletemp); émettre(sw sommet(pilereg), T ); // stocke le résultat en T ProdCode(n2); émettre(lw sommet2(pilereg), T ) ; // charge T émettre(op sommet(pilereg), sommet2(pilereg), sommet(pilereg) ); empiler(piletemp, T)

242 Exemple pour (a + b) - (c - (d + e)) avec 2 registres : lw R1, a lw R2, b add R1, R1, R2 sw R1,T// T := a+b lw R1, d lw R2, e add R1,R1,R2// R1 = d+e lw R2, c sub R1, R2, R1// R1 = c-(d+e) lw R2, T sub R1, R2, R1// R1 = (a+b)-(c-(d+e)) abc de _ + + _

243 Bloc de base le graphe de flot de contrôle (ou ordinogramme) donne les successions possibles dinstructions un bloc de base est une suite dinstructions sans branchements entrants ni sortants. D579 W563 B ex: while B do S S

244 Partage de calculs : DAG représente les calculs dun bloc de base les sous-expressions communes sont partagées forme: graphe acyclique : –les feuilles sont des variables ou des constantes –les nœuds sont des opérateurs –les nœuds sont étiquetés par les variables affectées –on distingue la valeur initiale (x 0 ) et la valeur finale Hyp. simplificatrice : pas de synonymie D598 W575

245 Exemple : DAG simple c := a[i]+1; b := 1-a[i]; b c [ ] 1 a i

246 Registres pour DAG En cas de partage, la technique en pile nest pas toujours optimale On divise le DAG en arbres en coupant aux nœuds partagés D619 b c [ ] 1 a i t b c [ ] - + a i 1 t t 1

247 Pipelines Dans les processeurs à pipeline, le résultat nest disponible quaprès un délai Il faut insérer des instructions indépendantes Algorithme glouton: – tri topologique du DAG –choix dune instruction parmi les minimales –calcul des collisions Augmente lemploi des registres W580

248 Algorithme pour pipelines Simplification : le délai est 1 cycle. Candidats := minimaux(DAG); /* instructions minimales non exécutées */ Collisions := {instruction précédente }; /* instructions en cours dexécution */ répéter b := ChoixHeuristique(Candidats \ enCollision(Candidats, Collisions ); si b = erreur alors insérer NOP; Collisions := vide; sinon enlever b de Candidats; Collisions := {b}; ajouter dans candidats les nœuds dont b était le seul prédécesseur jusquà Candidats vide

249 2. Instructions 2.1 conditionnelles 2.2 boucles 2.3 case

250 Instructions conditionnelles La plupart des machines ont un jeu dinstructions qui contient : exemple : MIPS un goto absoluj q :goto q un goto conditionnelbeq $rs $rt q :if $rs = $rt then goto PC+q un goto calculéjr $r :goto $r change le PC (program counter), le registre qui contient l adresse de la prochaine instruction.

251 Instructions conditionnelles code D (e) beq $r, $zero code(st 1 ) j code(st 2 ) if e then st 1 else st 2 code D (e) beq $r, $zero code(st) if e then st (a) deux branches(b) une seule branche Instructions traduisant les instructions conditionnelles

252 Boucles code D (e) beq $r, $zero code(st) j while e do st repeat st until e (a) boucle while(b) boucle repeat code D (e) beq $r, $zero Génération de code pour les boucles

253 Instruction case case e of 0 : st 0 ; 1 : st 1 ;. k : st k end code D e sub $t1, q, $t1 jr $t1 code st 0 j exit code D st 1 j exit code st k j exit j L1 j L0 j Lk Laisse la valeur du sélecteur dans un registre $re Branchement indexé vers la fin de la Table des branchements Branchement vers la fin de linstruction Table des branchements q : exit : L0: Lk :

254 3. Allocation de mémoire les variables ont deux emplois différents : –à gauche de « := », cest une adresse –à droite de « := », cest la valeur stockée à cette adresse le langage source admet-il: –la récursivité ? si oui: nouvelles variables à créer –limbrication de procédures ? si oui : retrouver les liens

255 Allocation La mémoire est habituellement divisée en: –code : lecture seule –constantes : lecture seule –variables globales : adresse statique –pile : pour les variables locales de procédures récursives –tas : pour les autres variables dynamiques

256 Tableaux En Pascal les dimensions dun tableau sont statiques Les extensions de Pascalont des tableaux Algol-68taille dynamique Ada C } var : array [l 1.. u 1,..., l k.. u k ] of ex: var a : array[1..2,1..3] of integer; la ième dimension d i = u i - l i + 1 (si u i > l i ) Rangement par ligne: le dernier indice varie dabord: ex: a[1,1] a[1,2] a[1,3] a[2,1] a[2,2] a[2,3] par colonne le premier indice varie dabord: ex: a[1,1] a[2,1] a[1,2] a[2,2] a[1,3] a[2,3]

257 Tableaux : indices Pour accéder à un élément a[e,f,g] on calcule ladresse a+( (e-l 1 )* d 2 *d 3 + (f-l 2 )*d 3 + (g-l 3 ) )*t en Pascal seuls e,f,g sont dynamiques on peut précalculer la partie statique Le schéma de Horner limite les multiplications : e* d 2 *d 3 + f *d 3 + g = (e* d 2 + f) *d 3 + g

258 Records En Pascal tous les types ont une taille statique pour chaque champ on a un déplacement relatif Ex.record a : array [1.. 5, 1.. 5] of boolean1 byte par bool. x : integer4 byte par int. y : real8 byte par real end déplacement Les machines ont souvent des contraintes dalignement : p.ex. un réel doit avoir une adresse multiple de 4 on doit laisser du remplissage ou réordonner les champs Traduction d un accès à un champ code G (v.c i ) = code G (v) ; # laisse l adresse de v dans un registre $t add $t, (c i ), $t #laisse l adresse du champ dans $t. # (c i ) est le déplacement de c i

259 Pointeurs Les cases créées par new ne peuvent pas être allouées sur la pile car elles vivent plus longtemps que la procédure qui les a créées. On réserve une zone spéciale, le TAS. La gestion du tas -comment récupérer la place lors dun dispose ? -Si le dispose est automatique => algorithme de ramasse-miettes -risque de fragmenter la mémoire si plusieurs tailles => algorithmes de regroupement PILETAS SP D488 W25

260 Procédures récursives Chaque appel à une procédure récursive doit avoir de nouvelles variables locales Lallocation est LIFO, donc en pile Les instances de procédures sont donc stockées dans une pile. Souvent un registre SP pointe vers le sommet de la pile.

261 D433 Pile de contrôle Lexécution des procédures (récursives) est imbriquée représentable par une pile Le contenu de la pile représente une branche de larbre dactivation. La pile contient des blocs dactivation. Le registre FP (frame pointer) point sur le bloc courant, sommet de la pile. Chaque bloc contient: la valeur renvoyée (pour une fonction) létat des registres à restaurer, en particulier: ladresse de retour est la valeur du PC (program counter) le lien daccès ou prédécesseur statique (si imbrication) le lien de contrôle ou prédécesseur dynamique (état du FP) pointe vers le bloc appelant les paramètres (parfois dans des registres) les variables locales des temporaires (pour l évaluation d expressions).

262 Protocole d appel Répartit les rôles de l appelant et de l appelé. Par exemple: 1. l appelant crée le bloc dactivation 2. l appelant évalue les arguments et les met dans les registres ($a) ou dans le bloc 3. l appelant calcule le lien d accès en suivant le sien. 4. l appelant sauve le PC et saute au début de l appelé 5. l appelé alloue et initialise les variables locales 6. l appelé commence son exécution (qui calcule la valeur de retour) Au retour: 1. l appelé restaure les registres, en dernier le PC (saut de retour) D

263 Accès aux noms non locaux Algol, Pascal, Ada, ont des procédures imbriquées Ils emploient la portée statique : les variables sont recherchées dans le texte englobant la portée dune variable est le sous-programme où elle est déclarée On emploie la déclaration la plus locale D453

264 Passage de paramètres Diffère dun langage à lautre Principaux types : –par valeur –par référence (ou par variable) –par copie (in out) –par nom D467

265 Passage par valeur Le paramètre est comme une variable locale Lappelant évalue la valeur de largument et le place comme valeur initiale du paramètre

266 Passage par référence Ladresse de largument est passée. En Pascal: noté par var

267 Exemple procedure Troquer(var x, y : integer); var t : integer; begin t := x; x := y; y := t end; Naurait aucun effet en passage par valeur !

268 Passage par copie Utilisé p.ex. en Ada (mode in out) La valeur de largument est copiée dans le paramètre ; au retour la valeur du paramètre est copiée dans largument Même effet que le passage par référence sauf en cas de synonymie. D470

269 Exemple program ValeurResultat(output); var a : integer; procedure Hasardeuse(var x:integer); begin x:=2 ; a := 0 end; begin a:=1; Hasardeuse(a) ; writeln(a) end. a=0 si passage par référence, a=2 si passage par copie. D471

270 Passage par nom Remplacement textuel du paramètre par largument (comme pour une macro) Utilisé seulement en Algol-60. D471

271 Exemple procedure Troquer(x,y:integer); var t:integer; begin t := x; x := y; y := t end; Troquer(i, t[i] ) met i dans t[t[i]] !

272 Passage de fonctions en paramètre Pour les langages à portée statique (p.ex. Pascal): On doit passer ladresse de début du code et le lien daccès

273 Exemple : fonction en paramètre Program HP proc p(func h) h proc q func f p(g) p(f) func g q HP q p f q p f g p (a) Un programme avec fonction en paramètre (b) situation de la pile après appel de p(f) et (en pointillé) après appel de h (c) situation de la pile après appel de p(g) et (en pointillé) après appel de h

274 Introduction à la Sémantique

275 Quest-ce que cest ? La sémantique donne le sens dun langage Pour un langage de programmation, elle permet de prévoir le comportement du programme Pour un langage séquentiel, on suppose que le seul comportement observable est le résultat final.

276 A quoi ca sert ? La sémantique permet de: –décider ce que doit faire un programme dans des cas complexes –calculer si des programmes sont équivalents, ce qui permet à un compilateur de remplacer lun par lautre. –dériver la plupart des analyses de programmes –construire des compilateurs fiables

277 Types de sémantique Sémantique opérationnelle : décrit comment un programme peut sexécuter Sémantique dénotationnelle : donne un objet (p.ex. une fonction des données vers les résultats) comme sens dun programme Sémantique axiomatique : donne des règles pour raisonner sur les programmes

278 Liens entre types de sémantique les 3 types de sémantique ont leur utilité: –la sémantique opérationnelle facilite la construction de compilateurs –la sémantique dénotationnelle donne les concepts du langage –la sémantique axiomatique est la plus utile pour les programmeurs On peut passer de lune à lautre en démontrant leur équivalence.

279 Sémantique opérationnelle Sémantique opérationnelle = on donne le sens du programme en donnant un ensemble dexécutions possibles. + Avantages : + intuition claire + facilité de construire un interpréteur + traitement du non-déterminisme Inconvénients fréquents : non compositionnel : on ne peut pas donner de sens à certaines parties peu abstrait : difficile de prouver que 2 programmes sont équivalents. difficile de construire un compilateur optimisant.

280 Sémantique Opérationnelle Structurée On évite les inconvients habituels en ajoutant: –Compositionalité : On donne des règles dinférences qui donnent les exécutions possible s en fonction de celles des composants. –Abstraction : On ajoute des règles de similarités disant quelles exécutions sont équivalentes.

281 Système de déduction Une règle dinférence est de la forme : prémisses conclusion « Si on a prouvé F 1... F n on peut déduire F 0 ». (Ici les F i décriront des exécutions possibles) Sil ny a pas de prémisses, on lappelle un axiome. Une règle peut contenir des méta-variables càd des variables qui représentent nimporte quel texte dune catégorie syntaxique donnée. On lappelle alors un schéma de règle. Une preuve est un arbre fini composé de règles dinférences ; elle a une conclusion à la racine, appelée théorème. La théorie dun système de déduction est lensemble des théorèmes.

282 Sémantique Opérationnelle Structurée : Définition Les formules qui nous intéressent: e 1 e 2 « de létat e 1, par un pas dexécution on peut arriver dans létat e 2 »

283 Etats Les états doivent contenir linformation nécessaire à lexécution : –le point dexécution dans le programme (ici, on le représente par la partie du programme restant à exécuter); –la valeur des variables; –létat de la pile de récursion; –etc.

284 Exemple : expressions Pascal on ne traite dabord que des expressions sans variables et sans effet de bord, donc la mémoire nest pas (encore) nécessaire.

285 Règles de congruence : on peut simplifier n importe quelle sous-expression en Pascal : où f est un opérateur ou un appel de fonction de calcul : pour chaque opérateur Pascal, on donne des règles pour calculer la valeur du résultat à partir de la valeur des arguments –par exemple : not true false not false true

286 Exemple Pour C: les arguments sont évalués de gauche à droite: Si le côté gauche suffit, on névalue pas le côté droit: le premier pas est la règle de congruence pour le 2ème argument; sa prémisse est justifiée par la règle de calcul pour *. le second pas est le calcul.

287 Expressions avec mémoire Un état a maintenant 2 composantes: –lexpression à évaluer; –létat de la mémoire : une fonction Identificateur Valeur de congruence : on peut simplifier une sous-expression de calcul : (not true, m) (false, m) (not false, m) (true, m) de recherche de valeur en mémoire: (id, m) (m(id), m)

288 Exemple : expression congruence recherche congruence calcul * congruence recherche congruence calcul * congruence calcul +

289 Instructions affectation : –dabord évaluer lexpression –ensuite modifier létat pour la variable avec la constante ainsi calculée conditionnelle : –dabord évaluer lexpression –ensuite évaluer la branche choisie (2 cas) boucle : –créer une copie de lexpression –lévaluer (en gardant l expression du while pour les itérations) séquence : –évaluer la première instruction –lorsquelle se termine exécuter la 2ème instruction

290 Instructions Affectation :1. (e, m) (e, m ) congruence (id := e, m) (id := e, m ) calcul := 2.(id := n, m) (skip, update (id, n, m)) instruction vide Conditionnelle :1. (e, m) (e, m) (if e then S 1 else S 2 m) (if e then S 2 else S 2 m) 2.1 (if true then S 1 else S 2, m) (S 1, m) 2.2 (if false then S 1 else S 2, m) (S 2, m) abréviation (if e then S 1, m) (if e then S 1 else skip, m) Boucle :(while e do S, m) (if e then begin S ; while e do S end, m) Séquence : (S 1, m) (S 1, m) (S 1 ; S 2, m) (skip ; S, m) (S, m) e : expr id : identificateur n : const

291 Système de transitions Les règles de la SOS définissent une machine à états infinis, quon appelle aussi un système de transitions. On peut aussi la voir comme un graphe.

292 Questions importantes 1. Il y a-t-il plusieurs suites de flèches partant dun même état ? (déterminisme) 2. Certaines de ces suites sont-elles infinies ? (terminaison) 3. Aboutissent-elles toutes au même état ? (confluence) 4. Quelle forme ont les états finals ? Les état finals corrects ? Déf. : C final = il ny a pas de C : C C (forme normale) 5. Les flèches préservent-elles les types ?

293 Equivalence sémantique La SOS détaille les calculs, donc peu de programmes sont équivalents Deux programmes P,Q sont équivalents ssi: –ils mènen t aux mêmes états finaux –ils bouclent dans les mêmes circonstances : p *q signifie quun chemin dexécution mène de p à q. p signifie quun chemin dexécution infini part de p.

294 Sémantique dénotationnelle Donne pour chaque partie de programme, un objet qui est son sens: p.ex. un programme déterministe séquentiel dénote une fonction Compositionnelle si le sens dun programme dépend du sens de ses parties mais pas de leur forme. Abstraite si le sens ne conserve que linformation quon peut observer.

295 Compositionnalité Si S1, S2 sont deux instructions dont le sens de chacune est une fonction des états de mémoire (de départ) vers les états de mémoire darrivée : f1, f2, alors la sequence S1; S2 a comme sens la fonction composée de f1 et f2

296 Sémantique axiomatique Donne des règles pour construire des programmes Les règles peuvent être démontrées à partir d une autre sémantique (p.ex. opérationnelle) Notation : {pre} P {post} signifie que si P démarre dans un état de mémoire satisfaisant pre, alors il se termine dans un état de mémoire satisfaisant post. pre post

297 Exemple de règles règle pour laffectation: { post [e/x] } x := e {post } la règle est valide si x ne peut être accédée que par ce nom (pas de synonymie) règle pour le if: { pre et b} t {post } { pre et non b} e {post } { pre } if b then t else e {post }


Télécharger ppt "IHDC 2105 Syntaxe et sémantique des langages de programmation Pierre-Yves Schobbens Bureau 409 081/72 49 90 rue Grandgagnage 21 5000 Namur"

Présentations similaires


Annonces Google