Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
43 views29 pages

Unit III

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views29 pages

Unit III

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

AUTOMATA THEORY& COMPILER DESIGN


UNIT III
PARSERS
Introduction:
Parser is a compiler that is used to break the data into smaller elements coming from lexical analysis
phase. A parser takes input in the form of sequence of tokens and produces output in the form of
parse tree. Parsing is of two types: top down parsing and bottom up parsing.

Top down paring :


 The top down parsing is known as recursive parsing or predictive parsing.
 Bottom up parsing is used to construct a parse tree for an input string.
 In the top down parsing, the parsing starts from the start symbol and transform it into the
input symbol.
Parse Tree representation of input string "acdb" is as follows:

Bottom up parsing
 Bottom up parsing is also known as shift-reduce parsing.

 Bottom up parsing is used to construct a parse tree for an input string.


 In the bottom up parsing, the parsing starts with the input symbol and construct the parse
tree up to the start symbol by tracing out the rightmost derivations of string in reverse.
Department of Computer Science and Engineering

Example
E→T
T→T*F
T → id
F→T
F → id
Parse Tree representation of input string "id * id" is as follows:

TOP-DOWN PARSING:

Top-down parsing technique parses the input and starts constructing a parse tree from the root
node gradually moving down to the leaf nodes. The types of top-down parsing are depicted
below:

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 2


Department of Computer Science and Engineering

Recursive Descent Parsing

Recursive descent is a top-down parsing technique that constructs the parse tree from the top and
the input is read from left to right. It uses procedures for every terminal and non-terminal entity.
This parsing technique recursively parses the input to make a parse tree, which may or may not
require back-tracking. But the grammar associated with it (if not left factored) cannot avoid
back-tracking. A form of recursive-descent parsing that does not require any backtracking is
known as predictive parsing.

This parsing technique is regarded recursive as it uses context-free grammar which is recursive
in nature.

Back-tracking

Top- down parsers start from the root node (start symbol) and match the input string against the
production rules to replace them (if matched). To understand this, take the following example of
CFG:

S → rXd | rZd
X → oa | ea
Z → ai

For an input string: read, a top-down parser, will behave like this:

It will start with S from the production rules and will match its yield to the left-most letter of the
input, i.e. „r‟. The very production of S (S → rXd) matches with it. So the top-down parser
advances to the next input letter (i.e. „e‟). The parser tries to expand non-terminal „X‟ and checks
its production from the left (X → oa). It does not match with the next input symbol. So the top-
down parser backtracks to obtain the next production rule of X, (X → ea).

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 3


Department of Computer Science and Engineering

Now the parser matches all the input letters in an ordered manner. The string is accepted.

Recursive Descent Parser

Recursive Descent Parser uses the technique of Top-Down Parsing without backtracking. It can
be defined as a Parser that uses the various recursive procedure to process the input string with
no backtracking. It can be simply performed using a Recursive language. The first symbol of the
string of R.H.S of production will uniquely determine the correct alternative to choose.

The major approach of recursive-descent parsing is to relate each non-terminal with a procedure.
The objective of each procedure is to read a sequence of input characters that can be produced by
the corresponding non-terminal, and return a pointer to the root of the parse tree for the non-
terminal. The structure of the procedure is prescribed by the productions for the equivalent non-
terminal.

The recursive procedures can be simply to write and adequately effective if written in a language
that executes the procedure call effectively. There is a procedure for each non-terminal in the
grammar. It can consider a global variable lookahead, holding the current input token and a
procedure match (Expected Token) is the action of recognizing the next token in the parsing
process and advancing the input stream pointer, such that lookahead points to the next token to
be parsed. Match () is effectively a call to the lexical analyzer to get the next token.

For example, input stream is a + b$.

lookahead == a
match()
lookahead == +
match ()
lookahead == b
……………………….
……………………….
In this manner, parsing can be done.

EXAMPLE:
Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 4
Department of Computer Science and Engineering

Write down the algorithm using Recursive procedures to implement the following Grammar.
E → TE′
E′ → +TE′
T → FT′
T′ →∗ FT′|ε
F → (E)|id

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 5


Department of Computer Science and Engineering

One of major drawback or recursive-descent parsing is that it can be implemented only for those
languages which support recursive procedure calls and it suffers from the problem of left-
recursion.

