Übersetzung von Programmiersprachen Arnd Poetzsch-Heffter AG Softwaretechnik TU Kaiserslautern Wintersemester 2005/06 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 1 1.Kapitel: Einführung Aufbauend auf den Techniken zur syntaktischen Analyse formaler Beschreibungssprachen konzentriert sich diese Vorlesung auf - Techniken und Algorithmen zur - semantikerhaltenden und - optimierenden - Übersetzung von - Quellsprachprogrammen in - Zielsprachprogramme. Aufbau von Kapitel 1: • Überblick und Umfeld • Allgemeine Aspekt des Übersetzerbaus • Inhalt und Lernziele Literatur: R. Wilhelm, D. Maurer: Übersetzerbau. Springer-Verlag. 1992. A. Appel: Modern Compiler Implementation in Java. Cambridge University Press. 1999. 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 2 1.1 Überblick und Umfeld Begriffsklärung: • Übersetzungsaufgabe: Quellcode Übersetzer Fehlermeldung | Zielcode • Übersetzer (im weiteren Sinne) realisiert: Analyse & Optimierung & Übersetzung • Quellcode: Eingabe(-Zeichenreihe) für Übersetzer; sollte der Syntax der Quellsprache (QS) genügen. • Zielcode: Ausgabe(-Zeichenreihe) des Übersetzer; muss der Syntax der Zielsprache (ZS) genügen. 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 3 • typische Quellsprachen: - Programmiersprachen: C, C++, C#, Java, ML, Cobol, Smalltalk, Prolog, ... Skriptsprachen (JavaScript), Kommandosprachen - Sprachen für Konfigurationsmanagement (make,..) - Anwendungs- & werkzeugspezifische Sprachen (Excel, Lex, Max, ...) - Spezifikationssprachen (Z, Isabelle/HOL, CASL) - Formatierungs- und Datenbeschreibungssprachen (LaTeX, HTML, XML,...) - Entwurfs- & Architekturbeschreibungssprachen (UML, SDL, VHDL, Darwin,...) • typische Zielsprachen: - Assembler- und Maschinensprachen - Programmiersprachen (z.B. C) - Daten- und Layoutbeschreibungssprachen - Sprachen zur Drucksteuerung 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 4 Zur Übersetzungszeit: während der Übersetzer läuft. Alle Informationen und Aspekte, die schon zur Übersetzungszeit bekannt sind, nennt man statisch. Z.B. Typprüfung der Programms, Konstante Ausdrücke auswerten, Relativadressen festlegen, ... Zur Laufzeit: während das übersetze Programm ausgeführt wird. Alle Informationen und Aspekte, die statisch noch unbekannt sind, nennt man dynamisch. Z.B. Allokation von Feldern variabler Größe, Bereichsprüfung von Feldern, dynamische Bindung von Methoden, Speicherverwaltung für rekursive Prozeduren. Da der Übersetzer dynamische Aspekte nicht zur Übersetzungszeit behandeln kann, erzeugt er dafür Code. Der Code erledigt die Aspekte dann zur Laufzeit. 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 5 Anwendungsbereiche der Techniken: (exemplarisch) • Realisierung von Programmierumgebungen: - kontextsensitive Editoren, Klassenbrowser, ... - graphische Programmierwerkzeuge - Präprozessoren - Übersetzer - Interpreter - Debugger - Laufzeitumgebung (Laden, Linken, Ausführen, Speicherverwalten) • Generierung von Programmen aus Entwurfsdokumenten (UML, ... ) • Programmverstehen, Reengineering • Entwurf und Implementierung anwendungsspezifischer Sprachen: - Robotersteuerung - Simulationswerkzeuge - Tabellenkalkulatoren, aktive Dokumente • Web-Technologie: - Analyse von Web-Sites - aktive Webseiten (mit integrierter Funktionalität) - abstrakte Plattformen: JVM, .Net - Optimieren von Caching 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 6 Angrenzende Gebiete: • Formale Sprachen, Sprachspezifikation, -entwurf • Programmier- und Spezifikationssprachen • Programmierung, Softwareentwicklung, SW-Generierung, SW-Architektur • Systemsoftware, Rechnerarchitektur gegenseitige Wechselwirkung Implementierungsaufgaben: Analyse: Übersetzung: Interpretation: Quellcode Quellcode Quellcode Eingabedaten Analysator Übersetzer Analyseinformation Zielcode Interpreter Ausgabedaten häufig Kombination der Aufgaben 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 7 Beispiele: (Übersetzung) 1. Übersetzung eines C-Programms: int main() { printf("Willkommen zur Vorlesung!"); return 0; } gcc .file "hello_world.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "Willkommen zur Vorlesung!" .text .align 16 .globl main .type main,@function main: pushl %ebp movl %esp,%ebp subl $8,%esp ... 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 8 Das vollständige Zielprogramm: .file "hello_world.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "Willkommen zur Vorlesung!" .text .align 16 .globl main .type main,@function main: pushl %ebp movl %esp,%ebp subl $8,%esp addl $-12,%esp pushl $.LC0 call printf addl $16,%esp xorl %eax,%eax jmp .L2 .p2align 4,,7 .L2: movl %ebp,%esp popl %ebp ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.95.2 19991024 (release)" 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 9 2. Übersetzung eines LaTeX-Dokuments: groovy.tex (104 bytes) \documentclass{article} \begin{document} \vspace*{7cm} \centerline{\Huge\bf It‘s groovy} \end{document} latex groovy.dvi (207 bytes, binary) ... dvips groovy.ps (7136 bytes) %!PS-Adobe-2.0 %%Creator: dvips(k) 5.86 ... %%Title: groovy.dvi ... 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 10 1.2 Allgemeine Aspekt des Übersetzerbaus • Anforderungen • Architektur • Konstruktionstechniken • Dimensionen des Übersetzerbaus Anforderungen an Übersetzer • Gute Fehlerbehandlung (statisch & dynamisch) • Effizienter Zielcode • Wahlmöglichkeit: schnelle Übersetzung & weniger effizienter Code versus langsamere Übersetzung & hoch effizienter Code • semantisch korrekte Übersetzung: „Übersetztes Programm verhält sich gemäß der Sprachdefinition der Quellsprache“ 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 11 D.h. mit semQS: QS-Programme x QS-Daten QS-Daten semZS: ZS-Programme x ZS-Daten ZS-Daten compile: QS-Programme ZS-Programme QS-Daten ZS-Daten decode: ZS-Daten QS-Daten code: sollte für alle QS-Programme P, QS-Daten D gelten: semQS(P,D) = decode(semZS(compile(P),code(D))) Architektur von Übersetzern Bei Übersetzern unterstellt man normalerweise eine Phasenzerlegung in Analyse- und Synthesephasen. Unterschiede gibt es bei: - der Verwaltung von globaler Information - der Repräsentation der Zwischenformen - der Behandlung von Varianten 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 12 Übersetzerphasen: Quellcode als Zeichenreihe Scanner Symbolfolge Parser Analyse Syntaxbaum Namensbinden Typisieren Attributieren & Optimieren Attributierter Baum ( QS-nahe Repr.) Übersetzer im engeren Sinn Synthese Attributieren & Optimieren Zwischensprache ( ZS-nahe Repr.) Codegenerator PeepholeOptimierer 15.11.2005 Zielcode als Zeichenreihe © A. Poetzsch-Heffter, TU Kaiserslautern 13 Aspekte von Übersetzerarchitekturen: • Phasen zunächst einmal konzeptionell gemeint • Ausführung der Phasen kann verschränkt sein • Unterschied: Phase versus Pass (Pass: ein Durchgang durch das Programm) • genaue Festlegung der Phasen ist von Quell-, Zielsprache und Entwurfsentscheidungen abhängig • Kombination mit anderen Architekturentscheidungen: QS_1 QS_2 .... QS_m gemeinsame Zwischensprache ZS_1 ZS_2 ... ZS_n • getrennte Übersetzung: Programmteile können unabhängig von einander übersetzt werden; Schnittstelleninformation benutzter Elemente anderer Programmteile muss verfügbar sein. 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 14 Konstruktionstechniken A. Schrittweise Konstruktion: Programmierung basiert üblicherweise auf Existenz eines Übersetzers für die Implementierungssprache. Bei Übersetzerkonstruktion kann davon im Allg. nicht ausgegangen werden; stehe ZS QS PS für einen Übersetzer der in Sprache PS geschrieben ist und QS in ZS übersetzt. 1. Konstruktion mit Übersetzer für andere Sprache: Gesucht: QS-Compiler, Ziel MS, läuft auf MS Annahme: C-Compiler existiert auf Plattform mit Maschinensprache MS QS zu entwickeln MS QS C MS C MS MS MS durch Übersetzung existiert 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 15 2. Konstruktion mit Übersetzer für anderen Rechner: Gesucht: C-Compiler auf MS 1 für MS 1 Annahme: C-Compiler auf MS 2 für MS 2 existiert Methode: realisiere zunächst Cross-Compiler 1.Schritt: MS 1 C C C MS 1 MS 2 MS 2 C MS 2 Cross-Compiler 2.Schritt: MS 1 C C C MS 1 MS 1 MS 1 C MS 2 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 16 3. Bootstrapping: Gesucht: QS-Compiler auf MS für MS Annahme: kein Compiler verfügbar Methode: 1. Entwerfe Teilsprachen QS i von QS mit QS 1 QS 2 U U U QS 0 QS 2. Implementiere QS 0 -Compiler für MS in MS 3. Implementiere QS i+1-Compiler für MS in QS i 4. Erzeuge QS i+1-Compiler für MS in MS durch Erweiterung QS MS QS 2 QS 2 QS 2 MS QS 1 QS 1 QS 1 QS MS QS 0 QS 0 MS MS MS MS MS MS MS MS durch Übersetzung von Hand 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 17 B. Mit Generierungswerkzeugen: • Scanner-Generator / reguläre Ausdrücke • Parser-Generator / kontextfreie Grammatik • Attributauswertungsgenerator / Attributgrammatik • Codegenerator-Generator / Maschinenbeschreibung • weitere phasenspezifische Werkzeuge • Interpretergeneratoren / Sprachsemantik C. Spezielle Programmiermethodiken: • allgmeine Technik: syntaxgesteuert • speziell: rekursiver Abstieg 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 18 Dimensionen des Übersetzerbaus • Programmiersprachen (-sprachklassen): - sequentielle prozedurale, oo. Sprachen - funktionale, logische Sprachen - parallele Sprachen/Sprachkonzepte • Zielsprachen/Maschine: - Code für abstrakte Maschine - Assembler - Maschinensprache (CISC, RISC,Superskalar,...) - Multiprozessorarchitekturen - Speicherhierarchie • Übersetzungsaufgaben: Analyse, Optimierung, Synthese • Konstruktionsmethoden und Werkzeuge Bootstrapping, Generatoren, ... • Portabilität, Spezifikation, Korrektheit 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 19 1.3 Inhalt und Lernziele 1. Einführung: 1.1 Überblick und Umfeld 1.2 Allgemeine Aspekt des Übersetzerbaus 1.3 Inhalt und Lernziele 2. Übersetzung in die Zielsprache 2.1 Übersetzung prozeduraler Programmiersprachen 2.2 Übersetzung objektorientierter Sprachkonstrukte 2.3 Einblick in die Übersetzung funktionaler Sprachen 2.4 Ein einfacher Übersetzer 3. Ausgewählte Aspekte der Übersetzung 3.1 Zwischensprachen in der Übersetzung 3.2 Optimierung 3.3 Registerzuteilung 3.4 Weitere Aspekte der Übersetzung 4. Speicherbereinigung 4.1 Reference Counting 4.2 Mark & Sweep 4.3. Copying Collection 5. Zusammenfassung und Ausblick 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 20 Allgemeine Lernziele: • Grundlagen der Übersetzung von Programmiersprachen • Vertiefung in Programmiersprachen • Genauere Kenntnis über die Ausführung von Programmen • Erlernen ausgereifter, vielseitig einsetzbarer Methoden und Werkzeuge • Kennen lernen des Zusammenwirkens von Theorie, Algorithmen, Ingenieurmethoden am Beispiel eines gereiften Gebiets der Informatik Übertragung in andere Gebiete 15.11.2005 © A. Poetzsch-Heffter, TU Kaiserslautern 21