Wenn jemand eine neue Programmiersprache schreibt, in was schreibt er sie?


162

Bitte entschuldigen Sie meine Unwissenheit. Ich beschäftige mich mit PHP und bekomme nasse Füße, wenn ich SO surfe, und fühle mich gezwungen, eine Frage zu stellen, über die ich mich seit Jahren wundere:

In was schreiben Sie eine völlig neue Programmiersprache ?

Das klingt für alle Programmierer, denen ich großen Respekt entgegenbringe, wahrscheinlich sehr albern, aber für mich ist es eine verwirrende Henne-Ei-Sache. Wie geht's? Sag dir heute Heute werde ich eine neue Sprache erfinden! und dann hochfahren ... Editor? Sind alle Compiler auf zuvor existierenden Sprachen aufgebaut, so dass man sich die Mühe machen könnte, alle Programmiersprachen, die jemals entwickelt wurden, auf einen monströsen verzweigten Baum zu zeichnen, der schließlich auf ... Ich weiß nicht, etwas Altem?

Mit meinem schwachen Verstand finde ich das faszinierend ... Bitte erziehe mich!

Antworten:


193

Es ist keine dumme Frage. Es ist eine ausgezeichnete Frage.

Wie bereits beantwortet, lautet die kurze Antwort "Eine andere Sprache".

Nun, das führt zu einigen interessanten Fragen? Was ist, wenn es die allererste Sprache ist, die für Ihre spezielle Hardware geschrieben wurde? Ein sehr reales Problem für Leute, die an eingebetteten Geräten arbeiten. Wie bereits geantwortet "eine Sprache auf einem anderen Computer". Tatsächlich erhalten einige eingebettete Geräte niemals einen Compiler, ihre Programme werden immer auf einem anderen Computer kompiliert.

Aber Sie können es noch weiter zurückschieben. Was ist mit den ersten Programmen, die jemals geschrieben wurden?

Nun, die ersten Compiler für "Hochsprachen" wären in der sogenannten "Assemblersprache" geschrieben worden. Assemblersprache ist eine Sprache, in der jeder Befehl in der Sprache einem einzelnen Befehl an die CPU entspricht. Es ist eine sehr niedrige Sprache und extrem ausführlich und sehr arbeitsintensiv zu schreiben.

Aber selbst das Schreiben von Assemblersprache erfordert ein Programm namens Assembler, um die Assemblersprache in "Maschinensprache" zu konvertieren. Wir gehen weiter zurück. Die allerersten Assembler wurden in "Maschinencode" geschrieben. Ein Programm, das ausschließlich aus Binärzahlen besteht, die eine direkte Eins-zu-Eins-Entsprechung mit der Rohsprache des Computers selbst darstellen.

Aber es hört immer noch nicht auf. Selbst eine Datei mit nur rohen Zahlen darin noch übersetzt werden. Sie müssen diese Rohzahlen noch in einer Datei auf den Computer übertragen.

Ob Sie es glauben oder nicht, die frühen Computer hatten eine Reihe von Schaltern an der Vorderseite. Sie haben die Schalter umgelegt, bis sie eine Binärzahl darstellen, dann haben Sie einen anderen Schalter umgelegt und diese einzelne Zahl in den Computerspeicher geladen. Dann schalteten Sie weiter um, bis Sie ein minimales Computerprogramm geladen hatten, das Programme von Datenträgerdateien oder Lochkarten lesen konnte. Sie haben einen anderen Schalter umgelegt und das Programm gestartet. Als ich in den 80er Jahren zur Universität ging, sah ich Computer, die diese Kapazität hatten, aber nie den Auftrag erhielten, ein Programm mit den Schaltern zu laden.

Und noch früher mussten Computerprogramme mit Steckdosen fest verdrahtet werden !


20
+1, ich denke diese Antwort passt wirklich zum Geist der Frage.
stderr

30
Ich habe einmal eine Assembler II-Klasse besucht und der Professor fragte, warum wir das Wahlfach gewählt haben. Ich entschied mich für die lustige Antwort: "Weil ich ein einfaches A wollte." Ich dachte, ich hätte die beste Antwort, aber wir hatten ein Honeywell-Werk in der Stadt und der nächste sagte: "Ich schreibe den ganzen Tag Mikrocode und wollte eine Hochsprache lernen."
T. Rob

