102

言語をブートストラップする、つまり、言語自体のコンパイラ/インタプリタを作成するという考えを聞いたことがあります。どうやってこれを達成できるのだろうと思って、少し周りを見回したところ、誰かがそれはどちらかによってのみ行うことができると言っているのを見ました

  • 別の言語で最初のコンパイラを作成します。
  • アセンブリで最初のコンパイラをハンドコーディングします。これは、最初のコンパイラの特殊なケースのようです。

私には、どちらも外部サポートを必要とするという意味で、実際に言語をブートストラップしているようには見えません。実際に独自の言語でコンパイラを作成する方法はありますか?

4

11 に答える 11

111

実際に独自の言語でコンパイラを作成する方法はありますか?

新しいコンパイラを作成するは、既存の言語が必要です。たとえば、C++ コンパイラを新しく作成する場合は、C++ で作成し、まず既存のコンパイラでコンパイルします。一方、新しい言語用のコンパイラを作成する場合、それを Yazzleof と呼びましょう。最初に別の言語で新しいコンパイラを作成する必要があります。通常、これは別のプログラミング言語になりますが、そうである必要はありません。アセンブリ、または必要に応じてマシン コードにすることができます。

Yazzleof 用のコンパイラをブートストラップする場合、通常、最初に完全な言語用のコンパイラを作成することはありませ。代わりに、Yazzleof の可能な限り最小のサブセットである Yazzle-lite 用のコンパイラを作成します (まあ、少なくともかなり小さなサブセットです)。次に、Yazzle-lite で、完全な言語用のコンパイラを作成します。(明らかに、これは 1 回のジャンプではなく反復的に発生する可能性があります。) Yazzle-lite は Yazzleof の適切なサブセットであるため、これで、それ自体をコンパイルできるコンパイラーができました。

Bootstrapping a simple compiler from nothingというタイトルの、可能な限り低いレベル (最新のマシンでは基本的に 16 進エディター) からのコンパイラーのブートストラップに関する非常に優れた記事あります。https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.htmlにあります。

于 2008-08-17T07:20:55.103 に答える
20

あなたが読んだ説明は正しいです。Compilers: Principles, Techniques, and Tools (the Dragon Book)でこれについての議論があります:

  • 言語 Y で言語 X のコンパイラ C1 を作成する
  • コンパイラ C1 を使用して、言語 X で言語 X 用のコンパイラ C2 を記述します。
  • 現在、C2 は完全なセルフ ホスティング環境です。
于 2008-08-17T07:00:39.310 に答える
8

これに関する非常に興味深い議論は、Unix の共同作成者であるKen Thompsonチューリング賞の講演にあります。

彼は次のように始めます。

これから説明することは、コンパイラが独自の言語で記述されたときに発生する多くの「鶏が先か卵が先か」の問題の 1 つです。ここでは、C コンパイラの特定の例を使用します。

そして、C コンパイラがログイン プログラムを認識して特別なコードを追加するため、常にパスワードなしでログインできるバージョンの Unix C コンパイラをどのように作成したかを示します。

2 番目のパターンは、C コンパイラを対象としています。置換コードは、両方のトロイの木馬をコンパイラに挿入するステージ I の自己再生プログラムです。これには、ステージ II の例のように学習フェーズが必要です。まず、修正したソースを通常の C コンパイラでコンパイルして、バグのあるバイナリを生成します。このバイナリを公式の C としてインストールします。コンパイラのソースからバグを削除できるようになり、新しいバイナリはコンパイルされるたびにバグを再挿入します。もちろん、login コマンドにはバグが残っており、ソースのどこにもトレースがありません。

于 2008-08-17T07:07:05.037 に答える
6

私が聞いた方法は、非常に制限されたコンパイラを別の言語で作成し、それを使用して、新しい言語で作成されたより複雑なバージョンをコンパイルすることです。この 2 番目のバージョンを使用して、それ自体と次のバージョンをコンパイルできます。コンパイルされるたびに、最後のバージョンが使用されます。

これはブートストラップの定義です:

同じ目的を果たすより複雑なシステムを起動する単純なシステムのプロセス。

編集:コンパイラのブートストラップに関するウィキペディアの記事は、私よりも優れた概念をカバーしています。

于 2008-08-17T07:00:23.787 に答える
4

