web-dev-qa-db-ja.com

CはCで書かれていますが、これはどのようにして可能ですか?

可能性のある複製:
最初のC++コンパイラをC++で作成するにはどうすればよいですか?

私の質問は、言語が生まれる地下の銀河の洞窟に行き、ラムダ数学と光年のグーグル研究が関係していることを知っています。しかし、言語を作成するにはどのような知識が必要ですか?

41
H_7

「ブートストラップ」を検索します。

基本的には、少しだけ機能的なコンパイラを定義するコードをコンパイルするために使用できる最小限のプロセス/関数セットから始めます。これにより、次のコンパイラーが作成され、さらに多くのことができるコードをビルドするために使用できます。すべての言語機能をコンパイルできる本格的なコンパイラができるまで、このプロセスを繰り返します。

もう1つの方法は、コンパイラの最初のバージョンを別の言語で記述してから、次のバージョンをターゲット言語で記述することです。

77
ChrisF

ChrisFの答えは素晴らしいですが、ブートストラップに関するコンピューターサイエンスコースの後でいつも私が行き詰まるこの例を追加したいと思いました。

文字列のエスケープコードをまだサポートしていない基本的なCコンパイラがあり、それを追加したいとします。次のようなコードスニペットを追加できます。

if( str[i] == 0x5c ) {       // ASCII code for backslash
   switch( str[i+1] ) {
      case 'n': return 0x0a; // ASCII code for new line
      case 't': return 0x09; // ASCII code for tab
      // ...                 // more ASCII code for other escapes
      default: return str[i+1];
   }
}

これをコンパイラに追加し、新しいコンパイラバイナリを生成したら、これを次のように書き換えることができます。

if( str[i] == '\\' ) { 
   switch( str[i+1] ) {
      case 'n': return '\n';
      case 't': return '\t';
      // ...
      default: return str[i+1];
   }
}

これにより、ASCIIコードに関する知識がコンパイラのソースコードから削除されますが、コンパイラは依然として魔法のように正しいコードを生成します。

22
fishinear

ブートストラップは、今日のコンパイラを構築する標準的な方法です。しかし、言語でプログラムを書くためにコンパイラやインタプリタは必要ないことを覚えておいてください。たとえば、Christopher Stracheyは、CPLでチェッカーを再生できる有名なAIプログラムを作成しました CPLのコンパイラが存在する前 。彼はプログラムを "手動で"マシンコードに変換する必要がありましたが、これは面倒でエラーが発生しやすくなりますが、それほど難しくはありません(そのため、コンピューターは非常にうまく機能します)。

18
nikie

これがトピックから外れていないことを願っていますが、1つのプラットフォームXに対して1つのCコンパイラを用意したら、クロスコンパイルを使用して他のプラットフォームのブートストラップを実行できることを指摘しておきます。

  • アーキテクチャX上で実行されるアーキテクチャX用のCコンパイラc1があります。
  • Cで書かれたアーキテクチャY用のCコンパイラc2を作成します。
  • Xでコンパイラc2をc1を使用してコンパイルし、Xで実行されるコンパイラc2のバイナリを取得します。
  • Xで実行されるc2のバイナリを使用してそれ自体をコンパイルし、Yで実行されるc2のバイナリを取得します。

つまり、最初の卵を手に入れれば、より多くの卵を作るのは簡単です。

10
Giorgio