Symboltabelle
Im Informatik, a Symboltabelle ist ein Datenstruktur verwendet von einer Sprache Übersetzer so wie ein Compiler oder Dolmetscher, wo jeweils Kennung (oder Symbole), Konstanten, Verfahren und Funktionen in einem Programm eines Programms Quellcode ist mit Informationen in Bezug auf seine verbunden Erklärung oder Aussehen in der Quelle. Mit anderen Worten, die Einträge einer Symbol Tabelle speichern die Informationen, die sich auf das entsprechende Symbol des Eintrags beziehen.[1]
Hintergrund
Eine Symboltabelle kann während des Übersetzungsprozesses nur im Gedächtnis existieren, oder es kann in die Ausgabe der Übersetzung eingebettet sein, z. B. in einem Abi Objektdatei Für spätere Verwendung. Zum Beispiel kann es während eines interaktiven verwendet werden Debugging -Sitzungoder als Ressource für die Formatierung eines diagnostischen Berichts während oder nach Hinrichtung eines Programms.[2]
Beschreibung
Die in einer Symboltabelle enthaltenen Mindestinformationen, die von einem Übersetzer verwendet werden und Zwischendarstellung (IR) enthält den Namen des Symbols und seinen Standort oder seine Adresse. Für einen Compiler, der auf eine Plattform mit einem Konzept der Umzugsfähigkeit abzielt, enthält er auch Relokatabilitätsattribute (absolut, verlängerbar usw.) und die erforderlichen Umzugsinformationen für laufbare Symbole. Symboltabellen für hochrangige Programmiersprachen kann den Typ des Symbols speichern: String, Ganzzahl, Gleitkomma usw., seine Größe und seine Dimensionen und seine Grenzen. Nicht alle diese Informationen sind in der Ausgabedatei enthalten, können jedoch für die Verwendung in bereitgestellt werden Debuggen. In vielen Fällen das Symbol des Symbols Querverweis Informationen werden mit der Symboltabelle gespeichert oder verknüpft. Die meisten Compiler drucken einige oder alle dieser Informationen am Ende der Übersetzung in den Symboltabellen und in den Querverweis.[1]
Implementierung
Zahlreich Datenstrukturen sind für die Implementierung von Tabellen verfügbar. Bäume, lineare Listen und selbstorganisierende Listen kann alle verwendet werden, um eine Symboltabelle zu implementieren. Die Symboltabelle wird durch die meisten Phasen eines Compilers zugegriffen, beginnend mit lexikalische Analyseund durch Optimierung fortgesetzt.
Ein Compiler kann eine große Symboltabelle für alle Symbole verwenden oder getrennte, hierarchische Symboltabellen für verschiedene verwenden Bereiche. Zum Beispiel in einer Scoped -Sprache wie z. Algol oder Pl/i Ein Symbol "P" kann in mehreren Verfahren separat deklariert werden, möglicherweise mit unterschiedlichen Attributen. Der Umfang jeder Erklärung ist der Abschnitt des Programms, in dem sich auf "P" auf diese Erklärung beziehen. Jede Deklaration repräsentiert eine eindeutige Kennung "P". Die Symboltabelle muss einige Mittel haben, um Verweise auf die verschiedenen "P" zu unterscheiden.
Eine gemeinsame Datenstruktur zur Implementierung von Symboltabellen ist die Hash-tabelle. Die Zeit für die Suche in Hash -Tabellen ist unabhängig von der Anzahl der in der Tabelle gespeicherten Elemente, daher ist sie für eine große Anzahl von Elementen effizient. Es vereinfacht auch die Klassifizierung von Literalen im tabellarischen Format durch Einbeziehung der Klassifizierung in die Berechnung des Hash -Schlüssels.[3]
Da der lexikalische Analysator einen großen Teil seiner Zeit damit verbringt, die Symboltabelle nachzuschlagen, hat diese Aktivität einen entscheidenden Einfluss auf die Gesamtgeschwindigkeit des Compilers. Eine Symboltabelle muss so organisiert werden, dass Einträge so schnell wie möglich gefunden werden können. Hash -Tabellen werden normalerweise verwendet, um eine Symboltabelle zu organisieren, in der das Schlüsselwort oder die Bezeichnung „Hashed“ zur Erstellung eines Array -Indexs ist. Kollisionen sind in einer Hash -Tabelle unvermeidlich, und eine häufige Möglichkeit, sie zu behandeln, besteht darin, das Synonym im nächsten verfügbaren freien Speicherplatz in der Tabelle zu speichern.
Anwendungen
Ein Objektdatei Enthält eine Symboltabelle der von ihnen enthälten Kennungen, die extern sichtbar sind. Während der Verknüpfung verschiedener Objektdateien a Linker Identifiziert und behebt diese Symbolreferenzen. Normalerweise werden alle undefinierten externen Symbole in einem oder mehreren gesucht Objektbibliotheken. Wenn ein Modul gefunden wird, das dieses Symbol zusammen mit der ersten Objektdatei definiert, und alle und definierten externen Kennungen zu der Liste der zugeschauten Kennungen hinzugefügt werden. Dieser Prozess wird fortgesetzt, bis alle externen Referenzen gelöst wurden. Es ist ein Fehler, wenn einer oder mehrere am Ende des Prozesses ungelöst bleiben.
Während Reverse Engineering Eine ausführbare Datei beziehen sich auf die Symboltabelle, um zu überprüfen, welche Adressen globalen Variablen und bekannten Funktionen zugewiesen wurden. Wenn die Symboltabelle war abgestreift oder gereinigt, bevor sie in eine ausführbare Datei konvertiert werden, fällt es Tools schwerer, Adressen zu bestimmen oder etwas über das Programm zu verstehen.
Beispiel
Betrachten Sie das folgende Programm in C:
// eine externe Funktion deklarieren extern doppelt Bar(doppelt x); // eine öffentliche Funktion definieren doppelt Foo(int zählen) { doppelt Summe = 0,0; // alle Werte mit Bar (1) in die Bar (Graf) zusammenfassen zum (int i = 1; i <= zählen; i++) Summe += Bar((doppelt) i); Rückkehr Summe; }
Ein C -Compiler, der diesen Code analysiert, enthält mindestens die folgenden Symbol -Tabelleneinträge:
Symbolname | Typ | Zielfernrohr |
---|---|---|
Bar | Funktion, doppelt | extern |
x | doppelt | Funktionsparameter |
Foo | Funktion, doppelt | global |
zählen | int | Funktionsparameter |
Summe | doppelt | Lokal blockieren |
i | int | For-Loop-Erklärung |
Darüber hinaus enthält die Symboltabelle auch Einträge, die vom Compiler für intermediäre Expressionswerte erzeugt werden (z. B. den Ausdruck, der die ausgibt i
Schleifenvariable in a doppelt
und der Rückgabewert des Aufrufs zur Funktion Bar()
), Aussage Beschriftungen und so weiter.
Beispiel: sysv abi
Adresse | Typ | Name |
---|---|---|
00000020 | a | T_bit |
00000040 | a | F_bit |
00000080 | a | ICH BISS |
20000004 | t | Irqvec |
20000008 | t | fiqvec |
20000c | t | Initreset |
20000018 | T | _hauptsächlich |
20000024 | t | Ende |
20000030 | T | AT91F_US3_CFGPIO_USB |
2000005c | t | AT91F_PIO_CFGPERIPH |
200000b0 | T | hauptsächlich |
20000120 | T | AT91F_DBGU_PRINTK |
20000190 | t | AT91F_US_TXREADY |
200001c0 | t | AT91F_US_PUTCHAR |
200001f8 | T | AT91F_SpuriousHandler |
20000214 | T | AT91F_DATAABORT |
20000230 | T | AT91F_Fetchabort |
2000024c | T | AT91F_UNDEF |
20000268 | T | AT91F_UNDEFHandler |
20000284 | T | At91f_lowlevelinit |
200002e0 | t | AT91F_DBGU_CFGPIO |
2000030c | t | AT91F_PIO_CFGPERIPH |
20000360 | t | At91f_us_configure |
200003DC | t | AT91F_US_SETBAUDRATE |
2000041c | t | AT91F_US_BOUDRATE |
200004ec | t | AT91F_US_SETTIMEGUARD |
2000051c | t | At91f_pdc_open |
2000059c | t | AT91F_PDC_DISABLERX |
200005C8 | t | AT91F_PDC_DISABLETX |
200005f4 | t | AT91F_PDC_SETNEXTTX |
20000638 | t | AT91F_PDC_SETNEXTRX |
2000067c | t | AT91F_PDC_SETTX |
200006C0 | t | AT91F_PDC_SETRX |
20000704 | t | AT91F_PDC_ENABLERX |
20000730 | t | AT91F_PDC_ENABLETX |
2000075c | t | AT91F_US_ENABLETX |
20000788 | T | __aabi_Uidiv |
20000788 | T | __udivsi3 |
20000884 | T | __aabi_Uidivmod |
2000089c | T | __aabi_idiv0 |
2000089c | T | __aabi_ldiv0 |
2000089c | T | __div0 |
200009a0 | D | _Daten |
200009a0 | A | _ETEXT |
200009a0 | D | Holaamigosh |
200009a4 | A | __bss_end__ |
200009a4 | A | __bss_start |
200009a4 | A | __bss_start__ |
200009a4 | A | _edata |
200009a4 | A | _Ende |
Ein Beispiel für eine Symboltabelle kann in der gefunden werden Sysv Anwendung Binärschnittstelle (ABI) Spezifikation, die vorschreibt, wie Symbole sind in einer binären Datei ausgelegt, so dass verschiedene Compiler, Linker und Lader alle konsequent die Symbole in einem kompilierten Objekt finden und arbeiten können.
Das SYSV ABI wird in der implementiert Gnu Binutils ' nm Dienstprogramm. Dieses Format verwendet eine sortierte Speicheradresse Feld, ein Feld "Symboltyp" und ein Symbolkennung (genannt "Name").[4]
Die Symboltypen im SYSV ABI (und NM -Ausgang) geben die Art jedes Eintrags in der Symboltabelle an. Jeder Symboltyp wird durch ein einzelnes Zeichen dargestellt. Beispielsweise werden Symbol -Tabelleneinträge, die initialisierte Daten darstellen Text Abschnitt einer Objektdatei). Darüber hinaus gibt die Kapitalisierung des Symboltyps die Art der Verknüpfung an.
Beispiel: Das Python -Symbol -Tabelle
Das Python Die Programmiersprache umfasst umfassende Unterstützung für das Erstellen und Manipulieren von Symboltabellen.[5] Eigenschaften, die abgefragt werden können, gehören, ob ein bestimmtes Symbol a ist freie Variable oder ein gebundene Variable, ob es ist Blockbereich oder globaler Umfang, ob es importiert wird und was Namespace es gehört.
Beispiel: Dynamische Symboltabellen
In einigen Programmiersprachen kann die Symboltabelle zur Laufzeit manipuliert werden, sodass Symbole jederzeit hinzugefügt werden können. Schläger ist ein Beispiel für eine solche Sprache.[6]
Beide LISPELN und die Planen Mit Programmiersprachen können beliebige, generische Eigenschaften mit jedem Symbol zugeordnet werden.[7]
Das Prolog Die Programmiersprache ist im Wesentlichen eine Manipulationssprache mit Symboltabelle. Symbole werden aufgerufen Atomeund die Beziehungen zwischen Symbolen können überrealiert werden. Ähnlich, OpenCog liefert eine dynamische Symboltabelle, die als die genannt Atomspace, was verwendet wird für Wissensrepräsentation.
Siehe auch
Verweise
- ^ a b Copper & Torczon 2011, p. 253.
- ^ Nguyen, Binh (2004). Linux -Wörterbuch. p. 1482. Abgerufen 14. April, 2018.
- ^ Copper & Torczon 2011, p. 254.
- ^ "nm". Sourceware.org. Abgerufen 30. Mai, 2020.
- ^ symptable - Python -Dokumentation
- ^ Symbole - Schlägerdokumentation
- ^ Symbole - Guile -Dokumentation
Literaturverzeichnis
- Kupfer, Keith D.; Torczon, Linda (18. Januar 2011). Engineering ein Compiler (2 ed.). Houston, Texas: Elsevier, Rice University. doi:10.1016/c2009-0-27982-7. ISBN 978-0-12-088478-0.