Check out podcast Software Engineering Radio episode 61 (2007-07-06) which discusses GCC compiler internals, as well as the GCC bootstrapping process.

于 2009-05-20T09:29:29.450 に答える
4

Donald E. Knuthは、コンパイラを記述してWEBを実際に構築し、アセンブリ コードまたはマシン コードに手作業でコンパイルしました。

于 2011-08-10T14:56:40.810 に答える
3

私が理解しているように、最初のLispインタープリターは、コンストラクター関数とトークンリーダーを手動でコンパイルすることによってブートストラップされました。その後、インタプリタの残りの部分がソースから読み込まれました。

元のマッカーシーの論文、記号式の再帰関数と機械によるそれらの計算、パートIを読むことで、自分自身を確認できます。

于 2011-07-09T19:54:17.183 に答える
2

もう 1 つの方法は、言語用のバイトコード マシンを作成し (または、機能がそれほど珍しいものでない場合は既存のマシンを使用して)、バイトコードまたは別の中間体を使用して目的の言語でバイトコードにコンパイラを記述することです。 AST を XML として出力し、XSLT (または別のパターン マッチング言語とツリーベースの表現) を使用して XML をバイトコードにコンパイルするパーサー ツールキット。別の言語への依存が取り除かれるわけではありませんが、ブートストラップ作業の多くが最終的なシステムで終了することを意味する可能性があります。

于 2008-08-17T13:21:16.500 に答える
2

私が考えることができる言語(CPyPy)のブートストラップのすべての例は、動作するコンパイラがあった後に行われました。どこかから始める必要があり、言語自体を再実装するには、最初に別の言語でコンパイラを作成する必要があります。

他にどのように機能しますか?それ以外の方法で行うことは概念的にも不可能だと思います。

于 2008-08-17T07:01:08.340 に答える
2

これは、ニワトリが先か卵が先かのパラドックスのコンピューター サイエンス バージョンです。初期コンパイラをアセンブラやその他の言語で書かない方法は考えられません。それができたなら、私は Lisp ができたはずです。

実際、私は Lisp がほとんど資格を持っていると思います。ウィキペディアのエントリを確認してください。この記事によると、Lisp eval 関数は機械語でIBM 704に実装でき、完全なコンパイラ (Lisp 自体で記述) は 1962 年にMITで作成されました。

于 2008-08-17T07:06:30.577 に答える
0

一部のブートストラップ コンパイラまたはシステムは、ソース フォームとオブジェクト フォームの両方をリポジトリに保持します。

  • ocamlは、バイトコード インタープリター (つまり、Ocaml バイトコードへのコンパイラー) とネイティブ コンパイラー (x86-64 または ARM などへのアセンブラー) の両方を持つ言語です。その svn リポジトリには、コンパイラのソース コード (ファイル*/*.{ml,mli}) とバイトコード (ファイル) 形式の両方が含まれています。boot/ocamlcしたがって、ビルドするときは、最初に (以前のバージョンのコンパイラの) バイトコードを使用してそれ自体をコンパイルします。その後、新しくコンパイルされたバイトコードは、ネイティブ コンパイラをコンパイルできます。したがって、Ocaml svn リポジトリには、*.ml[i]ソース ファイルとboot/ocamlcバイトコード ファイルの両方が含まれます。

  • Rustコンパイラは ( を使用するため、インターネット接続が必要です) バイナリの以前のバージョンをダウンロードして、wgetそれ自体をコンパイルします。

  • MELTはGCCをカスタマイズおよび拡張するための Lisp に似た言語です。ブートストラップ トランスレータによって C++ コードに変換されます。トランスレータの生成された C++ コードは配布されるため、svn リポジトリにはトランスレータの*.meltソース ファイルとmelt/generated/*.cc「オブジェクト」ファイルの両方が含まれます。

  • J.Pitrat のCAIA人工知能システムは完全に自己生成型です。これは、数千のデータ ファイルのコレクションを含む、数千の[A-Z]*.c生成されたファイル (生成されたdx.hヘッダー ファイルも含む) のコレクションとして利用できます。_[0-9]*

  • いくつかの Scheme コンパイラもブートストラップされます。Scheme48、チキンスキーム、...

于 2015-05-01T08:16:01.393 に答える