コンテキストフリーのグラマーから左の再帰を削除 - 非ターミナルの注文
-
16-10-2019 - |
質問
私は最近、コンテキストのない文法から左翼回復を削除するためのPaullのアルゴリズムを実装しました。
文法の非ターミナルに注文$ a_1、 dots、a_n $を割り当てます。
$ i:= 1 $ to $ n $ for begin
$ quad $ for $ j:= 1 $ to $ i-1 $ do begin
$ quad quad $ form form of form $ a_i to a_j alpha $ do begin $ a_i
$ quad quad quad $削除$ a_i にa_j alpha $を文法から削除します
$ quad quad quad $ form form for for for $ a_j to beta $ do begin
$ quad quad quad quad $ add $ a_i to beta alpha $ to the Grammar
$ quad quad quad $ end
$ quad quad $ end
$ quad $ end
$ quad $ $ a_i $ -productionsを変換して、直接左の再帰を排除します
終わり
によると このドキュメント, 、アルゴリズムの効率は、最初に選択された非ターミナルの順序に大きく依存します。この論文では、この問題について詳しく説明し、最適化を提案しています。
いくつかの表記:
シンボル$ x $は 直接左隅 右側に左端のシンボルとして$ x $の$ a $ -Productionがある場合、非ターミナル$ a $の場合。を定義します 左コーナー関係 直接的な左コーナー関係の反射的な推移的閉鎖であるため、 適切な左角の関係 直接的な左コーナー関係の推移的閉鎖になること。非ターミナルはです 左再帰 それがそれ自体の適切な左隅である場合;非ターミナルはです 直接左再帰 それがそれ自体の直接左隅である場合;そして非ターミナルはです 間接的に再帰的な左 再帰的なままになっているが、直接再帰的なままになっていない場合。
著者が提案するものは次のとおりです。
Paullのアルゴリズムの内側ループでは、非ターミナル$ a_i $および$ a_j $の場合、$ i> j $および$ a_j $が$ a_i $の直接左隅になり、$ a_j $のすべての出来事を直接として置き換えます$ a_i $の左隅が$ a_j $のすべての可能な拡張を備えています。
これは、$ a_i $が左再帰的な非ターミナルであり、$ a_j $が$ a_i $を再帰的にするパスにある場合、文法からの左再帰の排除にのみ貢献します。つまり、$ a_i $が$ a_j $の左コーナーである場合($ a_j $が$ a_i $の左コーナーであることに加えて)。
文法の非ターミナルを注文できる場合、左の再帰を削除するのに役に立たない交換を排除することができます。 $ a_j $の左隅。
これを達成することができます。非ターミナルに、それらが持っている明確な左隅の数の減少順序で注文することができます。
左コーナーの関係は推移的であるため、CがBの直接左隅である場合、Cのすべての左隅もBの左隅です。
さらに、左コーナーの関係を反射的であると定義したため、Bはそれ自体の左隅です。
したがって、CがBの直接左隅である場合、BがCの左隅でない限り、異なる左角の数の減少順序でBを追跡する必要があります。
私が欲しいのは、最初に非ターミナルを注文する方法を知ることだけですが、私はそれを紙から得ません。誰かがそれをより簡単に説明できますか? Pseudocodeは私がそれをよりよく理解するのに役立ちます。
解決
これは実際にはそれほど複雑ではありません。 Epsilon Productionsはすでに言語から排除されていると仮定します。なぜなら、それは「左隅」の重要な概念を曖昧にするだけだからです。
頂点がすべて文法の非端子であるグラフGを形成します。 「A-> b [...]」のように見える生産ルールがある場合、AからBへの指向的なエッジを描画します。このペーパーは、Aの「直接左隅」をAと呼びます。より一般的には、このグラフのエッジに沿ってAからCまでのパスがある場合、他の非末端CはAの「左隅」と呼ばれます。これは、計算することで実行できます 推移的閉鎖 Gの、それをHと呼びます。
このペーパーでは、各頂点Aに左角の数を数えることで頂点を注文することをお勧めします(つまり、グラフhのaから到達できる他の非ターミナル、またはaの程度aの程度)、次にそれらを減少して並べ替えますこの番号によって。
このポリシーの手波の動機の1つは、他の多くのシンボルとの接続を持つ重要な非ターミナル(スタート記号など)がある場合、早くから左再帰をパージすることは理にかなっていることです。後で拡張する必要があるSのコピーが増えます。論文の説明はより説得力があると思いますが、おそらくそれほど明白ではありません。