Table des symboles Pr ZEGOUR DJAMEL EDDINE Ecole
Table des symboles Pr ZEGOUR DJAMEL EDDINE Ecole Supérieure d’Informatique (ESI) www. zegour. uuuq. com email: d_zegour@esi. dz
Table des symboles Introduction Symboles Portée des symboles Types Univers
Rôles de la table des symboles 1. Elle range tous les noms déclarés avec leurs attributs • • • type valeur (pour les constantes) adresse (pour les variables locales et les paramètres de procédures) paramètre (pour les procédures). . . 2. Elle est utilisée pour retrouver les attributs d’un nom • Fonction : nom (type, value, adresse, . . . ) Contenu de la table des symboles • Les nœuds de symbole : information sur les noms déclarés • Les nœuds de Structure : information sur les types déclarés ÞC’est plus commode de l’implémenter par une structure de données dynamique : - liste linéaire chaînée - arbre binaire - Hash-code
Table des symboles comme une liste Soient les déclarations suivantes const int n = 10; class T {. . . } int a, b, c; void M () {. . . } Nous obtenons la liste linéaire chaînée suivante "n" Const "T" Type "a" Field "b" Field "c" Field "M" Meth Pour chaque nom déclaré il existe un nœud de symbole + simple + l’ordre des déclarations est retenu (important si les adresses sont attribuées plus tard) - lent s’il existe beaucoup de déclarations Interface de base public class Tab { public static Symbol Insert (Symbol. Kinds kind, string name, . . . ); public static Symbol Find (string name); }
Table des symboles comme un arbre binaire Déclarations const int n = 10; class T {. . . } int a, b, c; void M () {. . . } Arbre binaire résultant "M" Meth "T" Type "b" Field "a" Field + rapide "c" Field "n" Const - l’arbre peut dégénérer sauf s’il est équilibré - Consommation de la mémoire - l’ordre des déclarations est perdu Utile seulement s’il y a beaucoup de déclarations
Table des symboles comme une table hash-code Déclarations const int n = 10; class T {. . . } int a, b, c; void M () {. . . } Table hash-code résultante 0 "M" Meth 1 "b" Field 2 "n" Const 3 "c" Field + rapide "T" Type "a" Field - plus compliqué qu’une liste - l’ordre des déclarations est perdu Pour notre propos une liste est suffisante • Chaque étendue (portée) est une liste de ses propres déclarations • Une étendue a à peine plus de 10 noms
Table des symboles Introduction Symboles Portée des symboles Types Univers
Les nœuds de symbole Chaque nœud déclaré est rangé dans un nœud de symbole Sortes courants de symboles • • constantes variables globales champs paramètres variables locales types méthodes programme public enum Kinds { Const, Global, Field, Arg, Local, Type, Meth, Prog } Quelles sont les informations désirées sur les objets? • • • pour tous les symboles pour les constantes pour les paramètres pour les variables locales pour les méthodes nom, type structuré, sorte de symbole, . . valeur adresse (= ordre de déclaration) nombre d’arguments et variables locales, symboles locaux (paramètres + variables locales) • pour le programme symboles globaux(= locaux au programme) • pour les variables globales, champs, types, ….
La classe des symboles class Symbol { public enum Kinds { Const, Global, Field, Arg, Local, Type, Meth, Prog } Kinds string Struct Symbol int int Symbol kind; name; type; next; val; adr; n. Args; n. Locs; locals; Défini plus loin // Const: value // Arg, Local: address // Meth: number of arguments // Meth: number of local variables // Meth: parameters & local variables; Prog: symbol table of program } Exemple const int n = 10; class T {. . . } int a, b; void M (int x, int y) char ch; {. . . } kind name next val adr n. Args n. Locs locals Const "n" Type "T" Global "a" Global "b" Meth "M" 10 - - 2 1 Arg "x" Arg "y" Local "ch" 0 - 1 - 0 -
Introduction des noms dans la table des symboles La méthode suivante est appelée quand un nom est déclaré Symbol sym = Tab. Insert(kind, name, type); • • • Crée un nouveau nœud d’objet avec kind, name, type Vérifie si name est déjà déclaré (si c’est le cas => message d’erreur) Attribuer des adresses successives aux variables et champs Entrer le niveau de déclaration pour les variables (Global, Local, …) Ajouter le nouveau nœud en fin de la liste linéaire des symboles Retourner le nouveau nœud à l’appelant Exemple d’appel à la méthode Insert() Var. Decl< Symbol. Kinds kind> = Type< type> ident (. Tab. insert(kind, name, type); . ) { "; " ident (. Tab. insert(kind, name, type); . ) }.
Les symboles (noms) prédéfinis Exemples de noms prédéfinis ? • Types standards : int, char • Constants standards : null • Fonctions Standards : ord(ch), chr(i), len(arr) On peut aussi ranger les noms prédéfinis dans la table des symboles ("Univers") kind name val adr n. Args n. Locs locals Type "int" - Type "char" - Const "null" 0 kind name val adr n. Args n. Locs locals Meth "ord" 1 0 Meth "chr" 1 0 Meth "len" 1 0 Arg "ch" 0 - Arg "i" 0 - Arg "arr" 0 -
Noms spéciaux comme des mot-clés int et char peuvent aussi être implémentées comme des mot-clés. Exige un traitement spécial dans la grammaire Type< Struct type> = ident (. Symbol sym = Tab. Find(token. str); type = sym. type; . ) | "int" (. type = Tab. int. Type; . ) | "char" (. type = Tab. char. Type; . ). C’est plus simple de les avoir pré déclarés dans la table des symboles Type< Struct type> = ident (. Symbol sym = Tab. Find(token. str); type = sym. type; . ) + traitement uniforme pour les noms pré déclarés et les noms utilisateur - on peut re déclarer "int" comme un type utilisateur
Table des symboles Introduction Symboles Portée des symboles Types Univers
Portée = Domaine où l’objet est valide(connu) Il y a des portées séparées (listes d’objets) pour • • L’ "univers" Le programme Chaque méthode Chaque classe contient les noms pré définis ( on ajoute le symbole ‘P’ pour programme) contient noms globaux (= constantes, variables globales, classes, méthodes) contient les noms locaux (= arguments et variables locales) contient des champs Exemple "int" class P int a, b; { void M (int x) int b, c; {. . . } "char" . . . "P" univers (noms pré déclarés) "a" "b" "M" Portée P (tous les noms déclarés dans P) "x" "b" "c" Portée M (tous les noms déclarés dans M) outer locals top. Scope • La recherche d’un nom commence toujours dans top. Scope • Si non trouvé, la recherche continue dans la prochaine portée englobante (outer) • Exemple: recher b, a et int
Les nœuds d’une portée class Scope { Scope outer; Symbol locals; int n. Args; int n. Locs; } // vers la portée englobante // vers les symboles de cette portée // nombre of arguments de cette portée (pour l’attribution des adresses) // nombre de variables locales dans cette portée (pour l’attribution des adresses) Méthode pour l’ouverture d’une portée static void Open. Scope () { // in class Tab Scope s = new Scope(); s. n. Args = 0; s. n. Locs = 0; s. outer = top. Scope; top. Scope = s; } • • Appelée au début d’une méthode ou une classe Relie la nouvelle portée avec celles existantes La nouvelle portée devient top. Scope Tab. Insert() crée toujours des symboles dans top. Scope Méthode pour la fermeture d’une portée static void Close. Scope () { // in class Tab • Appelée à la fin d’une méthode ou une classe top. Scope = top. Scope. outer; • La prochaine portée englobante(outer) devient } top. Scope
Introduction des noms dans une portée Les noms sont toujours introduit dans top. Scope class Tab { static Scope top. Scope; // pointer to current scope. . . static Symbol Insert (Symbol. Kinds kind, string name, Struct type) { //--- create symbol node Symbol sym = new Symbol(name, kind, type); if (kind == Symbol. Kinds. Arg) sym. adr = top. Scope. n. Args++; else if (kind == Symbol. Kinds. Local) sym. adr = top. Scope. n. Locs++; //--- insert symbol node Symbol cur = top. Scope. locals, last = null; while (cur != null) { if (cur. name == name) Error(name + " declared twice"); last = cur; cur = cur. next; } if (last == null) top. Scope. locals = sym; else last. next = sym; return sym; }. . . } Struct : Défini plus loin
Ouverture et fermeture d’une portée Method. Decl = Type< type> ident. . . "{". . . "}" (. Struct type; . ) variable globale (. cur. Method = Tab. insert(Symbol. Kinds. Meth, token. str, type); Tab. Open. Scope(); . ) (. cur. Method. n. Args = top. Scope. n. Args; cur. Method. n. Locs = top. Scope. n. Locs; cur. Method. locals = Tab. top. Scope. locals; Tab. Close. Scope(); . ) . Remarques • Le nom de la méthode est introduit dans la portée englobant la méthode • Avant de fermer une portée, les objets locaux sont attribués au champ locals de la méthode en cours • Même principe pour les classes(les portées sont aussi ouvertes et fermés pour les classes)
Exemple "int" class P Tab. Open. Scope(); top. Scope "char" . . . "P"
Exemple "int" class P int a, b; { Tab. Insert(. . . , "a", . . . ); Tab. Insert(. . . , "b", . . . ); "a" top. Scope "char" "b" . . . "P"
Exemple class P int a, b; { void M () "int" Tab. Insert(. . . , "M", . . . ); Tab. Open. Scope(); "a" top. Scope "char" "b" . . . "M" "P"
Exemple "int" class P int a, b; { void M () int x, y; Tab. Insert(. . . , "x", . . . ); Tab. Insert(. . . , "y", . . . ); top. Scope "char" "a" "b" "x" "y" . . . "M" "P"
Exemple class P int a, b; { void M () int x, y; {. . . } "int" "a" meth. locals = Tab. top. Scope. locals; Tab. Close. Scope(); top. Scope "char" "b" . . . "P" "M" "x" "y"
Exemple class P int a, b; { void M () int x, y; {. . . } "int" prog. locals = Tab. top. Scope. locals; Tab. Close. Scope(); top. Scope "a" "char" "b" . . . "P" "M" "x" "y"
Recherche des noms dans la table des symboles La méthode suivante est appelée quand un nom est utilisé Symbol sym = Tab. Find(name); • La recherche commence dans top. Scope • Si non trouvé, la recherche continue dans la portée englobante (pointeur outer ) static Symbol Find (string name) { for (Scope s = top. Scope; s != null; s = s. outer) for (Symbol sym = s. locals; sym != null; sym = sym. next) if (sym. name == name) return sym; Parser. Error(name + " is undeclared"); return no. Sym; } int char a b m x b c outer locals top. Scope Si un nom est non trouvé la méthode retourne un symbole spécial : no. Sym Const kind name "no. Symbol" type 0 val 0 adr 0 n. Args 0 n. Locs locals no. Type • Symbole pré déclaré • Mieux que null, car il évite les effets de bord (exceptions)
Table des symboles Introduction Symboles Portée des symboles Types Univers
Les types Chaque objet a un type avec les propriétés suivantes • taille • structure (champs pour les classes, type des éléments pour les tableaux, . . . ) Sortes de types ? • types primitives (int, char) • tableaux • classes Les types sont représentés par des nœuds de structure class Struct { public enum Kinds { None, Int, Char, Arr, Class } Kinds kind; Struct elem. Type; // Arr: element type Symbol fields; // Class: list of fields }
Nœuds de structure pour les types primitifs int a, b; char c; kind name type next val adr n. Args n. Vars locals Local "a" 0 - Local "b" Local "c" 1 - 2 - Nœud d’objet Nœud de structure kind elem. Type fields Int - Char - Il existe un seul nœud de structure pour le type int dans toute la table des symboles. Tous les symboles de type int référencent celui-ci. Même chose pour le nœud de structure correspondant au type char.
Nœuds de structure pour les tableaux int[] a; int b; kind name type next val adr n. Args n. Vars locals Local "a" Local "b" 0 - 1 - kind elem. Type fields Arr - Int - La longueur d’un tableau peut ne pas être connue au moment de la compilation. Elle sera déterminée à l’exécution.
Nœuds de structure pour les class C { int x; int y; int z; } C v; kind name type next val adr n. Args n. Vars locals Type "C" Global "v" - Int - kind Class elem. Type fields kind name type next val adr n. Args n. Vars locals Field "x" Field "y" Field "z" - - -
Table des symboles Introduction Symboles Portée des symboles Types Univers
Structure de l "univers" chr. Sym kind name type val adr n. Args n. Locs locals ord. Sym len. Sym no. Sym Type "int" Type "char" Const "null" Meth "chr" Meth "ord" Meth "len" Const "no. Symbol" - - 0 - 1 - 1 - 0 - Arg "i" Arg "ch" Arg "arr" 0 - 0 - kind elem. Type fields Int - Char - int. Type char. Type Class - null. Type Arr - None - no. Type
Interface de la table des symboles class Tab { static Scope top. Scope; // current top scope static Struct int. Type; char. Type; null. Type; no. Type; // predefined types static Symbol chr. Sym; ord. Sym; len. Sym; no. Sym; // predefined symbols static Symbol static void Insert (Symbol. Kinds kind, string name, Struct type) {. . . } Find (string name) {. . . } Open. Scope () {. . . } Close. Scope () {. . . } static void Init () {. . . } } // builds the universe and initializes Tab
- Slides: 32