web-dev-qa-db-ja.com

現代の言語はまだパーサージェネレーターを使用していますか?

これが出てきたとき、私はwikipediaのgccコンパイラスイートについて調査していた here

GCCは、Bisonで生成されたLALRパーサーの使用を開始しましたが、次第に手書きの再帰下降パーサーに切り替えました。 2004年のC++、および2006年のCおよびObjective-Cの場合。現在、すべてのフロントエンドは手書きの再帰降下パーサーを使用しています。

つまり、その最後の文までに(そして私がWikipediaを信頼している限り)、C(gcc)、C++(g ++)、Objective-C、Objective-C++、Fortran(gfortran)、Java(gcj)、Ada(GNAT)、Go(gccgo)、Pascal(gpc)、... Mercury、Modula-2、Modula-3、PL/I、D(gdc)、およびVHDL(ghdl ) "はすべて、パーサージェネレーターを使用しなくなったすべてのフロントエンドです。つまり、すべて手書きパーサーを使用しています。

私の質問は、この慣習はどこにでもあるのですか?具体的には、[Python、Swift、Ruby、Java、Scala、ML、Haskell]の「xの標準/公式実装には、手書きのパーサーがありますか」に対する正確な答えを探しています。 (実際、他の言語の情報もここで歓迎されます。)たくさんの調査の結果、私は自分でこれを見つけることができると確信しています。しかし、これはコミュニティによって簡単に答えられると確信しています。ありがとう!

38
eatonphil

私の知る限り、GCCは特に手書きのパーサーを使用して、構文エラーの診断を改善します(つまり、構文エラーに関する人間に意味のあるメッセージを提供します)。

解析理論(およびそれから派生する解析ジェネレータ)は、correct入力フレーズを認識して解析することを主な目的としています。しかし、コンパイラーは、いくつかの誤った入力に対して、意味のあるエラーメッセージを表示する(そして、構文エラーの後に残りの入力を意味のある形で解析できる)ことを期待しています。

また、C11やC++ 11などの古いレガシー言語(最新のリビジョンが3年前であっても概念的には古い)は、まったく文脈自由ではありません。パーサージェネレーター(つまり bison または menhir )の文法でその状況依存性に対処するのは、退屈なほど困難です。

34

パーサージェネレーターとパーサーエンジンは非常に一般的です。一般性の利点は、全体的なスキームにおいて、正確なパーサーをすばやく構築して機能させるのが簡単なことです。

パーサーエンジン自体は、その一般性のためにパフォーマンスの面で問題があります。手書きのコードは、常にテーブル駆動のパーサーエンジンよりもはるかに高速です。

パーサージェネレーター/エンジンが困難な2番目の領域は、実際のプログラミング言語はすべて状況依存であり、多くの場合非常に微妙な点にあります。 LR言語はコンテキストフリーです。つまり、位置付けと環境について、構文で適切に伝えることができない微妙な点が数多くあります。属性グラマーは、「使用前に宣言する」などの基本的な言語規則に対処しようとします。この状況依存性を手書きのコードに配線するのは簡単です。

7
BobDalgleish