Bup PDF
Bup PDF
Bup PDF
BOTTOM-UP PARSING
Bottom up parsing is another parsing strategy in which we start with the input string and try to obtain the
start symbol of the grammar using successive reductions. If we could reduce the input string to the start
symbol, the parse is successful otherwise it is unsuccessful. The reduction traces out the rightmost derivation
in the reverse order. The rightmost derivation in reverse is a natural choice for bottom up parsers because
rightmost sentential forms have the property that all symbols beyond the rightmost non terminal are terminal
symbols. The most important aspect of bottom up parsing is the process of detecting handles and using them
in reductions.
A general form of bottom-up parsing is called shift reduce parsing. Shift Reduce parsing attempts to
construct a parse tree for an input string beginning at the leaves (bottom) and working towards the root (top).
We can think of this process as one of reducing a string to the start symbol of a grammar. The shift reduce
parsing consists of shifting input symbols onto a stack until the right side of a production appears on top of
the stack. The right side may then be replaced by (reduced to) the symbol on the left side of the production
and the process is repeated.
A rightmost derivation in reverse can be obtained by “handle pruning”. That is, we start with a string of
terminals w that we wish to parse. If w is a sentence of the grammar at hand, then w = n, where n is the nth
right-sentential form of some as yet unknown rightmost derivation
S = 0 1 2 … n-1 n = w.
Viable prefixes: The set of prefixes of right sentential forms that can appear on the stack of a shift reduce
parser are called viable prefixes. A viable prefix of a right sentential form is a prefix which does not extend
beyond the right end of its handle. That is, prefixes of right sentential forms do not contain any symbols to
the right of the handle. A viable prefix is, so called because it is always possible to add terminal symbols to
the end of a viable prefix to obtain a right sentential form(rm).
Parsing by handle pruning requires two problems to be solved. The first is to locate the substring to be
reduced in a right-sentential form, and the second is to determine what production to choose in case there is
more than one production with that substring on the right side.
Implementation of a shift-reduce parser uses a stack to hold grammar symbols and an input buffer to hold
the string w to be parsed. We use $ to mark the bottom of the stack and also the right end of the input.
Initially, the stack is empty, and the string x is on the input as follows:
STACK INPUT
$ x$
The parser operates by shifting zero or more input symbols onto the stack until a handle is on top of the
stack. The parser then reduces to the left side of the appropriate production. The parser repeats this cycle
until it has detected an error or until the stack contains the start symbol and the input is empty.
STACK INPUT
$S $
After entering this configuration, the parser halts and announces successful completion of parsing.
There are four possible actions a shift-reduce parser can make: (1) shift, (2) reduce, (3) accept, and (4) error.
1. In a shift action, the next input symbol is shifted onto the top of the stack.
2. In a reduce action, the parser knows the right end of the handle is at the top of the stack. It must then
locate the left end of the handle within the stack and decide with what non terminal to replace the
handle.
3. In an accept action, the parser declares as successful completion of parsing.
4. In an error action, the parser encounters that a syntax error has occurred and calls an error recovery
routine.
Solution:
Stack Input Operation
$ id1 + id2 + id3 $ shift
$ id1 + id2 + id3 $ reduce by (4)
$T + id2 + id3 $ reduce by (3)
$E + id2 + id3 $ shift
$E+ id2 + id3 $ shift
$ E + id2 + id3 $ reduce by (4)
$E+T + id3 $ reduce by (2)
$E + id3 $ shift
$E+ id3 $ shift
$ E + id3 $ reduce by (4)
$E+T $ reduce by (2)
$E $ reduce by (1)
$S $ accept
1. $ id1+id2*id3$ shift
2. $id1 +id2*id3$ reduce by E -> id
3. $E +id2*id3$ shift
4. $E+ id2*id3$ shift
5. $E+id2 *id3$ reduce by E ->id
6. $E+E *id3$ shift
7. $E+E* id3$ shift
8. $E+E*id3 $ reduce by E-> id
9. $E+E*E $ reduce by E -> E*E
10. $E+E $ reduce by E->E+E
11. $E $ accept
Example Consider the following grammar where the productions are numbered as shown below:
E -> E + T {PRINT ‘1’}
E -> T { PRINT ‘2’ }
T -> T * F { PRINT ‘ 3’ }
T -> F { PRINT ‘ 4’ }
E -> ( E ) { PRINT ‘5’ }
F -> id { PRINT ‘6’ }
If a shift – reduce parser writes the production number immediately after performing any production , what
string will be printed if the parser input is id+id*id
Solution:
Stack Input Operation
$ id + id * id$
$ id + id * id $ Shift
$F + id*id $ Reduced by F -> id Print ‘6’
$T +id * id $ Reduced by T -> F Print ‘4’
$E +id * id $ Reduced by E -> T Print ‘2’
$E+ id * id $ Shift
$ E + id * id $ Shift
$E+F * id $ Reduced by F -> id Print ‘6’
$E+T * id $ Reduced by T -> F Print ‘4’
$E+T* id $ Shift
$ E + T * id $ Shift
$E+T*F $ Reduced by F -> id Print ‘6’
$E+T $ Reduced by T -> T * F Print ‘3’
$E $ Reduced by E -> E + T Print ‘1’
Therefore the final string obtained is ‘64264631’.
Example : A shift reduces parser carries out the actions specified within braces immediately after reducing
with the corresponding rule of the following grammar:
S -> xxW PRINT ‘1’
S -> y PRINT ‘2’
W -> Sz PRINT ‘3’
If a shift – reduce parser writes the production number immediately after performing any production , what
string will be printed if the parser input is xxxxyzzz
Solution:
Input Applicable Production Transformed Input Output
x - - -
xx - - -
xxx - - -
xxxx - - -
xxxxy S->y xxxxS 2
xxxxS - - 2
Operator-Precedence Parsing
There are some important class of grammars, we can easily construct efficient shift-reduce parsers by hand.
These grammars have the property that no production on the right side has two adjacent non
terminals(variables) or is empty string . A grammar with the first property is called an operator grammar.
That is in an operator grammar, any sentential form cannot contain two consecutive non-terminals. A
grammar is an operator grammar if it contains no productions of the form S -> αABβ, where α, β are
terminal strings and A, B are non-terminals. Thus two non-terminals cannot occur side by side on the right
hand side of a production, but must be separated by at least one terminal symbol.
To obtained operator grmammar replace P by right side strings P-productions. The resultant grammar S-
productions S -> S+S| S-S | S*S | S/S | S S/(E) | -E | id is an operator grammar.
In operator-precedence parsing, we define three disjoint precedence relations, <∙, = and ·>, between certain
pairs of terminals. These precedence relations guide the selection of handles and have the following
meanings:
Relation Meaning
a <· b a “precedence to” b
a=b a “has the same precedence as” b
a ·> b a “takes precedence over” b
An operator precedence grammar is an € free operator grammar in which at most one of the relations: <·, =,
·> holds between any pair of terminals.
Using Operator-Precedence relations
The intention of the precedence relations is to delimit the handle of a right sentential form, with <· marking
the left end, = appearing in the interior of the handle, and ·> marking the right end.
The handle can be found by the following process.
Scan the string from the left end until the first ·> is encountered.
Then scan backwards (to the left) over any +’s until a <· is encountered.
The handle contains every thing to the left of the first ·> and to the right of the <· encountered in
step 2, including any intervening or surrounding non terminals.
α a b β
Fig : a = b
If there exists a production S -> αAbβ, A -> raδ, then they need to be reduced to A before b can take part on
a reduction to S.
α A b β
r a δ
Fig : a ·>b
If there exists a production S -> αaBβ, B -> rbδ, then b needs to be reduced prior to a to S.
S
α a B β
r b δ
P -> (E) | id
Sentential form: E + id * id
E + T
T * F
F P
P id
id
Fig : Parse tree for E + id * id
From above tree we can observe that
+ <· id id will be reduced before +
id ·> * id will be reduced before *
* <· id id will be reduced before *
+ <· * * will be reduced before +
Example : Consider the following grammar:
S -> S + S | S - S | S * S | S / S | S S | (S) | - S | a
Assuming
1. is of highest precedence and right association.
2. * and / are next highest precedence and left association.
3. + and – are of lowest precedence and left associative.
2. If Q1 and Q2 are operators of equal precedence, then make Q1·>Q2 and Q2·>Q1 , if the operators
are left associative, or make Q1<·Q2 and Q2<·Q1 if they are right associative.
Expression Handle
S-S+S S-S therefore, +,- are left associative
+ ·> + ->-
+ ·> - ->+
S S S last S S therefore, right associative
<·
3. Make Q<· id, id·>Q, Q<·(, (<·Q, )·>Q, Q·>), Q·>$, $<·Q for all operators Q. Also let:
(=) $ <· ( $ <· id
( <· ( id ·> $ ) ·> $
( <· id id ·> ) ) ·> )
$ serves as both the left and right end marker.
These rules ensure that both id and (S) will be reduced to S.
Now trace the following input strings for the above grammar by the operator precedence relations.
i. id * ( id +id )
ii. id * ( id id ) – id / id
+ - * / a ( ) $
+ ·> ·> <· <· <· <· <· ·> ·>
- ·> ·> <· <· <· <· <· ·> ·>
* ·> ·> ·> ·> <· <· <· ·> ·>
/ ·> ·> ·> ·> <· <· <· ·> ·>
·> ·> ·> ·> <· <· <· ·> ·>
a ·> ·> ·> ·> ·> Error Error ·> ·>
( <· <· <· <· <· <· <· = Error
) ·> ·> ·> ·> ·> Error Error ·> ·>
$ <· <· <· <· <· <· <· Error Error
Parsing of id * ( id + id ):
Step Sentential form Handle Reduction
1. $<·a·>*<(<·a·>+<·a·>)·>$ a X1 -> a
2. $X1<·*<·(<·a·>+<·a·>)·>$ a X2 -> a
3. $X1<·*<·(X2<·+<·a·>)·>$ a X3 -> a
4. $X1<·*<·(X2<·+X3·>)·>$ X2+X3 X4->X2+X3
5. $X1<·*<·(X4=)·>$ (X4) X5 -> (X4)
6. $X1<·*X5·>$ X1*X5 X6-> X1*X5
7. $X6$
E
X6
E * E
X1 * X5
a ( E )
a ( X4 X)
E + E
X2 + X3
a a
a a
h k A + * $
a E ·> ·> ·>
+ <· ·> <· ·>
* <· ·> ·> ·>
$ <· <· <· E
ka ha
h* k*
k+ h+
h$ k$
a + * $
h 4 2 4 0
k 5 1 3 0
Fig : Resulting Precedence Functions
LR Parsers
This technique is an efficient, bottom-up parser technique that can be used to parse a all class of context-free
grammars. This technique is called LR(k) parsing; the “L” is for left-to-right scanning of the input, the “R”
for constructing a rightmost derivation in reverse, and the k for the number of input symbols of lookahead
that are used in making parsing decisions. When (k) is omitted, k is assumed to be 1.
INPUTt a1 … ai … an $
LR
STACK sm Parsing Program OUTPUT
Xm
sm-1
Xm-1
…
Action Goto
s0
Fig : Model of LR Parsing
The parsing program reads characters from an input buffer one at a time. The program uses a stack to
store a string of the form s0X1s1X2s2…Xmsm, where sm is on top. Each Xi is a grammar symbol and each si is
a symbol called a state. Each state symbol summarizes the information contained in the stack below it, and
the combination of the state symbol on the top of the stack and the current input symbol are used to index
the parsing table and determine the shift-reduce parsing decision.
The parsing table consists of two parts, a parsing action function Action and a Goto function Goto.
The program driving the LR parser behaves as follows. It determines sm, the state currently on top of the
stack, and ai, the current input symbol. It then consults action[sm, ai], the parsing table entry for stat sm and
input ai, which can have one of four values:
1. shift s, where s is a state
2. reduce by a grammar production A ,
3. accept, and
4. error.
The function goto takes a state and grammar symbol as arguments and produces a state. A
configuration of an LR parser is a pair whose first component is the stack contents and whose second
component is unexpected input:
(s0X1s1X2s2…Xmsm, aiai+1…an$)
This configuration represents the right-sentential form
X1X2…Xmaiai+1…an
is essentially the same way as a shift-reduce parser would; only the presence of states on the stack is new.
The next move of the parser is determined by reading ai, the current input symbol, and sm, the state
on top of the stack, and then consulting the parsing action table entry action[sm, ai]. The configurations
resulting after each of the four types of move are as follows:
1. If action[sm, ai] = shift s, the parser executes a shift move, entering the configuration
(s0X1s1X2s2…Xmsmais, ai+1…an$)
2. If action[sm, ai] = reduce A , then the parser executes a reduce move, entering
the configuration
(s0X1s1X2s2…Xm-rsm-rAs, aiai+1…an$)
where s = goto [sm-r, A] and r is the length of , the right side of the production.
3.If action[sm, ai] = accept, parsing is completed.
Prepared by T.Aruna Sri, Dept of CSE Page 11
UNIT 3 ---Bottom-Up parsing Techniques
4. If action[sm, ai] = error, the parser has discovered an error and calls an error recovery routine.
Sol :
As grammar is augmented grammar , we can start construction of LR(0) items directly with augmented
production S’ -> .SC.
LR(0) items :
(b) goto(I0 , S)
S -> S.A
S’ -> S.C
A -> .aSb
A -> .ab
goto(I0 , A)
S -> A.
goto(I0 , a)
A -> a.Sb
A -> a.b
S -> .SA
S -> .A
A -> .aSb
A -> .ab
goto(I1 , C)
S’ -> SC.
goto(I1 , A)
S -> SA.
goto(I3 , S)
A -> aS.b
S -> S.A
A -> .aSb
A -> .ab
goto(I3 , b)
A -> ab.
goto(I6 , b)
A -> aSb.
The GOTO graph for the given grammar is constructed as shown in below Fig
I0 I1
I4
C
S S’ -> S.C
S’ -> .SC S -> S.A S’ -> SC.
S -> .SA A -> .aSb
S -> .A A -> .ab I5
A -> .aSb I2 A
A -> .ab A S -> SA.
S -> A.
A I8
a A
I3 a A -> aSb.
I6
a A -> a.Sb
A -> a.b S b
S -> .SA A -> aS.b
S-> .A S -> S.A
a A -> .aSb
A -> .aSb
A -> .ab I7A -> .ab
A -> ab.
b
:
Fig : GOTO Graph
S
S' -> S S' -> S.
ε ε
( ε
ε
S -> (.S)S ε
S
S -> (S.) S
) S -> (S)S.
S -> (S).S
S
Fig : NFA of LR(0) Items
LR Grammars
A grammar for which we can construct a parsing table is said to be an LR grammar. An LR parser does not
have to scan the entire stack to know when the handle appears on top. Rather, the state symbol on top of the
stack contains all the information it needs.
There is a significant difference between LL and LR grammars. For a grammar to be LR(k), we must be able
to recognize the occurrence of the right side of a production, having seen all of what is derived from the
right side with k input symbols of lookahead. This requirement is far less stringent than that for LL(k)
grammars where we must be able to recognize the use of a production seeing only the first k symbols of
what its right side derives.
If G is a grammar with start symbol S, then G', the augmented grammar for G, is G with a new start symbol
S and production S' S. The purpose of this new starting production is to indicate to the parser when it
should stop parsing and announce acceptance of the input. That is, acceptance occurs when and only when
the parser is about to reduce by
S' S.
LR (0) items:
S’ -> .S
S -> .CC
C -> .aC
C -> .b
The GOTO graph for the given grammar is drawn in below Fig 7.10
I1
I0
S S’ -> S. I5
S’ -> .S
S -> .CC
C -> .aC S -> CC.
I2
C -> .b
C
c S -> C.C C
C -> .aC
C -> .b
d d
I6
I4
I3 c
C -> aC.
C -> a.
C -> a.C
C -> .aC C
a C -> .b
c
Fig : GOTO Graph
ACTION GOTO
State A b $ S C
0 Shift 4 Shift 3 1 2
1 Accept
2 Shift 4 Shift 3 5
3 Shift 4 Shift 6 6
Reduce by Reduce by Reduce by
4
C->b C->b C->b
Reduce by S Reduce by S Reduce by
5
-> CC -> CC S -> CC
Reduce by Reduce by Reduce by
6
C -> aC C -> aC C -> aC
The procedures closure and goto and the main routine items for constructing the sets of items are given
below.
function closure(I);
{
repeat
for each item [A ., a] in I,
each production B in G,
and each terminal b in FIRST(a)
such that [B ., b] is not in I do
add [B ., b] to I;
until no more items can be added to I;
return I
}
items(G);
{
C := {closure9{[S .S, $]})};
repeat
for each set of items I in C and each grammar symbol X
such that goto(I, X) is not empty and not in C do
add goto(I, X) to C
until no more sets of items can be added to C
}
(b) The LR(1) items for the grammar G are derived as shown below :
I0 :
S’ -> .S , {$}
S -> .BB , {$}
B -> .cB , {c,d}
B -> .d , {c,d}
I1 : goto(I0, S)
S’ -> S. , {$}
I2 : goto(I0,B)
S -> B.B , {$}
B-> .cB , {$}
B -> .d , {$}
I3 : goto(I0,c)
B-> c.B , {c,d}
B -> .cB , {c,d}
B -> .d , {c,d}
I4 : goto(I0,d)
B-> d. , {c,d}
I5 : goto(I2,B)
S -> BB. , {$}
I6 : goto(I2,c)
B -> c.B , {$}
B -> .cB , {$}
B -> .d , {$}
I7 : goto(I2,d)
B -> d. {$}
I8 : goto(I3,B)
B -> cB. , {c,d}
I9 : goto(I6,B)
B-> cB. , {$}
Below Fig shows the GOTO graph constructed for the sets of LR(1) items :
I0
I1 I2
S’ -> .S , {$} B
S’ -> S. , {$} S -> B.B , {$}
S S -> .BB , {$}
B -> .cB , {$}
B -> .cB , {c,d}
B -> .d , {$}
B-> .d , {c,d}
I4 d I7 d
B -> d. , {c,d} B
c B -> d. , {$} c
I5
d
I3 I6 d
c
B -> c.C , {c,d} S -> BB. , {$}
B -> c.B , {$}
B -> .cC , {c,d}
B -> .cB , {$}
B -> . d , {c,d}
B -> .d , {$}
I9
I8 B B -> cB. , {$}
C
B -> cB. , {c,d}
S -> A
A -> BA | ε
B -> aB | b
(i) Construct an CLR parsing table.
(ii) Find the action of LR(1) parser on input : aabb
Sol: Productions can be written as
(1) A -> ε
(2) A -> BA
(3) B -> b
(4) B -> aB
(i) The canonical parsing table for the given grammar is given in Table:
Action GOTO
State a b $ A B
Reduce by
0 Shift 3 Shift 4 1 2
A -> ε
1 Accept
Reduce by
2 Shift 3 Shift 4 5 2
A -> ε
3 Shift 3 Shift 4 6
Reduce by Reduce by Reduce by
4
B -> b B -> b B -> b
Reduce by Reduce by
5
A -> BA A ->BA
Reduce by Reduce by Reduce by
6
B -> aB B -> aB B -> aB
1. Consider sets of item I3 and I6 are replaced by their merge of second componets, therefore we get
new sets item I36
2. Now lets us consider another sets of item I4 and I7 are replaced by their merge result, therefore we
get new sets item I47
LALR Parsing table for given grammar can be constructed as shown in Table :
Action GOTO
State c d $ S B
0 Shift 36 Shift 47 1 2
1 Accept
2 Shift 36 Shift 47 5
36 Shift 36 Shift 47 89
Reduce by Reduce by Reduce by
47
B ->d B->d B ->d
Reduce by
5
B ->cB
Reduce by Reduce by Reduce by
89
B -> cB B -> cB B ->cB
The declarations section for definitions, if present, must be the first section in the YACC program. The
mandatory rules section follows the definitions; if there are no definitions, then the rules section is first. In
both cases, the rules section must start with the delimiter %%. If there is a subroutines section, it follows
the rules section and is separated from the rules by another %% delimiter. If there is no second %%
delimiter, the rules section continues to the end of the file.
When all sections are present, a specification file has the format:
declarations
%%
rules
%%
subroutines
The example that follows is a complete yacc specification. The sample program generates a parser which
takes input in the form:
month day , year
This input is converted to output in the form:
day month year
In the example, the declarations section defines a data structure used to hold the values associated with
tokens, and declares all the token names used in the rules section. The rules section contains one rule and an
action associated with it. The subroutines section defines a function that is called in the action.
%union
{
char *text;
int ival;
}
%token t_DAY
%token t_MONTH
Prepared by T.Aruna Sri, Dept of CSE Page 22
UNIT 3 ---Bottom-Up parsing Techniques
%token t_YEAR
%%
date : t_MONTH t_DAY ',' t_YEAR
{ print_date ($2,$1,$4); };
%%
void print_date(d,m,y)
char *m;
int d,y;
{
printf("%d %s %d\n",d,m,y);
}
The parser uses a lexical analyzer that can return the tokens t_DAY, t_MONTH, and t_YEAR, and also can
associate each token with some value.
Practice:
S A#
A bB
B cC
B cCc
C dA
Aa
(i) Generate the sets of LR(1) items.
(ii) Is the grammar SLR(1)
(iii) Is the grammar LR(1)
If not why not?
3) What is LR(1) passing?
Construct canonical LR parse table for the following grammar
S → Aa | bAc | bBa
A→d
B → d.
4) Consider the following augmented grammar :
S -> E
E -> E + T | T
T -> a | (E)
Construct the SLR(1) parse table
5) Construct LR(0) parser for the following grammar :
S -> cA | ccB
A -> cA | a
B -> ccB | b
4. A language L is designed as [ ]
(a)set of symbols over given (b)set of strings of symbols over given
(c)set of alphabets (d)all of the above
10. What is the RE for the language, set of strings with at least one 1, one 2 and one 3?
(a)1+2+3 (b)11*22*33* (c)1*2*3* (d)both a&b [ ]
Cont2
18. A parse tree showing the values of attributes at each node is called as _____________
-oOo-
1.A sound type system eliminates _____,when the target program runs. [ ]
a)Type errors b)runtime errors c)compile type errors d)none
3.____________ determines the type of a language construct from the way it is used. [ ]
a)Type synthesis b)Type inference c)Type reference d)None
8. The code generator, produces the target program from the transformed ______. [ ]
a)High level code b)Low level code c) Intermediate code d)All the above
Cont..[2]
12. The runtime representation of an object program in the logical address space consists of ___________.
14. The activations of procedures during the running of an entire program by a tree called _________.
15. The substitution of values for names whose values are constant is known as ______.
17. If a transformation of a program performed by locking only at the statements in a basic blocks, called
________________.
18. The code improvement phase consists of _____________ followed by the application of transformation.
20. The relative address for a field name is relative to the __________ for that record.
-oOo-
5. The code generator, produces the target program from the transformed ______. [ ]
a)High level code b)Low level code c) Intermediate code d)All the above
10.____________ determines the type of a language construct from the way it is used. [ ]
a)Type synthesis b)Type inference c)Type reference d)None
Cont..[2]
11. The activations of procedures during the running of an entire program by a tree called _________.
12. The substitution of values for names whose values are constant is known as ______.
14. If a transformation of a program performed by locking only at the statements in a basic blocks, called
________________.
15. The code improvement phase consists of _____________ followed by the application of transformation.
17. The relative address for a field name is relative to the __________ for that record.
19. The runtime representation of an object program in the logical address space consists of ___________.
-oOo-
3. The code generator, produces the target program from the transformed ______. [ ]
a)High level code b)Low level code c) Intermediate code d)All the above
8.____________ determines the type of a language construct from the way it is used. [ ]
a)Type synthesis b)Type inference c)Type reference d)None
Cont..[2]
1. [ ]
d)All the above
[ ]
[ ]
a)Copy propagation b)Flow of control c)Constant folding d)dead-code elimination
6.____________ determines the type of a language construct from the way it is used. [ ]
a)Type synthesis b)Type inference c)Type reference d)None
Cont..[2]
11. The code improvement phase consists of _____________ followed by the application of transformation.
13. The relative address for a field name is relative to the __________ for that record.
15. The runtime representation of an object program in the logical address space consists of ___________.
17. The activations of procedures during the running of an entire program by a tree called _________.
18. The substitution of values for names whose values are constant is known as ______.
20. If a transformation of a program performed by locking only at the statements in a basic blocks, called
________________.
-oOo-
1. (a) Consider the following declaration grammar & write the translation scheme
for identifying the type of the identifier:
P D; E
D D; D/id : T
T char/int/ T/array[num]ofT
Find the type of each entry.
(b) Consider following grammar:
E num.num/literal/num/E%E/E+E/ E''E / *E / E[E]
Construct semantic rules to find type of expression. [8+8]
2. (a) Describe in English the sets denoted by the following regular expressions:
i. [00 + 11 + (01 + 10)(00 + 11) (01+ 10) ]
ii. 10+(0+11)0*1
(b) Prove following identities for regular expressions r, s & t. Here r=s means
L(r)=L(s)
i. (r*s*)*=(r+s)*
ii. (r+s)+t=r+(s+t)
5. (a) Generate code for the following C statements. Assume all the variables are
static and three registers are available:
i. x=a+b*c
ii. x=a/(b+c)-d*(e+f)
(b) Generate code for the following C statements. Assume all the variables are
automatic and three registers are available:
i. x=a+b*c
ii. x=a/(b+c)-d*(e+f) . [8+8]
1
UNIT 3 ---Bottom-Up parsing Techniques
8. (a) What are the merits & demerits of recursive descent parsing.
(b) Explain predictive parsing in detail. [8+8]
?????
2
UNIT 3 ---Bottom-Up parsing Techniques
2. (a) Discuss lexical scoping with nested procedures and without nested procedures.
(b) Describe the method to obtain faster access to nonlocals. [8+8]
(a) (rs+r)*s=r(sr+r)*
(b) (r+s)*=r*+s*
(c) s(rs+s)*r=rr*s(rr*s*)
(d) r(s+t)=rs+rt [16]
?????
Prepared by T.Aruna Sri, Dept of CSE Page 35
3
UNIT 3 ---Bottom-Up parsing Techniques
1. (a) What is left recursion? Remove left recursion from following grammar:
S Aa/b
A Ac/Sd/
(b) Check for LL(1) for following grammar:
prog begin d semi X end
X d semi X/sY
Y semi s Y/. [6+10]
3. (a) Consider following grammar & identify the type of subexpression. Use type
error as a type expression in error condition.
E literal/num/id/EmodE/E[E]/ E
(b) Write about type checking. Consider following C declarations:
typedef struct
int a, b;
CELL,*PCELL;
CELL foo[100];
PCELL bar(x,y)
int x;
CELL y..
Write type expressions for the types of foo and bar. [8+8]
4. (a) Discuss lexical scoping with nested procedures and without nested procedures.
(b) Consider the following code:
prog copyint()
var a:int
proc unsafe(var x;int)
begin x=2, a=0 end
begin
a=1
unsafe(a);
Prepared by T.Aruna Sri, Dept of CSE Page 36
4
UNIT 3 ---Bottom-Up parsing Techniques
5. Generate code for the following C statements. Assume all the variables are static
and three registers are available:
(a) x=a+b*c
(b) x=a/(b+c)-d*(e+f)
(c) a[i][j]=b[i][k]*c[k][j]
(d) a[i]+=b[j] [16]
(a) dominators.
(b) natural loops.
(c) inner loops.
(d) preheaders. [16]
?????
37
5
UNIT 3 ---Bottom-Up parsing Techniques
4. (a) Consider following grammar & identify the type of subexpression. Use type
error as a type expression in error condition.
E literal/num/id/EmodE/E[E]/ E
6. (a) Compare and contrast the quadruples, triples & indirect triples.
6
Code No: 45116 R07 Set No - 4
(b) What is the significance of syntax- directed definition. [8+8]
?????
39