あるプログラミング言語から別のプログラミング言語への自動翻訳者がいないのはなぜですか?[閉まっている]


37

ほとんどのプログラミング言語はチューリング完全です。つまり、ある言語で解決できるタスクは、別の言語で、またはチューリングマシン上でも解決できます。それでは、プログラムを特定の言語から他の言語に変換できる自動翻訳者がいないのはなぜですか?2つの言語に対するいくつかの試みを見てきましたが、それらは常に言語の限られたサブセットでのみ機能し、実際のプロジェクトの変換にはほとんど使用できません。

少なくとも理論的には、すべての言語間で100%正しい翻訳者を書くことは可能ですか?実際の課題は何ですか?働く既存の翻訳者はいますか?


5
「すべての言語」には、Oook!などの愚かな言語も含まれます。(完全性の確認はすべてではありません。実際にはシステムコールも必要です。)
ドナルフェローズ

幾つかある。CからPascalおよびPascalからCへのトランスレーターは、ある時点では非常に一般的でした。以下の回答が示唆するように、出力は通常、少なくともいくつかの手作業を片付けないと読めなかった。そして、これらは比較的単純なライブラリを備えた比較的単純な言語です。たとえば、C ++からHaskellまたはその逆の作業をうまく行うことはおそらく不可能でしょう。
Steve314

C#をVBに、またはその逆に変換する機能を持つサービスとしての.netコンパイラーRoslynをチェックしてください。
ダニエルリトル

2
すべてのコンパイラはPLを別のPLに変換しますが、ターゲットPLのコードが読みやすいことを保証しません
jk。

Googleの翻訳の正確さを確認した後、私は自分の人生で普遍的な翻訳者に会えると確信しています。はい、それは挑戦的な努力になるだろうし、githubやstackoverflowのような大きなコードベースの分析の場合のように多大な努力を必要とするかもしれませんが、これは起こり、そのようなツールの需要も今後の年齢で増加します、特に今AIとMLを勉強するプログラマーがたくさんいること。そのようなツールをすべて自分で開発する人はいないかもしれません。ただし、この問題に対処するボットを開発するためにボットを開発する場合があります。
ガネーシュ・カマス-「コードフレンジー」

回答:


32

最大の問題は、プログラムコードの実際の翻訳ではなく、プラットフォームAPIの移植です。

PHPからJavaへのトランスレーターを検討してください。PHPバイナリの一部を埋め込まずにこれを実行する唯一の実行可能な方法は、JavaでPHPのすべてのモジュールとAPIを再実装することです。これには、10.000以上の関数の実装が含まれます。それに比べて、実際に構文を翻訳する仕事はパイのように簡単です。そして、すべての作業が終わっても、Javaコードはありません。Javaプラットフォーム上で偶然に実行される怪物のようなものがありますが、それは内部でPHPのように構成されています。

そのため、頭に浮かぶ唯一のツールは、コードを翻訳してデプロイすることであり、後で維持することではありません。GoogleのGWTは、JavaをJavaScriptに「コンパイル」します。FacebookのヒップホップはPHPをCにコンパイルします。



誰かがPHPからJavaへのトランスレータを作成し、実際にPHPバイナリを埋め込んだようです。それはあなたのポイントを変えないけれども合意した。runtimeconverter.com/single-post/2017/09/15/...
user1122069

20

中間形式がある場合は、言語Xのプログラムその形式に変換するものを実装できます。またその形式から言語Yに変換することもできます。興味のあるすべての言語にこれらの変換を実装します。

さて、あなたは何を知っていますか?そのようなフォーマットは既に存在します:アセンブリ。コンパイラーは既に「言語Xからアセンブリー」への変換を行い、逆アセンブラーは「アセンブリーから言語Yへ」の変換を行っています。

現在、アセンブリは逆変換を行うためのそれほど優れた言語ではありませんが、MSILは実際にはそれほど悪くはありません。Reflectorをダウンロードすると、.NETアセンブリをさまざまな言語に分解するオプションがあります(プラグインはさらに多くを提供します)。そのため、C#でプログラムを取得してDLL(つまり、MSIL)にコンパイルし、リフレクターを使用してVB、C ++ / CLI、F#、およびその他多数に分解することができます。もちろん、他のすべての変換も機能します。F#ファイルを取得し、DLLにコンパイルし、Reflectorを使用してC#に変換します。

