2013-02-06 2 views
7

でLLVM JITパーサーを書くLLVM tutorialsには単純なJITコンパイラを書く方法があります。このチュートリアルのUnfortunatelly、lexer、parserは手作業で書かれています。私は、このようなソリューションは学習目的には良いと思っていましたが、複雑で生産準備が整ったコンパイラを書くのには適していません。 GCCや他のいくつかの "ビッグコンパイラ"が手書きで書かれているようです。しかし、私は、これらすべてのパーサジェネレータは、独自のコンパイラを書くときに大きな助長を与えると思います(特に、あなたがチームを持たずに単独でそれをやっているとき)。Bison/Antlr/Packrat/Elkhound/

Bison/Antlr/Packrat/Elkhoundなどの既存のパーサージェネレータをLLVMとともに使用してJITコンパイラを作成することはできますか?私は式を使ってパーサーに常に(一度ではなく)「フィード」し、実行時にコンパイルできるようにしたい。

追加 "私は、最高の現代的な"パーサジェネレータ(このようなもの:https://stackoverflow.com/questions/428892/what-parser-generator-do-you-recommend)について多くの質問を見つけました。これらのツールを使用してLLVM JITコンパイラを作成することができれば、この特定のケースでパフォーマンスと柔軟性の点で最も優れたヒントや推奨事項があれば感謝します。

+0

"このようなソリューションは学習目的には適していますが、複雑で生産準備が整ったコンパイラを書くのには適していません。私はいつもGCCは複雑で生産準備が整ったコンパイラだと思っていました。何でも... –

+0

GCCは最初はバイソンを使っていましたが、あなたは正しいです - 私は私の質問でそれを修正しています。しかし、実際には、可能であれば、この作業を簡単にするためにジェネレータを使用したいと考えています。 –

+5

yacc、Bison、et alは、学習目的などには適していますが、深刻な制作作業では手書きパーサーが要件を満たす唯一の方法かもしれません。 –

答えて

9

bisonやantlrのようなパーサジェネレータを使用すると、特に言語を開発する際に多くの利点があります。間違いなく、文法を変更することになるでしょう。最終的な文法の文書を手に入れたいと思うでしょう。ドキュメントから自動的に文法を生成するツールは本当に便利です。彼らはまた、言語の文法が(a)あなたが思っているものと(b)あいまいではないという自信を与えるのに役立ちます。

あなたの言語が実際にLALR(1)以上、LL(1)であり、LLTツールを使用してASTとIRを構築している場合は、実行する必要はないでしょう文法を書き留めて、ASTを構築するための簡単なアクションをいくつか提供するだけではありません。それはしばらくあなたを続けるでしょう。

「実際のプログラマーがパーサージェネレーターを使用していない」以外に、人々が最終的に独自のパーサーを構築する通常の理由は、構文エラー、特にLR(1)で良い診断を提供することは容易ではないということです。 )解析。それがあなたの目標の1つであれば、あなたは文法LL(k)を解析可能にしようとするべきです(LL(k)で良い診断を提供するのは簡単ではありませんが、 Antlrのようなフレームワーク。

診断を提供しようとしてもなく、LL(1)よりも柔軟性の高いLALR(1)パーサーを使用して、プログラムテキストをできるだけ簡単に解析する戦略があります。解析が失敗した場合、ASTの生成方法はわかりませんが、ソースの場所を追跡して構文エラーから回復しようとする、遅い、場合によっては逆戻りするパーサを使用して再度解析することができます。 ASTを無効にすることなく構文エラーから回復することは、解析を続けることよりもさらに困難です。試してはいけないと言われることはたくさんあります。また、ソースの位置を追跡することは本当に遅く、診断を生成する必要がない場合(デバッグアノテーションを追加する必要がない場合)はあまり役に立ちません。そのため、解析をかなり高速化することができますロケーショントラッキング。

個人的には、私はPEGによって解析された実際の言語が何であるかはっきりしないので、パックラーの解析に偏っています。他の人はそれほど気にしないし、YMMV。

+1

なぜ実際の言語は「不明」であるのですか? PEGはよく定義されていますが、パックラットが行うことができるすべてのクールなハック(高次の解析など)でさえも、よく定義されています。 –

+1

@ SK-logic:明確に定義されたものは明確ではありません。 C++で書かれた手作りのパーサーは、よく定義されています。チューリングマシンは明確に定義されています。はい、PEGは明確に定義されています。しかし、それらのすべてについて、指定された文字列が言語内にあるかどうかを確認する唯一の方法は、コードを実行することです。 (これらの3つの選択肢のうち、PEGは最も悪いものではありませんが、私はまだ正式な文脈自由文法を好んでいますが、私が言ったように、PEGのような他の人たちはあなたのために働くものは私には涼しいです。) – rici

+0

私の実践的な経験からPEGは最も明確で読みやすい文法です。言語仕様を少しでも変更してPEGに変換することができます。それはもちろん、難読化することは可能ですが、私は本当に悪い文法をまだ見ていません。希望のYacc文法を超えて多くのものが読めない。 –