In der Informatik ist eine Symboltabelle eine Datenstruktur, die von einem Sprachübersetzer wie einem Compiler oder Interpreter verwendet wird, wobei jeder Bezeichner (auch als Symbol bezeichnet) im Quellcode eines Programms Informationen enthält, die sich auf beziehen seine Erklärung oder sein Aussehen in der Quelle. Symboltabelle speichert die Informationen, die sich auf das Symbol beziehen.
Hintergrund [ edit ]
Eine Symboltabelle kann nur während des Übersetzungsvorgangs im Speicher vorhanden sein oder in die Ausgabe der Übersetzung eingebettet sein, beispielsweise in ein ABI-Objekt Datei für spätere Verwertung. Es kann beispielsweise während einer interaktiven Debugging-Sitzung verwendet werden oder als Ressource zum Formatieren eines Diagnoseberichts während oder nach der Ausführung eines Programms. [1]
Beschreibung [ edit ]
The Mindestinformationen, die in einer von einem Übersetzer verwendeten Symboltabelle enthalten sind, umfassen den Namen des Symbols, seine Attribute für die Relokabilität (absolut, relocationfähig usw.) sowie dessen Ort oder Adresse. Für verlagerbare Symbole müssen einige Verlagerungsinformationen gespeichert werden. Symboltabellen für übergeordnete Programmiersprachen speichern den Typ des Symbols: Zeichenfolge, Ganzzahl, Fließkommazahl usw., seine Größe, seine Abmessungen und seine Grenzen. Nicht alle diese Informationen sind in der Ausgabedatei enthalten, können jedoch zur Verwendung beim Debuggen bereitgestellt werden. In vielen Fällen werden die Querverweisinformationen des Symbols mit der Symboltabelle gespeichert oder verknüpft. Die meisten Compiler drucken einige oder alle dieser Informationen in Symboltabellen und Querverweislisten am Ende der Übersetzung.
Implementierung [ edit ]
Zur Implementierung von Tabellen stehen zahlreiche Datenstrukturen zur Verfügung. Bäume, lineare Listen und selbstorganisierende Listen können verwendet werden, um eine Symboltabelle zu implementieren. Auf die Symboltabelle wird von den meisten Phasen eines Compilers zugegriffen, angefangen mit der lexikalischen Analyse bis hin zur Optimierung.
Ein Compiler kann eine große Symboltabelle für alle Symbole oder getrennte, hierarchische Symboltabellen für verschiedene Bereiche verwenden. Beispielsweise kann in einer Umfangssprache wie Algol oder PL / I ein Symbol "p" in mehreren Prozeduren separat deklariert werden, möglicherweise mit unterschiedlichen Attributen. Der Geltungsbereich jeder Deklaration ist der Abschnitt des Programms, in dem Verweise auf "p" zu dieser Deklaration aufgelöst werden. Jede Deklaration repräsentiert eine eindeutige Kennung "p". Die Symboltabelle muss über einige Mittel verfügen, um Verweise auf die verschiedenen "p" zu unterscheiden.
Eine allgemeine Datenstruktur, die zur Implementierung von Symboltabellen verwendet wird, ist die Hashtabelle. Die Zeit für die Suche in Hash-Tabellen ist unabhängig von der Anzahl der in der Tabelle gespeicherten Elemente, sodass sie für eine große Anzahl von Elementen effizient ist. Es vereinfacht auch wie? die Klassifizierung von Literalen in Tabellenform.
Da der lexikalische Analysator einen großen Teil seiner Zeit in die Symboltabelle blickt, hat diese Aktivität einen entscheidenden Einfluss auf die Gesamtgeschwindigkeit des Compilers. Eine Symboltabelle muss so organisiert sein, dass Einträge so schnell wie möglich gefunden werden können. Hashtabellen werden verwendet, um eine Symboltabelle zu organisieren, bei der das Schlüsselwort oder der Bezeichner "hashed" ist, um einen Array-Index zu erzeugen. Kollisionen sind in einer Hashtabelle unvermeidlich, und die Handhabung ist normalerweise üblich, das Synonym im nächsten freien Speicherplatz in der Tabelle zu speichern.
Anwendungen [ edit ]
Eine Objektdatei enthält eine Symboltabelle der Bezeichnungen, die extern sichtbar sind. Während des Verlinkens verschiedener Objektdateien wird ein Linker diese Symbolreferenzen identifizieren und auflösen [ how? ] .
Beim Reverse Engineering einer ausführbaren Datei verwenden viele Tools die Symboltabelle, um zu überprüfen, welche Adressen globalen Variablen und bekannten Funktionen zugewiesen wurden. Wenn die Symboltabelle vor der Umwandlung in eine ausführbare Datei entfernt oder bereinigt wurde, wird es für Tools schwieriger, Adressen zu ermitteln oder etwas über das Programm zu verstehen.
Beispiel [ edit ]
Betrachten Sie folgendes in C geschriebenes Programm:
// Deklaration einer externen Funktion
extern double bar ( double x );
// Definieren einer öffentlichen Funktion
double foo ( int count )
{
doppelt sum = 0.0 ; Addiere alle Werte bar (1) zu bar (count)
für ( int i = 1 ; i i = count ; i ++ )
sum + = bar ([] double ] i );
return sum ;
}
Ein AC-Compiler, der diesen Code analysiert, enthält mindestens die folgenden Symboltabelleneinträge:
| Symbolname | Typ | Umfang |
|---|---|---|
Bar | Funktion, doppelt | extern |
x | double | Funktionsparameter |
foo | Funktion, doppelt | global |
count | int | Funktionsparameter |
Summe | doppelt | lokaler Block |
i | int | for-loop-Anweisung |
Darüber hinaus enthält die Symboltabelle auch vom Compiler generierte Einträge für Zwischenausdruckswerte (z. B. den Ausdruck, der die Schleifenvariable i in ein -Doppel verwandelt, und die Rückgabewert des Aufrufs an function bar () ), Anweisungsbeschriftungen usw.
Beispiel: SysV ABI [ edit ]
Ein Beispiel für eine Symboltabelle finden Sie in der Spezifikation der SysV Application Binary Interface (ABI), in der festgelegt wird, wie Symbole zu setzen sind out in einer Binärdatei, so dass verschiedene Compiler, Linker und Loader alle Symbole in einem kompilierten Objekt konsistent finden und damit arbeiten können.
Die SysV-ABI ist im nm-Dienstprogramm von GNU binutils implementiert. Dieses Format verwendet ein sortiertes Speicheradressfeld, ein Feld "Der Symboltyp" und eine Symbolkennung ("Name" genannt).
Ein Eintrag ist ein Datensymbol, das mit dem Typ "D" bezeichnet wird. Viele Funktionen, einschließlich sowohl benutzerdefinierter Funktionen als auch Bibliotheksfunktionen, sind ebenfalls vorhanden. [ weitere Erläuterung erforderlich
| Adresse | Geben Sie den Namen | ein |
|---|---|---|
| 00000020 | a | T_BIT |
| 00000040 | a | F_BIT |
| 00000080 | a | I_BIT |
| 20000004 | t | irqvec |
| 20000008 | t | fiqvec |
| 2000000c | t | InitReset |
| 20000018 | T | _main |
| 20000024 | t | Ende |
| 20000030 | T | AT91F_US3_CfgPIO_useB |
| 2000005c | t | AT91F_PIO_CfgPeriph |
| 200000b0 | T | main |
| 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_Baudrate |
| 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 | __ aeabi_uidiv |
| 20000788 | T | __ udivsi3 |
| 20000884 | T | __ aeabi_uidivmod |
| 2000089c | T | __ aeabi_idiv0 |
| 2000089c | T | __ aeabi_ldiv0 |
| 2000089c | T | __ div0 |
| 200009a0 | D | _Data |
| 200009a0 | A | _text |
| 200009a0 | D | holaamigosh |
| 200009a4 | A | __ bss_end__ |
| 200009a4 | A | __ bss_start |
| 200009a4 | A | __ bss_start__ |
| 200009a4 | A | _edata |
| 200009a4 | A | Ende |
Beispiel: Die Python-Symboltabelle [ edit ]
Die Programmiersprache Python enthält umfangreiche Unterstützung für das Erstellen und Bearbeiten von Symboltabellen Symbol ist eine freie Variable oder eine gebundene Variable, unabhängig davon, ob es sich um einen Blockbereich oder einen globalen Bereich handelt, ob sie importiert wird und zu welchem Namensraum sie gehört.
Beispiel: Dynamische Symboltabellen [ edit ]
Einige Programmiersprachen erlauben die Manipulation der Symboltabelle zur Laufzeit, so dass Symbole jederzeit hinzugefügt werden können. Racket ist ein Beispiel für eine solche Sprache [3].
Sowohl die LISP- als auch die Scheme-Programmiersprache ermöglichen die Zuordnung von beliebigen, generischen Eigenschaften zu jedem Symbol. [4]
Die Prolog-Programmiersprache ist im Wesentlichen eine Symboltabellensprache. Symbole werden als Atome bezeichnet, und die Beziehungen zwischen Symbolen können überlegt werden. In ähnlicher Weise bietet OpenCog eine dynamische Symboltabelle mit dem Namen atomspace die zur Darstellung von Wissen verwendet wird.
Không có nhận xét nào:
Đăng nhận xét