もちろん、2つの大きな問題があります。

  1. コードは基本的に判読できません。MSILは(デバッグ情報を含む)元のソースから多くの情報を削除するため、翻訳版は100%の忠実度を持ちません(理論的にはC#-> MSIL-> C#変換を行うと元のコードが返されますが、しません)。
  2. 多くの.NET言語には、独自のカスタムライブラリ(VBランタイムライブラリ、F#ライブラリなど)があります。これらも変換を行うときに含める(または変換する)必要があります。

#2を回避することは本当にありませんが、おそらくMSILにいくつかの追加の注釈を付けて(おそらく属性を介して)#1を回避することができます。もちろん、それは追加の作業になります。


元のソースからのメタデータの多くはMSILに含まれています(XMLコメント、元のメソッド、プロパティ、およびメンバー名を含む)ので、C#への変換はあなたが言うほど読めないと思います。.NETフレームワークの一部を分解してみてください。とても読みやすいです。もちろん、F#からC#への変換では状況が異なる場合があります。
ロバートハーベイ

@Robert:XMLコメントはMSILに含まれていません。Microsoft.NET\Framework\v2.0.50727\enたとえば、見てみると、システムライブラリのすべてのXMLドキュメントを見ることができます。これは、Reflector(など)がコメントを表示するために使用するものです。変換は判読できません。私が言っていたのは、ソースレベルの翻訳から期待される100%の忠実度ではないということだけです。
ディーンハーディング

2
逆アセンブラーは、マシン実行可能バイナリをその特定のプロセッサータイプのアセンブラーに変換し直します(すべてがx86ではありません)。あなたは本当に、コンパイルされたコードをソースに戻す逆コンパイラを意味します。これは、各最適化レベルの各メーカーの各コンパイラがソース行を異なる出力バイナリ形式に変換するため、恐ろしく困難なタスクです。
uɐɪ

20

少なくとも理論的には、すべての言語間で100%正しい翻訳者を書くことは可能ですか?実際の課題は何ですか?

  • より構造化された言語からチューリング完全なまだ構造化されていない言語への翻訳は常に可能です。
    • この主張は厳密に技術的な意味で見る必要があります。つまり、翻訳されたプログラムは、実行時にまったく同じ結果を生成するということです。
    • 翻訳されたコードの可読性、または元のプログラム構造の保存については何も暗示されていません。
  • 構造化されていない言語から構造化された言語への翻訳は可能ですが、翻訳されたコードは構造化されていない形式のままです。

1
頭に釘を打ちます。LLVMのCバックエンドから出てくるコードを読んでみてください。技術的には正当なCコードですが、It Ai n't Pretty(TM)ではありません。
dsimcha

1
@dsimcha:読みやすさはさておき、Cバックエンドはデバッグや逆アセンブリよりも出力を読みやすくします。しばらくメンテナンスが終了した後、彼らがそのバックエンドを再び持ち帰ってくれてとてもうれしいです。
JMベッカー

10

なぜプログラムを変換したいのですか?

ソース言語とターゲット言語の両方の言語は、とにかく(仮想)マシンコードにコンパイルされます*。そのため、技術的な理由から、別の高レベル言語へのコンパイラーは必要ありません。

言語は人間向けです。したがって、あなたの質問の暗黙の要件は次のとおりです:「なぜ読み取り可能なコードを生成する翻訳者がいないのか」そして答えは(私見)でしょう:十分に異なる2つの言語がある場合、「読み取り可能なコード」の書き方アルゴリズムを変換するだけでなく、異なるアルゴリズムを使用するという点で異なります。

たとえば、Cでの典型的な反復とlispでの反復を比較します。または、慣用的なルビーを使用したpythonの「最高の方法」。

ここでは、英語からドイツ語に翻訳するときに「雨が降っている猫と犬」を「バケツからのように注いでいる」という意味の何かに翻訳するなど、あなたが実際の言語で持っている同じ問題が現れ始めますもう単語ごとに翻訳しますが、意味を探す必要があります。

そして、「意味」は取り組むのが簡単な概念ではありません。

*)まあ、コーヒースクリプトがあります...


1
いい答えだ。2つの言語の機能とイディオムがまったく同じ場合、ある言語を別の言語にかなり効率的に翻訳することは可能ですが、ほとんどの言語は、作成者が適切ではないと感じる機能とイディオムをサポートする目的で設計されています他の言語でサポートされています。保守可能なコードの機械翻訳は、ターゲット言語の機能とイディオムがソース言語の機能とイディオムのスーパーセットである場合に機能する場合がありますが、そのような状況はそれほど一般的ではありません。
-supercat

6

理論的には可能ですが、ほとんど役に立ちません。ほとんどすべてのソース言語とターゲット言語の組み合わせが可能ですが、ほとんどの場合、誰も結果を見たり使用したりすることはありません。

存在するほぼすべてのプラットフォームでCコンパイラーが利用可能なため、かなりの数のコンパイラーがCをターゲットにしています(また、プロセッサーを設計し、新しいプロセッサーをターゲットとするCコンパイラーを自動的に生成できる自動コンパイラージェネレーターがあります)。もちろん、.NET、JVM、C-、LLVMなどのさまざまな仮想マシンで使用される言語をターゲットとするかなりの数の実装もあります。

ただし、重要なのは、ターゲットが基本的にはコンパイルプロセスのステップとしてのみ使用されるアセンブリ言語である場合にのみ有効であるということです。特に、通常、通常のプログラマーにその結果を読んだり、その結果を処理させたりすること望ましくありませ。通常はあまり読みにくいでしょう。


5

FWIW、JavaからDへのトランスレーターがあります。TioPortと呼ばれ、SWTをDに移植するかなり深刻な試みで使用されました。主な問題は、Java標準ライブラリの大部分を移植する必要があること。


4

それ自体はコード翻訳ではありませんが、言語ワークベンチの概念は、すべての言語間で100%正しい翻訳者に似たものを実装する方法を示しています。

現在のアプローチでは、ソースコードはテキスト形式で保存されます。コンパイル時に、これらの人間が読み取れるテキストファイルは、抽象構文ツリー表現に解析され、バイトコードまたはマシンコードの生成に使用されます。ただし、この抽象表現は一時的であり、コンパイラの内部にあります。

言語ワークベンチのアプローチでは、同様の抽象構文ツリー表現が永続的な保存されたアーティファクトです。この抽象的な表現に基づいて、マシンコードとテキストの「ソース」コードの両方が生成されます。このような方法の結果の1つは、プログラムの抽象表現が実際には言語に依存せず、実装された言語でテキストコードを生成するために使用できることです。一人が最も適切だと思う言語を使用してシステムのさまざまな側面で自由に作業できること、またはチームの各メンバーが最も慣れ親しんだ言語で共有プロジェクトで作業できることを意味します。

私が知る限り、この技術はまだ主流の開発で使用できるにはほど遠いですが、独立して取り組んでいるいくつかのグループがあります。それらのいずれかが彼らの約束を果たすかどうかを見分けるのは難しいが、それが起こるのを見るのは面白いだろう。


これらのグループに名前を付けていただけますか?
Qwertie

4

ありますいくつかの自動翻訳が。読み取り可能なコードではなく、コンパイル可能なコードを作成することが目標である場合、それは非常に頻繁ではなく、非常に可能性があり、時には有用です。有名なことですが、最初のC ++コンパイラは実際にはコンパイラではなく、C ++を(本当に複雑な)Cソースに変換し、Cコンパイラによってコンパイルされました。多くのコンパイラーは、要求に応じてアセンブリコードを生成できますが、通常、アセンブリテキストを出力してマシンコードに変換する代わりに、マシンコードを直接生成できます。

言語Aの完全な仕様を考えると、いくつかの言語Bでディレクティブを表現するプログラムを書くことは原則としてそれほど難しくありません。しかし、通常、問題に遭遇する人は誰でも「言語B」に本当に低いレベルを選択します: 、または最近のバイトコード:Jythonは、Java VMによって解釈されるJavaバイトコードを生成するPythonの実装です。Javaクラス階層を記述してコンパイルする必要はありません!


3

これは常に行われます。

すべてのコンパイラ、C ++などの「プライマリ言語」を、マシンのネイティブアセンブリ言語またはインタープリター言語の場合はアーキテクチャに依存しないバイトコードに変換します。

しかし、それはあなたが話していることではないと思います。C ++をJavaやPythonのようなものに変換するトランスレーターが必要でしょう。しかし、それのポイントは何ですか?せいぜい、最終結果は元のソースとまったく同じ効率になります。(実際には、さらに悪化します。)

コードを翻訳して、理解できる言語として読むことができるようにしたい場合、そのような翻訳者は望みの効果とは逆になります。謎めいた、直感的で読めないコードがたくさん残されます。

これは、最も些細なことだけが、ある言語から別の言語に直接翻訳されるためです。多くの場合、1つの言語で単純なことは、別の言語の巨大なライブラリを必要とします-または完全に不可能な場合があります。したがって:

  1. プログラムが些細なものであれば、まともな結果が得られるかもしれません。しかし、それがそれほど単純な場合、翻訳者を介してそれを実行するポイントさえ何ですか?
  2. プログラムが自明でない場合、コードは低品質になります。

最後に、良いコードを書く唯一の方法は、実際にそれを書くことです。 コンピューターは、読みやすさ、ベストプラクティス、エレガントなソリューションの点で、少なくとも少なくともまだ人間とは一致しません。

要するに、それだけの価値はありません。


あなたの類推は通常のコンパイルにも適用されますが、経験的にはそうではないことがわかっています!コンピューターは、高品質のコードを「生成」(書き込みではなく)します。彼らがしばしばひどくやることは、読みやすさ/保守性です。誰かがそのようなプロセスを必要とし、それは私がときどき行うと信じていますが、どちらの問題もストッパーではありません。もしそうなら、当然、翻訳はもともと決して重要ではなかったことは明らかです。
JMベッカー

1

プログラミング言語は非常に複雑であるため、プログラミング言語用の言語翻訳者はいません。仮説的には可能ですが、多くの課題があります。

最初の課題は、単に言語の受け入れ可能な実践にあります。JavaとC ++のような2つのオブジェクト指向言語間の変換は非常に複雑で、どちらもCベースです。翻訳プログラムは、両方の言語の標準ライブラリに関する完全な知識を持ち、動作の違いを知ることができなければなりません。大規模な辞書を作成する必要がありますが、プログラマーごとのプログラミングスタイルの違いは、変更の実行方法を推測する必要があることを意味します。

構文の翻訳を取得したら、最初の言語のコンストラクトを2番目の言語のコンストラクトに変換する方法を理解する必要があります。C ++のオブジェクトからJavaのオブジェクトに移動する場合(これは比較的簡単です)、これは問題ありませんが、C ++構造体で何をしますか?または、C ++クラス外の関数ですか?これを処理する方法を決定することは、別の問題、つまりblobオブジェクトの作成につながる可能性があるため、注意が必要です。ブロブは、十分に一般的なアンチパターンです。

これは問題の完全なリストではありませんが、それらは2つだけであり、大きな問題です。私の教授の一人は、80年代に誰かがマシンコードからCに作ることができると雇用主に納得させたと言いましたが、それはうまくいきませんでした。完全に機能するものがあるとは思わない。


既存のライブラリを知る必要はないと思います。ライブラリをそのまま翻訳できます(利用可能なソースがある場合)。
セルグ

1
その場合、実際には2番目の問題の複雑さが増します。そして、それはあなたがそれを翻訳するためにソースコードにアクセスできると仮定しています。いずれにせよ、それはまだかなり実行不可能です。
indyK1ng

ライブラリに関する+1ポイントは完全に有効であり、常にライブラリがあります。
ダンローゼンスターク

1

コンパイルのポイントは、コンピューターに役立つものを取得することです。すなわち、実行できるもの。なぜあなたがそれを書いたものよりも高いレベルかもしれない何かにコンパイルしますか?

.NETの戦略の方が好きです。すべてを共通言語にコンパイルします。これにより、言語が(N ^ 2)-Nクロス言語コンパイラを作成することなく通信できるという利点が得られます。

たとえば、10個のプログラミング言語がある場合、.NETモデルの下で10個のコンパイラを記述するだけでよく、それらはすべて相互に通信できます。可能なすべてのクロスランゲージコンパイラを作成した場合、90個のコンパイラを作成する必要があります。それは少しの利益のために多くの余分な仕事です。

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