Hi Mira: below I did a cd for a part of the new language. It was part of the final exam for fall 97. Does this look right? -- Karl ============== From: /proj/adaptive/www/course/exams/f-3360-f97 Preparation in: /proj/asl/lieber/java/new-java-envs/fall97/ Question 2: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 UNKNOWNs, 10 points each You are given the following artifacs: program.cd defines a new visitor notation program.input gives an example of the new visitor notation DisplayVisitor.beh generated from program.cd by gendisplayvis.beh gendisplayvis.beh DisplayVisitor generator A summary of demjava.cd only what is important for display visitor generation out the output produced by DisplayVisitor.beh for the object in program.input program.cd ==================================== Visitors = Visitor_List. Visitor = VisitorName [Modification] VisitorBody. Modification = "modifies" VisitorName. VisitorBody = VisitorEntry_CList. VisitorEntry : ModifyStructure | ModifyBehavior | During | Boundary. ModifyStructure : DataMember | Init | Return. Boundary : Start | Finish *common* Strat JavaCode. ModifyBehavior = ClassExp BehaviorOrStructure_CList. BehaviorEntry : WhenVisiting *common* JavaCode. BehaviorOrStructure : BehaviorEntry | ModifyStructure2. ModifyStructure2 = ModifyStructure. // to prevent multiple inheritance WhenVisiting = "when-visiting". During = "during" Strat ModifyBehavior_CList. DataMember = "local" Ident ";". Init = "init" JavaCode. Return = "return" JavaCode. Start = "start". Finish = "finish". ClassExp = Ident. JavaCode = Text. Main = . VisitorName = Ident. Strat = "strategy". Visitor_List ~ {Visitor}. VisitorEntry_CList ~ "{" {VisitorEntry} "}". BehaviorOrStructure_CList ~ "{" {BehaviorOrStructure} "}". ModifyBehavior_CList ~ "{" {ModifyBehavior} "}". program.input ========================================= DFTVisitor // some strategy type // {-> Graph Adjacency // -> Adjacency Vertex // -> Vertex Adjacency} { // visitor entries Adjacency { local mark; init (@ mark = false; @) return (@ mark @) when-visiting (@ if (mark==false) {mark=true;}; @) } } ConnectivityVisitor modifies DFTVisitor { //visitor entries local count; init (@ count = 0;@) return (@ count @) during strategy // {-> Graph Adjacency stop} { Adjacency { when-visiting (@ if (next.return()=false) // check whether unmarked {count+=1; next();}; @) } } } DisplayVisitor.beh ============================================== 1 // This file is automatically generated by Demeter/Java. 2 DisplayVisitor { 3 (@ 4 private java.io.PrintWriter out = new java.io.PrintWriter(System.out, true); 5 java.io.PrintWriter get_out() { return out; } 6 void set_out(java.io.PrintWriter new_out) { out = new_out; } 7 DisplayVisitor(java.io.PrintWriter out) { set_out(out); } 8 DisplayVisitor(java.io.PrintStream out) 9 { set_out(new java.io.PrintWriter(out, true)); } 10 @) 11 before Visitors (@ 12 out.print(": Visitors ("); 13 indent++; 14 @) 15 after Visitors (@ 16 out.print(" )"); 17 indent--; 18 @) 19 before -> Visitors, visitor_list, Visitor_List (@ 20 out.println(); for (int i = 0; i < indent; i++) out.print("\t"); 21 out.print(" "); 22 @) 23 before Visitor (@ 24 out.print(": Visitor ("); 25 indent++; 26 @) 27 after Visitor (@ 28 out.print(" )"); 29 indent--; 30 @) 31 before -> Visitor, visitorname, VisitorName (@ 32 out.println(); for (int i = 0; i < indent; i++) out.print("\t"); 33 out.print(" "); 34 @) 35 before -> Visitor, modification, Modification (@ 36 out.println(); for (int i = 0; i < indent; i++) out.print("\t"); 37 out.print(" "); 38 @) OMITTED 139 before -> DataMember, ident, Ident (@ 140 out.println(); for (int i = 0; i < indent; i++) out.print("\t"); 141 out.print(" "); 142 out.print(" : Ident"); 143 out.print(" \"" + source.get_ident() + "\""); 144 @) 145 before Init (@ 146 out.print(": Init ("); 147 indent++; 148 @) 149 after Init (@ 150 out.print(" )"); 151 indent--; 152 @) 153 before -> Init, javacode, JavaCode (@ 154 out.println(); for (int i = 0; i < indent; i++) out.print("\t"); 155 out.print(" "); 156 @) 157 before Return (@ 158 out.print(": Return ("); 159 indent++; 160 @) CUT gendisplayvis.beh: (the first part is numbered; the second part contains some utility functions which are not numbered. This code is taken from the Demeter/Java source and was written by Doug Orleans and Geoff Hulten.) ====================================== 1 // genuniversal.beh -- generate code for DisplayVisitor. 2 // $Id: gendisplayvis.beh,v 1.8 1997/10/09 11:30:02 dougo Exp $ 3 Program { 4 /** Add a "DisplayVisitor" class to the set of class definitions. 5 Don't call this until after buildClassDefTable()! */ 6 void addDisplayVisitor(String name) (@ 7 addClassDef(ClassDef.parse("*notparsed* *visitor* " + name 8 + " = int.")); 9 @) 10 /** Generate the behavior file for DisplayVisitor. */ 11 void generateDisplayVisitor(String name, File file) = allParts { 12 before Program (@ 13 host.openOutputFile(file); 14 Program.out.println(host.genericOutputVisitorPreamble(name)); 15 @) 16 (@ ClassName classname; @) 17 before ClassDef (@ 18 classname = host.get_classname(); 19 // don't do anything for alternation classes 20 if (host.isAlternationClass()) return; 21 boolean rep = classname.isOrWasRepetitionClass(); 22 String body = 23 " out.print(\": " + classname + " " 24 + (rep ? "{" : "(") + "\");\n" 25 + " indent++;\n"; 26 Program.out.println(classname.makeBefore(body)); 27 body = 28 " out.print(\" " 29 + (rep ? "}" : ")") + "\");\n" 30 + " indent--;\n"; 31 Program.out.println(classname.makeAfter(body)); 32 @) 33 before Part (@ 34 ClassName dest = host.get_classname(); 35 String deststr = dest.toString(); 36 PartName partname = host.get_partname(); 37 String body = 38 " out.println();" 39 + " for (int i = 0; i < indent; i++) out.print(\"\\t\");\n" 40 + " out.print(\"<" + partname + "> \");\n"; 41 if (dest.isBuiltinType()) { 42 if (deststr.equals("char")) { 43 body += " out.print(\" '\"" 44 + " + source.get_" + partname + "() + \"' \");\n"; 45 } else { 46 body += " out.print(\" : " 47 + dest + " \\\"\" + dest + \"\\\"\");\n"; 48 } 49 } else if (dest.isTerminalClass()) { 50 body += " out.print(\" : " + dest + "\");\n"; 51 if (deststr.equals("String")) { 52 body += " out.print(\" \\\"\"" 53 + " + source.get_" + partname + "() + \"\\\" \");\n"; 54 } else if (deststr.equals("Text")) { 55 body += " out.print(\" " + Text.begin + "\"" 56 + " + source.get_" + partname + "() + " 57 + Text.quoted_end + " + \" \");\n"; 58 } else if (deststr.equals("Character")) { 59 body += " out.print(\" '\"" 60 + " + source.get_" + partname + "() + \"' \");\n"; 61 } else { 62 body += " out.print(\" \\\"\" + source.get_" + partname + "() + \"\\\"\");\n"; 63 } 64 } 65 Program.out.println(host.makeBefore(classname, body)); 66 @) 67 after Program (@ 68 Program.out.println("}"); 69 host.closeOutputFile(); 70 @) 71 } 72 } ClassNameAccessor { before ClassSpec (@ @) before ClassName (@ @) } ClassDef { traversal toClassName(ClassNameAccessor v) { bypassing { ClassParts, ClassMethods, -> *,parameters,* } to ClassName; } } { Subclass, Superclass, Part, RepeatedPart } { traversal toClassName(ClassNameAccessor v) { bypassing { -> *,actual_parameters,* } to ClassName; } } { ClassDef, Subclass, Superclass, Part, RepeatedPart } { ClassName get_classname() = toClassName { before ClassName (@ return_val = host; @) } } { ClassDef, Part, RepeatedPart } { void set_classname(ClassName classname) = toClassName { before ClassSpec (@ host.set_classname(classname); @) } } Part { (@ boolean isTerminal() { ClassDef def = Program.prog.findClassDef(get_classname()); return def == null || def.isInterface(); } String makeWrapper(ClassName source, String body) { return new PartGlob(source, get_partname(), get_classname()) + " " + Text.begin + body + Text.end; } String makeBefore(ClassName source, String body) { return " before " + makeWrapper(source, "\n" + body + " "); } String makeAfter(ClassName source, String body) { return " after " + makeWrapper(source, "\n" + body + " "); } @) } ClassName { (@ String makeWrapper(String body) { return this + " " + Text.begin + body + Text.end; } String makeBefore(String body) { return " before " + makeWrapper("\n" + body + " "); } String makeAfter(String body) { return " after " + makeWrapper("\n" + body + " "); } @) } ClassName { (@ private static String builtinTypes[] = { "boolean", "char", "byte", "short", "int", "long", "float", "double" }; private static String terminalClasses[] = { // from java.lang.*: "Boolean", "Character", "Integer", "Long", "Float", "Double", "Number", "String", "StringBuffer", // from demeter.*: "Ident", "Text" }; boolean isBuiltinType() { String s = toString(); for (int i = 0; i < builtinTypes.length; i++) { if (builtinTypes[i].equals(s)) return true; } return false; } boolean isTerminalClass() { String s = toString(); for (int i = 0; i < terminalClasses.length; i++) { if (terminalClasses[i].equals(s)) return true; } return false; } boolean isKnownTerminal() { return isBuiltinType() || isTerminalClass(); } @) } PartGlob { public String toString() (@ return "-> " + source + ", " + name + ", " + dest; @) } { Program, ClassDef } { traversal allParts(PartVisitor v) { to { Part, RepeatedPart }; } } A summary of demjava.cd: ========================================================= ========================================================= Instead of giving you the class dictionary for Demeter/Java (which has several hundred lines) I summarize the information it must contain for the purpose of generating the DisplayVisitor: generateDisplayVisitor: {-> Program ClassDef -> ClassDef Part} get_classname: {-> {ClassDef,Part} ClassName} get_partname: {-> Part PartName} This means that there must be classes Program ClassDef Part ClassName PartName which are connected as follows: There must be a path from Program via ClassDef to Part. From ClassDef and Part there must be a path to ClassName. From Part there must be a path to PartName. out: ======================================================= 1 CLASSPATH=./gen:$CLASSPATH java Main < program.input 2 done 3 : Visitors ( 4 : Visitor_List { 5 : Nonempty_Visitor_List ( 6 : Visitor ( 7 : VisitorName ( 8 : Ident "DFTVisitor" ) 9 : VisitorBody ( CUT Here come the unknowns: Example: line 3 in out: : Visitors ( is printed by lines UNKNOWN100 in DisplayVisitor.beh and those lines in DisplayVisitor.beh are printed by lines UNKNOWN200 in gendisplayvis.beh UNKNOWN100 = 12 UNKNOWN200 = 26 The following part of line 4 in out: is printed by lines UNKNOWN1 in DisplayVisitor.beh. Line 24 of DisplayVisitor.beh: out.print(": Visitor ("); is printed by line UNKNOWN2 in gendisplayvis.beh. Line 28 of DisplayVisitor.beh: out.print(" )"); is printed by line UNKNOWN3 in gendisplayvis.beh. Line 31 of DisplayVisitor.beh: before -> Visitor, visitorname, VisitorName (@ is printed by line UNKNOWN4 in gendisplayvis.beh. Line 142 of DisplayVisitor.beh: out.print(" : Ident"); is printed by line UNKNOWN5 in gendisplayvis.beh. We want to modify the program as follows: Instead of printing all the part names, as in: : Visitors ( : Visitor_List { : Nonempty_Visitor_List ( : Visitor ( : VisitorName ( : Ident "DFTVisitor" ) we want a simplified form of display which looks like: : Visitors ( : Visitor_List { : Nonempty_Visitor_List ( : Visitor ( : VisitorName ( : Ident "DFTVisitor" ) Give in UNKNOWN6 the line number(s) of gendisplayvis.beh which need to be changed, and indicate how to change them. Note the the indentation should be kept as shown in the above example. =========== The following is a utility function in Demeter/Java: // you can attach the same code to several classes { ClassDef, Subclass, Superclass, Part, RepeatedPart } { ClassName get_classname() bypassing { ClassParts, ClassMethods, -> *,parameters,* } to ClassName // the following is an inlined visitor { before ClassName (@ return_val = host; @) } } Explain the purpose of this code in UNKNOWN7.