


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
Various topics in programming languages, including advantages and components of compilation and interpretation, lambda calculus, high-level languages, and scheme programming. It also includes examples of parse trees, abstract syntax trees, and lambda term reduction.
Typology: Exams
1 / 4
This page cannot be seen from the preview
Don't miss anything!



(a) Programming languages can be implemented via two approaches: compilation and interpretation. Two advantages of the compilation approach are can afford heavy-weight optimizations and can detect errors early at compile time; two advantages of the inter- pretation approach are can change programs on the fly and are more knowledgable about program behavior. Enumerate two com- ponents that are required to implement both compilers and inter- preters: (1) syntax analysis, (2) semantic analysis. (b) Most programming languages are equivalent in power and can ex- press the class of partial recursive functions, which include all func- tions computable by a modern computer. An example of a non- computable problem is the halting problem. Lambda calculus is a small theoretical language but it is as powerful as practical lan- guages such as C. The pure lambda calculus language supports a single type of value: function abstraction, and supports a single op- eration: function application. A lambda term is in normal form if it can not be further reduced. Lambda terms are said to be confluent because they either have a unique normal form or lead to infinite reductions. (c) High-level languages such as C and Java have advantages over low- level machine languages because they are easier to maintain and are portable (machine independent). These languages can be sepa- rated into different programming paradigms. In particular, The C language belongs to the imperative paradigm, the Scheme language belongs to the functional paradigm, and the Java language belongs to the object-oriented paradigm. A key difference between Scheme and C is Scheme treat functions as first class objects, while C does not (other differences are also acceptable, e.g., Scheme program through expres- sions, while C through modifications and statements.). (d) A higher-order function is a function that takes other functions as parameters or returns a function as result. A language is said to treat functions as first-class objects if it treats functions the same as privative values. C does not treat func- tions as first-class objects because it does not allow functions to be returned as result.
(e) The Lisp abstract machine includes five components: (1) The expression to evaluate, (2) the continuation (the rest of the program) (3) The Association list (variable-to-value map) (4) the cons cells, (5) garbage collector. (f) The lexical syntax of languages can be formally expressed using regular expressions; The context-free syntax of languages can be for- mally expressed using BNF. The difference between concrete and abstract syntax is concrete syntax is what programmers write to precisely express algorithms; abstract syntax is what compilers/interpreters use to internally represent the input program. Compilers/interpreters generally use AST (Abstract Syntax Tree) as a form of internal representation for input programs.
(a) Suppose we have the following grammar, M ::= x | M, M | M ; M where x stands for all variable names. Give a parse tree and an abstract syntax tree for the expression a, b; c, d. Rewrite the gram- mar to be non-ambiguous so that โ;โ is left associative, โ,โ is right associative, and โ,โ has higher precedence than โ;โ.
The parse tree:
M / |
M ; M / | \ / |
M , M M , M | | | | x x x x | | | | a b c d
The AST: ; /
, , / \ /
a b c d
The rewritten grammar. M ::= M ; N | N N ::= x , N | x
(b) Give the context-free grammar for a small language that expresses the coordinates of a collection of objects. In particular, each sen- tence of the language is a sequence of objects separated by โ,โ and
(a) Write a Scheme function count which takes two parameters: x, an atomic value; and y, an arbitrary expression. The function returns how many times that x has appeared in y. For example, invoking (count 3 โ(3 7 9 z s (3 (78 2 3)))) should return 3, and invoking (count โs โ(9 z s (3 (78 s 3)))) should return 2.
(define count (lambda (x y) (cond ((eq? x y) 1) ((cons? y) (+ (count x (car y)) (count x (cdr y)))) (else 0))))
(b) Write a Scheme function collect numbers which takes an arbitrary expression, y, and returns an expression that contains only the num- bers in y (i.e., all the other elements in y are removed). For example, invoking (collect numbers โ((lambda x x x y 3 7) 9 (x z))) should return a list โฒ((3 7) 9).
(define collect_numbers (lambda (y) (cond ((number? y) y) ((cons? y) (let ((first (collect_numbers (car y))) (second (collect_numbers (cdr y)))) (if (null? first) second (cons first second)))) (else โ()))))
int foo(int x, int y) { return x + 2 * y; } int map(f, x1, x2) { return f (f(x1,x2), f(x2, x1)); } int main() { return map (foo, 2, 3); }
(ฮป f. ฮป x1. ฮป x2. f (f x1 x2) (f x2 x1)) (ฮป x. ฮป y. x + 2 * y) 2 3