Verloren im Labyrinth der IT-Begriffe? Hier finden Sie Definitionen und Basiswissen zu Rechenzentrums-IT und -Infrastruktur.

Mittler zwischen Mensch und Maschine Was ist ein Compiler?

Autor / Redakteur: M.A. Jürgen Höfling / Ulrike Ostler

Ohne Übersetzungsmechanismen würde eine global organisierte Gesellschaft wie die unsrige im babylonischen Chaos landen. Das gilt auch für die Kommunikation zwischen Mensch und Maschine. Dafür gibt es Compiler.

Firma zum Thema

Ohne Compiler und Konsorten gäbe es zwischen Mensch und Maschine eine babylonische Sprachverwirrung.
Ohne Compiler und Konsorten gäbe es zwischen Mensch und Maschine eine babylonische Sprachverwirrung.
(Bild: Henning-Hraban Ramm_pixelio.de)

Wer sich heute mit der Programmierung von Quantenrechnern beschäftigt, lernt von der rechentechnischen Pike auf: Quantenbit („Qubit“) für Quantenbit und Rechengatter für Rechengatter bauen er oder sie den Quanten-Assembler zusammen. Wenn man von der physikalischen Grundlage einmal absieht, hatten wir das schon einmal. In den Anfangsjahren des elektromechanischen beziehungsweise elektronischen Rechners war das ähnlich, nur dass man nicht so schrecklich viel messen musste wie in der Quantenrechnerei.

Die Umsetzung des Rechenplans („Programms“) war „very basic“, das heißt absolut maschinen- beziehungsweise prozessororientiert. Man musste die Hardware in- und auswendig kennen, wenn man überhaupt ein Ergebnis erzielen wollte; denn schnell war dabei das Rechenwerk „misshandelt“ oder der Speicher zu klein. Für die Programmierung musste man „binär“ oder „hexadec“ sprechen, etwas anderes verstanden und verstehen die Rechner nicht.

Ende der 1950er Jahre kamen mit Fortran und PL/1 prozedurale Programmiersprachen auf, die Rechenbefehle in einer Art Computer-Pidgin-Englisch näher an die menschliche Sprache heranbrachten. Und in der Assembler-Sprache wurden die binären Maschinenbefehle durch englische Worte („MOVE“ oder „STORE“) „verdolmetscht“.

Assembler war zwar maschinennäher als Fortran oder PL/1, hatte aber doch eine gewisse menschliche Nähe. Der Autor hat übrigens noch Anfang der 1980er Jahre seine Programme in Assembler geschrieben; denn Speicher war damals knapp.

Vom Rechenplan zum Laufzeitprogramm

Um Maschine und Mensch in der Programmierung näher zueinander zu bringen, sind Verständigungshilfen notwendig. Mit einem speziellen Übersetzungsprogramm werden die „pidgin-sprachlichen Rechenpläne wieder in die binäre oder hexadezimale Welt der Rechner transferiert.

Diese Übersetzungsprogramme oder Compiler zerlegen („parsen“) die Ausdrücke der jeweiligen Programmiersprache in ihre syntaktisch-semantischen Einzelelemente (Analysephase), finden in einer Transferphase für jedes Element eine geeignete Entsprechung im Maschinencode und setzen dann die gefundenen Teile des Maschinencodes wieder zusammen (Synthesephase).

Im Rahmen des Kompilierungsprozesses werden syntaktische Fehler, die bei der Codierung gemacht wurden, aufgezeigt. Nach ihrer (händischen) Korrektur wird automatisch der Zielcode erstellt, wobei das Übersetzungsprogramm jeweils maschinen-spezifische Optimierungen vornimmt. Endprodukt des Prozesses ist ein Laufzeitprogramm („Executable“).

In der Software-Entwicklung haben sich viele verschiedene Methoden entwickelt, wie man einen Algorithmus formalisiert und dann möglichst optimal und schnell auf einem Computer ablaufen lässt. Wie fast immer im Leben, kann man auch in der Computerei nicht alles auf einmal und nicht alles gleich effizient haben.