3
Ich kann Code: The Hidden Language von Computerhardware und -software nur empfehlen . Es behandelt im Wesentlichen das gleiche Material wie diese Antwort, von Vakuumröhren bis hin zu Compilern für Hochsprachen.
MatrixFrog

Computer haben sich genauso entwickelt wie Menschen, wenn auch in vergleichsweise unendlich kurzer Zeit.
Gaurav Ojha

Nun, dies wird ein nicht konstruktiver Kommentar sein, aber er muss geschrieben werden ... dies ist eine brillante, brillante Antwort in allen Formen, Formen und Informationen :-)
Lukáš Řádek

23

Die häufigste Antwort ist C. Die meisten Sprachen sind in C oder in einem Hybrid aus C mit Rückrufen und einem "Lexer" wie Flex und einem Parser-Generator wie YACC implementiert . Dies sind Sprachen, die für einen Zweck verwendet werden - um die Syntax einer anderen Sprache zu beschreiben. Wenn kompilierte Sprachen verwendet werden, werden sie manchmal zuerst in C implementiert. Dann wird die erste Version der Sprache verwendet, um eine neue Version zu erstellen, und so weiter. (Wie Haskell .)


1
Einige Sprachen sind in Assembler geschrieben, wie Picolisp. ( blog.kowalczyk.info/article/picoLisp-Arc-before-Arc.html )
Prof. Falken

1
Was ist mit den Programmen lex / yacc (flex / bison)? Werden diese als Ergänzungen zum Erstellen von Sprachen in C betrachtet?
Dave

1
Haben Sie etwas zu beweisen, dass die häufigste Antwort C ist?
RichardOD

Ich fing an, die Liste hier durchzugehen : google.com/Top/Computers/Programming/Languages/Open_Source Dann schloss ich versehentlich mein Editor-Fenster bei ungefähr Sprache 10 und verlor die Motivation, durchzugehen. Wie auch immer, ungefähr die Hälfte wurde bisher in C implementiert und der Rest meistens Bootstrapping für sich.
Prof. Falken

3
Ich denke, Sie müssen Lex / Yacc (oder Alternativen) erwähnen. Man beginnt im Allgemeinen nicht, eine Sprache in C zu schreiben, sondern mit einem Lexer und einem Parser, die dann mit C-Code unterstützt werden.
Steve Rowe

14

Viele Sprachen werden gebootet - das ist in sich selbst geschrieben . Warum Sie dies tun möchten, ist oft eine gute Idee, Ihr eigenes Hundefutter zu essen .

Der Wikipedia-Artikel, auf den ich mich beziehe, behandelt das Henne-Ei- Problem. Ich denke, Sie werden es ziemlich interessant finden.


5
Was nicht möglich ist, wenn Sie gerade erst anfangen.
Michael Borgwardt

1
Ja offensichtlich. Aber viele Sprachen werden so geschrieben, sobald es möglich ist. Ich wollte darauf hinweisen, wie es sonst niemand getan hat, und ich halte es für einen wichtigen Punkt.
RichardOD

+1 für die Verwendung des Begriffs Bootstrap. Es ist interessant, dass Sie Ihren Compiler zweimal kompilieren müssen. Das erste Mal ist offensichtlich mit dem Bare-Bones-Compiler, den Sie haben, und das zweite Mal mit dem Compiler, den Sie gerade erstellt haben. Angenommen, Sie haben Ihrem Compiler eine Optimierung hinzugefügt. Der von Ihnen erstellte Compiler kann mit diesen Optimierungen Code erzeugen, führt den optimierten Code jedoch erst selbst aus, wenn Sie ihn erneut mit dem optimierenden Compiler kompilieren.
Les

@ Les- Ja Bootstrapping ist ein interessantes Konzept.
RichardOD

2
Zufälliger Kommentar hier. Die Antwort auf die uralte Frage, wer zuerst kam (Huhn oder Ei), ist, dass das Huhn zuerst kam. Der Grund dafür ist, dass zum Reproduzieren / Replizieren etwas zuerst der Reproduzent / Replikator vorhanden sein muss, um das Reproduzieren / Replizieren durchzuführen.
SpicyWeenie

