web-dev-qa-db-ja.com

元のインタープリターから独立した「ブートストラップ」インタープリターを作成することは可能ですか?

Wikipediaによると、コンパイラの記述における「ブートストラップ」という用語はこれを意味します

コンピュータサイエンスでは、ブートストラップは、コンパイルするつもりのソースプログラミング言語でコンパイラ(またはアセンブラ)を記述するプロセスです。この手法を適用すると、セルフホスティングコンパイラが作成されます。

そして、それがどのように機能するか理解できます。ただし、通訳者の話は少し違うようです。もちろん、セルフホスティングのインタープリターを作成することも可能です。それは私が求めていることではありません。私が実際に求めているのは:セルフホストのインタープリターを元の最初のインタープリターから独立させることは可能ですか。私が何を意味するのかを説明するために、この例を考えてみましょう:

最初のインタープリターバージョンを言語[〜#〜] x [〜#〜]で記述し、インタープリターが作成する新しい言語用である[〜#〜] y [〜#〜]と呼ばれます。最初に言語[〜#〜] x [〜#〜]のコンパイラを使用して実行可能ファイルを作成します。新しい言語[〜#〜] y [〜#〜]で書かれたファイルを、言語[〜#〜] x [〜#〜]

今、私が理解している限り、言語で記述したインタプリタを「ブートストラップ」できるようにするには[〜#〜] x [〜#〜] 、インタプリタを言語で書き直す必要があります[〜#〜] y [〜#〜]。しかし、ここで問題があります。インタプリタ全体を言語[〜#〜] y [〜#〜]で書き換えたとしても、言語で記述した元のインタープリター[〜#〜] x [〜#〜]が必要になります。言語[〜#〜] y [〜#〜]でインタープリターを実行するため、ソースファイルを解釈する必要があります。しかし、ソースファイルを正確に解釈するにはどうすればよいでしょうか。もちろん、それは何もないわけではないため、最初のインタープリターを引き続き使用する必要があります。

言語で新しいインタープリターをいくつ書いても[〜#〜] y [〜#〜]、常に使用する必要があります[〜#〜] x [〜#〜]で記述された最初のインタープリターは、後続のインタープリターを解釈します。これは単に通訳者の性質のために問題のようです。

ただし、反対に このWikipediaのインタープリターに関する記事では、実際にセルフホスティングインタープリターについて説明しています 。以下は、関連する小さな抜粋です。

セルフインタープリターは、自分自身を解釈できるプログラミング言語で書かれたプログラミング言語インタープリターです。例は、BASICで書かれたBASICインタプリタです。セルフインタープリターは、セルフホスティングコンパイラーに関連しています。

言語を解釈するコンパイラが存在しない場合、セルフインタープリターを作成するには、ホスト言語(別のプログラミング言語またはアセンブラーである可能性があります)で言語を実装する必要があります。このような最初のインタープリターを持つことで、システムはブートストラップされ、インタープリターの新しいバージョンを言語自体で開発できます。

しかし、それがどのように行われるのかはまだはっきりしていません。どうしても、ホスト言語で書かれた最初のバージョンのインタープリターを使用せざるを得ないようです。

さて、上記の記事 Wikipediaが想定しているセルフホスティングインタープリターのいくつかの例を示している別の記事へのリンク 。しかし、よく調べてみると、これらのセルフホスティングインタープリターの多くの主な「解釈」部分(特にPyPyやRubiniusなどのより一般的なもの)は、実際にはC++やCなどの他の言語で書かれているようです。

それで、私が上で説明したことは可能ですか?セルフホストのインタープリターは元のホストから独立できますか?もしそうなら、これはどのように正確に行われますか?

21
Christian Dean

セルフホスティングインタープリターはそれ自体を実行するためにインタープリターを必要とし、コンパイラーと同じ意味でブートストラップできないことに注意するのは正しいことです。

ただし、自己ホスト型languageは、自己ホスト型インタープリターと同じものではありません。通常、コンパイラを構築するよりもインタープリタを構築する方が簡単です。したがって、新しい言語を実装するには、まず、無関係な言語でインタープリターを実装することがあります。次に、そのインタープリターを使用して、言語用のコンパイラーを開発できます。コンパイラが解釈されるため、言語は自己ホストされます。その後、コンパイラーはそれ自体をコンパイルし、完全にブートストラップされたと見なすことができます。

この特殊なケースは、セルフホスティングJITコンパイルランタイムです。ホスト言語のインタープリターから開始でき、新しい言語を使用してJITコンパイルを実装します。その後、JITコンパイラーはそれ自体をコンパイルできます。これは、セルフホスティングインタープリターのように感じますが、無限インタープリターの問題を回避します。このアプローチが使用されますが、まだあまり一般的ではありません。

関連するもう1つの手法は、解釈可能な言語で拡張機能を作成できる拡張可能なインタープリターです。たとえば、新しいオペコードを言語で実装する場合があります。これにより、循環依存を回避する限り、必要最小限のインタープリターを機能豊富なインタープリターに変えることができます。

実際にかなり一般的に発生するのは、言語が独自の構文解析に影響を与える能力です。解析時に評価されるマクロとして。マクロ言語は処理される言語と同じであるため、専用または制限付きのマクロ言語よりもはるかに機能が豊富になる傾向があります。ただし、拡張を実行する言語は、拡張後の言語とは少し異なる言語であることに注意してください。

「実際の」自己ホスト型通訳が使用される場合、これは通常、教育または研究の理由で行われます。例えば。 Scheme内にSchemeのインタプリタを実装することは、プログラミング言語を教えるためのクールな方法です(SICPを参照)。

7
amon