Aufgabe:
Sie müssen einen Interpreter erstellen, der Ausschnitte einer Programmiersprache analysieren kann. Die Sprache muss nicht komplex sein, sondern die folgenden syntaktischen Elemente enthalten:
- Möglichkeit, Variablen zuzuweisen und zu lesen (kann so einfach sein wie
a
-z
vorgefertigte Variablen zu sein) - If-Anweisungen (elseif und else sind nicht erforderlich)
- Schleifen (bis zu einer beliebigen Zahl zählen, Benutzerzugriff auf Zähler nicht erforderlich)
- Einfache Mathematik mit Variablen (Addition, Subtraktion, Multiplikation, Division, größer / kleiner als, gleich)
- Anweisungen drucken
Regeln:
- Sie dürfen die Syntax einer anderen populären Sprache nicht kopieren.
- Sie müssen Ihren eigenen Dolmetscher schreiben, nicht Änderungen an einem anderen Dolmetscher.
- Sie können Ihren Dolmetscher in jeder Sprache schreiben.
- Schreiben Sie ein Beispielprogramm für 99 Flaschen Bier in Ihrer Sprache (siehe hier ).
- Dies ist ein Beliebtheitswettbewerb , daher gewinnt die am meisten bewertete Antwort.
popularity-contest
interpreter
parsing
Der Doktor
quelle
quelle
Antworten:
DogeScript
Das 99 Flaschen Bier Programm:
Der PHP-Interpreter:
Die derzeitige Syntax:
Probieren Sie es hier aus .
Verbesserungsvorschläge sind willkommen.
quelle
BrainBack: Eine Stack-basierte kompilierte Sprache, die auf BrainFuck läuft
NB: Die Spezifikation wurde von "Erstellen eines Parsers" in "Erstellen eines Interpreters" geändert, nachdem ich diese Antwort gepostet habe. Diese Antwort ist ein Compiler, der auch den Quellcode analysiert.
Der Name ist ein Wortspiel auf Back , das das Gegenteil einer bekannten stapelbasierten Sprache ist, und Brain zeigt an, dass es eine esoterische Natur ist. Es sieht ein bisschen wie BrainFuck aus (ist es aber nicht), aber sein Compiler läuft auf BrainFuck und sein kompilierter Objektcode endet als BrainFuck-Binärdateien.
Die Sprache: * == zerstört seine Argumente
"constant"
druckt konstant#
druckt den obersten Stapel als Zahl>
dupliziert die Oberseite des Stapels<num>
Drücke die konstante Zahl<num>
als Wert nach oben<
Entfernen Sie die Oberseite des Stapels-
vom zweitobersten das oberste abziehen *+
addiere das oberste zum zweitobersten *!
nicht umschaltbar positiv / null *[ ... ]
tut eine Weile oben auf dem Stapel nicht Null, sehr ähnlich zu BrainFuck99 Flaschen Bier mit den richtigen Texten in BrainBack:
Der BrainBack-Compiler, geschrieben in Extended BrainFuck
So kompilieren Sie BrainBack:
So kompilieren Sie ein BrainBack-Programm:
Führen Sie die Binärdatei aus:
Hier verwende ich bf, das in den meisten Debian-Distributionen verfügbar ist.
beef
und andere können auch verwendet werden. Sowohl der EBF-Compiler als auch BrainBack und sein Objektcode werden zu recht kompatiblen BrainFuck-Binärdateien.Es sollte wahrscheinlich erweitert werden, um eine Zelle als ASCII zu drucken
.
, in der Lage zu sein, ein Byte einzulesen,
und verschiedeneswap
Operationen zu haben, um nützlicher zu sein. Dies ist unbedingt erforderlich, um einen BrainBack-Compiler oder -Interpreter in BrainBack zu erstellen.quelle
€
Ich verbringe die meiste Zeit mit PHP-Skripten und es stellte sich die Frage, warum ich gezwungen bin,
$
für meine Variablennamen zu verwenden.€
ist meine lokale Währung, also lasst es uns benutzen! Da € in vielen Ländern verwendet wird, habe ich einige Wörter aus EU-Sprachen als Stichwörter verwendet.Schlüsselwörter:
gleich
ist gleich in deutschmientras
ist während in Spanischtopo
ist größer Portugiesisch in (Update: es sollte sein maior stattdessen dank daHugLenny für den Tipp)odejmowanie
ist in polnischer Sprache subtrahierenafficher
ist in Französisch gedrucktnl
manchmal aufgerufen , und die TLD vonNETHERLANDS
istnl
, also habe ich eine Konstante definiertNETHERLANDS
, um Zeilenumbrüche anzuzeigenIch habe ein bisschen geschummelt, da es kein
if
Schlüsselwort gibt. Ich habe mich dafür entschieden, die letzten beiden Zeilen direkt auszudrucken.Dolmetscher in Python
Der Interpreter führt lediglich das Skript aus, um 99 Flaschen Bier anzuzeigen.
Speichern Sie beide Dateien und führen Sie dann die Python-Datei mit dem
.eu
Skript als Argument aus:quelle
topo
is top in Portuguese1Lang
1Lang ist eine funktionale Präfixsprache wie LISP oder Scheme, jedoch ohne Klammern, was das Lesen etwas erschwert, wenn alle unnötigen Leerzeichen entfernt werden. Klammern können entfernt werden, da alle Funktionen und Operatoren eine bekannte Anzahl von Parametern verwenden.
Klammern sind erforderlich, um Funktionskörper und bedingte Konsequenzen sowie alternative Codeblöcke, die aus einer Liste von Anweisungen bestehen können, abzugrenzen.
In LISP könnte Factorial folgendermaßen definiert werden:
in 1Lang wäre dies
die reduziert werden kann
1Lang unterstützt derzeit keine Nebenwirkungen.
1Lang ist in Bash geschrieben, sodass es derzeit einige Bash-Einschränkungen wie den Integer-Bereich aufweist.
NB: Listen sind nicht vollständig implementiert.
Ganzzahlen sind Bash-Ganzzahlen (bis zu -2 ^ 32 bis 2 ^ 31-1, denke ich). Negative Zahlen können nicht direkt verwendet werden. Um ein Negativ einzugeben, subtrahieren Sie es von Null. z.B. -5 würde als -0 5 eingegeben. Diese Einschränkung liegt daran, dass 1Lang in Arbeit ist und für diese Anwendung keine negativen Zahlen benötigt wurden. Ich überlege, ~ als unären negativen Operator zu verwenden, der die Eingabe von -5 als ~ 5 erlauben würde.
Leerraum ist erforderlich, um ganze Zahlen abzugrenzen. z.B. +2 3
Funktionsparameternamen können Aufrufervariablen überlasten. Alle innerhalb einer Funktion zugewiesenen Variablen sind lokal.
Drucken ist nicht erforderlich (obwohl dies nützlich sein könnte), da wie bei LISP jede Anweisung einen Wert zurückgibt und der zuletzt zurückgegebene Wert gedruckt wird.
Ein unerwartetes Verhalten der Präfixnotation ohne Klammern besteht darin, dass die Verkettung von Zeichenfolgen tatsächlich einfach zu schreiben ist. Angenommen, Sie möchten verketten
"a" " quick" " brown" " fox"
, könnte man schreiben:Eine besser lesbare und weniger fehleranfällige Methode ist jedoch die folgende:
oder
99 Flaschen Bier Code:
Funktion B liefert je nach x "No more bottles" oder "1 bottle" oder "bottles".
Funktion F gibt normale Verse oder letzte Verse zurück. Ein normaler Vers wird mit dem folgenden Vers verkettet, indem F rekursiv mit -x1 aufgerufen wird. Wenn x 0 ist, gibt F den letzten Vers zurück.
Dies erzeugt (für F5 bedeutet ab 5 Flaschen Bier ...):
1Lang-Interpreter (in Bash geschrieben) in weniger als 500 Zeilen.
quelle
@Mfxy{fxy}M+3 4
funktioniert hätte, aber dann müssen Sie die Funktion und den variablen Namespace verbinden. Es dauerte eine Weile, bis 99 Biere berechnet waren: pcons
Ihnen möglich istmap
M\x{*x2}C1C2C3C4/ => (2 4 6 8)
Hälfte (Dolmetscher / Übersetzer in Windows Batch)
Ich weiß nicht, warum ich in Windows Batch so viele Rätsel beantworte, aus irgendeinem kranken Grund denke ich, dass es mir Spaß macht übersetzt in Windows Batch von einem Skript, das auch in Windows Batch geschrieben ist. Es ist nicht besonders erstaunlich, aber es funktioniert.
99 Flaschen Bier
Syntax
In jeder Zeile werden nur drei durch Leerzeichen getrennte Token erkannt.
# ist ein Kommentar.
In den meisten Fällen, in denen ein Wert benötigt wird, bedeutet a
$
im zweiten Token, dass der dritte als Variablenname behandelt werden soll, während a~
einen Literalwert bezeichnet. Allgemeine Anweisungen haben die Form<instruction> [$~] <name>
. Das Setzen einer Variablen hat die gleiche Form, wird jedoch immer dann implementiert, wenn sie nicht erkannt wird.Definierte Befehle:
print
undwrite
beide schreiben Ausgabe, aberwrite
fügt keine neue Zeile hinzu. Benötigt $ oder ~.mark
Erstellt einen Punkt, zu dem gesprungen oder der als Unterroutine aufgerufen werden kann.jump
Entspricht goto in batch (oder einer anderen Sprache).proc
ruft ein Unterprogramm auf. Äquivalent voncall :label
.return
kehrt von einem Unterprogramm zurück. Beendet das Programm, wenn es sich nicht in einem befindet.if
bedingte Anweisung. Übernimmt den Vergleich aus der nächsten Zeile im Formular<var1> <operator> <var2>
. Die Operatoren sind die gleichen wieif
in Batch, dh.EQU, NEQ, LSS, LEQ, GTR, GEQ
. Führt Anweisungen danach nur aus, wenn der Vergleich wahr ist.endif
beendet eine if-Anweisung.cat
verkettet zwei Variablen.cat a b
speichert den Wert von ab in a.Wenn keiner dieser Befehle gefunden wird, wird der Ausdruck als Variablenzuweisung behandelt, wobei das erste Token als Variablenname verwendet wird.
$
und~
verhalten sich genauso wie inprint
, aber es gibt auch einen@
Bezeichner. Hiermit wird das letzte Token als mathematischer Ausdruck behandelt, der an übergeben wirdset /a
. Es umfasst die meisten Operatoren. Wenn keiner der drei Bezeichner gefunden wird, liegt ein Syntaxfehler vor und der Interpreter wird beendet.Dolmetscher (Windows Batch)
Der Interpreter übersetzt den Code tatsächlich in einen Windows-Stapel, legt ihn in eine temporäre Datei und führt ihn aus. Während Syntaxfehler in der halben Sprache erkannt werden, kann das resultierende Stapelskript Probleme verursachen, insbesondere bei Sonderzeichen wie Klammern, vertikalen Balken usw.
quelle
Flex Bison
Weisen Sie eine Variable zu, andernfalls einen Bedingungsblock und eine andere Additions- / Subtraktionsoperation.
Laxical Datei
lex.l
Parser-Datei
com.y
Kompilieren
Lauf
Compiler in.txt oder.txt
Eingabedatei
a = 3 + (4 · 7) -9; print a; c = a + 45; print c;
** Dies ist Kommentar speichern c;
** speichere c in der Datei print c * (a + 32);
Ausgabedatei 67
quelle
Dolmetscher
Anweisungen zum Ausführen dieses Codes finden Sie in meiner anderen Antwort: /codegolf//a/19935/13186
99 Flaschen Bier
Das Programm
quelle
99ISC
99ISC verwendet einen ganzzahligen Speicher beliebiger Größe. Der Speicher wird durch eine nicht negative Ganzzahl indiziert. Alle Werte im Speicher werden mit ihrer Adresse initialisiert. Z.B. Zur Laufzeit enthält die Adresse 0 den Wert 0 und die Adresse 9 den Wert 9.
99ISC hat zwei Anweisungen. Der erste druckt die Routine 99 Flaschen Bier an der Wand aus. Die Syntax besteht aus einer einzelnen Zeile (siehe unten). Die Ausführung wird mit der nächsten Zeile im Programm fortgesetzt.
Der zweite Befehl ist ein Befehl "subtrahieren und verzweigen, wenn nicht gleich Null". Die Syntax besteht aus einer einzelnen Zeile (siehe unten).
x
ist die Adresse der zu bearbeitenden Zahl,y
ist die Adresse der zu subtrahierenden Zahl undz
ist die nächste auszuführende Zeile, wenn das Ergebnis der Subtraktion nicht Null ist. Andernfalls wird die Ausführung mit der nächsten Zeile fortgesetzt.Das Vorhandensein des Befehls "Subtrahieren und Verzweigen, wenn nicht Null" macht 99ISC zu einem OISC (One Instruction Set Computer) und damit zu einem vollständigen Turing.
Hier ist ein Programm, das die ersten 10 Werte im Speicher löscht und dann die Routine "99 Flaschen Bier an der Wand" druckt.
Und hier ist ein 99ISC-Interpreter in Python.
quelle
Ich gebe dir:
Small Instruction Set Interpreter (SISI)
Die Syntax basiert auf BASIC und Assembly. Es hat vier Aussagen:
set
,print
,jump
(unbedingter goto) undjumpif
(bedingten goto). Vor jeder Aussage muss eine Zeilennummer stehen. Unterstützte Datentypen sind Ganzzahlen und Zeichenfolgen.Der Interpreter selbst befindet sich in Python 3 auf Github (sisi.py). Das 99 Bottles of Beer-Programm gibt es auch, aber ich werde es hier reproduzieren:
quelle
Pogo
https://github.com/nrubin29/Pogo
quelle
i
und setze sie auf 99. Während i größer als 0 ist, gebe ich eine Zahl ausi bottles of beer on the wall
und subtrahiere sie voni
. Wenn das Problem ist, dass mir einige Texte fehlen, kann ich noch mehr hinzufügen.