Skip to content

Commit be3d0ca

Browse files
committed
[lec14] exam walk-through
1 parent 85bd28a commit be3d0ca

File tree

2 files changed

+321
-2
lines changed

2 files changed

+321
-2
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Material: plt = course book, dragon = Dragon book. Slides follow closely the plt
5151
| Thu 21/11 | 13-15 | Interpreting | [slides](plt-book/ipl-book/slides/5-slides-ipl-book.pdf), plt 5, [script](notes/interpreter.html) |
5252
| Tue 26/11 | 13-14 | Hands-on with Lab 2 (Haskell) | [script](notes/monads.html), [live code](live/2024/lab2-live-haskell.zip) |
5353
| Tue 26/11 | 14-15 | Hands-on with Lab 2 (Java) | [script](notes/java.html), [Annotated.java](notes/Annotated.java) |
54-
| Thu 28/11 | 13-15 **SB-H5** | Code generation | [slides](plt-book/ipl-book/slides/6-slides-ipl-book.pdf), plt 6, dragon 6,7, [notes](notes/compilation.html), [prime.c](notes/prime.c), [prime.j](notes/prime.j) |
54+
| Thu 28/11 | 13-15 **SB-H5** | Code generation | [slides](plt-book/ipl-book/slides/6-slides-ipl-book.pdf), plt 6, dragon 6,7, [script](notes/compilation.html), [prime.c](notes/prime.c), [prime.j](notes/prime.j) |
5555
| Tue 03/12 | 13-14 | Hands-on with Lab 3 (Haskell) | [live code snippet](live/2024/lab3-live-haskell.hs) |
5656
| Tue 03/12 | 14-15 | Hands-on with Lab 3 (Java) | [live code snippet](live/2024/lab3-live-java.java) |
5757
| *Wed 04/12* | *23* | *Lab 2 deadline* | |
@@ -61,7 +61,7 @@ Material: plt = course book, dragon = Dragon book. Slides follow closely the plt
6161
| Thu 12/12 | 14-15 | Hands-on with Lab 4 (Java) | [live code](live/2024/lab4/Interpreter.java) |
6262
| Tue 17/12 | 13-15 | Dependent types (Agda) | live coding [start](live/2024/agda/JVM-start.agda) [stop](live/2024/agda/JVM.agda) |
6363
| *Wed 18/12* | *23* | *Lab 3 deadline* | |
64-
| Thu 19/12 **SB-H5** | 13-15 | Preparing for the exam | [last year's exam](exams/exam-plt-2024-1.pdf) |
64+
| Thu 19/12 **SB-H5** | 13-15 | Preparing for the exam | last year's [exam](exams/exam-plt-2024-1.pdf), live [solution](live/2024/exam.md) |
6565

6666
| 2025 | | | |
6767
|:-----------:|--------------|----------------------|-------------------|

live/2024/exam.md

+319
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
PLT 2024-12-19: Walk through exam
2+
=================================
3+
4+
Q1
5+
--
6+
7+
```
8+
-- Q1: Grammar for some C constructs
9+
10+
-- Question 1 (Grammars): Write a labelled BNF grammar that covers the following kinds of constructs of C:
11+
12+
-- • Program: int main() followed by a block
13+
14+
Prg. Program ::= "int" "main" "(" ")" Block;
15+
16+
-- • Block: a sequence of statements enclosed between { and }
17+
18+
Blk. Block ::= "{" [Stm] "}"
19+
20+
[]. [Stm] ::= ;
21+
(:). [Stm] ::= Stm [Stm];
22+
23+
-- • Statement:
24+
-- – statement formed from an expression by adding a semicolon ;
25+
26+
SExp. Stm ::= Exp ";" ;
27+
28+
-- – initializing variable declarations, e.g., int x = e;
29+
30+
SInit. Stm ::= Type Ident "=" Exp ";" ;
31+
32+
-- – assignment, e.g., x = e;
33+
34+
SAss. Stm ::= Ident "=" Exp ;
35+
36+
-- – loop: while followed by a parenthesized expression and a block
37+
38+
SWhile. Stm ::= "while" "(" Exp ")" Block;
39+
40+
-- • Atomic expression:
41+
-- – identifier
42+
43+
EId. Exp2 ::= Ident ;
44+
45+
-- – integer literal
46+
47+
EInt. Exp2 ::= Integer;
48+
49+
-- – function call with a single argument
50+
51+
ECall. Exp2 ::= Ident "(" Exp ")" ;
52+
53+
-- – pre-increment of identifier, e.g., ++x
54+
55+
EInc. Exp2 ::= "++" Ident;
56+
57+
-- • Expression (from highest to lowest precedence):
58+
-- – atomic expression
59+
-- – addition (+), left-assocative
60+
61+
EAdd. Exp1 ::= Exp1 "+" Exp2;
62+
63+
-- – less-than comparison of integer expressions (<), non-associative
64+
65+
ELt. Exp ::= Exp1 "<" Exp1;
66+
67+
-- coercions Exp 2;
68+
69+
_. Exp ::= Exp1;
70+
_. Exp1 ::= Exp2;
71+
72+
-- – parenthesized expression
73+
_. Exp2 ::= "(" Exp ")";
74+
75+
-- • Type: int or bool
76+
77+
TInt. Type ::= "int";
78+
TBool. Type ::= "bool";
79+
80+
-- Lines starting with # are comments.
81+
82+
comment "#";
83+
84+
-- You can use the standard BNFC categories Integer and Ident and the coercions pragma.
85+
-- Do not use list categories via the terminator and separator pragmas!
86+
```
87+
88+
Q2
89+
--
90+
91+
DFA: States 1(initial) 2 3 4 5(final)
92+
```
93+
1 --S--> 2
94+
2 --A--> 3
95+
3 --c--> 3
96+
3 --S--> 3
97+
3 --A--> 4
98+
4 --A--> 4
99+
4 --c--> 3
100+
4 --S--> 5
101+
```
102+
103+
RE: `SA(c+S)*AA*(c(c+S)*AA*)*S`
104+
105+
Q3
106+
--
107+
108+
```
109+
Start. S ::= M P ;
110+
MEmp. M ::= ;
111+
MBin. M ::= M A "*";
112+
PEmp. P ::= ;
113+
PBin. P ::= A "+" P ;
114+
X. A ::= "x" ;
115+
Y. A ::= "y" ;
116+
```
117+
Step by step, trace the shift-reduce parsing of the expression
118+
```
119+
x*y*y+x+
120+
```
121+
122+
123+
| Stack | Input | Action |
124+
|-------------|------------|----------------|
125+
| | `x*y*y+x+` | Reduce w MEmp |
126+
| M | `x*y*y+x+` | Shift |
127+
| M x | `*y*y+x+` | Reduce w X |
128+
| M A | `*y*y+x+` | Shift |
129+
| M A * | `y*y+x+` | Reduce w MBin |
130+
| M y | `*y+x+` | Reduce w Y |
131+
| M A | `y+x+` | Shift |
132+
| M A * | `y+x+` | Reduce w MBin |
133+
| M | `y+x+` | Shift |
134+
| M y | `+x+` | Reduce w Y |
135+
| M A | `+x+` | Shift |
136+
| M A + | `x+` | Shift |
137+
| M A + x | `+` | Reduce w X |
138+
| M A + A | `+` | Shift |
139+
| M A + A + | | Reduce w PEmp |
140+
| M A + A + P | | Reduce w PBin |
141+
| M A + P | | Reduce w PBin |
142+
| M P | | Reduce w Start |
143+
| S | | Accept |
144+
145+
146+
Q4
147+
--
148+
149+
### Checking statements
150+
151+
```
152+
SExp. Stm ::= Exp ";" ;
153+
SInit. Stm ::= Type Ident "=" Exp ";" ;
154+
SAss. Stm ::= Ident "=" Exp ;
155+
SWhile. Stm ::= "while" "(" Exp ")" Block;
156+
157+
Blk. Block ::= "{" [Stm] "}"
158+
[]. [Stm] ::= ;
159+
(:). [Stm] ::= Stm [Stm];
160+
```
161+
162+
```
163+
Env: stack of blocks each mapping variables names to types
164+
165+
-- mutually defined:
166+
Env check (Env env, Stm s)
167+
Env check (Env env, Block b)
168+
Env check (Env env, [Stm] ss)
169+
170+
-- assuming
171+
Type inferExp (Env env, Exp e)
172+
void checkExp (Env env, Exp e, Type t)
173+
174+
-- cases
175+
176+
check(env, SExp e) = do
177+
t ← inferExp(env, e)
178+
return env
179+
180+
check(env, SInit t x e) = do
181+
if x is in top block of env then error
182+
env1 ← addVar(env, t, x)
183+
checkExp(env1, e, t)
184+
return env1
185+
186+
check(env, SAss x e) = do
187+
t ← lookupVar (env, x) -- throws error if x is not in env
188+
checkExp(env, e, t)
189+
return env
190+
191+
check(env, SWhile e b) = do
192+
checkExp(env, e, TBool)
193+
checkBlock(env, b)
194+
return env
195+
196+
check(env, SBlock ss) = do
197+
env1 ← newBlock(env)
198+
check(env1, ss)
199+
return env
200+
201+
check(env, []) = return env
202+
check(env, s:ss) = do
203+
env1 ← check(env, s)
204+
env2 ← check(env1, ss)
205+
return env2
206+
```
207+
208+
### Evaluating expressions
209+
210+
```
211+
EId. Exp2 ::= Ident ;
212+
EInt. Exp2 ::= Integer;
213+
ECall. Exp2 ::= Ident "(" Exp ")" ; -- omit
214+
EInc. Exp2 ::= "++" Ident;
215+
EAdd. Exp1 ::= Exp1 "+" Exp2;
216+
ELt. Exp ::= Exp1 "<" Exp1;
217+
```
218+
219+
```
220+
Env: maps identifiers to values
221+
222+
Val: either VInt (with an integer)
223+
or VBool (with a boolean)
224+
225+
-- assuming
226+
Val lookupVar (Env env, Ident x)
227+
228+
(Env, Val) eval (Env env, Exp e)
229+
230+
eval(env, EId x) = do
231+
v ← lookupVar(env, x)
232+
return (env, v)
233+
234+
eval(env, EInt i) = return (env, VInt i)
235+
236+
eval(env, EInc x) = do
237+
VInt i ← lookupVar(env, x)
238+
env1 ← updateVar(env, x, i+1)
239+
return (env1, VInt (i+1))
240+
241+
eval(env, EAdd e1 e2) = do
242+
(env1, VInt i1) ← eval(env, e1)
243+
(env2, VInt i2) ← eval(env1, e2)
244+
return (env2, VInt (i1 + i2))
245+
246+
eval(env, ELt e1 e2) = do
247+
(env1, VInt i1) ← eval(env, e1)
248+
(env2, VInt i2) ← eval(env1, e2)
249+
return (env2, VBool (i1 < i2))
250+
```
251+
252+
Q5
253+
--
254+
255+
```
256+
.method public static int main()
257+
.limit locals 3
258+
.limit stack
259+
260+
;; int n=42;
261+
262+
ldc 42
263+
istore 0
264+
265+
;; int i=0;
266+
267+
ldc 0
268+
istore 1
269+
270+
;; int k=0;
271+
272+
ldc 0
273+
istore 2
274+
275+
Lstart:
276+
;; while(k<101)
277+
278+
iload 2
279+
ldc 101
280+
if_icmpge Ldone
281+
282+
;; { n = k;
283+
284+
iload 2
285+
istore 0
286+
287+
;; k = n + ++i; }
288+
289+
iload 0
290+
iinc 1 1
291+
iload 1
292+
iadd
293+
istore 2
294+
295+
goto Lstart
296+
297+
Ldone:
298+
;; printInt(n);
299+
300+
iload 0
301+
invokestatic Runtime/printInt(I)V
302+
303+
ldc 0
304+
ireturn
305+
306+
.end method
307+
```
308+
309+
| Instruction | P | V | S | P' | V' | S' | Condition |
310+
|------------------|---|-----|-----------|-----|----------|-----------|------------|
311+
| `ldc` i | P | V | S | P+1 | V | S.i | |
312+
| `istore` a | P | V | S.i | P+1 | V[a=i] | S | |
313+
| `iload` a | P | V | S | P+1 | V | S.V[a] | |
314+
| `iinc` a i | P | V | S | P+1 | V[a=v+i] | S | v=V[a] |
315+
| `iadd` | P | V | S.i1.i2 | P+1 | V | S.(i1+i2) | |
316+
| `goto` L | P | V | S | L | V | S | |
317+
| `if_icmpge` L | P | V | S.i1.i2 | P+1 | V | S | if i1 < i2 |
318+
| `if_icmpge` L | P | V | S.i1.i2 | L | V | S | if i1 ≥ i2 |
319+
| `invokestatic` m | P | V | S.v | P+1 | V | S.m(v) | m unary |

0 commit comments

Comments
 (0)