Midterm Exam 1 with Resolution - Programming Languages and Compilers | CS 421, Exams of Computer Science

Material Type: Exam; Class: Progrmg Languages & Compilers; Subject: Computer Science; University: University of Illinois - Urbana-Champaign; Term: Unknown 1989;

Typology: Exams

Pre 2010

Uploaded on 03/16/2009

koofers-user-sdc
koofers-user-sdc 🇺🇸

9 documents

1 / 12

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CS 421 Midterm 1 Name:____________________________________ 1
CS421 Spring 2008 Midterm
Wednesday, February 27, 2008
You have 60 minutes to complete this exam.
This is a closed-book exam.
Do not share anything with other students. Do not talk to other students. Do not look at
another students exam. Do not expose your exam to easy viewing by other students.
Violation of any of these rules will count as cheating.
If you believe there is an error, or an ambiguous question, you may seek clarification
from one of the TAs. You must use a whisper, or write your question out. Speaking out
aloud is not allowed.
Including this cover sheet, there are 12 pages to the exam. Please verify that you have
all 12 pages.
Please write your name and NetID in the spaces above, and also at the top of every
page.
Question Possible points Points earned
1 6
2 12
3 6
4 8
5 8
6 10
7 10
8 10
9 10
10 10
11 10
Total 100
Name:
NetID:
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download Midterm Exam 1 with Resolution - Programming Languages and Compilers | CS 421 and more Exams Computer Science in PDF only on Docsity!

CS421 Spring 2008 Midterm

Wednesday, February 27, 2008

  • You have 60 minutes to complete this exam.
  • This is a closed-book exam.
  • Do not share anything with other students. Do not talk to other students. Do not look at another student’s exam. Do not expose your exam to easy viewing by other students. Violation of any of these rules will count as cheating.
  • If you believe there is an error, or an ambiguous question, you may seek clarification from one of the TAs. You must use a whisper, or write your question out. Speaking out aloud is not allowed.
  • Including this cover sheet, there are 12 pages to the exam. Please verify that you have all 12 pages.
  • Please write your name and NetID in the spaces above, and also at the top of every page. Question Possible points Points earned 1 6 2 12 3 6 4 8 5 8 6 10 7 10 8 10 9 10 10 10 11 10 Total 100

Name:

NetID:

  1. (6 pts) Give the types of each of the following Ocaml functions:

(a) let alwaysfour x = 4

val alwaysfour : 'a -> int

(b) let add x y = x + y

val add : int -> int -> int

(c) let concat x y = x ^ y

val concat : string -> string -> string

(d) let addmult x y = (x + y, x * y)

val addmult : int -> int -> int * int

(e) let rec f x = if x=[] then [] else hd x @ f (tl x)

val f : 'a list list -> 'a list

(f) let rec copy x = if x=[] then [] else hd x :: copy (tl x)

val copy : 'a list -> 'a list

  1. (6 pts) Given type definition type ‘a tree = Node of ‘a * (‘a tree) list we define a tree as a labeled node with zero or more children. For example, let t1 = Node(1, [Node(2, [Node(3, []); Node(4, [])]); Node(5, [Node(6, []); Node(7, [])])]) represents the tree

Define the mutually recursive functions preorder : ‘a tree -> ‘a list and preorder_list : (‘a tree) list -> ‘a list such that preorder t gives the pre- order traversal of t, and preorder_list appends the pre-order traversals of its component trees together. Your functions should be mutually recursive. You may use @ or append.

E.g. preorder t1 = [1;2;3;4;5;6;7]

let rec preorder (Node(x, ts)) = x::preorder_list ts

and preorder_list lst = match lst with [] -> [] | t::ts -> preorder t @ preorder_list ts

  1. (8 pts) An identifier is any sequence of one or more characters 'a' - 'z' that is not a keyword. Our language recognizes identifiers and the keywords 'of' and 'as'. Give a deterministic finite- state machine that recognizes our language. Each state should be labeled with either S (start state), O ('of' keyword), A ('as' keyword) or I (identifier).
  2. (8 pts) Write an ocamllex specification for tokens of the following type:

