MiniJava+ Abstract Syntax The next stage of the compiler requires you to: 1. Define the abstract syntax structures to represent Minimjava+ constructs 2. Coordinate with parser to generate the abstract syntax (run tests) 3. Prepare the abstract syntax structures to be compatible with the visitor design pattern. 4. Test parser/abstract syntax by writing a program to translate Minijava+ to another language Unless you're not very familiar with inheritance and the visitor pattern, this part of the assignment is going to seem tedious, though still time consuming. Unfortunately I've no better solution. You can try to generate some of the monotonous code you'll be writing automatically, but it's probably better to just use editor macros. You already have some experience with the abstract syntax of the truth table program, though you didn't have to use the visitor pattern. If you look here: (follow Textbook resources link): http://www.cs.princeton.edu/~appel/modern/java/project.html You will find a very old version of the abstract syntax for a older version of minijava. These little classes may give you some ideas but I don't recommend basing your code on it. It does not use the visitor pattern, and neither does it use the newer features of Java such as generic types. I will give you an idea of what I did in terms of the following interfaces and class examples: public interface construct // overall interface for all Minijava+ constructs { public T accept(visitor v); } interface stat extends construct {} // statements interface typ extends construct {} // type expressions interface expr extends construct // value expressions { expr left(); // left and right subexpressions: expr right(); // these turned out to be not very useful so far (for me) } // superclass for all absyn classes (construct) // lines commented out represent options not used in my own code. class synbase { // public String mjtype = "void"; // type of expression or statement public String currentclass = null; // null indicates global public int line; // the line number in src where the construct starts public static abslexer lexer; // contains line() function public static String filename; // name of file being compiled. public expr left() {return null;} // for compatibility with expr interface public expr right() {return null;} } // Sample abstract syntax class for integer constants class intexp extends synbase implements expr { int val; // value of int public intexp(int x) {val=x;} public T accept(visitor v) {return v.visit(this);} } // Sample class for expressions of the form object.field, such as // A.length were A is an array. class fieldexp extends synbase implements expr // A.x { public expr target; // target object public String fname; // name of field/function public fieldexp(expr a, String b) { target=a; fname=b; line = lexer.line(); } public expr left() {return target;} public expr right() {return new strexp(fname);} public T accept(visitor v) {return v.visit(this);} } // function/method calls: target.function(args) can be statement or expression: class methodcall extends fieldexp implements expr,stat { public ArrayList args; // actual arguments public methodcall(expr a, String b, ArrayList c) { super(a,b); // super.fname is now the function name if (c==null) c = new ArrayList(); args = c; } public T accept(visitor v) {return v.visit(this);} } interface visitor // overall visitor interface { T visit(intexp x); T visit(strexp x); T visit(boolexp x); T visit(varexp x); T visit(thisexp x); T visit(multexp x); T visit(sumexp x); T visit(subexp x); T visit(divexp x); T visit(andexp x); T visit(orexp x); T visit(notexp x); T visit(ltexp x); T visit(modexp x); T visit(eqexp x); T visit(indexexp x); T visit(fieldexp x); T visit(methodcall x); T visit(newarrayexp x); T visit(newobjexp x); T visit(inttyp x); T visit(strtyp x); T visit(booltyp x); T visit(arraytyp x); T visit(voidtyp x); T visit(vartyp x); T visit(whilestat x); T visit(ifstat x); T visit(vardec x); T visit(returnstat x); T visit(assignstat x); T visit(arrayassignstat x); T visit(nopstat x); T visit(blockstat x); // T visit(printfstat x); T visit(program x); T visit(mainclass x); T visit(classdec x); T visit(mthdec x); T visit(formal x); }// visitor // Not all of your visitors will need to visit every class - some, for // example, may only visit expressions, others may only visit types. // The following class is both an example of a visitor and something // that can be inherited by other visitors so that you won't have to // write dummy code to visit objects that you don't want to visit. // Alternatively, you can be more refined and define exprvisitors, // typevisitors, statementvisitors, etc. /////// skeleton nullvisitor class nullvisitor implements visitor { public T visit(intexp x) { return null; } public T visit(strexp x) { return null; } public T visit(boolexp x) { return null; } public T visit(varexp x) { return null; } public T visit(thisexp x) { return null; } public T visit(multexp x) { return null; } public T visit(sumexp x) { return null; } public T visit(subexp x) { return null; } public T visit(divexp x) { return null; } public T visit(andexp x) { return null; } public T visit(orexp x) { return null; } public T visit(notexp x) { return null; } public T visit(ltexp x) { return null; } public T visit(modexp x) { return null; } public T visit(eqexp x) { return null; } public T visit(indexexp x) { return null; } public T visit(fieldexp x) { return null; } public T visit(methodcall x) { return null; } public T visit(newarrayexp x) { return null; } public T visit(newobjexp x) { return null; } public T visit(inttyp x) { return null; } public T visit(strtyp x) { return null; } public T visit(booltyp x) { return null; } public T visit(arraytyp x) { return null; } public T visit(vartyp x) { return null; } public T visit(voidtyp x) { return null; } public T visit(whilestat x) { return null; } public T visit(ifstat x) { return null; } public T visit(vardec x) { return null; } public T visit(returnstat x) { return null; } public T visit(assignstat x) { return null; } public T visit(arrayassignstat x) { return null; } public T visit(nopstat x) { return null; } public T visit(blockstat x) { return null; } // public T visit(printfstat x) { return null; } public T visit(program x) { return null; } public T visit(mainclass x) { return null; } public T visit(classdec x) { return null; } public T visit(mthdec x) { return null; } public T visit(formal x) { return null; } }//nullvisitor // sample visitor: class idvisitor extends nullvisitor { public Object visit(varexp v) {System.out.println("found variable id "+v.vname); return null; } public Object visit(vartyp v) {System.out.println("found type id "+v.classname); return null; } public Object visit(vardec v) {System.out.println("var "+v.dname+ " is being declared"); return null; } } ///////////////// Writing a Translator /////////////////////// The main purpose of this part of the assignment is to stress test your parser, abstract syntax, and skills with the visitor pattern. You are to write a program that translates any Minijava+ program into another language (excluding Java). If you don't mind being bored to death, you can translate it to C#. Slightly more interesting would be a translation to C++. Here, you will need to define in CPP a class to capture java arrays for example. You don't have to worry about garbage collection. More interesting will be to translate it to Python or a similar scripting language. Note: if you choose a scripting language, which is usually not statically typed, you still need to visit the type expressions and print out AS COMMENTS the type of the variables in your translated program. You do not have to translate printf statements precisely: just make sure the content is printed. Your translated program must run correctly. Be careful with the \ character in your strings. For example in "hello\n", THERE IS NO \ character. In this string there are 6 characters, the last one being carriage return. Some programmers wonder why s.replace("\\","\\\\") won't work on such strings :O What they really want is something like s.replace("\n","\\n"). Also, don't do this at the level of the lexer, only when strings are printed. Strings are not always printed.