$date = getdate(); $part2 = $date['mday'] >= 12; function updateText($str){ print("$str"); } ?>
| Part 2 accepted for 90% credit or 1 late day by | 9/17 @ 11:59 PM |
| Part 2 accepted for 80% credit or 2 late days by | 9/18 @ 11:59 PM |
| Part 2 accepted for 70% credit or 3 late days by | 9/19 @ 11:59 PM |
In this assignment, you will write several Java classes to be used later in the semester to represent a symbol table. This is a simple assignment to get you up to speed with our computing environment, Java, and our programming and testing conventions. If it seems difficult, ask for help; you may be misunderstanding something.
Each student must do this assignment alone. You may talk about the assignment with other students, but you may not share code.
For this assignment you will implement four Java classes: SymTable, Sym, DuplicateSymException, and EmptySymTableException. You will also write a program called P1.java to test your implementations.
The SymTable class will be used by the compiler you write later in the semester to represent a symbol table: a data structure that stores the identifiers declared in the program being compiled (e.g., function and variable names) and information about each identifier (e.g., its type, where it will be stored at runtime). The symbol table will be implemented as a List of HashMaps. Eventually, each HashMap will store the identifiers declared in one scope in the program being compiled.
The HashMap keys will be Strings (the declared identifier names) and the associated information will be Syms (you will also implement the Sym class). For now, the only information in a Sym will be the type of the identifier, represented using a String (e.g., "int", "double", etc.).
The DuplicateSymException and EmptySymTableException classes will define exceptions that can be thrown by methods of the SymTable class.
In addition to defining the four classes, you will write a main program to test your implementation. You will be graded on the correctness of your Sym and SymTable classes, on how thoroughly you test the classes that you implement, on the efficiency of your code, and on your programming style.
The Sym class must be in a file named Sym.java. You must implement the following Sym constructor and public methods (and no other public or protected methods):
| Sym(String type) | This is the constructor; it should initialize the Sym to have the given type. |
| String getType() | Return this Sym's type. |
| String toString() | Return this Sym's type. (This method will be changed later if ($part2){ updateText("in a future project"); } ?> when more information is stored in a Sym. ) |
The SymTable class must be in a file named SymTable.java. It must be implemented using a List of HashMaps. (Think about the operations that will be done on a SymTable to decide whether to use an ArrayList or a LinkedList.) The HashMaps must map a String to a Sym. This means that the SymTable class will have a (private) field of type List<HashMap<String,Sym>>.
List and HashMap are defined in the java.util package. This means that you will need to have the line
import java.util.*;
at the top of SymTable.java.
You must implement the following SymTable constructor and public methods (and no other public or protected methods):
| SymTable() | This is the constructor; it should initialize the SymTable's List field to contain a single, empty HashMap. |
| void addDecl(String name, Sym sym) throws DuplicateSymException, EmptySymTableException | If this SymTable's list is empty, throw an EmptySymTableException. If either name or sym (or both) is null, throw a NullPointerException. If the first HashMap in the list already contains the given name as a key, throw a DuplicateSymException. Otherwise, add the given name and sym to the first HashMap in the list. |
| void addScope() | Add a new, empty HashMap to the front of the list. |
| Sym lookupLocal(String name) | If this SymTable's list is empty, return null. Otherwise, if the first HashMap in the list contains name as a key, return the associated Sym; otherwise, return null. |
| Sym lookupGlobal(String name) | If any HashMap in the list contains name as a key, return the first associated Sym (i.e., the one from the HashMap that is closest to the front of the list); otherwise, return null. |
| void removeScope() throws EmptySymTableException | If this SymTable's list is empty, throw an EmptySymTableException; otherwise, remove the HashMap from the front of the list. |
| void print() | This method is for debugging. First, print "\nSym Table\n". Then, for each HashMap M in the list, print M.toString() followed by a newline. Finally, print one more newline. All output should go to System.out. |
These two classes (which must be in files named DuplicateSymException.java and EmptySymTableException.java) will simply define the two checked exceptions that can be thrown by the SymTable class. Each exception must be able to be created using a constructor that takes no arguments.
To define a checked exception named XXX, you can use code like this:
public class XXX extends Exception {
}
Note that the class has an empty body (it will have a no-argument constructor by default).
To test your SymTable implementation, you will write a main program in a file named P1.java. The program must not expect any command-line arguments or user input. It can read from one or more files; if you set it up to do that, be sure to hand in the file(s) along with P1.java.
Be sure that your P1.java tests all of the Sym and SymTable operations and all situations under which exceptions are thrown. Also think about testing both "boundary" and "non-boundary" cases.
It is up to you how your program works. A suggested approach is to write your program so that output is only produced if one of the methods that it is testing does not work as expected (e.g., if the lookupLocal method of the SymTable class returns null when you expect it to return a non-null value). This will make it much easier to determine whether your test succeeds or fails. The one exception to this approach is that P1.java will need to test the print method of the SymTable class and that will cause output to be produced.
To help you understand better the kind of code you would write using this suggested approach, look at TestList.java. This file contains a main program designed to test a (fictional) List class whose methods are documented in TestList.java. You are being asked to write something similar (in a file called P1.java) to test the Sym and SymTable classes. You should be able to write P1.java before you write the classes that it's designed to test.
if($part2){ updateText("By now, you should have handed in your P1.java. You should now use OUR P1.java, accessible here, and test it against the expected output, accessible here. Make sure that your actual output matches this expected output."); } else { ?> You will hand in your P1.java on the 11th. The next day, we will give you our version of P1.java and the output we expect when it is run with your Sym, SymTable, DuplicateSymException, and EmptySymTableException classes. } ?>
On a Linux machine you can see whether two files match by using the diff utility. For example, typing
diff file1 file2
compares the two files file1 and file2. Typing
diff -b -B file1 file2
does the same comparison, but ignores differences in whitespace.
If you send the output of P1.java to a file, you can use diff to make sure that it matches the expected output. To send the output of P1.java to a file named out.txt (on a Linux machine) type the following:
java P1 >& out.txt
The machines available for your use are the CS Department Linux and Windows workstations on the first floor of the Computer Sciences building. You may work on other machines (e.g., your own computer), but you will need to use the following tools for programming assignments other than this one:
You may be able to download those tools onto your own machines, but be aware that you will also need to copy your code to the class directory for grading, and your code must run on the CS Linux machines. If there are differences between the tools that you download and the versions on the Linux machines, this may cause your code not to work correctly when it is graded.
By the Part 1 deadline, electronically submit your P1.java file (and the files that it reads, if any)
By the Part 2 deadline, electronically submit the rest of your .java files. This should include your Sym.java, SymTable.java, DuplicateSymException.java, and EmptySymTable.java
Electronically submit the rest of your .java files by September 18th at 11:59 pm (or refer to the late policy).
if($part2){ updateText("This should include your Sym.java, SymTable.java, DuplicateSymException.java, and EmptySymTable.java"); } ?>Do not turn in any .class files and do not create any subdirectories in your submission. If you accidentally turn in (or create) extra files or subdirectories, make a new submission that does not include them.
Note that your P1.java will be worth 15% of your grade and will not be accepted late.
General information on grading criteria can be found on the Assignments page.
For this program, extra emphasis will be placed on style. In particular,
The goal is to make your code readable to an experienced Java programmer who is used to the conventions. The goal is not to develop your own personal style, even if it's "better" than the standard. For more advice on Java programming style, see Code Conventions for the Java Programming Language. See also the style and commenting standards used in CS 302 and CS 367.
Also be very sure that you use the specified file names (being careful about the upper- and lower-case letters in those names). And be sure that the output that is produced when we run our P1.java using your implementations of the Sym, SymTable, DuplicateSymException, and EmptySymTableException classes matches the expected output that we provide. We will test that output by automatically comparing it to the expected output and you will lose points for even minor differences.