type token = PLUS | MINUS | INT of int

where these represent, respectively, the sequences “+”, “-“, and any string of one or more characters '0' - '9'. (You will want to use the function int_of_string: string → int.)

rule tokenize = parse ‘+’ { PLUS } | ‘-‘ { MINUS } | [‘0’-‘9’]+ as i { INT (int_of_string i) }

  1. (10 pts) Given the following ambiguous grammar

E → E. id |! E | E [ E ] | id

a) Give a sentence that has two distinct parse trees. Show the parse trees.

! a. b (or !a[b], as well as others)

b) Explain how you might disambiguate the grammar using ocamlyacc precedence and associativity declarations. You are free to choose the precedence order and associativity of operators, but you must say what declarations you would use and what effect they would have. Assume the following declaration:

%token DOT IDENT BANG LBRACK RBRACK

%left DOT %nonassoc BANG %nonassoc LBRACK

These declarations give precedence to BANG over DOT, so the above sentence would be parsed as the tree on the right. It also gives precedence to LBRACK, which has an ambiguity as noted above.

  1. (10 pts) Suppose we are given grammar that contains the following rules:

Expression → "do" Stmt "while" "(" Expression ")" | Stmt ";" Expression | Ident

Assume the token type is

type token = DO | WHILE | LPAREN | RPAREN | SCOLON | IDENT of string

the abstract syntax for the Expression non-terminal is

type exp = DoWhile of stmt * exp | Sequence of stmt * exp | Id of string

and you are provided with the parseStmt function of the following type.

parseStmt: token list -> stmt * token list

Implement the parseExp: token list -> exp * token list function. Ignore error cases. Also, assume that DO and IDENT are not in FIRST(Stmt).

let rec parseExp toks = match toks with DO::rest -> ( match parseStmt rest with (st, WHILE::LPAREN::rest2) -> match parseExp rest2 with (e, RPAREN::etc) -> (DoWhile(st, e), etc) ) | IDENT s::rest -> (Id s, rest) | _ -> ( match parseStmt toks with (st, SCOLON::rest) -> match parseExp rest with (e, etc) -> (Sequence(st, e), etc) )

(where NEG, ZERO, and POS are new keywords). It would execute S0, S1, or S2, depending upon the value of e, and then jump to the end of the CIF statement (like a regular IF). Furthermore, any of the three statements can contain a break statement, which exits from the CIF statement. Give a compilation scheme for CIF. [CIF (e) { NEG S0 ZERO S1 POS S2 }] =

let (I, t) = [e] L0, L1, L2, L3, L4 = fresh labels in I t1 = t < 0 CJUMP t1, L0, L L0: [S0] (^) L JUMP L L1: t1 = t == 0 CJUMP t1, L2, L L2: [S1] (^) L JUMP L L3: [S2] (^) L L4:

  1. (10 pts) Some languages have a “break-to-label” construct. In these languages, any statement can be labeled, and if a statement labeled L contains a “break L”, it jumps to the end of the labeled statement. For example, in such a language:

while (cond) { … break; … }

and

while (cond) { … continue;

is equivalent to

L: while (cond) { … break L; … }

is equivalent to

while (cond) { L: { … break L; … } }

… } To generate code for such a language, you need to handle two new kinds of statements, labeled statements and break-to-label. For various reasons, we cannot assume that the labels that appear in source programs are the same as the labels in IR code, so we still have to generate new labels when generating code. Define a scheme

[ S ]T = instruction list

where T is a table mapping source-level labels to IR labels. You can use the following operations: add: table -> source-label -> IR-label -> table get: table -> source-label -> IR-label genlabel: unit -> IR-label.

Define [L: S] (^) T and [break L] (^) T

[L: S] (^) T = let L0 = genlabel() in let newT = add T L L in [S]newT L0:

[break L] (^) T = let L0 = get T L in JUMP L