PREDICTIVE PARSER:

Predictive parser is a recursive descent parser, which has the capability to predict which
production is to be used to replace the input string. The predictive parser does not suffer from
backtracking.

To accomplish its tasks, the predictive parser uses a look-ahead pointer, which points to the next
input symbols. To make the parser back-tracking free, the predictive parser puts some constraints
on the grammar and accepts only a class of grammar known as LL(k) grammar.

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 6


Department of Computer Science and Engineering

Predictive parsing uses a stack and a parsing table to parse the input and generate a parse tree.
Both the stack and the input contains an end symbol $ to denote that the stack is empty and the
input is consumed. The parser refers to the parsing table to take any decision on the input and
stack element combination.

In recursive descent parsing, the parser may have more than one production to choose from for a
single instance of input, whereas in predictive parser, each step has at most one production to
choose. There might be instances where there is no production matching the input string, making
the parsing procedure to fail.

LL Parser

An LL Parser accepts LL grammar. LL grammar is a subset of context-free grammar but with


some restrictions to get the simplified version, in order to achieve easy implementation. LL
grammar can be implemented by means of both algorithms namely, recursive-descent or table-
driven.

LL parser is denoted as LL(k). The first L in LL(k) is parsing the input from left to right, the
second L in LL(k) stands for left-most derivation and k itself represents the number of look
aheads. Generally k = 1, so LL(k) may also be written as LL(1).

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 7


Department of Computer Science and Engineering

LL Parsing Algorithm

We may stick to deterministic LL(1) for parser explanation, as the size of table grows
exponentially with the value of k. Secondly, if a given grammar is not LL(1), then usually, it is
not LL(k), for any given k.

Given below is an algorithm for LL(1) Parsing:

Input:
string ω
parsing table M for grammar G

Output:
If ω is in L(G) then left-most derivation of ω,
error otherwise.

Initial State : $S on stack (with S being start symbol)


ω$ in the input buffer

SET ip to point the first symbol of ω$.

repeat
let X be the top stack symbol and a the symbol pointed by ip.

if X∈ Vt or $
if X = a
POP X and advance ip.
else
error()
endif

else /* X is non-terminal */
if M[X,a] = X → Y1, Y2,... Yk
POP X
PUSH Yk, Yk-1,... Y1 /* Y1 on top */
Output the production X → Y1, Y2,... Yk
else
error()
endif
endif
until X = $ /* empty stack */

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 8


Department of Computer Science and Engineering

A table-driven predictive parser has an input buffer, a stack, a parsing table, and an output
stream. The input buffer contains the string to be parsed, followed by $, a symbol used as a right
end marker to indicate the end of the input string. The stack contains a sequence of grammar
symbols with $ on the bottom, indicating the bottom of the stack. Initially, the stack contains the
start symbol of the grammar on top of $. The parsing table is a two dimensional array M[A,a]
where A is a non-terminal, and a is a terminal or the symbol $. The parser is controlled by a
program that behaves as follows. The program considers X, the symbol on the top of the stack,
and a, the current input symbol. These two symbols determine the action of the parser. There are
three possibilities.

1. If X= a=$, the parser halts and announces successful completion of parsing.


2. If X=a!=$, the parser pops X off the stack and advances the input pointer to the next
input symbol
3. If X is a non terminal, the program consults entry M[X,a] of the parsing table M. This
entry will be either an X-production of the grammar or an error entry. If, for example,
M[X,a]={X- >UVW}, the parser replaces X on top of the stack by WVU( with U on
top). As output, we shall assume that the parser just prints the production used; any other
code could be executed here. If M[X,a]=error, the parser calls an error recovery routine.

Predictive parsing table construction:


The construction of a predictive parser is aided by two functions associated with a grammar G :
1. FIRST
2. FOLLOW

Rules for first( ):


1. If X is terminal, then FIRST(X) is{X}.
2. If X → ε is a production, then add ε toFIRST(X).
3. If X is non-terminal and X → aα is a production then add a toFIRST(X).
4. If X is non-terminal and X → Y1 Y2…Yk is a producƟon, then place a in FIRST(X)if for
some i, a is in FIRST(Yi), and ε is in all of FIRST(Y1),…,FIRST(Yi-1);that is, Y1,….Yi-1=> ε.
If ε is in FIRST(Yj) for all j=1,2,..,k, then add ε to FIRST(X).

