(16 points) Consider the following grammar for pre-fix expressions:
Exp -> Atom | Opn
Atom -> number | id
Opn -> ( + Exp_List )
| ( * Exp_List )
Exp_List -> Exp_List Exp
| Exp
- Write a leftmost derivation for the string (+ a 23 (* 16 44))
- Draw a parse tree for the string of part (a).
(16 points) Suppose you have the following C++ code:
class Menu {
protected:
string selectedItem;
list *menuItems;
public:
getSelectedItem() { return selectedItem }
Menu(list *items) { menuItems = items; }
virtual void draw() = 0;
};
class PulldownMenu : public Menu {
public:
void draw() {
...
code that references selectedItem and menuItems
...
}
};
Answer the following questions:
- Logically, is PulldownMenu lexically nested within Menu?
Answer "yes" or "no".
- Write down the list of scope ids that get created and which
name creates them. I will start your list:
0: predefined names
1: global names
2: Menu
- Based on the LeBlanc-Cook symbol table presented in class,
draw a picture of what the symbol table records for the following
names might look like:
- Menu
- selectedItem
- draw in PulldownMenu
For example (this example is from the book--I know that A2
is not declared in the above code):
-------------------------------------
| Name Category Scope Type |
| A2 param 4 int |
-------------------------------------
For your answer:
- Do not bother with the "other" field and do not draw a
symbol table. I only want to see what the records for
these three names should look like.
- Fill in the type field with the actual type of the
name, if it has one.
(23 points) Suppose you have the following assembly pseudo-code:
(1) r1 = A
(2) r2 = B
(3) r2 = r1 + r2
(4) C = r2
(5) r1 = D
(6) r2 = r1 + 5
(7) E = r2
Assume that loads and stores to memory have a one-cycle delay
(i.e., require 2 CPU cycles) and
that arithmetic can be done in a single cycle. Answer the
following questions:
- For each CPU "cycle" shown below, write the number of the
instruction that would execute during that cycle or write
"delay" if there is a load/store delay. Complete the first
row of cycles before starting the second row of cycles.
I have intentionally
provided more cycles than are required--leave the excess ones
blank.
_______ _______ _______ _______ _______ _______ _______ _______
_______ _______ _______ _______ _______ _______ _______ _______
- List one flow dependence between two instructions (e.g., 7->5)
- List one anti-dependence between two instructions (e.g., 7->5)
- List one output dependence between two instructions (e.g., 7->5)
- Rewrite the above instructions in the same order, but use
register renaming to remove the anti and output dependencies.
- Using your register renaming, reorder the
instructions to produce a more efficient
instruction schedule. Rather than writing out the instructions,
just show me the new schedule below by filling in the CPU
slots with either an instruction or the word "delay". You
will not be able to eliminate all the delays (minimally there
will be a delay after the last store instruction). More
efficient instruction schedules (i.e., instruction schedules
that require fewer cycles) will receive more credit than
less efficient instruction schedules.
_______ _______ _______ _______ _______ _______ _______ _______
_______ _______ _______ _______ _______ _______ _______ _______