最も強力な種類のパーサーは何ですか?


28

サイドプロジェクトとして、Pythonを使用して言語を書いています。私はPlyと呼ばれるフレックス/バイソンクローンを使用することから始めましたが、そのスタイルの文法で表現できる力の限界に近づいており、インピーダンスミスマッチのために言語をハッキングすることに興味はありません。ツール。したがって、自分で書くことに嫌気はありません。

それでは、最も強力なパーサーのタイプは何ですか?論文への引用(および入門記事)も歓迎します。

(「パワフル」が正確に定義されていないことは知っていますが、少しパワフルになって、答えがどこに行くか見てみましょう)


1
ダウン投票:研究レベルではありません。
ウォーレンシューディ

3
@ウォーレン:質問する前によくある質問をチェックしました-それは要件ではないようです
ポールビガー

1
実際には2つのFAQがあります。1つは一般サイト用、もう1つはCStheory用です。CStheoryの1つは、例えばWikipediaを読むことで答えられる質問はトピックから外れていることを示しています。「どのような質問が基本的すぎますか?」を参照してください。でmeta.cstheory.stackexchange.com/questions/225/...
ウォーレンシューディ

1
@ウォーレン:それは私が読んだFAQです。ウィキペディアを読んでいましたが、これには実際の洞察が必要だと感じました。
ポールビガー

1
あなたは、生産または理論的なパーサー、つまりCFG以外の文法タイプをカバーするパーサーを意味しますか?
ラファエル

回答:


33

通常、文法はContext Free文法として定義されます-正確な定義はウィキペディアのページに記載されていますが、BLYに基づくPLYの場合と同じように機能し、Bisonyaccに基づいています。

ここでは、PLYがLALRパーサーを使用することを示しています。これは本質的に、ルックアップテーブルが圧縮されたLRパーサーであり、場合によっては構文解析の競合が発生し、LR文法(LRパーサーが解析できるコンテキストフリーの文法)の表現力の一部が低下します。パーサーのこの特定のブランチと他のパーサーのブランチの制限について知りたい場合は、すべての種類の解析手法(LL、LRなど)の概要をここに示します

あなたの質問に答えるために:言語が曖昧であっても(つまり、入力を解釈する方法が複数ある)、文脈自由言語を解析できる解析アルゴリズムが存在します:

最初のこのようなアルゴリズムはCYKアルゴリズムで、残念ながら実行時間は。ここで、nは入力文字列の長さ、| G | は文法のサイズであるため、言語の解析には実用的ではありません。O(n3|G|)n|G|

2番目のアルゴリズムはEarleyアルゴリズムです。このアルゴリズムは、文脈自由文法を解析することもできます。アルゴリズムはあいまいな言語を解析するために時間を必要としますが、あいまいな言語を解析するためにO n 2時間のみを必要とします。さらに、ほとんどのLR文法では線形時間で動作するようで、特に左再帰の文法で動作します。O(n3)O(n2)

ここでは、Earleyアルゴリズム(の適応)の実用的な実装について議論している論文を見つけることができます。「LRLR(1)解析と比較したEarley解析の一般性((おおよそPLYが行うこと))を考え、PEP((Earleyのアルゴリズムの実装)でさえ)最悪の時間はAユーザー、これは素晴らしい結果です」。

最後のタイプのパーサーはGLRパーサーです。これは、LR解析の一般化バージョンであり、コンテキストフリー言語を解析できます。

GLRの成熟した実装はASF + SDFです。BisonはGLRパーサーも生成できますが、その実装は「標準」GLRアルゴリズムとはわずかに異なります。Elkhoundアルゴリズム GLR / LALRハイブリッドアルゴリズムです。可能な場合はLALRを使用し、必要に応じてGLRを使用して、高速で文法を解析できるようにします。

文脈自由文法以外にも文脈依存文法がありますが、これらは一般に解析するのが難しく、それほど多くの表現力を追加しません。自然言語。

