Ich habe mehrere handgeschriebene Compiler für sehr einfache Sprachen erstellt, aber jetzt möchte ich versuchen, eine dynamische Sprache zu entwickeln, ähnlich einer vereinfachten Python oder Ruby. Es fiel mir jedoch leicht, mich mit der Funktionsweise von Compilern zu beschäftigen. Primitive Compiler übersetzen einfach. Aber ich kann das nicht tun, wenn die Sprache dynamisch ist. Ich muss einen Interpreter oder eine VM schreiben, die die Informationen zur Laufzeit verfolgt und viel mehr Arbeit auf mich ausübt.
Kurz gesagt, gibt es Ressourcen, die ich überprüfen sollte, wenn ich weiß, wie Compiler funktionieren, aber auf die Erstellung eines Interpreters migrieren möchte? Es gibt einige VMs für dynamische Sprachen, aber ich habe kein Problem damit, meine eigenen zu rollen. Dies ist alles nur für meine persönliche Erfahrung.
Ich suche Informationen darüber, wie ich von einem Compiler zu einem Interpreter wechseln kann. Wenn ich bereits einen Compiler für Sprache X erstellt habe, aber jetzt einen Interpreter schreiben soll, was muss getan werden und gibt es Ressourcen, die den Prozess durchlaufen?
Ich möchte keine umfassenden oder abstrakten Ressourcen, die sich mit der Funktionsweise von Compilern oder virtuellen Maschinen befassen. Ich habe viele Lehrbücher zu diesem Thema. Alle Ressourcen, die ich online gefunden habe, setzen entweder voraus, dass Sie keine Erfahrung haben, und beginnen Sie daher mit einer lexikalischen oder syntaktischen Analyse, oder sie sind äußerst abstrakt. Ich habe einen funktionierenden Compiler, möchte ihn aber jetzt in einen Interpreter verwandeln und der Sprache dynamische Funktionen hinzufügen.
Ich konnte keine Ressourcen für diesen Prozess finden, der Umfang ist möglicherweise zu begrenzt, oder Ressourcen für das "Back-End" eines Dolmetschers, ohne zu theoretisch zu sein, weshalb ich hier gepostet habe.
quelle
Antworten:
Erfahren Sie zunächst, wie Sie Dolmetscher implementieren. Ich empfehle PLAI (Programmiersprachen: Anwendung und Interpretation) . Es kommt schnell zum Fleisch der Interpretation, ohne sich mit der Syntax zu beschäftigen.
Für Ihre Sprache können Sie das Front-End (meistens Parser) und die Laufzeitbibliothek des Compilers (GC, Datenstrukturen, primitive Operationen usw.) wiederverwenden.
Natürlich können Sie auch eine dynamische Sprache mit einem Compiler implementieren, der Code erzeugt, der (einige) dieselben Datenstrukturen manipuliert, die Sie in einem Interpreter verwenden würden. In einem Interpreter können Sie beispielsweise globale Variablen als String-indizierte Hash-Tabelle implementieren. In einem Compiler würden Sie globale Variablenreferenzen in den Code kompilieren, der die Suche unter Verwendung derselben Tabelle durchführt. Im Gegensatz dazu könnten Sie lexikalische Variablen zu einer effizienteren Darstellung zusammenstellen ("native" Argumente und Verschlussstrukturreferenzen).
quelle
Wenn Sie die Grundlagen der Implementierung eines Interpreters für eine dynamische Sprache erlernen möchten, kann ich mir keinen besseren Ausgangspunkt vorstellen als die Ursprünge der allerersten dynamischen, interpretierten Programmiersprache: Lisp.
In seiner ursprünglichen Arbeit von 1960 definierte John McCarthy 5 primitive Funktionen, die für ein Lisp notwendig sind. Natürlich beabsichtigte McCarthy seine Arbeit über Lisp nur als akademische Übung; Es war ein Doktorand, der sich
eval
an der Montage beteiligte und den ersten Lisp-Dolmetscher schuf. Paul Graham identifiziert sieben Grundelemente : Zitat, Atom, Gleichung, Nachteile, Auto, CDR und Kond.Die Sache ist, dass Sie Lisp wirklich in jeder Sprache implementieren können; Sobald Sie implementiert haben
eval
, ist es einfach, eine REPL einzurichten, und Sie haben einen interaktiven Interpreter. Die Leute waren gelangweilt oder neugierig genug, um Lisps in C, Java, Ruby, Python und vielen anderen Sprachen zu implementieren. Und nicht immer absichtlich; Es ist wichtig, sich an die zehnte Regel von Greenspun zu erinnern :Ich sage nicht, dass Ihr Endziel eine Lisp-Implementierung sein sollte. Homoikonizität hat jedoch ihre Vorteile, wenn sie lernt, eine dynamische Sprache zu implementieren. Warum sollten Sie sich mit Syntaxproblemen befassen, wenn Sie in einer Sprache lernen können, in der die idiomatische Syntax mit dem AST einer Sprache identisch ist, die einen Lexer / Parser verwendet?
Jedenfalls ... nur ein Vorschlag. Aber es ist aus gutem Grund, dass die meisten der großen Programmiersprachen seit C zumindest ein wenig von der Lisp-Natur haben.
quelle
Ich habe dies (~ 600 Zeilen C #) öffentlich zugänglich gemacht, was quote / list / apply / eval / test / etc unterstützt und es ermöglicht, eine Lisp-ähnliche Syntax und / oder die semantischen Buildins einfach anzupassen:
https://repl.it/CdjV/3
Z.B:
'HTH,
quelle
Angenommen, Sie kennen ein bisschen Schema (z. B. SICP gelesen ) oder Lisp, dann empfehle ich Queinnecs Buch Lisp In Small Pieces . Es werden verschiedene Varianten von Lisp-ähnlichen Interpreten und Compilern erläutert (einschließlich Bytecode oder C).
Lesen Sie auch Scotts Programmiersprache Pragmatik , das neueste Drachenbuch , das GC-Handbuch , Pierces Typen und Programmiersprachen .
Dann könnten eine teilweise Bewertung (& Futamura-Projektionen) und ein fortlaufender Stil relevant sein.
quelle