









Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Material Type: Exam; Professor: Kamin; Class: Progrmg Languages & Compilers; Subject: Computer Science; University: University of Illinois - Urbana-Champaign; Term: Spring 2010;
Typology: Exams
1 / 17
This page cannot be seen from the preview
Don't miss anything!










(a) (1pt) let f = 3.
float
(b) (1pt) let f x = x + 2
int → int
(c) (1pt) let f x y = if x then y else y *. 2.
bool → float → float
(d) (1pt) let f (x, y) z = (x, y, z)
‘a * ‘b → ‘c → ‘a * ‘b * ‘c
(e) (1pt) let f (x, y) (a, b) = if x = a then y else b
‘a * ‘b → ‘a * ‘b → ‘b
(f) (2pt) let rec f x y = match x with [] -> y | a::b -> a::f b y ‘a list → ‘a list → ‘a list
(g) (3pt) let f (x, y) = match x with [] -> [x; y] | :: -> [y; x] ‘a list * ‘a list → ‘a list list
(b) (6pts) Write a function rev : ’a list -> int -> ’a list such that rev xl n re- turns a list of the first n elements of xl in reverse order, followed by the remaining elements in their original positions. You can assume that n is between 0 and the length of xl.
Examples:
let rec rev_aux xl rl n = if n <= 0 then rl@xl else match xl with [] -> rl | x::xs -> rev_aux xs (x::rl) (n - 1)
let rev xl n = rev_aux xl [] n
let rec is_square_aux n m = if m > n then false else if m * m = n then true else is_square_aux n (m + 1)
let is_square n = is_square_aux n 0
(a) An int is a either the digit ‘0’ by itself, or a digit ‘1’ - ‘9’ followed by zero or more digits ‘0’ - ‘9’. Your states should be labeled Start, Error, or Int.
(b) A hexadecimal constant, or hex, is “0x” followed by a sequence of one or more hexadec- imal digits (‘0’ - ‘9’, ‘A’ - ‘F’, ‘a’ - ‘f’). Your states should be labeled Start, Error, or Hex.
(c) An octal constant is ‘0’ followed by a sequence of one or more octal digits (‘0’ - ‘7’). (Note that a single ‘0’ is not a valid octal constant.) Your states should be labeled Start, Error, or Octal.
(d) Give a DFA that recognizes ints, hexes and octals. Your states should be labeled Start, Error, Int, Hex, or Octal.
Int
1-
0-
Start Error Hex 0 0-9, A-F, a-f
0-9, A-F, a-f
Int x
Octal
0- 0-
Please write your solution to the problem from the previous page here:
let digit = [’0’ - ’9’] let hexdigit = [’0’ - ’9’, ’A’ - ’F’, ’a’ - ’f’] let octdigit = [’0’ - ’7’]
rule tokenize = parse
(* add your rules below *)
| ’+’ { PLUS } | ’’ { TIMES } | (’0’ | [’1’-’9’] digit) as s { INT (int_of_string s) } | ’0’ octdigit+ as s { OCTAL (octal_of_string s) } | "0x" hexdigit+ as s { HEX (hex_of_string s) }
S → | S + S | S * S
(a) (1pt) Give a sentence that has two parse trees.
(b) (1pt) Show the two parse trees.
S
S
1.0 + 1.
S
S
1.0 + 1.
(c) (3pts) Based on those parse trees, show a stack/lookahead configuration where there are two different actions - either a shift and a reduce, or two different reduces - that would lead to the two parse trees shown, and say which action leads to which tree.
Here the central. separates the stack from the remaining input. Shifting results in the first parse tree; reducing results in the second.
exception Parse_failure type token = LBRACKET | RBRACKET | LPAREN | RPAREN | COMMA | SEMICOLON | INT of int
We want to write a recursive descent parser recognizing the language of lists of pairs of integers (e.g. [], [(1, 2)], [(1, 2); (3, 4); (0, 1)].) Note that pair items are separated by a comma and list items are separately by semicolons. Your parser should have the following signature:
parse : token list -> bool
parse takes in a list of tokens and returns true if the corresponding string is in the language. If the string is not in the language, parse raises the exception Parse_failure.
(a) (5 pts.) Write a grammar for this language. Make sure it is not left-recursive and does not require an “obvious” left-factoring (i.e. there are no two productions for any non-terminal that begin exactly the same).
P → ( , ) U → | ; P U
Note: Alternatively, you can use tokens (LBRACKET, etc...) in the above grammar.
(b) (5 pts XC) Argue that your grammar is LL(1) by showing that the FIRST sets of right- hand sides do not overlap. (You can ignore FOLLOW sets, even if your grammar has -productions.)
In regards to T: First() = {•}, whereas First(P U ) =First(P ) = {(}, so there is no intersection
In regards to U: First() = {•}, whereas First(; P U ) = {; }, so there is no intersection.
(c) (5 pts) Write a recursive-descent parser based on this grammar.
let rec parse_S toks = match toks with LBRACKET::toks’ -> ( match parse_T toks’ with RBRACKET::toks’’ -> toks’’ | _ -> raise Parse_failure ) | _ -> raise Parse_failure and parse_T toks = match toks with LPAREN::_ -> parse_U (parse_P toks) | _ -> toks and parse_P toks = match toks with LPAREN::INT _::COMMA::INT _::RPAREN::toks’ -> toks’ | _ -> raise Parse_failure and parse_U toks = match toks with SEMICOLON::toks’ -> parse_U (parse_P toks’) | _ -> toks
let parse toks = match parse_S toks with [] -> true | _ -> raise Parse_failure
(a) True False OCaml is a statically typed language
(b) True False OCaml employs automatic memory management
(c) True False Any program written in OCaml is guaranteed to terminate, due to OCaml’s strong type system
(d) True False In OCaml, every element of a tuple must have the same type
(e) True False Every LL(1) grammar is unambiguous
(f) True False Every unambiguous grammar is LL(1)
(g) True False Nested comments can be recognized by a regular expression
(h) True False LR(1) parsers are capable of recognizing any context-free language
(i) True False LR(1) (bottom-up) parsers cannot handle left recursion.
(j) True False The use of let rec instead of let provides a note to the programmer that a function is recursive, but has no significance to the OCaml compiler.
Write a function counts : ’a list -> (’a * int) list.
counts xl returns a list of n pairs, where n is the number of distinct elements in xl. The ith pair is (x, j) where x is the ith distinct element of xl (ordering distinct elements of xl by first occurrence in xl), and j is the total number of times x occurs in xl. Example:
let rec count_instance a xl = match xl with [] -> [(a, 1)] | (b, n)::xs -> if b=a then (a, n + 1)::xs else (b, n)::count_instance a xs
let rec counts_aux xl rl = match xl with [] -> rl | x::xs -> counts_aux xs (count_instance x rl)
let counts xl = counts_aux xl []