Rules for follow( ):


1. If S is a start symbol, then FOLLOW(S) contains$.
2. If there is a production A →αBβ, then every thing in FIRST(β)except ε is placed in follow(B).
3. If there is a production A → αB, or a producƟon A → αBβ where FIRST(β) contains ε, then
everything in FOLLOW(A) is in FOLLOW(B).

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 9


Department of Computer Science and Engineering

Algorithm for construction of predictive parsing table:


Input : Grammar G
Output : Parsing table M Method :
1. For each production A → α of the grammar, do steps 2 and3.
2. For each terminal a in FIRST(α), add A → α to M[A,a].
3. If ε is in FIRST(α), add A → α to M[A, b] for each terminal b in FOLLOW(A). If εis in
FIRST(α) and $ is in FOLLOW(A) , add A → α to M[A,$].
4. Make each undefined entry of M beerror.
Example:
Consider the following grammar :
E→E+T|T
T→T*F|F
F→(E)|id
After eliminating left-recursion the grammar is
E →TE‟
E‟ → +TE‟ | ε
T →FT‟
T‟ → *FT‟ | ε
F → (E)|id
First( ) :
FIRST(E) = { ( ,id}
FIRST(E‟) ={+ , ε}
FIRST(T) = { ( ,id}
FIRST(T‟) = {*, ε}
FIRST(F) = { ( , id }
Follow( ):
FOLLOW(E) = { $, ) }
FOLLOW(E‟) = { $, ) }
FOLLOW(T) = { +, $, ) }
FOLLOW(T‟) = { +, $, ) }
FOLLOW(F) = {+, * , $ , ) }

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 10


Department of Computer Science and Engineering

Predictive parsing Table

The parsing table entries are single entries. so, each location has not more than one entry.
This type of grammar is called LL(1) grammar.
Simulation of parser table for the input symbol id+id*id

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 11


Department of Computer Science and Engineering

Consider this following grammar:


S→iEtS | iEtSeS| a
E→b

After eliminating left factoring, we have


S→iEtSS‟|a S‟→ eS | ε
E→b
To construct a parsing table, we need FIRST() and FOLLOW() for all the non-terminal.
FIRST(S) = { i, a }
FIRST(S‟) = {e, ε }
FIRST(E) = { b}
FOLLOW(S) = { $ ,e }
FOLLOW(S‟) = { $ ,e }
FOLLOW(E) = {t}
Parsing table:

Since there are more than one production, the grammar is not LL(1) grammar.

Implementation of predictive parser:


1. Elimination of left recursion, left factoring and ambiguous grammar.

2. Construct FIRST () and FOLLOW() for all non-terminals.

3. Construct predictive parsing table.

4. Parse the given input string using stack and parsing table

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 12


Department of Computer Science and Engineering

BOTTOM-UP PARSER:

Bottom-up parsing starts from the leaf nodes of a tree and works in upward direction till it
reaches the root node. Here, we start from a sentence and then apply production rules in reverse
manner in order to reach the start symbol. The image given below depicts the bottom-up parsers
available.

Handle:

• Informally, a handle of a string is a substring that matches the right side of a production
rule.

– But not every substring matches the right side of a production rule is handle

• A handle of a right sentential form  ( ) is

a production rule A   and a position of 

where the string  may be found and replaced by A to produce

the previous right-sentential form in a rightmost derivation of .

S  A  

• If the grammar is unambiguous, then every right-sentential form of the grammar has
exactly one handle.

• We will see that  is a string of terminals.

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 13


Department of Computer Science and Engineering

Handle Pruning:

• A right-most derivation in reverse can be obtained by handle-pruning.

S=0  1  2  ...  n-1  n= , input string

• Start from n, find a handle Ann in n, and replace n in by An to get n-1.
• Then find a handle An-1n-1 in n-1, and replace n-1 in by An-1 to get n-2.
• Repeat this, until we reach S.

E  E+T | T

T  T*F | F

F  (E) | id

Right-Most Derivation of id+id*id