10

So ziemlich jede Sprache, obwohl die Verwendung einer Sprache, die für die Arbeit mit Grafiken und anderen komplexen Datenstrukturen geeignet ist, viele Dinge einfacher macht. Produktionscompiler werden aus Leistungsgründen häufig in C oder C ++ geschrieben, aber Sprachen wie OCaml, SML, Prolog und Lisp eignen sich wahrscheinlich besser für das Prototyping der Sprache.

Es gibt auch mehrere "kleine Sprachen", die im Sprachdesign verwendet werden. Lex und yacc werden beispielsweise zum Festlegen von Syntax und Grammatik verwendet und zu C kompiliert. (Es gibt Ports für andere Sprachen wie ocamllex / ocamlyacc und viele andere ähnliche Tools.)

Als Sonderfall werden neue Lisp-Dialekte häufig auf vorhandenen Lisp-Implementierungen aufgebaut, da sie auf den meisten derselben Infrastruktur huckepack nehmen können. Das Schreiben eines Scheme-Interpreters kann in Scheme unter einer Codeseite erfolgen. An diesem Punkt können problemlos neue Funktionen hinzugefügt werden.

Grundsätzlich sind Compiler nur Programme, die etwas einlesen und in etwas anderes übersetzen - Konvertieren der LaTeX-Quelle in DVI, Konvertieren von C-Code in Assembler und dann in Maschinensprache, Konvertieren einer Grammatikspezifikation in C-Code für einen Parser usw. Der Designer gibt dies an die Struktur des Quellformats (Parsing), was diese Strukturen bedeuten, wie die Daten vereinfacht werden (Optimierung) und die Art der zu generierenden Ausgabe. Dolmetscher lesen die Quelle und führen sie direkt aus. (Dolmetscher sind normalerweise einfacher zu schreiben, aber viel langsamer.)


4

Eigentlich können Sie in fast jeder Sprache schreiben, die Sie möchten. Nichts hindert Sie daran, einen C-Compiler in Ruby zu schreiben. "Alles", was Sie tun müssen, ist das Programm zu analysieren und den entsprechenden Maschinencode auszugeben. Wenn Sie Dateien lesen / schreiben können, wird Ihre Programmiersprache wahrscheinlich ausreichen.

Wenn Sie auf einer neuen Plattform von vorne anfangen, können Sie Cross-Compiling durchführen: Schreiben Sie einen Compiler für Ihre neue Plattform, der in Java oder nativ auf x86 ausgeführt wird. Entwickeln Sie auf Ihrem PC und übertragen Sie das Programm dann auf Ihre neue Zielplattform.

Die grundlegendsten Compiler sind wahrscheinlich Assembler und C.


Diese "beliebige" Sprache sollte jedoch rekursive Aufrufe unterstützen. Andernfalls wird die Implementierung eines Syntaxanalysators und eines Parsers eine echte Herausforderung sein.

2
Wenn Sie eine ungeeignete Sprache für eine Aufgabe auswählen, ist dies Ihre eigene Schuld. Dies kann für jedes Projekt geschehen, nicht nur für Compiler / Interpreter.
Ziggystar

4

"Eine neue Programmiersprache schreiben" beinhaltet technisch gesehen keinen Code. Es wird lediglich eine Spezifikation erstellt, wie Ihre Sprache aussieht und wie sie funktioniert. Sobald Sie eine Vorstellung davon haben, wie Ihre Sprache ist, können Sie Übersetzer und Dolmetscher schreiben, damit Ihre Sprache tatsächlich "funktioniert".

Ein Übersetzer gibt ein Programm in einer Sprache ein und gibt ein gleichwertiges Programm in einer anderen Sprache aus. Ein Interpreter gibt ein Programm in einer bestimmten Sprache ein und führt es aus.

