MT2ProblemsSol.pdf

Computer Science 414
Midterm 2 Practice Problems
Solutions
1. Give the LR(0) states and transitions, as well as the LR(0) parse table, for the following grammars
(a)
Terminals
Non-Terminals
Rules
=
=
=
=
Start Symbol
=
{id, ., [, ], int }
{S, V }
(0) S → V $
(1) V → id
(2) V → V . id
(3) V → V [ V ]
(4) V → V [ int ]
S
1
3
S
V
V
V
V
->
->
->
->
->
.V$
.id
.V <dot> id
.V [ V ]
.V [ int ]
V -> V [ int . ]
2
id
V -> id .
]
int
V
4
6
id
5
V -> V [ int ] .
S
V
V
V
->
->
->
->
V
V
V
V
.
.
.
.
[
$
<dot> id
[ V ]
[ int ]
V
V
V
V
V
V
->
->
->
->
->
->
V
V
.
.
.
.
[ . V ]
[ . int ]
V <dot> id
V [ V ]
V [ int ]
id
<dot>
V
7
[
8
<dot>
V -> V <dot> . id
V
V
V
V
id
10
->
->
->
->
[
V
V
V
V
.
.
.
]
. ]
<dot> id
[ V ]
[ int ]
V -> V [ V ] .
V -> V <dot> id .
1
2
3
4
5
6
7
8
9
10
int
s4
r(1)
id
s6
r(1)
s3
r(4)
s2
r(4)
s10
r(3)
r(2)
r(3)
r(2)
[
]
¡dot¿
$
r(1)
r(1)
s6
r(1)
r(1)
s7
accept
s5
S
g4
g4
r(4)
r(4)
r(4)
r(4)
s5
r(3)
r(2)
s9
r(3)
r(2)
s10
r(3)
r(2)
r(3)
r(2)
Terminals
Non-Terminals
Rules
=
=
=
Start Symbol
=
{a, (, ), $}
{S 0 , S, A}
(0) S 0 → S$
(1) S → SA
(2) S → A
(3) A → (S)
(4) A →a
S0
1
9
V
a
a
2
3
1
a
S’
S
S
A
A
A -> a .
a
->
->
->
->
->
.
.
.
.
.
S $
S A
A
( S )
a
(
A
S
(
A
S
S
A
A
->
->
->
->
->
(
.
.
.
.
. S )
S A
A
( S )
a
A
S
(
4
A
S
A
A
A
->
->
->
->
(
S
.
.
S . )
. A
( S )
a
)
5
S’
S
A
A
->
->
->
->
S
S
.
.
. $
. A
( S )
a
6
S -> A .
7
A -> ( S ) .
(
A
8
1
2
3
4
5
6
7
7
a
s2
r(4)
s2
s2
s2
r(2)
r(3)
r(1)
(
s3
r(4)
s3
s3
s3
r(2)
r(3)
r(1)
S -> S A .
)
$
r(4)
r(4)
s7
r(2)
r(3)
r(1)
accept
r(2)
r(3)
r(1)
S
g5
A
g6
g4
g6
g8
g8
2. Create a set of LR(0) items and transitions for the following grammar. Show that the grammar is not
LR(0). Give the SLR(1) parse table for the grammar.
Terminals
Non-Terminals
Rules
=
=
=
Start Symbol
=
{num, id, [, ], $}
{E 0 , E, V }
(0) E 0 → E$
(1) E → V
(2) E → num
(3) V → id
(4) V → V [E]
E0
2
accept
1
2
$
E
E’
E
E
V
V
->
->
->
->
->
.
.
.
.
.
E$
V
num
id
V[E]
E’ -> E . $
3
num
E -> num .
id
6
V -> id .
V
id
4
num
[
V
V E
E
V
V
E -> V .
V -> V . [E]
->
->
->
->
->
V[ . E]
. V
. num
. id
. V[E]
5
The LR(0) parse table has duplicate entries:
1
2
3
4
5
6
num
s3
id
s6
[
]
$
r(2)
r(1)
s3
r(3)
r(2)
r(1)
s6
r(3)
r(2)
r(1),s5
r(2)
r(1)
accept
r(2)
r(1)
r(3)
r(3)
r(3)
First and follow
Non-Terminal
E0
E
V
E
g2
V
g4
g4
sets:
First
num, id
num, id
id
Follow
$, ]
$, ], [
The SLR(1) parse table:
1
2
3
4
5
6
num
s3
s3
id
s6
[
]
$
s5
r(2)
r(1)
accept
r(2)
r(1)
s6
E
g2
V
g4
g4
r(3)
r(3)
r(3)
3. Standard Java allows loop exits using the “break” and “continue” statements. A “break” statement
leaves the current loop entirely, and a “continue” statement jumps to the end of the current loop. A
break statement can only appear inside a loop or a switch statement, and a continue can only appear
inside a loop. If we add “break” and “continue” to simpleJava, what changes must be made to the
semantic analyzer to ensure that these statements only appear within loops?
For the semantic analyzer, we only need to know if we are currently in a loop or not. Now, we could
just try to use a global (to the iterator) boolean to denote if we were in the loop or not, but that would
be difficult because of nesting loops. Instead, we couuld keep a count of how deeply nested we were in
a loop. Every time a loop starts, increment the depth, and every time it ends, decrement the loop. A
3
break is legal if the nesting level is greater than zero. What about for creating the abstract assembly
tree? We need to know what label to jump to on the break. We could keep a stack of “end loop labels”
– every time we start a loop, push the end of the loop label onto the stack, and every time we end a
loop, pop off the top. Any time we need to generate code for a break or continue, use the label at the
top of the stack.
4. When creating the Abstract Assembly for a function definition, Do we need to store the Stack Pointer
on the stack? What about the Frame Pointer and Return Register? Explain.
We do not need to store the old Stack Pointer on the stack, since we know the size of our stack
frame. Instead, we could just subtract (or add a negative) appropriate offest to the stack pointer at
the beginning of the function call, and then add (or subtract, if negative) the same offset at the end of
the function call. We do, however, need to store the old Frame Pointer and Return register, since we
do not know who called us at compile time.
5. Given the following class definitions, and the local variable declarations in the function foo:
class c1 {
int w;
boolean z;
}
class c2 {
c1 y[];
int z;
}
int foo(int x,y) {
boolean a;
boolean b[];
c1 C;
c2 D[];
/*
Body of foo
*/
}
Give the abstract assembly tree for each of the following statements, if they appeared in the body of
foo:
(a) y++;
Move
MEM
+
+
FP
MEM
1
+
8
FP
8
(b) b[3] = false;
4
Move
0
MEM
MEM
Could simplify this
to 12
*
4
3
4
FP
(c) C.w = x + y;
Move
+
MEM
MEM
MEM
MEM
-
+
+
8
FP
4
FP
8
FP
(d) D[x].z--;
MOVE
-
MEM
1
MEM
-
4
MEM
4
-
MEM
-
MEM
*
MEM
-
*
4
MEM
-
12
FP
4
MEM
+
12
FP
+
4
FP
4
FP
(e) D[C.w].y[x].z = x > 3;
MOVE
MEM
>
3
MEM
8
MEM
+
FP
MEM
4
*
MEM
4
MEM
+
-
4
FP
MEM
*
4
MEM
FP
12
MEM
-
FP
8
(f) while (x < 10) x = x + 3;
5
SEQ
SEQ
Jump
whileTest
SEQ
Label
whileStart
SEQ
Move
MEM
+
+
CJUMP(whileStart)
Label
MEM
whileStart
<
3
10
MEM
FP
4
+
+
FP
4
FP
4
6