Gibt es Programme, die Quellcode zwischen zwei beliebigen Sprachen 'übersetzen' können (vorausgesetzt, der Übersetzer hat Zugriff auf die erforderlichen Bibliotheken)?
Wenn ja, wie funktionieren sie (eingesetzte Techniken, erforderliche Kenntnisse usw.)? Wie würden sie realisierbar sein?
Wenn nicht, welche Einschränkungen verhindern ihre Entwicklung? Handelt es sich um ein AI-vollständiges Problem (die natürliche Übersetzung wird als eines aufgeführt)?
EDIT- Konvertierung wird nur erwartet, wenn die Sprache die gleiche Ausdruckskraft hat, die gleiche Art von Problemen lösen kann und der zu konvertierende Code in der Zielspracheausgedrücktwerden kann . (ZB wird keine Konvertierung von einem Shell-Skript nach MATLAB erwartet).
computability
programming-languages
compilers
Tobi Alafin
quelle
quelle
Antworten:
TLDR; das ist möglich aber nicht praktikabel.
Dies ist am Ende ein heikles Thema und ein Teil dessen, warum solche Dinge in der Praxis nicht zum Einsatz kommen.
Alle Compiler sind Übersetzer. Das Übersetzen von einer Sprache in eine andere ist definitiv möglich, und das ist buchstäblich alles, was ein Compiler tut. Die Sprache, die ein Compiler als Ausgabe ausgibt, ist im Allgemeinen Maschinencode oder Assembly, dies ist jedoch nur eine andere Sprache, und es gibt Compiler (manchmal Transpiler oder Transcompiler genannt), die zwischen zwei Sprachen übersetzen . Zum Beispiel gibt es eine Reihe von Compile-to-Javascript-Sprachen wie PureScript, Elm, ClojureScript usw.
Das Übersetzen zwischen zwei beliebigen Turing Complete-Sprachen ist immer möglich. Ignorieren von Dingen wie Bibliotheksaufrufen und FFI und anderen unangenehmen praktischen Dingen, die im Weg stehen. Wenn eine Sprache Turing Complete ist, haben Sie:
Um also von Sprache A in Sprache B zu übersetzen, konvertieren Sie den A-Code in eine Turing-Maschine und anschließend diese Maschine in B-Code.
In der Praxis stören natürlich die praktischen Aspekte, und dazu müssen Sie auch über die verfügbaren Übersetzungen verfügen. Sie existieren für praktisch jede Sprache, aber das bedeutet nicht, dass sich jemand die Zeit genommen hat, sie aufzuschreiben.
Diese Übersetzung effizient durchzuführen ist schwierig . Unterschiedliche Sprachen priorisieren unterschiedliche Dinge. Wenn Sie beispielsweise von C nach Python übersetzen, müssen Sie wahrscheinlich den Speicher von C als Python-Wörterbuch simulieren, damit Sie Zeigerarithmetik ausführen können. Dies ist mit einem Mehraufwand verbunden, da Sie jetzt nicht auf die Anweisungen für den Bare-Metal-Speicher zugreifen.
Unterschiedliche Sprachen haben unterschiedliche Leistungsprioritäten. Daher ist es möglicherweise nicht möglich, dass etwas, das durch eine Sprache optimiert wird (oder eine Implementierung einer Sprache optimiert wird), in einer anderen Sprache schnell ausgeführt wird. Das Übersetzen einer funktionalen Sprache mit richtigen Tail Calls führt zu einer Verlangsamung, wenn Sie sie in eine Sprache ohne richtige Tail Calls übersetzen.
Durch diese Übersetzung wird der Code nicht lesbar . Es ist einfach, einen Code in Sprache B zu erhalten, der sich genauso verhält wie der Code in Sprache A. Es ist aus mehreren Gründen schwierig, ihn so aussehen zu lassen, als hätte ein Mensch ihn in B geschrieben. A und B haben möglicherweise unterschiedliche Abstraktionswerkzeuge, und der Computer hat keine Ahnung, was den Code lesbar macht. Dies gilt insbesondere dann, wenn Sie die zuvor beschriebene Übersetzung von Turing Machine verwenden.
Dies wirft die Frage auf: Was bringt eine solche Übersetzung? Wenn Sie am Ende nur einen Block langsamen, unlesbaren Codes erhalten, warum kompilieren Sie ihn nicht einfach zu Maschinencode und verwenden eine Art FFI oder prozessübergreifende Kommunikation, um die Teile miteinander zu verbinden?
Hiervon gibt es einige Ausnahmen. Manchmal brauchen Sie Dinge in einer bestimmten Sprache (wie JavaScript). Manchmal ist die Sprache ähnlich und eine sinnvolle Übersetzung ist einfach. Manchmal ist eine Sprache nicht dafür gedacht, ausgeführt zu werden, sondern ihren Code in eine andere Sprache (wie z. B. Coq) zu extrahieren.
Aber im Allgemeinen ist es keine sehr praktische Sache.
quelle
Es gibt solche Programme. Zum Beispiel Lisp-to-Fortran-Übersetzer, die zu ihrer Zeit weit verbreitet waren. Einzige Lisp-Compiler kompilieren Lisp nicht direkt, sondern generieren C-Code, der dann von einem regulären C-Compiler kompiliert wird. Ein weiteres Beispiel wäre Vala, das nicht direkt kompiliert, sondern erst in C ++ übersetzt wird, bevor der C ++ - Code kompiliert wird. Qt ist in MOC geschrieben, einer Sprache, die zum Kompilieren in C ++ übersetzt wird (aber da MOC nur C ++ mit ein paar zusätzlichen Befehlen ist, kann man sich darüber streiten, ob es wirklich eine "neue Sprache" heißen soll) - und davor gab es C ++ - Compiler gab es C ++ - in-C-Übersetzer. Und einige Projekte wurden in Pascal geschrieben und dann in C übersetzt. Auch Clang und Java tendieren dazu, C ++ - und Java-Code in eine Zwischensprache zu übersetzen, die dann weiterverarbeitet werden kann.
Was Sie von der Ausgabe eines Sprachübersetzers nicht erwarten können, ist, dass das Ergebnis für einen menschlichen Leser keinen Sinn ergibt: Die Aufgabe des Programms besteht darin, Code zu schreiben, der dazu führt, dass ein Programm das Gleiche tut wie der ursprüngliche Code (was nach meiner Erfahrung möglicherweise oder möglicherweise der Fall ist) nicht funktionieren, je nachdem, welche Funktionen der Sprache und welche externen Bibliotheken Sie verwendet haben). Da jedoch nicht bekannt ist, zu welchem Zweck diese Aufgabe ausgeführt wird, kann der Rest der Programmbedeutung weitgehend verloren gehen.
quelle
Keine direkte Antwort, aber es gibt einen Toolaufruf ILSpy , der für das .Net Framework geschrieben wurde und es Ihnen ermöglicht, eine .Net-Assembly in C # oder VB.Net zu dekompilieren.
Wenn Sie mit der Natur von .Net nicht vertraut sind, können Sie .Net-Code in vielen Sprachen schreiben, in erster Linie jedoch in C # oder VB.Net. Wenn der Compiler die Anwendung kompiliert, übersetzt er den Code in einen Code in "Intermediate Language" (oder kurz IL). Dieser Code wird dann in .Net-Binärdateien kompiliert.
Da .Net-Anwendungen Binärdateien sind, die aus dem IL-Code kompiliert wurden, kann ILSpy die .Net-Anwendung in IL-Code umwandeln und anschließend einen Schritt weitergehen und in C # oder VB.Net umwandeln.
Mit diesem Tool müssen Sie lediglich eine Anwendung kompilieren und können dann die kompilierten Dateien als IL-, C # - oder VB.Net-Code durchsuchen. Um es klar auszudrücken, spielt es keine Rolle, in welcher Sprache der Code ursprünglich geschrieben wurde. Solange es sich bei der Binärdatei um eine .Net-Assembly handelt, kann sie die kompilierten Dateien rückentwickeln und den Inhalt in einer dieser drei Sprachen ausgeben.
Ich weiß, dass dies nicht gerade ein Compiler ist, aber es ist ein Tool, das ein Endergebnis ähnlich dem bietet, was Sie suchen, und tatsächlich habe ich dies verwendet, um VB.Net-Projekte ein wenig zu "übersetzen" mir vertrauter - C #.
quelle
Für Ihren Anwendungsfall (basierend auf Kommentaren) scheint SWIG nützlich zu sein.
quelle
Ich erinnere mich an das ehrwürdige f2c , das die Übersetzung von Quelle zu Quelle von Fortran 77 nach C durchführt.
Es wurde (wird manchmal ...) hauptsächlich verwendet, um numerischen Code aus Jahrzehnten zu übersetzen, ohne einen fortran-Compiler in Ihre Toolchain integrieren zu müssen.
quelle
Die Theorie, die besagt, dass solche Programme im Prinzip existieren, nennt man zulässige Nummerierungen . Wir können beweisen, dass es zwischen zwei solchen Nummerierungen berechenbare Compiler gibt, und jeder Turing-vollständige Formalismus (oder jede Programmiersprache) ist im Wesentlichen einer.
quelle