Beispielsweise übersetzt ein C-Compiler normalerweise C-Quellcode (die Eingabesprache) in ein Assembler-Programm (die Ausgabesprache). Der Assembler nimmt dann das Assemblersprachenprogramm und erzeugt die Maschinensprache. Sobald Sie Ihre Ausgabe haben, brauchen Sie die Übersetzer nicht mehr, um Ihr Programm auszuführen. Da Sie jetzt ein Maschinensprachenprogramm haben, fungiert die CPU als Interpreter.

Viele Sprachen sind unterschiedlich implementiert. Ist beispielsweise javacein Übersetzer, der Java-Quellcode in JVM-Bytecode konvertiert. Die JVM ist ein Interpreter [1], der Java-Bytecode ausführt. Nachdem Sie ausgeführt haben javacund Bytecode erhalten haben, brauchen Sie nicht javacmehr. Wenn Sie jedoch Ihr Programm ausführen möchten, benötigen Sie die JVM.

Die Tatsache, dass Übersetzer nicht in der Nähe gehalten werden müssen, um ein Programm auszuführen, ermöglicht es, Ihre Sprache zu "booten", ohne dass sie "über" Ebenen und Ebenen anderer Sprachen ausgeführt wird.

[1] Die meisten JVMs übersetzen hinter den Kulissen, aber sie sind keine wirklichen Übersetzer, da die Schnittstelle zur JVM nicht "Eingabesprache -> Ausgabesprache" ist.


3

Im Allgemeinen können Sie fast jede Sprache verwenden, die Sie mögen. PHP wurde zum Beispiel in C geschrieben. Wenn Sie überhaupt keinen Zugriff auf einen Compiler haben, müssen Sie Assemblersprache schreiben und diese manuell in Maschinencode kompilieren.


2
Sie müssen keinen Maschinencode kompilieren. Es ist per Definition die Muttersprache der CPU.
Stu Thompson

1
Wahr. Was ich sagen wollte war "den Maschinencode aus Assemblersprache oder ähnlichem von Hand kompilieren". Ich könnte mich irren, aber ich vermute, dass nur wenige Leute den Code sofort als binär / hexadezimal eingeben.
Kaivosukeltaja

2

Viele Sprachen wurden zuerst in einer anderen verfügbaren Sprache geschrieben und dann in sich selbst neu implementiert und auf diese Weise gebootet (oder nur die Implementierung in der Fremdsprache beibehalten, wie PHP und Perl), aber einige Sprachen, wie der erste Assembler, wurden von Hand zu Maschinencode wie kompiliert Der erste C-Compiler wurde von Hand zur Montage kompiliert.

Ich habe mich für Bootstrapping interessiert, seit ich darüber gelesen habe. Um mehr zu erfahren, habe ich versucht, es selbst zu tun, indem ich meine eigene Obermenge von BF, die ich EBF nannte , selbst geschrieben habe. Die erste Version von EBF hatte 3 zusätzliche Grundelemente und ich habe die erste Binärdatei von Hand kompiliert. Dabei fand ich einen zweistufigen Rhythmus. Ich habe eine Funktion in der aktuellen Sprache in einer Version implementiert und hatte eine süße Version, in der ich den Code neu geschrieben habe, um die implementierte Funktion zu nutzen. Die Sprache war ausdrucksstark genug, um einen LISP-Interpreter zu erstellen .

Ich habe die handkompilierte Version zusammen mit der Quelle im ersten Release-Tag und der Code ist ziemlich klein. Die letzte Version ist 12-mal größer und der Code und ermöglicht kompakteren Code, sodass es schwierig ist, die aktuelle Version von Hand zu kompilieren.

Edmund Grimley Evans hat mit seiner HEX-Sprache etwas Ähnliches gemacht

Eines der interessanten Dinge dabei ist, dass Sie verstehen, warum manche Dinge so sind, wie sie sind. Mein Code war ein Produkt, wenn kleine inkrementelle Anpassungen vorgenommen wurden und es eher so aussieht, als ob es sich weiterentwickelt hat, als dass es von Grund auf neu entwickelt wurde. Ich denke daran, wenn ich heute Code lese, der meiner Meinung nach ein wenig anders aussieht.


1