最終ステップとして、無制限の文法があります。この時点では、文法はチューリング完全であるため、特定の言語を解析するのにかかる時間を与えることのできる限界はありません。これは、ほとんどの解析アプリケーションにとって望ましくありません。追加の電力はほとんど必要ありません。すべての機能を使用したい場合は、使用可能な言語マシンがあります。

最後に、特に高速にするために、独自のパーサージェネレーターを実装するのは簡単なことではありません。私は個人的にflex(レクサージェネレーター)のバージョンを作成しましたが、これは比較的単純なアルゴリズムの問​​題の練習のように思えましたが、特にUnicodeをサポートしようとすると、うまくいくのは非常に複雑になりました。独自に作成するのではなく、既存の実装を使用することを検討してください。


1
素晴らしい答え!! PEGがどのように適合するかについての考えはありますか?
ポールビガー

2
PEGはCFGとは「異なります」。PEGではないCFGがあり、その逆もあります。こちらをご覧ください:stackoverflow.com/questions/1857022/…
アレックス10ブリンク


1
実際、最も一般的なパーサージェネレーター(yacc、Antlr、bison)では、1つのルールを適用できるかどうかをチェックする述語または任意のコードによって、非CFの概念を許可しています。優先順位を決定します。これは、基本的な構文が本質的にコンテキストフリーのままであるため、主に静的セマンティクスを実装するために使用できます。
ラファエル

1
再帰言語とは、まさに、チューリングマシンを常に停止することで決定できる言語です。したがって、状況依存言語も再帰的ですが、状況依存言語は指数関数的に決定できるため、状況依存ではない再帰言語もあります。無制限の文法はさらに強力です。停止する問題は無制限の文法で説明できますが、再帰的な言語ではありません。
アレックス10ブリンク

15

今年のICFP 2010での論文Total Parser Combinatorsは、証明可能な終了パーサーコンビネーターライブラリについて説明し、パーサーが終了することが保証されていることを前提として、このライブラリーで「パーサーコンビネーターは可能な限り表現力が高い」ことも確立しています。残念ながら、「可能な限り表現力のある」ことの意味について著者が説明したことは覚えていませんが、それは確かに「力」についてのあなたの質問に関連しているようです。


1
私は汚染しない車を持っています、実際にはそれも動きません...だから問題は:どのような言語がこのライブラリーによって解析されるのですか?もちろん、この作品が面白くないという意味ではありません。
babou

2

プログラミング言語の構文解析のための文脈自由文法を超えたいが、まだ多項式時間で構文解析したい場合、式文法、またはブール文法の構文解析に頼ることができます-後者はLLおよびLRフレーバーでも利用可能です(こちらを参照)。形式言語理論では、強力でありながら線形時間で認識できるチャーチロッサー言語も研究されていますが、これらのパーサージェネレーターが実装されていることは知りません。

自然言語処理では、たとえば、あいまいさ(固有のあいまいさ)を扱うなど、好みが異なり、自由語の順序が非常に重要な役割を果たします。ここでは、キーワードがやや状況依存言語であり、オートマトン再起動すると、読み始めるのに役立ちます。


1
質問の質問方法と、CFの制約が大きすぎるという不満を考慮すると、答えは明らかに最高です。だから
...-babou

0

パーサージェネレーターツール:

ANTLRは非常に優れています。または、JavaCCを見ることができます


私はコンピューター科学者ではないので(私の学位は何と言っても;)、ここで私の言葉の重みを軽くするかもしれません。Sazzadに同意します-ANTLRは非常に強力なツールです。これは非常に完全であり、パーサージェネレーターに関する問題はまだ見つかっていません(正しくリコールした場合はLL(k))。一方、私は...やや複雑な文法のためのコンパイラを実装するためには至っていない
ヨルゲンSigvardsson

5
あなたは質問のポイント、そしておそらくサイト全体を見逃していると思います。実装とツールではなく、理論の解析に関するものです。
ポールビガー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.