Is this grammar LL(1) - parsing

I have been asked to convert:
S → Sa | bSb | bc
to LL(1) so far I have:
S → bY
Y → SbF | cF
F → aF | ε
Is this LL(1)? If not would this be LL(1):
S → bY
Y → bYbF | cF
F → aF | ε
if neither of these would somebody please give me the correct answer and why thanks in advance!

This is what I would do:
S → Sa | bSb | bc
Remove left recursion:
F -> aF | EPSILON```
Now left factor:
F -> aF | EPSILON
X -> SbF | cF```
Check the First and Follows:
S: b
X: b, c
F: a, EPSILON```
```Follows():
S: $, b
X: $, b
F: $, b```
Everything checks out so it is LL(1) parsable.

Related

Cannot get LL(1) form of grammar for recursive descent parser

I have grammar:
S -> bU | ad | d
U -> Ufab | VSc | bS
V -> fad | f | Ua
To contruct recursive descent parser I need LL(1) form.
Best I got is:
S -> bU | ad | d
U -> fY | bSX
Y -> adScX | ScX
X -> fabX | aScX | ε
Removed left recursions and done some left factoring but I am stuck.
Tried for several hours but I cannot get it...
E.g. valid string are:
bbdfabadc
bbdfabfabfabfab
bfadadcfabfab
bbadaadc
bfbbdfabc
Obviously my grammar form is ambiguous for some so I cannot make recursive descent parser...
From answer:
S -> bU | ad | d
U -> fYZ | bSZ
X -> fab | aSc
Y -> adA | bUc | dc
Z -> ε | XZ
A -> Sc | c
Still not LL(1). First and follow for Z are not disjoint.
Generally to make a grammar LL(1) you'll need to repeatedly left factor and remove left recursion until you've managed to get rid of all the non-LL things. Which you do first depends on the grammar, but in this case you'll want to start with left factoring
To left factor the rule
U -> Ufab | VSc | bS
you need to first substitute V giving
U -> Ufab | fadSc | fSc | UaSc | bS
which you then left factor into
U -> UX | fY | bS
X -> fab | aSc
Y -> adSc | Sc
now U is simple enough that you can eliminate the left recursion directly:
U -> fYZ | bSZ
Z -> ε | XZ
giving you
S -> bU | ad | d
U -> fYZ | bSZ
X -> fab | aSc
Y -> adSc | Sc
Z -> ε | XZ
Now you still have a left factoring problem with Y so you need to substitute S:
Y -> adSc | bUc | adc | dc
which you left factor to
Y -> adA | bUc | dc
A -> Sc | c
giving an almost LL(1) grammar:
S -> bU | ad | d
U -> fYZ | bSZ
X -> fab | aSc
Y -> adA | bUc | dc
Z -> ε | XZ
A -> Sc | c
but now things are stuck as the epsilon rule for Z means we need FIRST(X) and FOLLOW(Z) to be disjoint (in order to decide between the two Z rules). This is generally indicative of a non-LL language, as there's some trailing context that could be associated with more than one rule (via the S -> bU -> bbSZ -> bbbUZ -> bbbbSZZ exapansion chain -- trailing Zs can be recognized but either might be empty). Often times you can still recognize this language with a simple recursive-descent parser (or LL-style state table) by simply resolving the Z ambiguity/conflict in favor of the non-epsilon rule.

How to determine if the language is LL(1)?

P → PL | L
L → N; | M; | C
N → print E
M → print "W"
W → TW | ε
C → if E {P} | if E {P} else {P}
E → (EOE) | V (note: this has a variable O)
O → + | - | *
V → 0 | 1 | 2 | 3 (note: this has a terminal 0 (zero))
T → a | b | c | d
For the above grammar G, is it not LL(1) because it evokes FIRST/FIRST conflict when trying to predict the production of P?
I am really struggling on how to prove that it is not LL(1)...
Any help or advice would be very thankful!
A left-recursive grammar cannot be LL(k) for any k. P → P L is left-recursive.
In addition, L has two productions starting with the same terminal, so it is impossible to choose between them with only one symbol of lookahead.

Step by step elimination of this indirect left recursion

I've seen this algorithm one should be able to use to remove all left recursion.
Yet I'm running into problems with this particular grammar:
A -> Cd
B -> Ce
C -> A | B | f
Whatever I try I end up in loops or with a grammar that is still indirect left recursive.
What are the steps to properly implement this algorithm on this grammar?
Rule is that you first establish some kind of order for non-terminals, and then find all paths where indirect recursion happens.
In this case order would be A < B < C, and possible paths for recursion of non-terminal C would be
C=> A => Cd
and
C=> B => Ce
so new rules for C would be
C=> Cd | Ce | f
now you can simply just remove direct left recursion:
C=> fC'
C'=> dC' | eC' | eps
and the resulting non-recursive grammar would be:
A => Cd
B => Ce
C => fC'
C' => dC' | eC' | eps
Figured it out already.
My confusion was that in this order, the algorithm seemed to do nothing, so I figured that must be wrong, and started replacing A -> Cd in the first iteration (ignoring j cannot go beyond i) getting into infinite loops.
1) By reordering the rules:
C -> A | B | f
A -> Cd
B -> Ce
2) replace C in A -> Cd
C -> A | B | f
A -> Ad | Bd | fd
B -> Ce
3) B not yet in range of j, so leave that and replace direct left recursion of A
C -> A | B | f
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> Ce
4) replace C in B -> Ce
C -> A | B | f
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> Ae | Be | fe
5) not done yet! also need to replace the new rule B -> Ae (production of A is in range of j)
C -> A | B | f
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> BdA'e | fdA'e | Be | fe
6) replace direct left recursion in productions of B
C -> A | B | f
A -> BdA' | fdA'
A'-> dA' | epsylon
B -> fdA'eB' | feB'
B'-> dA'eB' | eB' | epsylon
woohoo! left-recursion free grammar!

Left recursion elimination

I have this grammar
S->S+S|SS|(S)|S*|a
I want to know how to eliminate the left recursion from this grammar because the S+S is really confusing...
Let's see if we can simplify the given grammar.
S -> S*|S+S|SS|(S)|a
We can write it as;
S -> S*|SQ|SS|B|a
Q -> +S
B -> (S)
Now, you can eliminate left recursion in familiar territory.
S -> BS'|aS'
S' -> *S'|QS'|SS'|e
Q -> +S
B -> (S)
Note that e is epsilon/lambda.
We have removed the left recursion, so we no longer have need of Q and B.
S -> (S)S'|aS'
S' -> *S'|+SS'|SS'|e
You'll find this useful when dealing with left recursion elimination.
My answer using theory from this reference
How to Eliminate Left recursion in Context-Free-Grammar.
S --> S+S | SS | S* | a | (S)
-------------- -------
Sα form β form
Left-Recursive-Rules Non-Left-Recursive-Rules
We can write like
S ---> Sα1 | Sα2 | Sα3 | β1 | β2
Rules to convert in equivalent Non-recursive grammar:
S ---> β1 | β2
Z ---> α1 |
α2 | α3
Z ---> α1Z |
α2Z | α3Z
S ---> β1Z | β2Z
Where
α1 = +S
α2 = S
α3 = *
And β-productions not start starts with S:
β1 = a
β2 = (S)
Grammar without left-recursion:
Non- left recursive Productions S --> βn
S --> a | (S)
Introduce new variable Z with following productions: Z ---> αn and Z --> αnZ
Z --> +S | S | *
and
Z --> +SZ | SZ | *Z
And new S productions: S --> βnZ
S --> aZ | (S)Z
Second form (answer)
Productions Z --> +S | S | * and Z --> +SZ | SZ | *Z can be combine as Z --> +SZ | SZ | *Z| ^ where ^ is null-symbol.
Z --> ^ use to remove Z from production rules.
So second answer:
S --> aZ | (S)Z and Z --> +SZ | SZ | *Z| ^

How to implement a left recursion eliminator?

How can i implement an eliminator for this?
A := AB |
AC |
D |
E ;
This is an example of so called immediate left recursion, and is removed like this:
A := DA' |
EA' ;
A' := ε |
BA' |
CA' ;
The basic idea is to first note that when parsing an A you will necessarily start with a D or an E. After the D or an E you will either end (tail is ε) or continue (if we're in a AB or AC construction).
The actual algorithm works like this:
For any left-recursive production like this: A -> A a1 | ... | A ak | b1 | b2 | ... | bm replace the production with A -> b1 A' | b2 A' | ... | bm A' and add the production A' -> ε | a1 A' | ... | ak A'.
See Wikipedia: Left Recursion for more information on the elimination algorithm (including elimination of indirect left recursion).
Another form available is:
A := (D | E) (B | C)*
The mechanics of doing it are about the same but some parsers might handle that form better. Also consider what it will take to munge the action rules along with the grammar its self; the other form requires the factoring tool to generate a new type for the A' rule to return where as this form doesn't.

Resources