Geschwindigkeit und Qualität des Codes beziehungsweise dessen vielseitige Verwendbarkeit sind als Ziele nicht immer zu vereinbaren. Es müssen in die eine oder andere Richtung Abstriche gemacht werden.

Interpretierer oder Compiler?

Je nachdem, welche Leistungsmerkmale einem besonders wichtig sind, wird man die eine oder die andere Programmiersprache und / oder die eine oder andere Übersetzungsmethode verwenden. Neben Programmiersprachen, die in der Regel mit einem Compiler verwendet werden, der ein Laufzeitprogramm für einen bestimmten Prozessortyp erzeugt, gibt es auch viele Programmiersprachen, die mit einem so genannten Interpretierer (englisch: Interpreter) arbeiten. Bei diesen Übersetzungsprogrammen gibt es keine scharfe (zeitliche) Trennung zwischen Übersetzung und Laufzeit.

Das Optimierungspotenzial der Interpreter ist deutlich geringer, dafür sind sie aber auch nicht so maschinenabhängig wie Compiler. Interpretierter Code läuft auf jedem Prozessor, auf dem auch der Interpreter laufen kann.

Im Prinzip arbeiten Interpreter deutlich langsamer als Compiler und sind für eher einfach strukturierte Sprachen geeignet. Frühe Interpreter-Sprachen sind BASIC und LISP. Letztere Sprache wurde in den 1960er Jahren für die nicht-numerische Datenverarbeitung entwickelt und besteht nur aus atomaren Ausdrücken und Listen.

Die Unterscheidung zwischen Compiler- und Interpreter-Sprachen ist im Lauf der letzten Dekaden allerdings zunehmend brüchig geworden. Mittlerweile gibt es so viele Mischformen, dass eine exklusive Zuordnung zu einer der beiden Klassen schwierig, letztlich aber auch unwichtig ist.

Unterschiedliche Übersetzertypen

Für manche Programmiersprachen wie etwa Smalltalk (eine objektorientierte Sprache der 1960er Jahre, in der damals erste KI-Anwendungen programmiert worden sind) gibt es (je nach Anbieter) das ganze Arsenal an Übersetzertypen: Interpreter, Bytecode-Interpreter, Just-in-Time-(JIT)Compiler oder auch Compiler in andere Sprachen (beispielsweise nach C oder .NET).

Zur Erklärung: Bytecode-Interpreter übersetzen den Programmcode nicht direkt in die Maschinensprache, sondern in einen Zwischencode (Bytecode) und JIT-Compiler (Java ist ein Beispiel für eine JIT-Compiler-Sprache) sind Compiler, die zur Laufzeit übersetzen, was eigentlich ja eher ein Typusmerkmal für Interpreter ist. Überdies gibt es auch für eine Sprache wie C, die als „typische Compilersprache“ gilt, Interpreter (zum Beispiel CINT). Das zeigt, dass Typisierungen durch die Wirklichkeit schnell überholt werden, zumal eine durch die quirlige IT-Community geprägte Wirklichkeit).

Compiler im Low-Code- und No-Code-Zeitalter

Noch viel bunter und unübersichtlicher wird die „Übersetzerszene“, wenn man Tendenzen wie grafisches und visuelles Programmieren, Low-Code- oder No-Code-Programmierung, in die Betrachtung einbezieht. Programmieren ohne Codieren begleitet im Grund die Programmierentwicklung in der einen oder anderen Form schon seit Beginn, ist aber erst heute ein gewichtiger Faktor geworden, einfach weil die Hardware das mittlerweile hergibt. Längst vorbei sind die Zeiten, wo unsereiner mit Assembler programmieren musste, weil das Programm tunlichst nicht mehr als 100 Kilobyte Speicher beanspruchen sollte.

(ID:47035065)

Über den Autor