-------------------------------------------------------------------------- Object-oriented Systems Fall 1995 COM 3360/NTU SE737 --------------------------------------------------------------------------- Assignment 2 Due date: Monday, Oct. 9 NTU: one week later --------------------------------------------------------------------------- This assignment is stored in file $OO/hw/2 in file assign.txt THEME: Writing class dictionary graphs You also identify several errors which can be made in class dictionaries and propagation patterns. ========= On CCS Northeastern machines, OO=/course/com3360 On the WWW, OO = http://www.ccs.neu.edu/research/demeter/course ========= Use the following header for your written homework submissions and put it at the top of the first page: Course number: COM 3360 / NTU SE737 (whichever applies) Name: Account name: Assignment number: Date: Put the solutions to this homework into directory /proj/adaptive3/projects/com3360-f95/YOUR_LOGIN/hw2 Whenever you have questions about course material, please send e-mail to: mail lieberherr@ccs.neu.edu ccs.courses.com3360@ccs.neu.edu Background tasks: - Frequently asked questions When you have questions use your editor to search file /ccs/ftp/pub/people/lieber/faq/Demeter-FAQ which is also at URL: ftp://ftp.ccs.neu.edu/pub/people/lieber/faq/Demeter-FAQ - Quick reference guide See file $OO/doc/Demeter-Tools-C++Quick-Reference and a copy is also in section 18.2, page 578 in my book. PART A: ====================================================================== Do Assignment 2 on page 547 of the textbook. Relevant parts are reproduced below to save you typing. Part 1: WRITING A POCKET CALCULATOR IN C++ (without Demeter) ------------------------------------------------------------ What to turn in: The C++ program fragment which you wrote. This part exercises a larger subset of C++ than hw 1. Specifically, you use now virtual functions. Write a C++ program to evaluate prefix expressions. You only have to write the data structure part and constructor functions. Your program should behave like a pocket calculator, e.g. the object corresponding to :Compound( :Mulsym :Compound ( :Addsym :Numerical ( :DemNumber "1") :Numerical ( :DemNumber "1")) :Numerical ( :DemNumber "3")) (A simpler representation would be: (* (+ 1 1) 3).) should evaluate to 6. Each object, such as the one above, has an optional name, followed by a colon, followed by a class name. A class name must be followed by ( ... ) or { ... } unless it is a name of a predefined class (DemIdent, DemNumber, DemString, DemReal). Inside the parentheses ( ... ) there is a list of named parts. Each part name is surrounded by angle brackets < ... >. After the part name is an object graph. Inside the curly braces { ... } there is a list of object graphs. Object-oriented analysis starts with identifying objects in the application domain. The prefix expressions which your program should handle are simple: They are defined by the following class dictionary graph: Exp : Numerical | Compound. Numerical = DemNumber. // DemNumber has a part val // containing an int Compound = Op Exp Exp . Op : Addsym | Subsym | Mulsym. Addsym = . Subsym = . Mulsym = . You might want to take the following program as a start. It implements most of the procedural part of your program. All you have to provide is the data structure part and constructor implementations. #include int DemNumber::eval() { return val;} int Numerical::eval() {return numValue->eval();} int Compound::eval(){ return op->apply_op(arg1->eval(), arg2->eval()); } int Exp::eval() { return 0; } int Addsym::apply_op(int n1,int n2) { return n1 + n2; } int Subsym::apply_op(int n1,int n2) { return(n1 - n2); } int Mulsym::apply_op(int n1,int n2) { return(n1 * n2); } int Op::apply_op(int n1,int n2) { return 0; } In the main program we build an object which then gets evaluated: main() { DemNumber* iNumber1 = new DemNumber(100); DemNumber* iNumber2 = new DemNumber(22); DemNumber* iNumber3 = new DemNumber(44); DemNumber* iNumber4 = new DemNumber(3); DemNumber* iNumber5 = new DemNumber(33); Numerical* iNumerical1 = new Numerical(iNumber1); Numerical* iNumerical2 = new Numerical(iNumber2); Numerical* iNumerical3 = new Numerical(iNumber3); Numerical* iNumerical4 = new Numerical(iNumber4); Numerical* iNumerical5 = new Numerical(iNumber5); Addsym* add = new Addsym(); Subsym* sub = new Subsym(); Mulsym* mul = new Mulsym(); Compound* c1 = new Compound(add, iNumerical1, iNumerical1); Compound* c2 = new Compound(add, iNumerical2, iNumerical3); Compound* c3 = new Compound(sub, c2, iNumerical5); Compound* c4 = new Compound(mul, iNumerical4, c3); cout<< "\n\n result_1: " ; cout<< " = " << c1->eval(); cout<< "\n result_2: " ; cout<< " = " << c2->eval(); cout<< "\n result_3: " ; cout<< " = " << c4->eval() << "\n\n" ; } Add the appropriate class definitions to make your prefix expression evaluator work. You should hand in all source code but no output is required. Part 2: Checking your solution with Demeter =========================================== What to turn in: A 5 line explanation why Demeter could solve the problem with the available information. In this part the Demeter Tools/C++ will solve part 1 for you. Copy the files in directory $OO/hw/2/expr.cl to one of your own directories by using cp $OO/hw/2/expr.cl/* YOUR-DIRECTORY The files are (you should inspect them): cd.cd demeter-input main.C prog.C user-calls.h Now type demeter >& sc & which saves the output of the demeter command into file sc. Get up and stretch while the computer is creating a class library as you did in part 1 of this homework. When it is done, type run The output of the program in Part1 will be produced. Turn in an explanation, at most 5 lines long. All the computer had available is in the above files. Part 3: Learning C++ ======= What to turn in: A certified class dictionary graph describing a fragment of the structure of the C++ Programming Language. (certified means that it has to pass the design rule test done by sem-check -n) Most programs we write in this course will be written or generated in C++. Therefore, we need to learn the structure of C++ programs from our text book. For example, the following class dictionary describes some of the structure of C++ member function definitions: Type = < name > DemIdent [ < attribute > Type_attribute ] . Pointer = . Type_attribute : Reference | Pointer . Reference = . Program = < program > FunctionDefinition_List . FunctionDefinition_List ~ FunctionDefinition_List_elements { FunctionDefinition_List_elements } . FunctionDefinition_List_elements : FunctionDefinition . FunctionDefinition = < returnType > Type < attachedToClass > ClassName < memberFunction > MemberFunctionName < formalArguments > FormalArgument_List < statements > Statement_List . ClassName = < n > DemIdent . MemberFunctionName = < n > DemIdent . FormalArgument_List ~ FormalArgument_List_elements { FormalArgument_List_elements } . FormalArgument_List_elements : FormalArgument . FormalArgument = . Statement_List ~ Statement_List_elements { Statement_List_elements } . Statement_List_elements : Assignment | FunctionMemberCall . Assignment = < lhs > VariableName < rhs > Numeral . VariableName = < n > DemIdent . Numeral = < n > DemNumber . FunctionMemberCall = < name > MemberFunctionName < actuals > ActualArgument_List . ActualArgument_List ~ ActualArgument_List_elements { ActualArgument_List_elements } . ActualArgument_List_elements : ActualArgument . ActualArgument = . Write a class dictionary graph with at least twice as many classes (about 40) which reflects more of the structure of the C++ language. Reuse the class definitions above and modify them if you like. Make heavy use of your C++ book. Part 4: Develop your own class dictionary graph ------- What to turn in: A certified class dictionary graph. Write your own class dictionary graph for your own favorite domain. Don't choose something long. It should require about 20 classes. Potential systems: A concert, a city, a home, a kitchen, a spaceship, you name it!! Be creative and imaginative. For both parts 3 and 4: After you have developed the class dictionary graphs, draw them in graphical form using the following rules: The lines starting with * are extensions to the basic model. Representation: class dictionary graphical textual class symbol vertex alternation hexagon : (after class name) construction square = (after class name) * repetition hexagon ~ (after class name) * with square inside Part-of relationship edge * optional thin, dotted [] required thin * empty repetition thin, dotted R ~ {S} * nonempty repetition thin R ~ S {S} Inheritance rel.ship edge alternation thick labeled part label < ... > on corresponding edge For the last two parts, turn in your class dictionary graphs in both textual and graphical form. Also use the sem-check -n command on each class dictionary and turn in a statement that your solutions passed sem-check -n. sem-check -n should not give any error messages; otherwise adapt your class dictionary graph. To draw and develop the class dictionary graphs graphically, you are invited to use the xcddraw command on a SUN workstation. To shorten your drawing time, you may use the class dictionary in $OO/hw/2/c-plus-plus.ps It is a PostScript file of the C++ class dictionary in hw2 part3. Note: when viewing with xcddraw, you will have to increase the work space size under the options menu. (This is for those who like to draw their class dictionaries with xcddraw.) PART B: ====================================================================== The Demeter System defines a class called Universal which is the superclass of any class defined through a class dictionary. Browse through expr.cl (after calling demeter) to find the name of the directory where the class interface of Universal can be found. What is the public interface of the class? class Universal { ... public: UNKNOWN } Answer the same question for class Terminal. class Terminal : public Universal { ... public: UNKNOWN } Turn in the two unknowns. PART C: ====================================================================== Part 1: Error messages of "sem-check -n" ======= Write a class dictionary graph which is syntactically wrong. Write a class dictionary graph which uses class A but fails to define it. Write a class dictionary graph which defines the same class twice. Write a class dictionary graph which contains a cycle of alternation edges. Write a class dictionary which violates the unique label rule. For each of the class dictionary graphs, run sem-check and turn in the class dictionary graph and the error messages produced by "sem-check -n". Part 2: Error messages of "demeter" ======= Write a class dictionary graph and a propagation pattern so that the propagation pattern refers to a class not defined in the class dictionary graph. Make a syntax error in a propagation pattern. Write a class dictionary graph and a propagation pattern so that the propagation pattern defines a traversal which is empty. (Like you use *from* A *to* B but in the class dictionary graph there is no path from A to B but A and B are defined in the class dictionary graph.) For each case, run demeter and turn in the class dictionary graph and propagation pattern and the error message produced by "demeter". ======================= E-mail submission ================= Please follow the following rules: WHERE Send your solution to the teaching assistant (kate) with subject line: Subject: COM3360/NTU SE737 HW number where number is the homework number. She stores the solutions and I can inspect them electronically. ONE ASCII FILE Send only ONE ascii file containing your hw solution. COMPLETE SOLUTION Send the complete text of your homework solution. Don't just send a message "my solution is in directory ...". This keeps your solution protected from access by others and allows for faster grading. POSTSCRIPT FILES (required for later homework) If a homework asks for graphical representations of class dictionary graphs, please send each graph separately as a postscript file. The mail message should not contain other information, only the postscript file. Put the following information into the subject line: cdg name, hw x part y cdg is an abbreviation for: class dictionary graph For example: cdg C++, hw 2, part 3 The recommended way to draw a cdg is to use xcddraw (Warning: some students have lost pictures, for others it has worked perfectly. Save your work every 15 minutes.). But you can use other means which create a postscript file.