Wie programmiert man eine Programmiersprache?

4 Antworten

Kurz gefasst: Definiere eine eigene Grammatik und schreibe zu dieser einen Compiler oder Interpreter (Parser mit Engine, die die gelesenen Tokens auswertet). Die Sprache muss es dem Programmierer erlauben, Vorgänge iterativ / rekursiv ausdrücken zu können.

Zur Geschichte der Programmiersprachen lies hier:

https://en.wikipedia.org/wiki/History_of_programming_languages#First_programming_languages

Eine Programmiersprache wird überhaupt nicht programmiert, denn die ist ja nur ein Regelwerk.

Was programmiert wird, ist ein Compiler (oder ein Interpreter).

In der Regel implementiert man den ersten Compiler einer neuen Sprache in einer bereits existierenden Sprache (oft in ANSI C, weil es für diese Sprache für so gut wie jede erdenkliche Architektur Compiler gibt). Nachdem es den ersten Compiler für eine neue Sprache gibt, implementiert man jeden weiteren Compiler in der Regel in der Sprache selbst. Dann übersetzt man jeden neuen Compiler zuerst mit seinem "Vorgänger" (denn der neue Compiler ist ja noch nicht fertig und kann damit noch nicht übersetzen) und, nachdem das passiert ist, noch einmal "mit sich selbst", d. h. die Binary des neuen Compilers, die mit dem alten Compiler erstellt wurde, übersetzt noch einmal den Quellcode des neuen Compilers. Das bewirkt, dass die Binary des neuen Compilers alle Optimierungen enthält, die der neue Compiler selbst enthält.

Den Vorgang, Compiler erst mit einem anderen Compiler zu übersetzen, bezeichnet man auch als Bootstrapping.

Die ersten Compiler musste man notwendigerweise in einer Assemblersprache implementieren und die ersten Assembler widerum tatsächlich in Maschinensprache, aber das ist lange her.

Bei Interpretern ist es in der Regel so, dass diese in einer anderen, compilierten Sprache implementiert sind. Die Referenzimplementierung des Interpreters für die Programmiersprache Python beispielsweise heißt CPython, weil sie in ANSI C implementiert ist.

Es gibt aber zum Beispiel auch einen Interpreter für Python mit dem Namen IronPython, der in C-Sharp implementiert ist. Diese Sprache ist widerum selbst interpretiert, beziehungsweise sie ist ein "Hybrid". Der Quellcode in C-Sharp wird zunächst in einen Zwischencode namens Common Intermediate Language (CIL) übersetzt, welcher anschließend von einem Interpreter namens Common Language Infrastructure (CLI) interpretiert wird.

Genauso ist es bei Java auch. Der Quellcode in Java wird zunächst in eine Zwischencode namens Bytecode übersetzt, welcher Anschließend von einem Interpreter namens Java Virtual Machine (JVM) interpretiert wird. Beide "Bytecode-Interpreter" verwenden dabei einen so genannten Just-in-Time-Compiler (JIT-Compiler), um häufig ausgeführte Codeabschnitte in Maschinencode zu übersetzen. Aus diesem Grund trägt die Referenzimplementierung der Java Virtual Machine auch den Namen Hotspot. Sie übersetzt (compiliert) häufig ausgeführte Codesegmente (Hotspots) in Maschinencode und interpretiert den Rest.

Sowohl die Java Virtual Maschine (JVM), als auch die Common Language Infrastructure (CLI) sind in compilierten Sprachen, sehr wahrscheinlich in ANSI C, implementiert. Die Klassenbibliotheken von Java und .NET hingegen sind größtenteils in der jeweiligen Hochsprache selbst implementiert, vermutlich mit ein paar "Schnipseln" C, um Betriebssystemdienste (z. B. ein GUI-Framework) ansprechen zu können.

Die Standardbibliothek von Go (einer compilierten Sprache) beispielsweise ist ebenfalls in Go implementiert und die Standardbibliothek von Python (einer interpretierten Sprache) zumindest größtenteils in Python. Bei Python kann es sogar passieren, dass man bei einem Programmfehler plötzlich vom Interpreter einen Stacktrace bekommt, der in die Standardbibliothek führt. Das ist dann immer besonders hilfreich. (Vorsicht, Ironie!) Bei einem solchen Stacktrace denke ich mir dann immer: "Ich möchte wissen, was ich bei der Verwendung dieser Bibliotheksfunktion falsch gemacht habe und nicht, welchen Ausnahmefall der Entwickler der Standardbibliothek vergessen hat, 'abzufangen', sodass ich nun einen Stacktrace in die Standardbibliothek bekomme." :-)

Bis jetzt habe ich Compilers und Interpreters  für neue Sprachen mit C unter LEX und YACC programmiert (OK ein mal in LISP)

Du hast es sehr gut beschrieben - Super!

4
@iwolmis


Wie man von C auf C++ gekommen ist, ist beschrieben in "The Design and Evolution of C++" von Bjarnene Stroustrup.

Mit Unix Power Tools habe ich einmal einen C++ zum C Convertor geschrieben :-)

OK, da habe ich "m4" total missbraucht.

Warum?

In der Firma, für ich damals Projekte gemacht habe,  war damals nur C im Einsatz und so ein Converter hat mir sehr viel Arbeit gespart :-)

Das war wie C-Front vom Stroustrup.





1

Dem ist eigentlich nicht weiter hinzuzufügen, nur eien Rückfrage aus Neugier. Nutzt Cython heute wirklich noch (pedantisch) Ansi-C, oder ist man auf eine neuere ISO-Variante umgestiegen?

1

Man könnte vielleicht mal eine Programmiersprache auf deutsch machen

1

Eine Programmiersprache kann man nicht programmieren, man kann nur einen Compiler oder ein Runtime programmieren.

Der Java Compiler ist zum Beispiel selbst in Java geschrieben und die Java VM HotSpot in C/C++.

Die ersten Compiler überhaupt hat man mit einer Assembler Sprache geschrieben (nur Maschinenbefehle in Wörter übersetzt) und die ersten Assembler musste man dann direkt mit Maschinensprache programmieren.

Man kann keine Programmiersprache programmieren. Man kann eine Syntax festlegen und einen Kompiler entwickeln der das dann in Maschinencode umsetzt.

Was möchtest Du wissen?