What you have looks correct! Here's a step-by-step way to see how to get there, along with why each transformation is necessary.
First, let's look at our S nonterminal. This nonterminal has two productions that start with m
, meaning that we have a FIRST/FIRST conflict between those productions. Left-factoring the productions S → mG and S → mKp gives us
S → mA
A → G
A → Kp
Now, did doing this expose any problems that previously weren't there? Fortunately, no. The nonterminal G can only produce strings starting with n
, and the nonterminal K can only produce string starting with q
or m
. That means that we didn't introduce any FIRST/FIRST conflicts here, so there's no need to touch anything further - at least, not yet.
Next, let's look at the G nonterminal, which has the productions G → nG and G → n. In other words, this produces a string of one or more copies of the letter n
. As it's currently written, there's a FIRST/FIRST conflict. There are many ways we can rewrite this. The one you proposed was essentially to split this into two pieces - one piece that generates a single n
, and a follow-up piece that generates zero or more copies of n
. I'll follow your lead here in doing that, which introduces a new nonterminal I'm going to call H to differentiate it from G:
G → nH
H → nH | ε
Now, we have to ask - does this ε production introduce any FIRST/FOLLOW conflicts? To answer that, we're going to need to determine what FOLLOW(H) is. We see that H only appears at the end of the productions H → nH (which doesn't give us anything new) and G → nH, which tells us that everything in FOLLOW(G) is going to also be in FOLLOW(H). And what's in FOLLOW(G)? G appears at the end of the production A → G, which tells us everything in FOLLOW(A) is going to be in FOLLOW(H). And A only appears in S → mA, meaning that the only token in FOLLOW(A) is the end-of-input marker $. Phew! So FOLLOW(H) = { $ }. And that's good news, because that doesn't conflict with the H → nH production.
That leaves behind the production rules for K, which fortunately don't have any issues with them.
Putting this all together, we get that the net transformed grammar is
S &rarr mA
A → G | Kp
G → nH
H → nH | ε
K → qKr | mn
This happens to be LL(1). Here's the parse table:
m n q r $
+------+------+------+------+------+
S | mA | | | | |
+------+------+------+------+------+
A | Kp G Kp | | |
+------+------+------+------+------+
G | | nH | | | |
+------+------+------+------+------+
H | | nH | | | eps |
+------+------+------+------+------+
K | mn | | qKr | | |
+------+------+------+------+------+
Look ma! No conflicts!
m
in there?S -> mQ
andQ -> mA
will give you an extram
, right? – Hassan$
for all follows except forK
, I thought maybe something is wrong since i haven't played with grammars that much. – Bobby$
. – rici