To check if LL (1) is a grammar, one option is to create an LL (1) parsing table and check for any conflicts. These conflicts may be
- FIRST / FIRST conflicts, where two different settings for a pair with nonterminal / final should be predicted.
- FIRST / FOLLOW, where two different settings are predicted, one of which means that it is necessary to produce some products and expand them to a non-zero number of characters, and one of them means that production should be used indicating that some non-terminals must be in the final account expanded to an empty string.
- FOLLOW / FOLLOW conflicts, in which two products indicating that the nonterminal should ultimately be expanded to empty lines conflict with each other.
Try this on your grammar by building FIRST and FOLLOW for each of the non-terminals. Here we get that
FIRST(X) = {a, b, z} FIRST(Y) = {b, epsilon} FIRST(Z) = {epsilon}
We also have that the FOLLOW sets are
FOLLOW(X) = {$} FOLLOW(Y) = {z} FOLLOW(Z) = {z}
From this, we can construct the following LL (1) parsing table:
abz $ X a Yz Yz Y bZ eps Z eps
Since we can build this conflict-free parsing table, LL grammar (1).
To check if the grammar is LR (0) or SLR (1), we start by creating all the configuration sets LR (0) for the grammar. In this case, assuming that X is your starting character, we get the following:
(1) X' -> .X X -> .Yz X -> .a Y -> . Y -> .bZ (2) X' -> X. (3) X -> Yz (4) X -> Yz. (5) X -> a. (6) Y -> bZ Z -> . (7) Y -> bZ.
It can be seen from this that the grammar is not LR (0), since in states (1) and (6) there are shift / decrease conflicts. In particular, because we have the abbreviation elements Z →, and Y →., We cannot determine whether to reduce the empty string to these characters or shift some other character. More generally, no grammar with & epsilon -productions is LR (0).
However, this grammar may be SLR (1). To verify this, we increase each contraction using a set of coordinates for specific non-terminals. This returns this set of SLR (1) configuration sets:
(1) X' -> .X X -> .Yz [$] X -> .a [$] Y -> . [z] Y -> .bZ [z] (2) X' -> X. (3) X -> Yz [$] (4) X -> Yz. [$] (5) X -> a. [$] (6) Y -> bZ [z] Z -> . [z] (7) Y -> bZ. [z]
Now we no longer have shift conflicts. The conflict in state (1) was eliminated, because we reduce it only when the lookahead is equal to z, which does not conflict with any of the other elements. Similarly, the conflict in (6) went away for the same reason.
Hope this helps!