Normalerweise mit einer für die Systementwicklung geeigneten allgemeinen Programmiersprache, z. B. C, Haskell, ML, Lisp usw., aber die Liste der Optionen ist lang. Außerdem normalerweise mit einigen domänenspezifischen Sprachen für die Sprachimplementierung, z. B. Parser- und lexikalischen Analysatorgeneratoren, Zwischensprachen wie LLVM usw. Und wahrscheinlich einigen Shell-Skripten, Testframeworks und einem Build-Konfigurationssystem, z. B. Autoconf.


1

Die meisten Compiler haben C- oder AC-ähnliche Programme geschrieben, wenn nicht C, dann ist Assembly Lang der richtige Weg. Wenn Sie jedoch eine neue Sprache von Grund auf neu schreiben und keine Makro-Bibliothek oder keinen Quellcode aus einer Prototypsprache haben, müssen Sie Ihre eigenen Funktionen definieren Jetzt in welcher Sprache? Sie können einfach eine Form "des Quellcodes mit dem Namen psedocode auf die Maschine schreiben, die wie eine BNF-Grammatik aus der objektorientierten strukturierten Lang-Spezifikation wie Fortran Basic Algo Lisp aussieht. Schreiben Sie also einen Cross-Code, der einer dieser Sprachsyntaxen ähnelt. Das ist Psedo-Code


1
Ich glaube nicht, dass Psedo-Code maschinenlesbar sein soll
Richard Tingle

0

Noch weitere Binär- oder Assemblyoperationen müssen in Funktionen übersetzt werden, dh in den Assembler- / Compiler-Job und dann in ein Objekt aus Daten und Funktionen, wenn Sie keine Quelldatei haben, um zu sehen, "wie diese Objektfunktionalität in Ihrer dargestellt werden soll." Sprachimplementierung, Dann müssen Sie die Implementierung "sehen" erkennen oder Ihre eigenen Funktionen, Prozeduren und Datenstrukturen definieren. Was viel Wissen erfordert, müssen Sie sich fragen, was eine Funktion ist. Ihr Verstand wird dann zur Sprachsimulation. Dies trennt einen Master-Programmierer vom Rest.


0

Auch ich hatte diese Frage vor einigen Monaten. Und ich habe nur wenige Artikel gelesen und mir einige Videos angesehen, die mir geholfen haben, meine eigene Sprache namens soft zu schreiben. Es ist noch nicht vollständig, aber ich habe viel von dieser Reise gelernt.

Grundlegende Dinge, die Sie wissen sollten, sind, wie der Compiler funktioniert, wenn er ein Code-Snippet ausführen muss. Der Compiler hat viele Phasen wie lexikalische Analyse, semantischer Analysator, AST (Abstract Syntax Tree) usw.

Was ich in meiner neuen Sprache getan habe, finden Sie hier - http://www.singhajit.com/writing-a-new-programming-language/

Wenn Sie zum ersten Mal eine Sprache schreiben, dann alles Gute und Sie haben noch einen langen Weg vor sich.


0

Was sind Programmiersprachen im Allgemeinen?

Programmiersprachen sind nur eine Möglichkeit, mit Computern zu sprechen. Zunächst grob gesagt, weil Computer nur Nullen und Einsen verstehen konnten (aufgrund der Tatsache, dass Computer aus Transistoren als Schalter bestehen, die nur zwei Zustände annehmen können, nennen wir diese beiden Zustände 0 und 1) und es schwierig war, mit 0,1 zu arbeiten Da wir Menschen Menschen sind, haben Informatiker beschlossen, eine Eins-zu-Eins-Zuordnung von jeder Anweisung in Binär (0,1) zu einer besser lesbaren Form vorzunehmen, die sie Assemblersprache nannten.

Zum Beispiel, wenn wir eine Anweisung hatten wie:

11001101

in der Montage würde es heißen:

LOAD_A 15

was bedeutet, dass der Inhalt von Register a in Speicherplatz 15 geladen wird. Wie gesagt, es war nur eine Konvention wie die Auswahl von 0 und 1 für zwei Zustände der Transistoren oder irgendetwas anderes im Computer. Auf diese Weise hat man ein Programm mit 50 Anweisungen. Das Erinnern an die Assemblersprache wäre einfacher. Der Benutzer würde also den Assembler-Code schreiben und ein Programm (in diesem Fall Assembler) würde die Codes in binäre Anweisungen oder Maschinensprache übersetzen, wie sie es nennen.

