1. As the hint for the problem states, the key is to define the SS class, in particular the Parse() method of that class, appropriately. It should look as follows (in C++ syntax): class SS { private: Stmt* s; SS* ss; public: SS() { s = null; ss = null; } parseSS() { // check next token; if it is an id, s = new Assign() // else if it is "if" s = new If() // else if it is "loop" s = new Loop() // ... etc. s->parseStmt(); // this is polymorphic and will dispatch to the // parse() method of Assign or If etc. depending on the // type of object that s is pointing to. // then check next token; if it is the start of another stmt: { ss = new SS(); ss->parseSS(); return; } // else return; } printSS() { s->printStmt(); if (ss=null) {return;} else {ss->printSS();} } execSS() { // similar to printSS() } What about the Stmt class? It doesn't really have much: class Stmt { // there are some mistakes below ... e.g., return type is missing public: virtual parseStmt() = 0; // equivalent to saying this is an // abstract method virtual printStmt() = 0; // equivalent to saying this is an // abstract method virtual execStmt() = 0; // equivalent to saying this is an // abstract method } That is it for Stmt class. But what purpose does it serve? It just ensures that every kind of will have a parseStmt(), printStmt(), and execStmt() defined on it. Each actual Stmt object will be an instance of Assign, or If, or Loop, or ... class. And each such object will carry three addresses, these being the addresses of the parseStmt(), printStmt(), and execStmt() methods defined in that particular class. So a call such as "s->pringStmt()" in the printSS() method above will be "dispatched" (by the runtime system) to the method defined in the appropriate derived class, Assign, or If, or Loop, etc. What do each of those derived classes look like? They are very similar to how we defined them in class when we didn't use polymorphism. So, e.g., class Loop : public Stmt { // says this is a derived class of Stmt private: Cond* c; SS* ss; public: Loop() { c = null; ss = null; } parseStmt() { // same as we had before except this method is called parseStmt(), not parseLoop() } printStmt() { // same as we had before except this method is called printStmt(), not printLoop() } execStmt() { // same as we had before except this method is called execStmt(), not execLoop() } } And if you were to introduce a new statement, say, [which is a different form of looping], all you would have to do is to define a corresponding new derived class of Stmt which will be very similar to the Loop class. You would also have to rewrite the parseSS() method to allow for the possibility that the first in this might be a . 2. a. This structure must be static because we want only *one* copy of the structure to exist, no matter how many identifiers, i.e., instances of the Id class, are in existence. The purpose of this structure is to keep references to all the existing identifier objects so, clearly, we want a single copy of it. That is what we ensure by specifying that it is static. b. A natural place for all the static entities in a program will be at the *bottom* of the stack (below the space for the stack frames that will be created corresponding to each function/method, including main(), that is executed at run-time). This space will be allocated when the program begins execution (before main() starts execution) and will be released after main() finishes execution, before control returns to the "system"/OS. The key issue is not so much *where* we allocate space for static variables as its *lifetime*. We have to make sure that the same space remains allocated from the start of the execution of the program to the end of its execution. It should not be deallocated (as might happen if it were allocated in the middle of a stack frame) or garbage-collected (as might happen if it is allocated on the heap) etc. So, as a general rule, static objects are allocated space in a separate part of the memory, distinct from both the stack and the heap; and this area of memory remains for use by the program until it finishes execution. --Neelam