文法がLL(1)、LR(0)、またはSLR(1)かどうかをどのように識別しますか?
誰でもこの例を使用して、または他の例を使用して説明できますか?
X→Yz | a
Y→bZ | ε
Z→ε
文法がLL(1)かどうかを確認するための1つのオプションは、LL(1)解析テーブルを構築し、競合をチェックすることです。これらの競合は
文法でこれを試してみましょう。各非終端記号の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)の競合も同じ理由でなくなりました。
お役に立てれば!
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の競合は発生しないことに注意してください。
簡単な答え:関連付けられた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.
LL(1)文法は、LL(1)パーサーで解析できるコンテキストのない明確な文法です。
LL(1)で
文法がLL(1)である場合、予測解析テーブルを描画できます。また、テーブルに複数のエントリが見つかった場合、文法はLL(1)ではないと言うことができます。
また、文法がLL(1)かどうかをチェックするためのショートカットです。 ショートカットテクニック