-------------------------------------------------------------------------- Software Design and Development Winter 1997 COM1205 Karl Lieberherr --------------------------------------------------------------------------- Midterm --------------------------------------------------------------------------- Open book and open notes. Question 1: 20 UNKNOWNs, 1 point each: 20 points Question 2: 2 unknowns, 20 points each: 40 points Question 3: 18 UNKNOWNS, 3 points each: 54 points Question 4: 25 UNKNOWNs, 3 points each: 75 points TOTAL: 189 /proj/asl/lieber/java/new-java-envs/t1/for-www To make the grading easier, please put your values for the unknowns on the enclosed answer sheet. THE GAME OF REDUNDANCY AND UNKNOWNS ----------------------------------- Most of the questions in this exam ask you to determine unknowns of the form UNKNOWN1, UNKNOWN2, ... This makes it easier for you to answer the questions, since you get extra context information. Yet you need to master the behavioral objectives of the course to answer the questions. Guessing an answer is not a successful strategy and therefore a "game of redundancy" test is more interesting than a multiple choice test. The questions have the following pattern: I show you several artifacts which are related by the theory of object-oriented design and programming. Because of the dependencies between the artifacts, some of the information is redundant and can be recovered from the context by applying the objectives covered in the course. The information which you should discover is marked UNKNOWNx. If an unknown is not uniquely determined, mark the answer with *CHOICE*. An unknown may be anything, e.g., a number, an identifier, a character, two identifiers with a blank between them, a string etc. If an unknown is the empty string, give NOTHING as answer, e.g., UNKNOWN = NOTHING. Example: 5 + UNKNOWN1 = 8 UNKNOWN1 = 3 --------------- UNKNOWN2 * UNKNOWN3 = 20 UNKNOWN2 = 4 *CHOICE* UNKNOWN3 = 5 *CHOICE* At the beginning of a question we give the number of points per unknown. Question 1: 20 UNKNOWNs, 1 point each: 20 points This question is about object serialization: taking an object and producing a sentence, using the visitor design pattern. It covers the following behavioral objectives of chapter 14 in the AP-book: Class dictionary textual representation (31) Printing (34) Parsing (38) Propagation operator (59) It covers the design patterns: Structure-shy Traversal Structure-shy Object (covered by the objectives above) Selective Visitor Note: The class dictionary below defines a different notation than Demeter/Java uses. Also, the PrintingVisitor defines a printing function which is different than the usual one. Consider the following class dictionary called TraversalPP: TraversalPP = "traversal-pp" ClassName FunctionName Args Body. Body = "{" Initialize Traversal VisitorMethods "}". Initialize = "initialize" JavaCode. Traversal : Simple | Compound. Simple = [ From ] Constraints To. Compound = Op Traversals. Op : Join. Join = "join". From = "from" ClassName. To = "to" ClassName. Constraint = [ Bypassing] Through. Bypassing = "bypassing" Edges. Through = "through" Edges. Edge = "->" ClassName LabelName ClassName. Arg = JavaTypeName Variable. VisitorMethod : Before | After *common* ClassNames JavaCode. Before = "before". After = "after". // Terminal-Buffer rule ClassName = Ident. JavaTypeName = Ident. Variable = Ident. LabelName = Ident. FunctionName = Ident. JavaCode = Text. // Repetition-Buffer rule Args = "(" [ CList(Arg) ] ")". ClassNames = "{" CList(ClassName) "}". VisitorMethods = NList(VisitorMethod) . Traversals = "(" CList(Traversal) ")". Edges = NList(Edge). Constraints = List(Constraint). // Repetition classes CList(S) ~ S {"," S}. NList(S) ~ S {S}. List(S) ~ {S}. Main = . // Visitors PrintingVisitor = . The behavior file program.beh is: TraversalPP { (@ void g_print() { PrintingVisitor pv = new PrintingVisitor(); this.t(pv); } @) traversal t(PrintingVisitor pv) {to *;} } Main { (@ static public void main(String args[]) throws Exception { TraversalPP a = TraversalPP.parse(System.in); a.g_print(); System.out.println(" "); } @) } PrintingVisitor{ before TraversalPP (@ System.out.println(" traversal-pp "); @) after TraversalPP (@ System.out.println(" "); @) before Body (@ System.out.println(" { "); @) after Body (@ System.out.println(" } "); @) before Initialize (@ System.out.println(" initialize "); @) before Join (@ System.out.println(" join "); @) before From (@ System.out.println(" from "); @) before To (@ System.out.println(" to "); @) before Bypassing (@ System.out.println(" bypassing "); @) before Through (@ System.out.println(" through "); @) before Edge (@ System.out.println(" -> "); @) before Before (@ System.out.println(" before "); @) before After (@ System.out.println(" after "); @) before ClassName (@ System.out.println (" " + host.get_n() + " "); @) before JavaTypeName (@ System.out.println (" " + host.get_name() + " "); @) before Variable (@ System.out.println (" " + host.get_name() + " "); @) before LabelName (@ System.out.println (" " + host.get_name() + " "); @) before FunctionName (@ System.out.println (" " + host.get_name() + " "); @) before JavaCode (@ System.out.println (" " + "(" + "@" + host.get_code() + "@" + ")" + " "); @) before Args (@ System.out.println(" ( "); @) after Args (@ System.out.println(" ) "); @) before ClassNames (@ System.out.println(" { "); @) after ClassNames (@ System.out.println(" } "); @) before Traversals (@ System.out.println(" ( "); @) after Traversals (@ System.out.println(" ) "); @) } The input program.input is: traversal-pp int sum_salaries(X x, Y y) { initialize (@ 0 @) bypassing -> A b B -> X y Y through -> K l L -> M n N to Salary before {Company, X} (@ @) before {Salary, Y} (@ @) } What is the output of the program? Find the UNKNOWNs below. java Main < program.input traversal-pp UNKNOWN1 UNKNOWN2 UNKNOWN3 UNKNOWN4 UNKNOWN5 UNKNOWN6 UNKNOWN7 UNKNOWN8 UNKNOWN9 UNKNOWN10 UNKNOWN11 UNKNOWN12 UNKNOWN13 UNKNOWN14 UNKNOWN15 UNKNOWN16 UNKNOWN17 UNKNOWN18 UNKNOWN19 UNKNOWN20 rest of output eliminated Question 2: 2 unknowns, 20 points each: 40 points This question reuses question 1. One line in the program program.beh has changed and you need to figure out which one and how it was changed based on the new input/output behavior of the program. Class dictionary TraversalPP as in question 1. The input is the same as in question 1. traversal-pp int sum_salaries(X x, Y y) { initialize (@ 0 @) bypassing -> A b B -> X y Y through -> K l L -> M n N to Salary before {Company, X} (@ @) before {Salary, Y} (@ @) } The output is: java Main < program.input traversal-pp { bypassing -> b -> y through -> l -> n } What is the changed line before the change? Put it into UNKNOWN1 What is the changed line after the change? Put it into UNKNOWN2 Question 3: 18 UNKNOWNS, 3 points each: 54 points We reuse the program and class dictionary of question 2 (with the change to the behavior file done in question 2): In this questions you have to figure out what the input was based on the given output: input: UNKNOWN1 R find(X x) UNKNOWN2 initialize (@ new R(); @) UNKNOWN3 UNKNOWN4 K UNKNOWN5 L UNKNOWN6 M UNKNOWN7 N UNKNOWN8 UNKNOWN9 A UNKNOWN10 B UNKNOWN11 X UNKNOWN12 Y UNKNOWN13 UNKNOWN14 S UNKNOWN15 T UNKNOWN16 P UNKNOWN17 Q to R before {R} (@ return_val = this; @) UNKNOWN18 output: traversal-pp { through -> l -> n bypassing -> b -> y through -> t -> q } Question 4: 25 UNKNOWNs, 3 points each: 75 points This question is about programming with visitors. We reuse the class dictionary from question 1 and add the following classes: SelectiveVisitor = PrintingVisitor SelectorVisitor. SelectorVisitor = Integer. The SelectiveVisitor is used in combination with a traversal to target C. When the traversal arrives at C, the SelectiveVisitor will interrogate the selector visitor soV to check whether this C-object should be processed. If the answer is positive, the C-object is processed by a traversal using the visitor in doingV. The reuse information for the SelectiveVisitor is as follows: Parameters: ---------------------------------------------------- t: A traversal. Where: A class which is the target of traversal t. t2: a traversal to process Where-objects. WhatVisitor: What needs to be done. A visitor class for traversing Where-objects. IfVisitor: Decides if something needs to be done. A visitor class for traversal t. ---------------------------------------------------- Visitor classes: SelectiveVisitor = // used with t WhatVisitor // used with t2 IfVisitor. // work done before entering Where-objects IfVisitor = Integer. Example: t = from TraversalPP to JavaCode t2 = from JavaCode to * Where = JavaCode WhatVisitor = PrintingVisitor IfVisitor = SelectorVisitor Define a traversal t(WhatVisitor,IfVisitor) with Target(t) = Where. SelectiveVisitor has a before method at Where: SelectiveVisitor{ before Where (@ if (soV.get_selected().intValue() == 1) { host.t2(doingV); soV.set_selected(new Integer(0)); } @) } The IfVisitor makes the selection decision and stores it in selected. Since SelectiveVisitor has a before method at Where, the IfVisitor must have made its decision before the Where-object is entered. Now we apply the SelectiveVisitor to print for a given TraversalPP-object all JavaCode-objects which are contained in a Before-object: Find the UNKNOWNs below: TraversalPP { (@ void selective_visit() { // a method using three visitors: // SelectiveVisitor: finds objects of class JavaCode // SelectorVisitor: determines which objects of // class JavaCode should be processed depending on whether // they are contained in some class Before. // assumes JavaCode-objects are contained in Before-objects. // PrintingVisitor: determines how selected objects // should be processed UNKNOWN1 sov = new UNKNOWN2(new Integer(0)); UNKNOWN3 siv = new UNKNOWN4(new UNKNOWN5(), UNKNOWN6); this.all(UNKNOWN7,UNKNOWN8); } @) traversal all(SelectorVisitor sov, SelectiveVisitor siv) { to UNKNOWN9;} } JavaCode { traversal UNKNOWN10(UNKNOWN11 doingV) { to *;} } Main { (@ static public void main(String args[]) throws Exception { TraversalPP a = TraversalPP.parse(System.in); a.selective_visit(); System.out.println(" "); } @) } SelectiveVisitor{ before UNKNOWN12 (@ if (UNKNOWN13.UNKNOWN14().UNKNOWN15() == 1) { host.UNKNOWN16(UNKNOWN17); UNKNOWN18.UNKNOWN19(new UNKNOWN20(0)); } @) } SelectorVisitor { before UNKNOWN21 (@ UNKNOWN22(UNKNOWN23 UNKNOWN24(UNKNOWN25)); @) } input: traversal-pp int sum_salaries(X x, Y y) { initialize (@ 0 @) to Salary before {Company, X} (@ // before @) after {Salary, Y} (@ // after @) before {Y} (@ // before2 @) } output: (@ // before @) (@ // before2 @)