Gibt es Programme, die Quellcode zwischen zwei beliebigen Sprachen 'übersetzen' können?

28

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).

Tobi Alafin
quelle
14
Was meinst du mit "zwei beliebigen Sprachen"? Es gibt sicherlich Programme, die von einer Sprache in eine andere übersetzen können. Sie werden "Compiler" genannt. Das ist wörtlich die Definition eines Compilers: ein Programm, das Programme von einer Sprache in eine andere übersetzt. Aber "zwei beliebige Sprachen"? Ich denke nicht, dass das möglich ist. Der Übersetzer muss sowohl die Ausgangs- als auch die Zielsprache kennen und ist in der Regel für ein bestimmtes Sprachpaar spezifisch.
Jörg W Mittag
Das Programm enthält die Quell- und Zielsprache. Ich denke darüber nach, ein Programm in C ++ zu schreiben, es in Java, Python, Perl, Ruby, Go usw. zu übersetzen. Es kann einige Einschränkungen geben (ich erwarte nicht, dass es Ihr Shell-Skript zum Beispiel in MATLAB konvertiert).
Tobi Alafin
4
Ja, sie heißen Compiler, arbeiten wie Compiler und können wie Compiler konstruiert werden.
user253751
1
Wenn Sie mit "zwei beliebigen Sprachen" wörtlich meinen, dass das (endliche) Programm eine unendliche Anzahl von Eingabesprachen lesen und verstehen kann, lautet die Antwort trivial nein . Nehmen Sie jedoch eine endliche Menge von Eingabesprachen und Sie können einen Compiler für all diese Sprachen finden ..
Bakuriu

Antworten:

57

TLDR; das ist möglich aber nicht praktikabel.

(vorausgesetzt, der Übersetzer hat Zugriff auf die erforderlichen Bibliotheken)?

Dies ist am Ende ein heikles Thema und ein Teil dessen, warum solche Dinge in der Praxis nicht zum Einsatz kommen.

  1. 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.

  2. 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:

    • Eine Übersetzung, die eine Turing-Maschine in Code in dieser Sprache konvertiert
    • Eine Übersetzung aus dieser Sprache in eine Turing-Maschine

    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.

  3. 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.

  4. 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.

jmite
quelle
5
Ein Beispiel für Punkt 4 ist asm.js . Heute ist es möglich , es zu machen sorta lesbar, mit Javascript Quelle Karten und das Element Inspector, aber niemand wird das tun wollen ...
Ismael Miguel
1
Modelica ist ein weiteres Beispiel für eine Sprache, die zum Kompilieren in eine andere Sprache entwickelt wurde (in diesem Fall C).
Setzen Sie Monica
Webassembly übersetzt von C ++ nach Javascript.
Surt
Es gibt zahlreiche Beispiele für Transpiler von X bis Y, aber das unterscheidet sich von einem universellen Compiler für alles. Es gibt offensichtlich Fälle, in denen eine Transpilation sinnvoll ist.
13.
Eine wichtige Ausnahme fehlt IMO: Kompilieren nach C. Der Grund dafür ist, dass viele ungewöhnliche Systeme über einen vorhandenen C-Compiler verfügen, der im Allgemeinen durchaus vernünftigen Maschinencode ausgeben kann. Wenn Sie also eine Sprache in C kompilieren, müssen Sie keine Backends für diese seltenen Architekturen haben.
MSalters
2

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.

Gunter königsmann
quelle
0

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 #.

RLH
quelle
0

Für Ihren Anwendungsfall (basierend auf Kommentaren) scheint SWIG nützlich zu sein.

SWIG ist ein Software-Entwicklungstool, das in C und C ++ geschriebene Programme mit einer Vielzahl von Programmiersprachen auf hohem Niveau verbindet. SWIG wird mit verschiedenen Arten von Zielsprachen verwendet, einschließlich gängiger Skriptsprachen wie Javascript, Perl, PHP, Python, Tcl und Ruby. Die Liste der unterstützten Sprachen umfasst auch Nicht-Skriptsprachen wie C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go-Sprache, Java, einschließlich Android, Lua, Modula-3, OCAML, Octave, Scilab und R Es werden auch mehrere interpretierte und kompilierte Schema-Implementierungen (Guile, MzScheme / Racket, Chicken) unterstützt.

Nathan Ringo
quelle
0

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.

Alexandre C.
quelle
0

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.

Raphael
quelle