その言語で言語のコンパイラをどのように書きますか? [複製
-
27-09-2019 - |
質問
私は見ていました ルビニウス, 、Rubyで書かれたコンパイラを使用してBytecodeにコンパイルするRubyの実装。私はこれに頭をつかむことができません。言語自体の言語のコンパイラをどのように書きますか?それを実行可能ファイルにコンパイルして、Rubyで書かれた将来のコードをコンパイルできるようにすることは何もないだけのようです。その文を入力するだけで混乱します。誰かがこれを説明するのを手伝ってもらえますか?
解決
簡素化するには、まず別の言語でコンパイラ用のコンパイラを書きます。次に、コンパイラとボイラをコンパイルします!
したがって、すでにコンパイラを備えたある種の言語が必要ですが、そのようなものがたくさんあるので、Rubyコンパイラコンパイラ(!)をCで書くことができます。これにより、Rubyコンパイラがコンパイルされ、Rubyプログラムをコンパイルできます。それ自体のさらにバージョン。
もちろん、元のコンパイラはマシンコードで作成され、アセンブリ用のコンパイラをコンパイルしました。これは、EG CまたはFortranのコンパイラをコンパイルし、ほとんどすべてのコンパイラをコンパイルしました。 行動中の反復開発。
プロセスは呼び出されます ブートストラップ - おそらく、彼が自分のブートストラップによって沼地から自分自身を引き抜いた男爵マンチャウゼンの物語にちなんで名付けられた:)
他のヒント
コンパイラのブートストラップに関しては、この悪魔のように賢いハックについて読む価値があります。
その文を読んでいるだけで混乱します。
コンパイラを翻訳者と考えるのに役立つかもしれません。コンパイラはしばしば呼ばれます。その目的は、人間が読み取り、コンピューターが読むことができるバイナリコードに翻訳できるソースコードを取ることです。 Rubiniusの場合、それが読み取るコードはたまたまRubyコードであり、それがマシンコードに変換されるコード(実際にはIntelマシンコードにさらにコンパイルされるLLVMマシンコードですが、それは単なる背景詳細です) 。ルビニウス自体は、ほぼあらゆるプログラミング言語で書かれている可能性があります。たまたまコンパイルするのと同じ言語で書かれていました。
もちろん、そもそもルビニウスを実行するために何かが必要であり、これはおそらく通常のルビー通訳者です。ただし、通訳でルビニウスを実行できたら、独自のソースコードを渡すことができ、コンパイルされたバージョンを作成して実行できることに注意してください。これは、「ブートストラップで自分自身を引き上げる」という古いフレーズからブートストラップと呼ばれます。
最後の注:Rubyプログラムは、任意のマシンコードを呼び出すことはできません。 Rubiniusのその部分は、実際にはC ++で書かれています。
さて、次の順序でそれを行うことが可能です。
- 任意の言語でコンパイラを書いて、RubyコードについてCと言ってください。
- Rubyコードをコンパイルできるようになったので、Rubyコードをコンパイルするコンパイラを作成し、ステップ1に書いたCコンパイラとこのコンパイラをコンパイルできます。 この文は奇妙です!
- これからは、2に書かれたコンパイラですべてのルビーコードをコンパイルできます:)
楽しむ! :)
コンパイラは、ソースコードを実行可能ファイルに変換するものです。だから、それが何に書かれているのかは関係ありません - それはそれがコンパイルしているのと同じ言語や、十分な力の他の言語である可能性があります。
楽しみは、同じ言語で書かれたプラットフォーム用の言語のコンパイラを書いているときに起こります。ここでの選択は、コンパイラを持っている別のプラットフォームでコンパイルするか、別の言語でコンパイラを作成し、それを使用して「実際の」コンパイラをコンパイルすることです。
それは2ステップのプロセスです:
- Rubyコンパイラがまだ存在しないと仮定して、Cのような他のラナグージャージにRubyコンパイラを書く
- Rubyコンパイラを持っているので、(新しい)RubyコンパイラであるRubyプログラムを書くことができます
誰かがすでにRubyコンパイラ(MATZ)を書いたので、あなたは「ただ」2番目の部分をしなければなりません。言うよりも簡単です。
これまでのすべての回答は、別のコンパイラを使用してコンパイラをブートストラップする方法を説明しています。ただし、代替手段があります。コンパイラを手でコンパイルします。コンパイラをマシンで実行する必要がある理由はありません。人間によって実行されることもあります。