2つの言語間でソースコードを「翻訳」できるプログラムはありますか?


28

2つの言語間でソースコードを「翻訳」できるプログラムはありますか(翻訳者が必要なライブラリにアクセスできると仮定します)?

ある場合、それらはどのように機能しますか(使用される技術、必要な知識など)?それらはどのように実行可能に構築されますか?

そうでない場合、開発を妨げる制限は何ですか?これはAIの完全な問題ですか(自然言語の翻訳は1つとしてリストされています)?

EDIT 変換は、言語に同じ表現力があり、同じ種類の問題を解決でき、変換されるコードが宛先言語で表現できる場合にのみ予想されます。(たとえば、シェルスクリプトからMATLABへの変換は想定されていません)。



14
「2つの言語」とはどういう意味ですか?確かに、ある言語から別の言語に翻訳できるプログラムがあります。それらは「コンパイラ」と呼ばれます。それは文字通りコンパイラの定義です。つまり、プログラムをある言語から別の言語に翻訳するプログラムです。しかし、「2つの言語」とは?私はそれが可能だとは思わない。翻訳者はソース言語とターゲット言語の両方を知っている必要があり、通常は特定の言語ペアに固有です。
ヨルグWミットタグ

プログラムには、ソース言語とターゲット言語が提供されます。C ++でプログラムを作成し、Java、Python、Perl、Ruby、Goなどに変換することを考えています。いくつかの制限があるかもしれません(たとえば、シェルスクリプトをMATLABに変換するとは思わない)。
トビアラフィン16

4
はい、それらはコンパイラと呼ばれ、コンパイラのように機能し、コンパイラのように構築できます。
user253751 16

1
「任意の2つの言語」によって、(有限の)プログラムが無限の数の入力言語を読み取って理解できるはずであることを文字通り意味する場合、答えはささいにnoです。しかし、これらの言語を入力言語の有限集合を取ると、あなたはすべてのためのコンパイラを見つけることができます。..
Bakuriu

回答:


57

TLDR; これは可能ですが、実用的ではありません。

(翻訳者が必要なライブラリにアクセスできると仮定します)?

これはややこしいことになり、このようなものが実際に使用されない理由の一部です。

  1. すべてのコンパイラは翻訳者です。ある言語から別の言語への翻訳は間違いなく可能です。これはまさに文字通りコンパイラーが行っていることです。コンパイラが出力として出力する言語は一般にマシンコードまたはアセンブリですが、これは単なる別の言語であり、2つの言語間で翻訳するコンパイラ(トランスパイラーまたはトランスコンパイラと呼ばれることもあります)があります。たとえば、PureScript、Elm、ClojureScriptなどのJavascriptにコンパイルされた言語の範囲があります。

  2. 任意の2つのチューリング完全言語間の翻訳は常に可能です。つまり、ライブラリ呼び出しやFFI、その他の邪魔になる実用的なビットを無視します。言語がチューリング完全である場合、次のものがあります。

    • チューリングマシンをこの言語のコードに変換する翻訳
    • この言語からチューリングマシンへの翻訳

    したがって、言語Aから言語Bに翻訳するには、Aコードをチューリングマシンに変換し、そのマシンをBコードに変換します。

    もちろん、実際には、実用的な部分が邪魔になります。また、これには翻訳にアクセスできる必要があります。それらは基本的にすべての言語に存在しますが、だれかが時間をかけてそれらを書くことを意味しません。

  3. この翻訳を効率的に行うことは困難です。異なる言語は異なるものを優先します。たとえば、CからPythonに変換する場合、おそらくポインター演算を実行できるように、CのメモリをPython辞書としてシミュレートする必要があります。ベアメタルメモリの命令にアクセスしていないため、これに関連するオーバーヘッドが発生します。

    言語によってパフォーマンスの優先順位が異なるため、ある言語が最適化する(または、ある言語の実装が最適化する)ことを別の言語で迅速に行うことは不可能です。適切なテールコールを使用して関数型言語を翻訳すると、適切なテールコールを使用しない言語に翻訳すると速度が低下します。

  4. この変換を行っても、コードは判読できません。言語Aのコードと同じように動作する言語Bのコードを取得するのは簡単です。多くの理由で、人間がBで書いたコードのように見せることは困難です。AとBは異なる抽象化ツールを持っている可能性があり、コンピューターはコードを読みやすくする理由を知りません。これは、前述のチューリング機械翻訳を使用することになった場合に特に当てはまります。

    これは疑問を提起します:そのような翻訳のポイントは何ですか?最後に遅くて読めないコードのブロックを取得した場合、それをマシンコードにコンパイルし、何らかのFFIまたはプロセス間通信を使用してピースをリンクしてみませんか?

    これにはいくつかの例外があります。特定の言語(JavaScriptなど)のものが必要な場合があります。言語が似ている場合もあり、賢明な翻訳は簡単です。言語は、実行されることを目的としていない場合がありますが、そのコードを別の言語(Coqなど)に抽出することもあります。

    しかし、一般的に、それは非常に実用的なものではありません。


