The objectives are two-fold. The primary goal is to understand the use of the visitor design pattern to create applications by writing new concrete visitors without having to change the code corresponding to the basic object structure. A secondary goal is to be able to understand a medium-sized code-base that was either developed by someone else or generated by a code-generator. You will end up reading lots of code, but not have to write much of it yourself (less than 100 SLOC).
While you need to understand some terminology related to token analysis, parsing, grammars, and syntax trees, the coding for these will be kept to a minimum. In fact, most of this code will be generated and provided to you.
First download the zip file that contains everything you need to begin the assignment. Unzip the file and note the contents. You will see an installation of jtb, javacc, and the JavaPrinter (contains code that you will work on). jtb and javacc were described in class, but you won't need to use them unless you want to regenerate the code that has been provided to you.
Extract the files from the zip file and you will find a root folder called visitor. Create an eclipse project from the JavaPrinter sub-folder as demonstrated in a lecture.
Refer to your lecture notes for a discussion of the visitor pattern and examples. In this assignment, you are given examples of several concrete visitors and you will need to implement one visitor.
We will use the Java Tree Builder (JTB) implementation of the visitor pattern. JTB is a front-end to the Java Compiler Compiler (JavaCC) parser generator. JTB takes a JavaCC grammar as input to generate the following (description taken from the JTB webpage http://compilers.cs.ucla.edu/jtb/):
You will develop an application that takes an uncommented Java file and inserts comment skeletons for the following sections. The comments should not be indented. They should start from the left-most side. This is for simplicity in coding. That way, the visitor does not need to maintain any state information. It only needs to get some state information from the tree structure.
/************* New nested class NAME *************/Otherwise, output the following just above the class declaration (no line gaps between the end of comment and the class declaration):
/************* New class NAME *************/In both cases, NAME refers to the class that is defined below the comment. Make sure you have the exact number of lines, whitespaces, *, etc, so that the grader can automatically compare the output. Copy and paste the above comment.
/************* New method NAME *************/Here, NAME refers to the method that is defined below the comment. Make sure you have the exact number of lines, whitespaces, *, etc, so that the grader can automatically compare the output.
/************* New constructor NAME *************/Here, NAME refers to the name of the constructor that is defined below the comment. Make sure you have the exact number of lines, whitespaces, *, etc, so that the grader can automatically compare the output.
// Class variable definition begins
Make sure you cover all the cases, including the following:
private static final ClassName instanceVar; public static final datatype(int, double,..) var; int var; (implicit visibility) public int var; public Classname instance;
Assume that only one variable is declared at a time. Variables declared inside methods (i.e., local variables) are not included.
// Class variable definition ends
Make sure you cover all the cases, including the following:
private static final ClassName instanceVar; public static final datatype(i.e., int, double,..) var; int var; (implicit visibility) public int var; public Classname instance;
Variables declared inside methods (i.e., local variables) are not included.
As an example, the following output should occur:
// Class variable definition begins private static final double var1; // Class variable definition ends // Class variable definition begins private static final double var2; // Class variable definition ends
Your output program must compile correctly, i.e. inserting the comments should not change anything else in the input programs.
You must ensure that the comments are inserted as described above. No extra lines or spaces can be inserted because the grading script will flag them as errors even though you may be inserting the comments in the correct places. Copy-paste the comments shown in this document so that you can ensure correct formats.
The JavaPrinter directory contains all the syntax tree classes, visitor interfaces, default concrete visitors generated from the Java 1.1 grammar. You do not need to generate these classes once again. However, in case you want to know how a parser generator works, you can follow the steps below.
To run JTB you also need JavaCC. The code and jar files needed to run both (along with the examples) are available in the zip file.
You can see detailed instructions in the tutorial, documentation, and examples pages. You can also try the following simplified instructions for the TreeDumper example. The files are available in the directory, visitor/JavaPrinter/ . The README file tells you what to do. The instructions are explained below:
The grammar for Java 1.1 is provided in the file Java1.1.jj.
You may glance over it quickly to identify the productions. Run:
java -jar <relative_path>/jtb132.jar Java1.1.jj
The file jtb132.jar is available in the directory, visitor/.
You will obtain the file jtb.out.jj in the same directory and several concrete visitor files in the directory, visitor (e.g., visitor/JavaPrinter/visitor/). All the syntax tree files are generated in the directory, syntaxtree (e.g., visitor/JavaPrinter/syntaxtree/). Read some of the generated files that correspond to the classes for each node type in the Java syntax tree. Also read the visitor interfaces that are generated.
The main executable for
JavaCC is available in visitor/javacc-4.0/bin.
Add the directory to your path to ensure that you are not running some
other javacc installed elsewhere in the department.
Run javacc for unix machines
and javacc.bat on windows machines. For example,
This creates a few other files.
You must follow these steps whether or not you are regenerating the parser code.
Create a file called Commenter.java inside the folder visitor/JavaPrinter/visitor. The class Commenter must be in the package visitor and must implement the concrete visitor to solve the problem described above. Find the concrete visitor called TreeDumper.java in the same directory and understand what it does, You must extend TreeDumper and override the necessary methods.
To help keep the outputs consistent, You must use the MainA6 file that is given to you, called MainA6.java. MainA6 creates the Commenter visitor instance and uses it. Do not change MainA6.java file in any way. Your new code must be in exactly one file called Commenter.java.
Either use eclipse or run the following commands:
Create a zip file called a6-YourEID.zip that contains only one file called Commenter.java. Submit the file via RamCT. The reason for creating a zip file for one Java file will be discussed in class.
We will use the following criteria to award points. However, if your program does not compile, you will get ZERO points.