-
In C-style array initializers, commas can serve to separate items or
to end items; for example, I could write
int foo[3] = {0,1,2};
int bar[3] = {0,1,2,};
The latter form is useful for long lists, either computer-generated
or human-maintained, which must change from time to time.
- Can you write a grammar for initializer lists for integer arrays?
Your grammar should be LALR(1), and should allow both forms of
the array initializer (with or without the final comma).
- When would you check the arrays to make sure that the initializer
was the right size? And what constitutes
the right size?
- Write an LALR(1) grammar for simple expressions with addition,
subtraction, multiplication, and negation.
- Consider the following code fragment:
class Pop {
int data;
public Pop pop_setter(int x) { data = x; return this; }
public int getter() { return data; }
}
class Kid extends Pop {
int data;
public Pop kid_setter(int x) { data = x; return this; }
public int getter() { return data; }
}
What do the vtable and object data layouts for Kid and Pop look like?
What would you get from this code:
System.out.println(new Kid().kid_setter(10).pop_setter(20).getter());
-
Is the following grammar LALR(1)? If not, why not? What can you
do to fix it?
A -> A + A
A -> B
B -> int
B -> C
C -> C int
C -> int
-
When we run Factorial.java in the MJ interpreter, what does the stack
look like just before the base case returns? Assume we are computing
3!.
-
Suppose we wanted to add range-check statements to MiniJava's expression
syntax. We will use parens or brackets to indicate open or closed
intervals, and a new keyword
in
for testing membership.
1 in [1, 2] // Returns true
1 in (1, 2] // Returns false
i in [0, array.length) // Check validity of an index
Describe what changes (if any) would need to be made to the lexer,
parser, AST syntax, type-checker, and interpreter in order to support
this construction.
-
Java supports not only inheritance, but also interfaces.
An interface defines a set of functions; a class that implements an
interface has definitions for all of those functions. How might you
extend the MiniJava interpreter to support interfaces?
-
Suppose that we allowed overloading in MiniJava, so that we could have
multiple functions with the same name, but different type signatures.
What would need to change in the interpreter to support this? How, and
when, would you decide which version of the function should be used?
Can you describe a procedure to check if there is any possible ambiguity
between two functions (e.g. if a class has methods foo(Pop p)
and foo(Kid k) and Kid extends Pop, then foo(new Kid())
is potentially ambiguous).
-
(Open-ended): You have decided that you want your version of MiniJava to
be strongly typed, but that you also would like to provide as few
type-declarations as possible. How could you augment MiniJava so that
the interpreter knows to create a new local integer variable the first
time it sees an expression like this?
i = i + 1;