• 締切済み

プログラム言語はなぜ相互変換できないのでしょうか?

当方perlしか分かりませんが、他の言語を見ると結構共通している部分がありCなども簡単な修正は勉強しなくても出来ます。 人が使う言葉ほどはややこしくありませんし、現状どの辺りが難しく相互変換(例えば、perl⇔php⇔ruby⇔C)が出来ないのでしょうか? また、機械語に翻訳された物であれば、それを逆に辿って好きな言語で表示させるなど素人考えでは出来そうな気がするのですが、どの辺りが難しいのでしょうか?

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.12

理論的に可能だが、実用的ではない、というところでしょう。 コンピュータが実行する以上、最終的には機械語に変換されます。 C言語のように直接機械語に翻訳したり、Perlのように機械語で作られた実行環境を利用したり、とやり方に違いはありますが。 CPUの基本動作は簡単です。 メモリの特定のアドレス(これをプログラムカウンタという変数で記憶しています)から必要なワード数読み出して、その値によって実行する計算を決めます。 Perlで書けばこんな感じ $command = $memory[$pc] ; if ( $command == 0x01 ) { # 0x01はaレジスタをデクリメントするコマンドとする $a -- ; # 計算結果が0になったらZフラグを立てる if( $a == 0 ) { $flag_Z = 1 ; } else { $flag_Z = 0 ; } # 計算結果が負になったらCフラグを立てる # 溢れた桁は無視される if( $a < 0 ) { $flag_C = 1 $a = $a & 0xffffffff ;; } else { $flag_C = 0 ; } } elsif ( $command ==0x02) { ...以下同様 これが、実用的な速度で動くものでは無い、というのはご理解いただけると思います。 逆コンパイルについて。 JavaはJavaVM用にコンパイルされます。プログラムの最適化は、実行時に行う部分が多く、コンパイル時にはあまり最適化されません。 そのため、元のソースが予想できるので、逆コンパイラの精度は高いです。 Cはコンパイル時に最適化を行います。 s=0;for(i=0;i<100;i++){s++;} を、「sは100回インクリメントされる。他では使われない」ということから s=100; と最適化する、等ということが行われます。(オプションで抑制できますが) s=100;から元のforにするのは無理です。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.11

話を簡単にするためにPerl⇔Cに絞って考えてみましょう。 Cで8ビットマイコンAVRのプログラムを書いたとします。 RAMのサイズは2Kバイト程度です。 さて、このマイコンでPerlのプログラムを動作させるにはどうすればいいでしょうか? 別の例を考えてみましょう。 非機能要件として1m秒以内に完了させなければならない処理をCで苦心して実装したとします。 これをPerlに変換する(もちろん非機能要件を満たす形で)にはどうすればいいでしょうか? これらを考えただけでも不可能なことがわかるはずです。 もちろん、ぬるい状況で簡単なプログラムを変換するぐらいならできる可能性はあります。

  • nak777r
  • ベストアンサー率36% (49/136)
回答No.10

例えば、ある言語では Dim testBuf(10) AS TYPE_A Dim i As Integer と変数を宣言しただけの状態で 別の言語に相互変換かけたら TYPE_A testBuf[11]; for ( int UniqueArg00124 = 0; UniqueArg00124 < 11; UniqueArg00124 ++ ) { testBuf[UniqueArg00124].ID= 0; testBuf[UniqueArg00124].NAME = ""; testBuf[UniqueArg00124].Address = ""; testBuf[UniqueArg00124].Value = 0.0; } int i; i = 0; と生成されたらどう思います? それだけで、相互変換ソフトなんて使いたく無いとおもいますよ (あくまでたとえです、そこは memset 使えよとかは無しでお願いします。)

  • SPROCKETER
  • ベストアンサー率26% (2129/8001)
回答No.9

 プログラム言語の仕様には用途に応じた特徴があり、相互変換しても冗長的になるだけで特性を生かせないからでしょう。  大昔の話ですが、BASIC言語と機械語が主流だった時代には、BASICから機械語へのコンパイラ言語、アセンブラから機械語へのアセンブル言語、機械語からアセンブラへの逆アセンブラ、機械語からBASICへの逆コンパイラというのがありました。  低級言語に比べ、高級言語になるほど相互変換が難しいのは、変換対象となる命令語が多くて最適化が難しいからでしょう。  BASIC言語をアセンブラ言語に変換するだけでも、対応する命令語の組み合わせが数多くあり、最適化が難しいのが現実です。変数をレジスタにするか、メモリー上のポインタにするかで、大きく違う為、結局はアセンブラで記述した方が処理が高速になる事が多かったです。  現在のC++言語でも同じで、他言語に変換する時点で元の言語に復元出来ないのではないでしょうか。言語変換しても効率が落ちるばかりで、処理の向上に繋がらないのではないでしょうか。  BASIC言語の時代でも解決が尽かなかったわけですから、現在のプログラム言語でも解決が尽かないのは当然かもしれません。人工知能で最適化出来る言語が出来ない限り、この問題の解決は難しいでしょう。  実の話、プログラムを人間が書いている時代が、今も続いているのが不思議です。プログラム言語を考えていると、最初に大雑把に変数処理を重視したプログラムに変換してから、それを変数よりもレジスタに置き換えた方が処理が速くなるプログラムに変換して行けば良いのは、誰でも気がつくのですが、実際に、それをやろうとすると、プログラムの処理系を変えても互換性が保てるように変換しなければならず、非常に複雑になります。  結局は、ある程度までしか最適化出来ないわけで、コンピュータがプログラムを最適化するよりも、人間が直接書いた方が無駄が少ない結果になるわけです。  プログラム言語の相互変換は、思考実験では簡単に思えても、実際にやるのは大変だということでしょう。

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.8

もしかして文法上似たような言語しか触ったことがないのでは? >当方perlしか分かりませんが、他の言語を見ると結構共通している部分がありCなども簡単な修正は勉強しなくても出来ます。 perlはCやawk, sedを参考に作られてるので似てるところがあるのは当然です。 LISP, FORTH, Prologなど系統の異なる言語は触ってみたことありますか? また逆コンパイラの紹介がありますが機械語になったものは逆コンパイラで元に戻すことは不可能です(いちおうソースはできますが元のものとは全く異なるものにしかなりません)。当然他の言語に変換などできるわけがありません。

  • ok-kaneto
  • ベストアンサー率39% (1798/4531)
回答No.7

システム開発を行う上で言語の選定は重要なファクターになります。で、「その言語にしかない強み」というのが言語選定上のポイントになったりします。例えばPHPなら正規表現でしょうし、C言語ならポインタでしょうし。 そういった所の互換性が無い以上、ツールを作成するコストは無駄に終わる可能性が高いわけで。 高級言語同士を変換するトランスレータはCOBOLからJava等いくつかありますが、スクリプト言語間はあるんでしょうかねー。特許を取ってたりしますしねー。 http://www.gp.hitachi.co.jp/service/migration/sol_conversion.html http://www.ekouhou.net/%E8%A8%80%E8%AA%9E%E5%A4%89%E6%8F%9B%E8%A3%85%E7%BD%AE%E3%80%81%E8%A8%80%E8%AA%9E%E5%A4%89%E6%8F%9B%E6%96%B9%E6%B3%95%E3%81%8A%E3%82%88%E3%81%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0/disp-A,2011-96083.html

  • mk48a
  • ベストアンサー率56% (1133/2007)
回答No.6

>人が使う言葉ほどはややこしくありませんし、現状どの辺りが難しく相互変換(例えば、perl⇔php⇔ruby⇔C)が出来ないのでしょうか? C言語ではポインタを使えますが、その他の言語ではポインタをどのように表現できますか? C言語でクラスはどのように実装しますか? そもそもスクリプト言語とコンパイルしなくてはならないC言語を相互変換できることにどのようなニーズがあるのでしょうか? たぶん、苦労のわりにニーズが無い->誰も作らない だと思います。 >また、機械語に翻訳された物であれば、それを逆に辿って好きな言語で表示させるなど素人考えでは出来そうな気がするのですが、どの辺りが難しいのでしょうか? リバースコンパイラで調べてください。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.5

>>当方perlしか分かりませんが、他の言語を見ると結構共通している部分がありCなども簡単な修正は勉強しなくても出来ます。 言っていることが矛盾していますね。いろいろな言語を経験して使いこなせるなら「結構共通している部分があり」っていう主張もわかるけど、「当方perlしか分かりませんが」では、「当方自転車に折れて運転できます。同じ運転なのでバスやトラックも運転っていう意味では似ているので、乗ってもいいですよね?」って放言しているようなものです。

回答No.4

「結構共通している部分がある」ということは、「共通してない部分がそれなりにある」ということになります。 そして、相互変換するということは、その、「共通してない部分」を含めて、対応しなければならないので、難しいのです。 また、それ以上に、「パラダイム」と呼ばれる言語の背景にあるものが、相互変換の障害になります。 たとえば、スクリプト言語だと、多くの場合、「型の制約がない」というのが特徴です。 一方で、CやC++は、「型の制約を強くすることで、コンパイル時にエラーを検出する」という思想です。 こういうものを始め、思想の異なる部分がそれなりにあって、機械的に変換するのは難しいです。 これは、ただ単に相互変換が難しいというだけではなくて、「異なる言語で作られたライブラリを相互に(直接)呼び出すのが難しい」ということにも通じます。 そして、これに対して、新しい枠組みを提供しようとするのが、.NET Framework の基盤になっている、共通言語基盤(CLI)という枠組みです。 おおよそ、どのような言語でも、対応できるような、オブジェクト言語を提供しようということで、考えられたものです。 実は、「機械語に翻訳」といっても、元のプログラム言語の(さらにはコンパイラ)特有の癖がありますから、それを、元の言語に逆コンパイルするのはともかくとして、別の言語に戻すのは、この「癖」が邪魔して、簡単なものではありません。 これも、共通言語基盤という枠組みであれば、このオブジェクト言語を経由して、相互変換できるかもしれません。 結局、プログラム言語で、「判断や繰り返しがある」とか、「代入ができる」とかいう見かけの共通点よりも、「どの範囲のものが代入できるのか」とか、「サブルーチンの呼び出しは、(バインディングなども含めて)どのような機構で行われるのか」とか、そういう点で、「かなり違いがある」ということになります。 また、世の中には、代入という考え方がなかったり、(直接には)ループが表現できなかったりという言語も存在しています。こういうものだと、さらに大変かもしれません。 と、ここまで書いていて、前言を翻すようですが、言語の相互変換というのは、「それ用のライブラリ」というものを介在させることで、対応できることもあります。 たとえば、ruby の文のひとつひとつに対応した、Cの関数を作っておいて、全部対応するCの関数呼び出しで実現するという方法などもあります。 こういうのだと、(美しくはないですが)一方向への変換はできることもあります。

回答No.3

#2です。 失礼、ちょっと先走りました。「逆コンパイル」というのは一応あります。 http://ja.wikipedia.org/wiki/%E9%80%86%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9 ただし、何でも自由自在ということでは当然ありません。

関連するQ&A

専門家に質問してみよう