Lesson 18
Lesson 18
Contents
Writing a Grammar
Lexical Vs Syntactic Analysis
Eliminating Ambiguity
Elimination of Left Recursion
Left Factoring
Non-Context-Free Language Constructs
Top Down Parsing
Recursive Decent Parsing
FIRST & FOLLOW
LL(1) Grammars
2
Elimination of Left Recursion
A grammar is left recursive if it has a non-terminal A such that
there is a derivation A ⇒+ Aα for some string α
A → Aα + β A → βA’
A’ → αA’ | ɛ
3
Elimination of Left Recursion..
Immediate left recursion can be eliminated by the following
technique, which works for any number of A-productions.
5
Elimination of Left Recursion...
Now we will discuss an algorithm that systematically eliminates left
recursion from a grammar.
INPUT:
Grammar G with no cycles or ɛ-productions.
OUTPUT:
An equivalent grammar with no left recursion.
7
Elimination of Left Recursion...
Ex. S→Aa|b
A→Ac|Sd|ɛ
8
Elimination of Left Recursion...
For i = 2 we substitute for S in A → S d to obtain the following A-
productions.
A→Ac|Aad|bd|ɛ
S →Aa|b
A → b d A’ | A’
A’ → c A’ | a d A’ | ɛ
9
Elimination of Left Recursion...
1. Extract the left common factor of this grammar.
2. Can the transformation of extracting the left common factor make
this grammar suitable for top-down parsing techniques?
3. After extracting the left common factor, the left recursion is
eliminated from the original method.
4. Is the resulting grammar suitable for top-down grammatical analysis?
S -> S S + | S S * | a
10
Elimination of Left Recursion...
Eliminate left recursion
1 ) S -> S S A | a
2) A -> + | *
// i = 1
1) S -> a B
2) B -> S A B | ε
3) A -> + | *
// i = 2, j = 1
1) S -> a B
2) B -> a B A B | ε
3) A -> + | *
11
Elimination of Left Recursion...
• S -> + S S | * S S | a
• first(S) = [+, *, a]
• follow(S) = [+, *, a, $]
12
Left Factoring
Left factoring is a grammar transformation that is useful for
producing a grammar suitable for predictive, or top-down, parsing.
If two productions with the same LHS have their RHS beginning with
the same symbol (terminal or non-terminal), then the FIRST sets will
not be disjoint so predictive parsing will be impossible
Ex.
13
Left Factoring..
if A → αβ1 | αβ2 are two A-productions
14
Left Factoring…
INPUT: Grammar G.
OUTPUT: An equivalent left-factored grammar.
METHOD:
For each non-terminal A, find the longest prefix α common to two or
more of its alternatives.
If α ≠ ɛ i.e., there is a nontrivial common prefix.
• Replace all of the A-productions A → αβ1 | αβ2 … | αβn | γ by
A → α A’ | γ
A' → β1| β2| …. | βn
15
Left Factoring…
Ex Dangling else grammar:
16
Left Factoring…
1. Extract the left common factor of this grammar.
2. Can the transformation of extracting the left common factor make
this grammar suitable for top-down parsing techniques?
3. After extracting the left common factor, the left recursion is
eliminated from the original method.
Is the resulting grammar suitable for top-down grammatical
analysis? S -> 0 S 1 | 0 1
17
Left Factoring…
Eliminate left recursion
// initial status
1) S -> 0 A
2) A -> S 1 | 1
// i = 1
// nothing changed
// i = 2, j = 1
1) S -> 0 A
2) A -> 0 A 1 | 1
18
Non-CFL Constructs
Although grammars are powerful, but they are not all-powerful to
specify all language constructs.
19
Non-CFL Constructs..
The abstract language is L1 = {wcw | w is in (a|b)*}
For this reason, a grammar for C or Java does not distinguish among
identifiers that are different character strings.
20
Top Down Parsing
Top-down parsing can be viewed as the problem of constructing a
parse tree for the input string, starting from the root and creating
the nodes of the parse tree in preorder (DFT).
21
Top Down Parsing..
Top Down Parsing for id + id * id
22
Top Down Parsing...
23
Top Down Parsing...
The class of grammars for which we can construct predictive
parsers looking k symbols ahead in the input is sometimes called
the LL(k) class.
24
Recursive Decent Parsing
Recursive Descent Parsing
Recursive descent parsers will look ahead one character and advance
the input stream reading pointer when proper matches occur.
25
Recursive Decent Parsing..
The following procedure accomplishes matching and reading process.
The variable called 'next' looks ahead and always provides the next
character that will be read from the input stream.
This feature is essential if we wish our parsers to be able to predict what
is due to arrive as input.
26
Recursive Decent Parsing...
What a recursive descent parser actually does is to perform a
depth-first search of the derivation tree for the string being parsed.
This provides the 'descent' portion of the name.
27
Recursive Decent Parsing...
Derivation tree for the expression id+(id+id)
28
Recursive Decent Parsing…
A recursive descent parser traverses the tree by first calling a
procedure to recognize an E.
This procedure reads an 'x' and a '+' and then calls a procedure to
recognize a T.
29
Recursive Decent Parsing...
In order to recognize a T, the parser must figure out which of the
productions to execute.
In this routine, the parser determines whether T had the form (E)
or x.
If not then the error routine was called, otherwise the appropriate
terminals and non-terminals were recognized.
30
Recursive Decent Parsing...
So, all one needs to write a recursive descent parser is a nice
grammar.
31
Recursive Decent Parsing...
S -> 0 S 1 | 0 1
Step1.Extract the left common factor
S -> 0 A
A -> S 1 | 1
step2. Eliminate left recursion
S -> 0 A
A -> 0 A 1 | 1
step3. Forecast analysis table
32