5
ポイント4の1つの例はasm.jsです。今日、することが可能であるみかん使用して、読めるJavascriptのソース地図 ...と要素インスペクタを、誰もそれをしたくないだろう
イスマエルミゲル

1
Modelicaは、別の言語(この場合はC)へのコンパイル用に設計された言語の別の例です。
モニカを

C ++からjavascriptに変換するWebアセンブリ。
スルト

XからYへのトランスパイラーの例は数多くありますが、これは万能の万能コンパイラとは異なります。明らかに、トランスパイリングが理にかなっている場合があります。
jmite 16

IMOが欠落している1つの重要な例外:Cへのコンパイル。理由は、多くの一般的ではないシステムには既存のCコンパイラがあり、一般に非常に合理的なマシンコードを出力できるためです。したがって、言語をCにコンパイルすることにより、これらの珍しいアーキテクチャのバックエンドを用意する必要がなくなります。
MSalters 16

2

そのようなプログラムがあります。たとえば、当時広く使用されていたLispからFortranへのトランスレーター。唯一のLispコンパイラはLispを直接コンパイルせず、代わりに通常のCコンパイラによってコンパイルされるCコードを生成します。別の例は、直接コンパイルされず、C ++コードがコンパイルされる前に最初にC ++に変換されるValaです。Qtは、コンパイルするためにC ++に翻訳される言語であるMOCで記述されています(ただし、MOCはいくつかの追加コマンドを備えたC ++であるため、実際に「新しい言語」と命名する場合は議論の余地があります) C ++コンパイラがあり、C ++-to-C-translatorがありました。また、一部のプロジェクトはPascalで作成されてからCに翻訳されました。また、clangとJavaは、C ++とJavaのコードを何らかの中間言語に変換し、さらに処理できるようなものです。

言語翻訳者の出力に期待できないのは、結果が人間の読者にとって意味があることです。プログラムのタスクは、元のコードと同じことを行うプログラムを作成するコードを書くことです(私の経験では、言語の機能と使用している外部ライブラリによっては機能しません)。しかし、目的がわからないので、このタスクはプログラムの残りの部分で行われますが、かなり失われる可能性があります。


0

直接的な答えではありませんが、.Net Framework用に作成されたILSpyというツールがあり、.NetアセンブリをC#またはVB.Netに逆コンパイルできます。

.Netの性質に不慣れな場合は、多くの言語で.Netコードを作成できますが、主にC#またはVB.Netです。コンパイラーは、アプリケーションをコンパイルするときに、コードを「中間言語」(または略してIL)コードに変換します。このコードは、.Netバイナリにコンパイルされます。

.NetアプリケーションはILコードからコンパイルされたバイナリであるため、ILSpyは.Netアプリケーションを取得し、それをILコードに戻し、その後さらに一歩進めてC#またはVB.Netに戻すことができます。

このツールを使用すると、アプリケーションをコンパイルするだけで、コンパイルしたファイルをIL、C#、またはVB.Netコードとして参照できます。明確にするために、コードが最初に記述された言語は関係ありません。バイナリが.Netアセンブリである限り、コンパイルされたファイルをリバースエンジニアリングし、これら3つの言語のいずれかとしてコンテンツを出力できます。

私はこれが正確にコンパイラーではないことを知っていますが、それはあなたが探しているものに似た最終結果を提供するツールであり、実際、これを使用してVB.Netプロジェクトを少し何かに「翻訳」しました私によく知っている-C#。


0

(コメントに基づく)ユースケースでは、SWIGが役立つように思えます。

SWIGは、CおよびC ++で記述されたプログラムをさまざまな高レベルプログラミング言語と接続するソフトウェア開発ツールです。SWIGは、Javascript、Perl、PHP、Python、Tcl、Rubyなどの一般的なスクリプト言語を含むさまざまな種類のターゲット言語で使用されます。サポートされる言語のリストには、C#、Common Lisp(CLISP、Allegro CL、CFFI、UFFI)、D、Go言語、Androidを含むJava、Lua、Modula-3、OCAML、Octave、Scilab、Rなどの非スクリプト言語も含まれますまた、いくつかの解釈およびコンパイルされたScheme実装(Guile、MzScheme / Racket、Chicken)もサポートされています。


0

Fortran 77からCへのソースからソースへの変換を行う由緒あるf2cを思い出します。

これは(時には...)、主に数十年前の数値コードを翻訳するために使用され、Fortranコンパイラをツールチェーンに統合する必要はありませんでした。


0

そのようなプログラムが存在することを原理的に教えてくれる理論は、許容可能な番号付けと呼ばれます。このような2つの番号付けの間に計算可能なコンパイラがあることを証明できます。チューリング完全形式(またはプログラミング言語)は、本質的には1つです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.