UNIT II-Syntax Analysis: CS416 Compilr Design 1
UNIT II-Syntax Analysis: CS416 Compilr Design 1
UNIT II-Syntax Analysis: CS416 Compilr Design 1
o A
| c an equivalent grammar
A A o
1
| ... | A o
m
| |
1
| ... | |
n
where |
1
... |
n
do not start with A
eliminate immediate left recursion
A |
1
A
| ... | |
n
A
A
o
1
A
| ... | o
m
A
| c an equivalent grammar
In general,
CS416 Compilr Design 19
Immediate Left-Recursion -- Example
E E+T | T
T T*F | F
F id | (E)
E T E
E
+T E
| c
T F T
*F T
| c
F id | (E)
eliminate immediate left recursion
CS416 Compilr Design 20
Left-Recursion -- Problem
A grammar cannot be immediately left-recursive, but it still can be
left-recursive.
By just eliminating the immediate left-recursion, we may not get
a grammar which is not left-recursive.
S Aa | b
A Sc | d This grammar is not immediately left-recursive,
but it is still left-recursive.
S Aa Sca or
A Sc Aac causes to a left-recursion
So, we have to eliminate all left-recursions from our grammar
CS416 Compilr Design 21
Eliminate Left-Recursion -- Algorithm
- Arrange non-terminals in some order: A
1
... A
n
- for i from 1 to n do {
- for j from 1 to i-1 do {
replace each production
A
i
A
j
by
A
i
o
1
| ... | o
k
where A
j
o
1
| ... | o
k
}
- eliminate immediate left-recursions among A
i
productions
}
CS416 Compilr Design 22
Eliminate Left-Recursion -- Example
S Aa | b
A Ac | Sd | f
- Order of non-terminals: S, A
for S:
- we do not enter the inner loop.
- there is no immediate left recursion in S.
for A:
- Replace A Sd with A Aad | bd
So, we will have A Ac | Aad | bd | f
- Eliminate the immediate left-recursion in A
A bdA
| fA
A
cA
| adA
| c
So, the resulting equivalent grammar which is not left-recursive is:
S Aa | b
A bdA
| fA
A
cA
| adA
| c
CS416 Compilr Design 23
Eliminate Left-Recursion Example2
S Aa | b
A Ac | Sd | f
- Order of non-terminals: A, S
for A:
- we do not enter the inner loop.
- Eliminate the immediate left-recursion in A
A SdA
| fA
A
cA
| c
for S:
- Replace S Aa with S SdA
a | fA
a
So, we will have S SdA
a | fA
a | b
- Eliminate the immediate left-recursion in S
S fAaS | bS
S
dA
aS | c
So, the resulting equivalent grammar which is not left-recursive is:
S fAaS | bS
S
dA
aS | c
A SdA
| fA
A
cA
| c
CS416 Compilr Design 24
Left-Factoring
A predictive parser (a top-down parser without backtracking) insists
that the grammar must be left-factored.
grammar a new equivalent grammar suitable for predictive parsing
stmt if expr then stmt else stmt |
if expr then stmt
when we see if, we cannot now which production rule to choose to
re-write stmt in the derivation.
CS416 Compilr Design 25
Left-Factoring (cont.)
In general,
A o|
1
| o|
2
where o is non-empty and the first symbols
of |
1
and |
2
(if they have one)are different.
when processing o we cannot know whether expand
A to o|
1
or
A to o|
2
But, if we re-write the grammar as follows
A oA
A |
1
| |
2
so, we can immediately expand A to oA
CS416 Compilr Design 26
Left-Factoring -- Algorithm
For each non-terminal A with two or more alternatives (production
rules) with a common non-empty prefix, let say
A o|
1
| ... | o|
n
|
1
| ... |
m
convert it into
A oA
|
1
| ... |
m
A
|
1
| ... | |
n
CS416 Compilr Design 27
Left-Factoring Example1
A abB | aB | cdg | cdeB | cdfB
A aA
bB | B
A aA
| cdA
A
bB | B
A
g | eB | fB
CS416 Compilr Design 28
Left-Factoring Example2
A ad | a | ab | abc | b
A aA | b
A d | c | b | bc
A aA | b
A d | c | bA
A c | c
CS416 Compilr Design 29
Non-Context Free Language Constructs
There are some language constructions in the programming languages
which are not context-free. This means that, we cannot write a context-
free grammar for these constructions.
L1 = { ece | e is in (a|b)*} is not context-free
declaring an identifier and checking whether it is declared or not
later. We cannot do this with a context-free language. We need
semantic analyzer (which is not context-free).
L2 = {a
n
b
m
c
n
d
m
| n>1 and m>1 } is not context-free
declaring two functions (one with n parameters, the other one with
m parameters), and then calling them with actual parameters.