E  E+T
 E+T*F TF
 E+T*id F  id
 E+F*id TF
 E+id*id F  id
 T+id*id ET
 F+id*id TF
 id+id*id F  id

Right-Most Sentential Form Reducing Production


id+id*id F  id
F+id*id TF
T+id*id ET
E+id*id F  id
E+F*id TF
E+T*id F  id
E+T*F T  T*F
E+T E  E+T
E

Handles are red and underlined in the right-sentential forms.

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 14


Department of Computer Science and Engineering

Shift-Reduce Parsing

• There are four possible actions of a shift-parser action:


1. Shift : The next input symbol is shifted onto the top of the stack.
2. Reduce: Replace the handle on the top of the stack by the non-terminal.
3. Accept: Successful completion of parsing.
4. Error: Parser discovers a syntax error, and calls an error recovery routine.
• Initial stack just contains only the end-marker $.
• The end of the input string is marked by the end-marker $.

Parse Tree:

token = next_token()

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 15


Department of Computer Science and Engineering

repeat forever
s = top of stack

if action[s, token] = “shift si” then


PUSH token
PUSH si
token = next_token()

else if action[s, token] = “reduce A::= β“ then


POP 2 * |β| symbols
s = top of stack
PUSH A
PUSH goto[s,A]

else if action[s, token] = “accept” then


return

else
error()

Conflicts During Shift-Reduce Parsing

 There are context-free grammars for which shift-reduce parsers cannot be used.
 Stack contents and the next input symbol may not decide action:
 shift/reduce conflict: Whether make a shift operation or a reduction.
 reduce/reduce conflict: The parser cannot decide which of several reductions to
make.
 If a shift-reduce parser cannot be used for a grammar, that grammar is called as non-
LR(k) grammar.
 An ambiguous grammar can never be a LR grammar.

LR Parser

The LR parser is a non-recursive, shift-reduce, bottom-up parser. It uses a wide class of context-
free grammar which makes it the most efficient syntax analysis technique. LR parsers are also
known as LR(k) parsers, where L stands for left-to-right scanning of the input stream; R stands
for the construction of right-most derivation in reverse, and k denotes the number of lookahead
symbols to make decisions.

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 16


Department of Computer Science and Engineering

There are three widely used algorithms available for constructing an LR parser:

 SLR(1) – Simple LR Parser:


 Works on smallest class of grammar
 Few number of states, hence very small table
 Simple and fast construction
 LR(1) – LR Parser:
 Works on complete set of LR(1) Grammar
 Generates large table and large number of states
 Slow construction
 LALR(1) – Look-Ahead LR Parser:
 Works on intermediate size of grammar
 Number of states are same as in SLR(1)
 LR Parsing Algorithm
 Here we describe a skeleton algorithm of an LR parser:

SLR Parser:

SLR is simple LR. It is the smallest class of grammar having few number of states. SLR is
very easy to construct and is similar to LR parsing. The only difference between SLR parser
and LR(0) parser is that in LR(0) parsing table, there‟s a chance of „shift reduced‟ conflict
because we are entering „reduce‟ corresponding to all terminal states. We can solve this
problem by entering „reduce‟ corresponding to FOLLOW of LHS of production in the
terminating state. This is called SLR(1) collection of items.
Steps for constructing the SLR parsing table :
1. Writing augmented grammar
2. LR(0) collection of items to be found
3. Find FOLLOW of LHS of production
4. Defining 2 functions: goto[list of terminals] and action[list of non-terminals] in the parsing table
EXAMPLE
Construct LR parsing table for the given context-free grammar.
S–>AA
A–>aA|b
Solution:
STEP1 – Find augmented grammar
The augmented grammar of the given grammar is:-
S‟–>.S [0th production]
S–>.AA [1st production]
A–>.aA [2nd production]
A–>.b [3rd production]
STEP2 – Find LR(0) collection of items. Below is the figure showing the LR(0) collection of
items. We will understand everything one by one.

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 17


Department of Computer Science and Engineering

The terminals of this grammar are {a,b}.


The non-terminals of this grammar are {S,A}
RULE –
If any non-terminal has „ . „ preceding it, we have to write all its production and add „ . „
preceding each of its production.
RULE –
from each state to the next state, the „ . „ shifts to one place to the right.
 In the figure, I0 consists of augmented grammar.

 Io goes to I1 when „ . „ of 0th production is shifted towards the right of S(S‟->S.). this state