Aber dann, da die Computer jeden Tag verbessert wurden, gab es Platz für kompliziertere Programme mit mehr Anweisungen, sagen wir 10000.

In diesem Fall würde eine Eins-zu-Eins-Zuordnung wie Assembly nicht funktionieren, sodass andere Programmiersprachen auf hoher Ebene erstellt wurden. Sie sagten zum Beispiel, wenn für eine Beziehung mit E / A-Geräten zum Drucken von etwas auf dem vom Benutzer erstellten Bildschirm etwa 80 Anweisungen erforderlich sind, lassen Sie uns hier etwas tun, und wir könnten den gesamten Code in eine Bibliothek packen und ihn beispielsweise printf aufrufen und erstellen Sie auch ein anderes Programm, das diesen Ausdruck hier in den zugehörigen Assemblycode übersetzen könnte, und von dort aus würde die Assembly den Rest erledigen. Also nennen sie es Compiler.

Jetzt muss jeder Benutzer, der nur etwas auf dem Bildschirm drucken möchte, nicht alle Anweisungen in Binär- oder Assembly-Form schreiben. Er gibt nur printf ("etwas") ein, und alle Programme wie der Compiler und der Assembler erledigen den Rest. Jetzt später werden andere längere Codes auf die gleiche Weise verpackt, um nur die Arbeit anderer zu erleichtern, da Sie sehen, dass Sie einfach eine Tausend-Code-Zeile in einem Code in Python vereinfachen und für die Verwendung durch andere Personen packen können.

Nehmen wir also an, Sie haben viele verschiedene Codes in Python gepackt und ein Modul erstellt (libray, package oder irgendetwas, das Sie aufrufen möchten), und Sie nennen dieses Modul mgh (nur meinen Namen). Nehmen wir jetzt an, wir haben dieses mgh irgendwie erstellt, dass jeder, der sagt:

import mgh
mgh.connect(ip,port.data)...

könnte leicht eine Verbindung zu einem Remote-Server mit der angegebenen IP- und Portnummer herstellen und die Daten anschließend senden (oder so ähnlich). Jetzt könnten die Leute alles mit einer einzigen Zeile machen, aber was passiert, ist, dass viele Codes ausgeführt werden, die aus der mgh-Datei abgerufen wurden. und das Verpacken diente nicht dazu, den Ausführungsprozess zu beschleunigen, sondern anderen Programmierern die Arbeit zu erleichtern. Wenn also hier jemand zuerst Ihren Code verwenden möchte, sollte er die Datei importieren, und dann erkennt der Python-Interpreter den gesamten darin enthaltenen Code und kann den Code interpretieren.

Wenn Sie nun eine Programmiersprache erstellen und ausführen möchten, muss zunächst eine Übersetzung erstellt werden. Nehmen wir beispielsweise an, Sie erstellen ein Programm, das die Syntax verstehen und in c konvertieren kann, in diesem Fall nach der Übersetzung bis c würde der Rest vom c-Compiler erledigt, dann vom Assembler, Linker, .... obwohl Sie den Preis dafür zahlen müssten, langsamer zu sein, da es zuerst in c konvertiert werden muss.

Jetzt können Sie auch ein Programm erstellen, das den gesamten Code in die entsprechende Assemblersprache übersetzt, genau wie dies bei c der Fall ist. In diesem Fall kann das Programm dies jedoch direkt tun, und von dort aus wird der Rest von der erledigt Linker. Wir wissen, dass dieses Programm Compiler heißt.

Ich spreche also davon, dass der einzige Code, den das System versteht, 0,1 ist. Sie sollten also irgendwie Ihre Syntax darauf umstellen, jetzt haben in unseren Betriebssystemen viele verschiedene Programme wie Assembler, Linker und ... wurde erstellt, um Ihnen mitzuteilen, dass Sie den Rest erledigen könnten, wenn Sie Ihren Code in Assembly konvertieren könnten, oder wie gesagt, Sie könnten sogar andere Programmiersprachen-Compiler verwenden, indem Sie Ihren Code in diese Sprache konvertieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.