web-dev-qa-db-ja.com

文法がLL(1)、LR(0)、またはSLR(1)かどうかを識別する方法

文法がLL(1)、LR(0)、またはSLR(1)かどうかをどのように識別しますか?

誰でもこの例を使用して、または他の例を使用して説明できますか?

X→Yz | a

Y→bZ | ε

Z→ε

59

文法がLL(1)かどうかを確認するための1つのオプションは、LL(1)解析テーブルを構築し、競合をチェックすることです。これらの競合は

  • FIRST/FIRSTの競合。非端末/端末ペアに対して2つの異なる生成を予測する必要があります。
  • FIRST/FOLLOW競合。2つの異なるプロダクションが予測されます。1つは何らかのプロダクションを取得してゼロ以外の数のシンボルに展開することを表し、もう1つはプロダクションを使用して非ターミナルを最終的に展開することを示すことを表します空の文字列。
  • FOLLOW/FOLLOWの競合。2つのプロダクションで、非終端文字が最終的に空の文字列に展開されることを示す場合、競合します。

文法でこれを試してみましょう。各非終端記号のFIRSTおよびFOLLOWセットを作成します。ここで、私たちはそれを得る

FIRST(X) = {a, b, z}
FIRST(Y) = {b, epsilon}
FIRST(Z) = {epsilon} 

また、次のセットが

FOLLOW(X) = {$}
FOLLOW(Y) = {z}
FOLLOW(Z) = {z}

これから、次のLL(1)解析テーブルを作成できます。

    a    b    z   $
X   a    Yz   Yz  
Y        bZ   eps
Z             eps

この解析テーブルは競合することなく構築できるため、文法はLL(1)です。

文法がLR(0)またはSLR(1)であるかどうかを確認するには、まず、文法のすべてのLR(0)構成セットを構築します。この場合、Xが開始記号であると仮定すると、次のようになります。

(1)
X' -> .X
X -> .Yz
X -> .a
Y -> .
Y -> .bZ

(2)
X' -> X.

(3)
X -> Y.z

(4)
X -> Yz.

(5)
X -> a.

(6)
Y -> b.Z
Z -> .

(7)
Y -> bZ.

このことから、状態(1)および(6)にshift/reduceの競合があるため、文法がLR(0)ではないことがわかります。具体的には、縮小アイテムZ→があるためです。およびY→。、空の文字列をこれらの記号に減らすか、他の記号にシフトするかを判断できません。より一般的には、ε-生成の文法はLR(0)ではありません。

ただし、この文法はSLR(1)である場合があります。これを確認するために、特定の非終端記号に対して先読みセットを使用して各リダクションを強化します。これにより、このSLR(1)構成セットのセットが返されます。

(1)
X' -> .X
X -> .Yz [$]
X -> .a  [$]
Y -> .   [z]
Y -> .bZ [z]

(2)
X' -> X.

(3)
X -> Y.z [$]

(4)
X -> Yz. [$]

(5)
X -> a.  [$]

(6)
Y -> b.Z [z]
Z -> .   [z]

(7)
Y -> bZ. [z]

現在、シフトとリデュースの競合はもうありません。先読みがzの場合にのみ削減するため、状態(1)の競合は解消されました。これは、他の項目と競合しないためです。同様に、(6)の競合も同じ理由でなくなりました。

お役に立てれば!

95
templatetypedef

FIRST/FIRSTの競合およびFIRST/FOLLOWの競合がない場合、文法はLL(1)です。

FIRST/FIRSTの競合の例:

S -> Xb | Yc
X -> a 
Y -> a 

最初の入力シンボルaだけを見ると、aがXとYの両方の最初のセットにあるため、プロダクションS-> XbまたはS-> Ycを適用するかどうかを知ることができません。

FIRST/FOLLOW競合の例:

S -> AB 
A -> fe | epsilon 
B -> fg 

最初の入力シンボルfのみを見ると、fがAの最初のセットとAのフォローセットの両方にあるため、プロダクションA-> feまたはA->イプシロンを適用するかどうかを決定できません(Aはイプシロンとして解析できます)およびB)f)。

イプシロンプロダクションがない場合、FIRST/FOLLOWの競合は発生しないことに注意してください。

10

簡単な答え:関連付けられたLL(1)解析テーブルの各テーブルエントリに最大1つの生成がある場合、文法はLL(1)と呼ばれます。

Take the simple grammar A -->Aa|b.[A is non-terminal & a,b are terminals]
   then find the First and follow sets A.
    First{A}={b}.
    Follow{A}={$,a}.

    Parsing table for Our grammar.Terminals as columns and Nonterminal S as a row element.

        a            b                   $
    --------------------------------------------
 S  |               A-->a                      |
    |               A-->Aa.                    |
    -------------------------------------------- 

[S、b]には2つのProductionが含まれているため、どちらのルールを選択するかに関して混乱が生じます。したがって、LL(1)ではありません。

文法がLL(1)かどうかを確認する簡単なチェック。 チェック1:文法を再帰的にしないでください。例:E-> E + T。再帰的であるため、LL(1)ではありません。 チェック2:文法を左ファクタリングする必要があります。

2つ以上の文法規則の選択肢が共通のプレフィックス文字列を共有する場合、左のファクタリングが必要です。例:S-> [〜#〜] a [〜#〜] + int | [〜#〜] a [〜#〜]

チェック:文法は曖昧であってはなりません。

These are some simple checks.
2
Anil Kumar

LL(1)文法は、LL(1)パーサーで解析できるコンテキストのない明確な文法です。

LL(1)で

  • 最初のLは、左から右への入力のスキャンを表します。 2番目のLは、左端派生を表します。 1は、各ステップで1つの入力シンボルを使用することを意味します。

文法がLL(1)である場合、予測解析テーブルを描画できます。また、テーブルに複数のエントリが見つかった場合、文法はLL(1)ではないと言うことができます。

また、文法がLL(1)かどうかをチェックするためのショートカットです。 ショートカットテクニック

1
Badal