CS 152: Compiler Design Final Exam

advertisement
Final Exam
Page 1 of 8
CS 152: Compiler Design
Final Exam
Peter H. Fröhlich
phf@cs.ucr.edu
March 14, 2003
Time: 40 Minutes
Start here: Fill in the following important information using a permanent pen before you do anything
else! Your exam will not be graded if you use a pencil or erasable ink on this page.
Name (print):
Student ID (print):
Login (print):
Cheat Sheet:
Signature:
Instructions: Please read these instructions carefully. Switch off your phones, pagers, and other noisy
gadgets! You can not have anything but your ID, a pen, your cheat sheet, and this exam on your desk.
You can not talk to anyone during the exam. If you have a question, please raise your hand quietly. You
must hand in your cheat sheet with the exam. You must remain seated quietly until all exams have been
collected. You can not claim grading errors if you do not use a permanent pen for your answers. And
finally: Good luck! :-)
Do not open the exam before you are told to do so!
You received
CS 152: Compiler Design
out of 40 points.
Winter 2003
Final Exam
1 Warmup
For each of the following statements, determine whether it is either true or false.
Page 2 of 8
(10 points)
(1 point each)
1. In a single-pass compiler, each compilation phase completes before the next compilation phase
starts.
2. It is not advisable to use a single intermediate representation for compiling both C++ and VAL (a
functional dataflow language).
3. The language produced by L → “y” | “x” L “x” is regular.
4. An LR(k) parser processes tokens from left to right, looks at most k tokens ahead, and performs
left-most reductions.
5. The regular expression (“a”|“b”)+ , the EBNF grammar E = {“a”|“b”} , and the BNF grammar
B → “a” B | “b” B | generate the same language.
6. In S IMPLE, the declaration CONST y = 0 + y + 1; leads to an error because we can not
apply constant folding to its expression.
7. Weak symbols can be used to re-synchronize the parser with the input stream after a syntax error
occurred.
8. Good error handling, although driven mostly by heuristics, is indispensable for production quality compilers.
9. The primary concern when developing static analyses that help with code optimization is that they
terminate quickly.
10. In terms of instruction selection, implementing a code generator for a RISC architecture is generally easier than implementing one for a CISC architecture.
CS 152: Compiler Design
Winter 2003
Final Exam
Page 3 of 8
2 Hard Choices
For each of the following questions, circle one answer out of the choices given.
(8 points)
(2 points each)
1. Consider the task of recognizing keywords during lexical analysis. Assume a large set of potentially
long keywords. Which of the following techniques is most appropriate (“efficient”)?
(a) Binary search on a sorted array of keywords.
(b) A switch on the first letter followed by cascaded if instructions.
(c) A hash table with a perfect hash function.
(d) An optimal binary search tree.
(e) None of the above.
2. Consider the syntax for declarations in S IMPLE (see also page 8). In both VarDecl and Type we
find the fragment {IdentifierList ":" Type ";"}. How can we simplify the grammar,
the parser, and the generation of symbol tables (all three at once)?
(a) Replace the fragment with {VarDecl} in Type.
(b) Split Type into NamedType, ArrayType, and RecordType, then do (a).
(c) Move "CONST", "VAR", and "TYPE" up into Declarations, then do (a).
(d) Do (b) but not yet (a), then do (c) including (a).
(e) None of the above.
3. Consider building a compiler for C and PASCAL which will generate code for x86 and PowerPC
platforms, with specific optimizations for about 10 members of each family. What compiler architecture is least suitable for this task?
(a) A multi-pass compiler consisting of separate programs communicating through files.
(b) A multi-pass compiler using source-level abstract syntax trees and a shared symbol table.
(c) A tightly integrated single-pass compiler with a shared symbol table.
(d) Since all of these can be made to work, I don’t prefer one or the other.
(e) None of the above.
4. Consider a language with parallel assignments such as “x, y := y, x” to swap the values of
two variables. Which evaluation strategy is most appropriate for this construct?
(a) Evaluate corresponding “pairs” in sequence, i.e. “x := y; y := x”.
(b) Evaluate corresponding “pairs” in reverse, i.e. “y := x; x := y”.
(c) Evaluate all designators (left side) into addresses first, then follow (a).
(d) Evaluate all expressions (right side) into values first, then follow (b).
(e) None of the above.
CS 152: Compiler Design
Winter 2003
Final Exam
Page 4 of 8
3 Syntactic Analysis
(8 points)
Consider logical expressions made up of the operators “and”, “or”, and “not”, as well as identifiers and
parenthesis “(” and “)”. Similar to S IMPLE’s arithmetic expressions (see page 8), these operators have
different precedences: “not” binds the strongest, followed by “and”, followed by “or”. For example,
the expression
a or not b and c
should be parsed as
(a or ((not b) and c))
which is a legal expression itself. Identifiers are defined below, and you should assume that operators are
treated as keywords (tokens).
1. Give a context-free grammar for logical expressions that models operator precedence and is suitable
for an LL(1) parser. Hint: This just asks for a grammar, it does not ask you to change the S IMPLE
grammar.
(6 points)
identifier = letter { letter } .
letter = "a" .. "z" | "A" .. "Z" .
2. If you were to add logical expressions to S IMPLE, what would you change in the concrete syntax
(see page 8) besides productions related to Expression?
(2 points)
CS 152: Compiler Design
Winter 2003
Final Exam
Page 5 of 8
4 Symbol Tables
(4 points)
Consider the following S IMPLE program and sketch the symbol table (ST) that should be generated for
it by the parser. You do not have to sketch an abstract syntax tree, but you must indicate pointers to it
where necessary (just label them “AST”).
PROGRAM ST;
TYPE A = ARRAY 1 OF INTEGER;
TYPE R =
RECORD
s, t:
RECORD
x, y: ARRAY 1 OF INTEGER;
END;
END;
END ST.
CS 152: Compiler Design
Type
Scope
Cons
tant
Varia
ble
Winter 2003
Final Exam
Page 6 of 8
5 Abstract Syntax Trees
(4 points)
Consider the following S IMPLE program and sketch the abstract syntax tree (AST) that should be generated for it by the parser. Include “the usual” AST transformations. You do not have to sketch a symbol
table, but you must indicate pointers to it where necessary (just label them “ST”).
PROGRAM AST;
TYPE A = ARRAY 3 OF
RECORD
x, y: INTEGER;
END;
VAR a: A;
BEGIN
READ a[1].y;
END AST.
CS 152: Compiler Design
Type
Node
Cons
tant
Varia
ble
Winter 2003
Final Exam
6 Code Generation
Page 7 of 8
(6 points)
Consider the following S IMPLE program and give the V MICS code that should be generated for it. You
must include a sketch of storage allocation for data memory, as well as the addresses of all instructions
in code memory. You can ignore bounds checking for arrays. You can not be smarter than the compiler
would be. Please comment your code to make sure that we can grade it easily; if things are too confusing,
we’ll ignore those parts we can’t make sense of.
PROGRAM VMICS;
CONST s = 16;
VAR i: INTEGER;
VAR a: ARRAY s OF INTEGER;
BEGIN
i := 0;
REPEAT
a[i] := i
UNTIL i > s END
END VMICS.
CS 152: Compiler Design
Winter 2003
Final Exam
Page 8 of 8
This page is intentionally mostly blank in case you run out of space elsewhere. If you
ended up here early, please go over everything again and remain seated quietly! You should
probably check that the title page is filled out using a permanent pen. Maybe you want to
“rewrite” your answers as well to be able to claim grading errors? If you’re really bored,
try this: Who can make a broken program work by breaking it some more?
Program = "PROGRAM" identifier ";" Declarations
["BEGIN" Instructions] "END" identifier "." .
Declarations = { ConstDecl | TypeDecl | VarDecl } .
ConstDecl = "CONST" {identifier "=" Expression ";"} .
TypeDecl = "TYPE" {identifier "=" Type ";"} .
VarDecl = "VAR" {IdentifierList ":" Type ";"} .
Type = identifier | "ARRAY" Expression "OF" Type |
"RECORD" {IdentifierList ":" Type ";"} "END" .
Expression = ["+"|"-"] Term {("+"|"-") Term} .
Term = Factor {("*"|"DIV"|"MOD") Factor} .
Factor = number | Designator | "(" Expression ")" .
Instructions = Instruction {";" Instruction} .
Instruction = Assign | If | Repeat | While |
Read | Write .
Assign = Designator ":=" Expression .
If = "IF" Condition "THEN" Instructions
["ELSE" Instructions] "END" .
Repeat = "REPEAT" Instructions
"UNTIL" Condition "END" .
While = "WHILE" Condition "DO" Instructions "END" .
Condition = Expression ("="|"#"|"<"|">"|"<="|">=")
Expression .
Write = "WRITE" Expression .
Read = "READ" Designator .
Designator = identifier Selector .
Selector = {"[" ExpressionList "]" | "." identifier} .
IdentifierList = identifier {"," identifier} .
ExpressionList = Expression {"," Expression} .
CS 152: Compiler Design
Mnenomic
Opcode
Data
Description
halt
error
push
pop
dup
swap
out
in
add
sub
mul
div
mod
load
store
$00
$01
$10
$11
$12
$13
$20
$21
$30
$31
$32
$33
$34
$40
$41
value
value
-
jump
jneg
jeql
jpos
$50
$51
$52
$53
value
value
value
value
stop execution
stop execution with error code
push value on stack
pop value from stack
duplicate top of stack
swap top two stack values
print pop()
push( input_value )
r = pop(); l = pop(); push( l+r
r = pop(); l = pop(); push( l-r
r = pop(); l = pop(); push( l*r
r = pop(); l = pop(); push( l/r
r = pop(); l = pop(); push( l%r
a = pop(); push( memory[a] )
a = pop(); v = pop();
memory[a] := v
pc := value
if pop() < 0 then pc := value
if pop() = 0 then pc := value
if pop() > 0 then pc := value
)
)
)
)
)
Winter 2003
Download