Ruby で書かれたコンパイラを使用してバイトコードにコンパイルする Ruby 実装であるRubiniusを見ていました。私はこれについて頭を悩ませることができません。言語自体で言語のコンパイラをどのように作成しますか? Ruby で書かれた将来のコードをコンパイルできる実行可能ファイルにコンパイルするための何もない単なるテキストのようです。その文を入力するだけで混乱します。誰でもこれを説明できますか?
7 に答える
簡単にするために、最初にコンパイラー用のコンパイラーを別の言語で作成します。次に、コンパイラをコンパイルします。
したがって、すでにコンパイラーを備えたある種の言語が必要ですが、そのような言語はたくさんあるので、たとえば C で Ruby コンパイラー コンパイラー (!) を書くことができます。それ自体のさらに別のバージョン。
もちろん、元のコンパイラは機械語で書かれ、アセンブリ用にコンパイルされたコンパイラであり、C や Fortran などのコンパイラをコンパイルし、ほとんどすべてのコンパイラをコンパイルしました。実際の反復開発。
このプロセスはブートストラップと呼ばれます- おそらくミュンヒハウゼン男爵が自分のブートストラップで沼から抜け出したという話にちなんで名付けられました :)
コンパイラのブートストラップに関しては、この非常に巧妙なハックについて読む価値があります。
その文を読んだだけで混乱してしまいます。
コンパイラーは、しばしば呼ばれるトランスレーターと考えるとわかりやすいかもしれません。その目的は、人間が読み取ることができるソース コードを取得し、それをコンピューターが読み取ることができるバイナリ コードに変換することです。Rubinius の場合、読み取るコードはたまたま Ruby コードであり、それを変換するコードはマシン コードです (実際には、それ自体が Intel マシン コードにさらにコンパイルされる LLVM マシン コードですが、それは単なる背景の詳細です)。 . Rubinius 自体は、ほぼすべてのプログラミング言語で記述できた可能性があります。たまたま、コンパイルするのと同じ言語で書かれていました。
もちろん、最初に Rubinius を実行するための何かが必要です。これはおそらく通常の Ruby インタープリターです。ただし、インタープリターで Rubinius を実行できるようになったら、それ自体のソース コードを渡すことができ、それ自体のコンパイル済みバージョンを作成して実行することに注意してください。これは、「ブートストラップで自分を引き上げる」という古い言い回しから、ブートストラップと呼ばれます。
最後に、Ruby プログラムは任意のマシン コードを呼び出すことはできません。Rubinius のその部分は、実際には C++ で書かれています。
これは2ステップのプロセスです。
- Rubyコンパイラがまだ存在しないと仮定して、Cなどの他の言語でRubyコンパイラを記述します。
- これでRubyコンパイラーができたので、(新しい)RubyコンパイラーであるRubyプログラムを作成できます。
誰かがすでにRubyコンパイラ(Matz)を書いているので、あなたは「ただ」2番目の部分をする必要があります。言うのは簡単です。
次の順序でそれを行うことができます。
- Ruby コードの C など、任意の言語でコンパイラを記述します。
- Ruby コードをコンパイルできるようになったので、Ruby コードをコンパイルするコンパイラーを作成し、このコンパイラーをステップ 1 で作成した C コンパイラーでコンパイルします。
- これからは、すべての Ruby コードを 2 で書かれたコンパイラでコンパイルできます。:)
楽しむ!:)
コンパイラは、ソース コードを実行可能ファイルに変換するものです。したがって、それが何で書かれているかは問題ではありません。コンパイルしている言語と同じ言語でも、十分な能力を持つ他の言語でもかまいません。
楽しいのは、同じ言語で書かれたプラットフォーム用の言語用のコンパイラを書いているときに、実装言語用のコンパイラがまだない場合です。ここでの選択肢は、コンパイラがある別のプラットフォームでコンパイルするか、別の言語でコンパイラを作成し、それを使用して「実際の」コンパイラをコンパイルすることです。
これまでの回答はすべて、別のコンパイラを使用してコンパイラをブートストラップする方法を説明しています。ただし、別の方法があります。コンパイラを手動でコンパイルすることです。コンパイラがマシンによって実行されなければならない理由はありません。人間によって実行されてもかまいません。