is the accepted state. S is seen by the compiler.
 Io goes to I2 when „ . „ of 1st production is shifted towards right (S->A.A) . A is seen by
the compiler
 I0 goes to I3 when „ . „ of the 2nd production is shifted towards right (A->a.A) . a is seen
by the compiler.
 I0 goes to I4 when „ . „ of the 3rd production is shifted towards right (A->b.) . b is seen by
the compiler.

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 18


Department of Computer Science and Engineering

 I2 goes to I5 when „ . „ of 1st production is shifted towards right (S->AA.) . A is seen by


the compiler
 I2 goes to I4 when „ . „ of 3rd production is shifted towards right (A->b.) . b is seen by the
compiler.
 I2 goes to I3 when „ . „ of the 2nd production is shifted towards right (A->a.A) . a is seen
by the compiler.
 I3 goes to I4 when „ . „ of the 3rd production is shifted towards right (A->b.) . b is seen by
the compiler.
 I3 goes to I6 when „ . „ of 2nd production is shifted towards the right (A->aA.) . A is seen
by the compiler
 I3 goes to I3 when „ . „ of the 2nd production is shifted towards right (A->a.A) . a is seen
by the compiler.
STEP3 –
Find FOLLOW of LHS of production
FOLLOW(S)=$
FOLLOW(A)=a,b,$

STEP 4-
Defining 2 functions:goto[list of non-terminals] and action[list of terminals] in the
parsing table. Below is the SLR parsing table.

 $ is by default a nonterminal that takes accepting state.


 0,1,2,3,4,5,6 denotes I0,I1,I2,I3,I4,I5,I6
 I0 gives A in I2, so 2 is added to the A column and 0 rows.
 I0 gives S in I1,so 1 is added to the S column and 1 row.
Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 19
Department of Computer Science and Engineering

 similarly 5 is written in A column and 2 row, 6 is written in A column and 3 row.


 I0 gives a in I3 .so S3(shift 3) is added to a column and 0 row.
 I0 gives b in I4 .so S4(shift 4) is added to the b column and 0 row.
 Similarly, S3(shift 3) is added on a column and 2,3 row ,S4(shift 4) is added on b column
and 2,3 rows.
 I4 is reduced state as „ . „ is at the end. I4 is the 3rd production of grammar(A–>.b).LHS of
this production is A. FOLLOW(A)=a,b,$ . write r3(reduced 3) in the columns of a,b,$ and
4th row
 I5 is reduced state as „ . „ is at the end. I5 is the 1st production of grammar(S–>.AA). LHS
of this production is S.
FOLLOW(S)=$ . write r1(reduced 1) in the column of $ and 5th row
 I6 is a reduced state as „ . „ is at the end. I6 is the 2nd production of grammar( A–>.aA).
The LHS of this production is A.
FOLLOW(A)=a,b,$ . write r2(reduced 2) in the columns of a,b,$ and 6th row
Construct SLR Parser for the following:

S→E
E→E+T|T
T→T*F|F
F → id

Solution:

Add Augment Production and insert '•' symbol at the first position for every production in G

S` → •E
E → •E + T
E → •T
T → •T * F
T → •F
F → •id

I0 State:
Add Augment production to the I0 State and Compute the Closure
I0 = Closure (S` → •E)
Add all productions starting with E in to I0 State because "." is followed by the non-terminal. So,
the I0 State becomes

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 20


Department of Computer Science and Engineering

