CS 326 - Midterm Exam
write a regular expression that describes the following language: the set of strings which starts with an a and conains an even number of b's, over alphabet {a, b}.
a* (b a* b a*) *
write a context-free grammar that describes scheme syntax. the following are examples of legal strings according to this grammar (the angle bracket is not part of the language): > 1 > (+ 2 3) > (* (+ 2 3) (/ 6 2)) > (define a 7) > a
expression -> atom | list atom -> number | ID list -> (exprs) exprs -> expression exprs | ε
indicate the value returned by the following scheme calls: (list '(a b c) '(d))
((a b c) (d))
indicate the value returned by the following scheme calls: (cons '(a b c) '(d))
((a b c) d)
indicate the value returned by the following scheme calls: (append '(a b c) '(d))
(a b c d)
indicate the value returned by the following scheme calls: (define x '(a b c d)) (set-cdr! x (cons (car (cdr x)) (cons 'm (cddr x))))
(a b m c d)
write a recursive function (double-each L), which multiplies by 2 each value in the list L. The following example illustrates the use of this function: > (double-each '(1 2 4 8 16)) (2 4 8 16 32)
(define (double-each L) (cond ((null? L) '()) (else (cons (*2 (car L)) (double-each (cdr L)))) ) )
Write a recursive Scheme function (get-dupes L), which returns a set built from list L by collecting duplicates, if any. You can use the predefined member function. Remember that the order of set elements does not matter. The following example illustrates the use of this function: > (get-dupes ' (4 3 5 3 4 1)) (4 3) Do not use any imperative features of the Scheme programming language.
(define (get-dupes L) (letrec ((dupes (lambda (L V) (cond ((null? L) V) ((member (car L) V) (dupes (cdr L) V)) (else (dupes (cdr L) (cons (car L) V)))))) (result (dupes L '()))) result))
indicate the value returned by the following scheme calls: (car (cdddr ' (3 6 9 12)))
12
What approach can a programmer take to make a recursion more efficient? What does it mean and why is it more efficient?
A tail-recursive function is a recursive function where the recursive call is the last operation performed in the function. They produce faster code because tail-recursive calls may reuse the same space on the stack.
Which of the following is an error reported by the parser in C?
A variable name that begins with a digit
Consider the following Scheme function f: (define (f V L) (cond ( (null? L) 0) ( (equal? V (car L)) (+ 1 (f V (cdr L)))) (else (f V (cdr L))))) Indicate the value returned by the following calls: A. (f 'a ' ()) B. (f 4 ' 2 3 4 3 9 4) ) C. (f 'a ' (b (a c) ada)) D. Is function f tail-recursive? Justify your answer.
A. 0 B. 2 C. 2 D. A function is tail-recursive if the recursive call is the last operation performed in each branch of the cond statement. In the f function, the recursive call is not the last operation because it's followed by addition (+) when (equal? V (car L)) is true.
Consider the following program fragment, written in no particular language: string tag = "i" // global declaration function print_formatted_string (string s) print "<", tag, ">", s, "'</", tag, ">" function emphasize (string s) string tag = "b" print_formatted string (s) begin // main program emphasize ("Hello World!") end A. What does this program print if the language uses static scoping? B. What does it print if the language uses dynamic scoping?
A. <i> Hello World! </i> static scoping (lexical scoping) uses global tag B. <b> Hello Ward! </b> dynamic scoping uses most recent tag
Why are macros useful?
Because they produce faster code, since they avoid the run-time overhead of stack maintenance.
Which of the following best characterizes the difference between declarative and imperative programming languages?
Declarative languages describe what to do; imperative languages describe how to do it.
True or False: Dynamically allocated variables can be initialized automatically at compile time.
False
True or False: Interpreters aren't running during execution, while compilers stay around during execution.
False
True or False: Scheme belongs to the class of imperative programming languages.
False
True or False: The expression 5 + 1 can only denote an 1-value.
False
True or False: There is a one-to-one correspondence between instructions in assembly language and instructions in a high-level language.
False
Is short circuiting useful just because it is more efficient, or can it also change the program behavior (i.e., by computing different results or by avoiding runtime crashes)? If it can, write a short program whose behavior is different depending whether or not the language uses short-circuiting. If not, explain why not.
Short-circuiting in programming is not just about efficiency; it can also change program behavior by avoiding the evaluation of certain expressions or by preventing runtime crashes. int a = 5; int b = 0; // Using short-circuiting with the logical OR (||) operator if (a != 0 || 10 / b == 2) { printf("Short-circuiting: This will be printed.\n"); } else { printf("Short-circuiting: This will not be printed.\n"); } In the first if statement, short-circuiting occurs because of the || operator. The second condition (10 / b == 2) is not evaluated because the first condition (a != 0) is true, and the program does not crash due to the division by zero error.
Given a programming language and its compiler, what is the formal language accepted by the scanner?
The set of all valid tokens in the programming language
True or False: Overloading is a type of polymorphism where several objects are implemented with the same name.
True
True or False: Subroutine closures are used in languages with deep binding.
True
True or False: The scanner analyzes the lexical structure of a program, while the parser analyzes its syntactical structure.
True