I0 = S` → •E
E → •E + T
E → •T
Add all productions starting with T and F in modified I0 State because "." is followed by the
non-terminal. So, the I0 State becomes.
I0= S` → •E
E → •E + T
E → •T
T → •T * F
T → •F
F → •id
I1= Go to (I0, E) = closure (S` → E•, E → E• + T)
I2= Go to (I0, T) = closure (E → T•T, T• → * F)
I3= Go to (I0, F) = Closure ( T → F• ) = T → F•
I4= Go to (I0, id) = closure ( F → id•) = F → id•
I5= Go to (I1, +) = Closure (E → E +•T)

Add all productions starting with T and F in I5 State because "." is followed by the non-terminal.
So, the I5 State becomes

I5 = E → E +•T
T → •T * F
T → •F
F → •id

Go to (I5, F) = Closure (T → F•) = (same as I3)


Go to (I5, id) = Closure (F → id•) = (same as I4)

I6= Go to (I2, *) = Closure (T → T * •F)

Add all productions starting with F in I6 State because "." is followed by the non-terminal. So,
the I6 State becomes

I6 = T → T * •F
F → •id

Go to (I6, id) = Closure (F → id•) = (same as I4)

I7= Go to (I5, T) = Closure (E → E + T•) = E → E + T•


I8= Go to (I6, F) = Closure (T → T * F•) = T → T * F•

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 21


Department of Computer Science and Engineering

Drawing DFA:

SLR (1) Table

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 22


Department of Computer Science and Engineering

CLR (1) Parsing

CLR refers to canonical lookahead. CLR parsing use the canonical collection of LR (1) items to
build the CLR (1) parsing table. CLR (1) parsing table produces the more number of states as
compare to the SLR (1) parsing.

In the CLR (1), we place the reduce node only in the lookahead symbols.

Various steps involved in the CLR (1) Parsing:

 Add Augment production in the given grammar


 Create Canonical collection of LR (0) items
 Draw a data flow diagram (DFA)
 Construct a CLR (1) parsing table

LR (1) item

LR (1) item is a collection of LR (0) items and a look ahead symbol.

LR (1) item = LR (0) item + look ahead

The look ahead is used to determine that where we place the final item.

The look ahead always add $ symbol for the argument production.

Construct CLR ( 1 ) Grammar for the following grammar.

S → AA
A → aA
A→b
Solution:
Add Augment Production, insert '•' symbol at the first position for every production in G and
also add the lookahead.

S` → •S, $
S → •AA, $
A → •aA, a/b
A → •b, a/b

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 23


Department of Computer Science and Engineering

I0 State:
Add Augment production to the I0 State and Compute the Closure
I0 = Closure (S` → •S)
Add all productions starting with S in to I0 State because "." is followed by the non-terminal. So,
the I0 State becomes
I0 = S` → •S, $
S → •AA, $
Add all productions starting with A in modified I0 State because "." is followed by the non-
terminal. So, the I0 State becomes.
I0= S` → •S, $
S → •AA, $
A → •aA, a/b
A → •b, a/b
I1= Go to (I0, S) = closure (S` → S•, $) = S` → S•, $
I2= Go to (I0, A) = closure ( S → A•A, $ )
Add all productions starting with A in I2 State because "." is followed by the non-terminal. So,
the I2 State becomes
I2= S → A•A, $
A → •aA, $
A → •b, $
I3= Go to (I0, a) = Closure ( A → a•A, a/b )
Add all productions starting with A in I3 State because "." is followed by the non-terminal. So,
the I3 State becomes
I3= A → a•A, a/b
A → •aA, a/b
A → •b, a/b
Go to (I3, a) = Closure (A → a•A, a/b) = (same as I3)
Go to (I3, b) = Closure (A → b•, a/b) = (same as I4)
I4= Go to (I0, b) = closure ( A → b•, a/b) = A → b•, a/b
I5= Go to (I2, A) = Closure (S → AA•, $) =S → AA•, $
I6= Go to (I2, a) = Closure (A → a•A, $)
Add all productions starting with A in I6 State because "." is followed by the non-terminal. So,
the I6 State becomes
I6 = A → a•A, $
A → •aA, $
A → •b, $
Go to (I6, a) = Closure (A → a•A, $) = (same as I6)
Go to (I6, b) = Closure (A → b•, $) = (same as I7)
I7= Go to (I2, b) = Closure (A → b•, $) = A → b•, $
I8= Go to (I3, A) = Closure (A → aA•, a/b) = A → aA•, a/b
I9= Go to (I6, A) = Closure (A → aA•, $) = A → aA•, $

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 24


Department of Computer Science and Engineering

Drawing DFA:

CLR (1) Parsing table:

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 25


Department of Computer Science and Engineering

LALR (1) Parsing:

LALR refers to the lookahead LR. To construct the LALR (1) parsing table, we use the canonical
collection of LR (1) items.

In the LALR (1) parsing, the LR (1) items which have same productions but different look ahead
are combined to form a single set of items

LALR (1) parsing is same as the CLR (1) parsing, only difference in the parsing table.

Construct LALR Parser for the following Grammar:

S → AA
A → aA
A→b

Solution:

Add Augment Production, insert '•' symbol at the first position for every production in G and
also add the look ahead.

S` → •S, $
S → •AA, $
A → •aA, a/b
A → •b, a/b

I0 State:
Add Augment production to the I0 State and Compute the ClosureL
I0 = Closure (S` → •S)
Add all productions starting with S in to I0 State because "•" is followed by the non-terminal. So,
the I0 State becomes
I0 = S` → •S, $
S → •AA, $
Add all productions starting with A in modified I0 State because "•" is followed by the non-
terminal. So, the I0 State becomes.
I0= S` → •S, $
S → •AA, $
A → •aA, a/b
A → •b, a/b
I1= Go to (I0, S) = closure (S` → S•, $) = S` → S•, $
I2= Go to (I0, A) = closure ( S → A•A, $ )

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 26


Department of Computer Science and Engineering

Add all productions starting with A in I2 State because "•" is followed by the non-terminal. So,
the I2 State becomes
I2= S → A•A, $
A → •aA, $
A → •b, $
I3= Go to (I0, a) = Closure ( A → a•A, a/b )
Add all productions starting with A in I3 State because "•" is followed by the non-terminal. So,
the I3 State becomes
I3= A → a•A, a/b
A → •aA, a/b
A → •b, a/b
Go to (I3, a) = Closure (A → a•A, a/b) = (same as I3)
Go to (I3, b) = Closure (A → b•, a/b) = (same as I4)
I4= Go to (I0, b) = closure ( A → b•, a/b) = A → b•, a/b
I5= Go to (I2, A) = Closure (S → AA•, $) =S → AA•, $
I6= Go to (I2, a) = Closure (A → a•A, $)

Add all productions starting with A in I6 State because "•" is followed by the non-terminal. So,
the I6 State becomes
I6 = A → a•A, $
A → •aA, $
A → •b, $
Go to (I6, a) = Closure (A → a•A, $) = (same as I6)
Go to (I6, b) = Closure (A → b•, $) = (same as I7)
I7= Go to (I2, b) = Closure (A → b•, $) = A → b•, $
I8= Go to (I3, A) = Closure (A → aA•, a/b) = A → aA•, a/b
I9= Go to (I6, A) = Closure (A → aA•, $) A → aA•, $
If we analyze then LR (0) items of I3 and I6 are same but they differ only in their
lookahead.
I3 = { A → a•A, a/b
A → •aA, a/b
A → •b, a/b
}
I6= { A → a•A, $
A → •aA, $
A → •b, $
}
Clearly I3 and I6 are same in their LR (0) items but differ in their lookahead, so we can
combine them and called as I36.

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 27


Department of Computer Science and Engineering

I36 = { A → a•A, a/b/$


A → •aA, a/b/$
A → •b, a/b/$
}
The I4 and I7 are same but they differ only in their look ahead, so we can combine them and
called as I47.
I47 = {A → b•, a/b/$}
The I8 and I9 are same but they differ only in their look ahead, so we can combine them and
called as I89.
I89 = {A → aA•, a/b/$}

Drawing DFA:

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 28


Department of Computer Science and Engineering

LALR (1) Parsing table:

LL vs. LR Comparison :

LL LR

Does a leftmost derivation. Does a rightmost derivation in reverse.

Starts with the root nonterminal on the stack. Ends with the root nonterminal on the stack.

Ends when the stack is empty. Starts with an empty stack.

Uses the stack for designating what is still to be


Uses the stack for designating what is already seen.
expected.

Builds the parse tree top-down. Builds the parse tree bottom-up.

Continuously pops a nonterminal off the stack Tries to recognize a right-hand side on the stack,
and pushes the corresponding right hand side. pops it, and pushes the corresponding nonterminal.

Expands the non-terminals. Reduces the non-terminals.

Reads the terminals when it pops one off the Reads the terminals while it pushes them on the
stack. stack.

Pre-order traversal of the parse tree. Post-order traversal of the parse tree.

Automata Theory & Compiler Design Mr. P.Krishnamoorthy Page 29

You might also like