| CIS 461/561 Home Page | Last updated 2008/05/11 20:42:45 |
This is the final phase of the project of building a compiler for the C minus language as described in Appendix A of the text book. With the completion of this phase, you will have built a complete compiler that takes source code in C minus and produces TM code that can be executed by the TM simulator. In this phase, you will use the semantic analyzer that you built in the previous phase of the project.
The purpose of this phase is to produce executable code. The target environment for this code is the TM simulator, a listing of which is provided in the appendix of the book and is available online. For your convenience, here is a local copy of tm.c, the source for the TM simulator. Your compiler will take a file containing C minus code and produce a file of TM code. This TM code can be loaded by the simulator and executed.
As in previous projects, you should start by understanding the implementation of the TINY compiler - either the Java object oriented version or the procedural version from the book.
You will build on the code for the previous project, and most of that code will not need to change.
Your code will likely consist of multiple files. Make sure that you submit all necessary source files (but not object files or files generated by JFLEX or CUP). You must provide a Makefile with a default target that builds the C-minus compiler and your code must compile without errors.
If you are working on a team, make sure that all team members' names appear in comments at the beginning of your code.
All of your code files should be submitted through the class site at Blackboard. You can upload and update your files as you develop your solution or upload them all at once. Multiple submissions up to the due date are permitted, so if you want to change something after you submit, you can retrieve your solution and upload new versions or add new files.
A reasonable way to approach the project is:
A simple program that should work with your implementation is:
int x;
int y;
void main(void) {
x = 17;
y = (x - 12) * 5;
output(x + y);
}
Once you have this much working, as time permits, implement code
for other constructs like local variables, and arrays. Then add
function calls without parameters and finally function calls with parameters.
The code generation in TINY is implemented by adding codegen methods to all of the syntax tree node classes in ASTnode.java. These methods use an argument of a Code object, which is created in the main routine, and passed to the codegen method of the top of the syntax tree, and then passed among all the codegen methods. The purpose of the Code object is to encapsulate the creation of the code output file as well as providing symbolic names for machine registers and interface methods for forming machine instructions.
Following is a list of all of the source files for the TINY implementation. tiny-compiler.tar is a tar of all of these files.
| Makefile | Compile commands and dependencies |
| Code.java | The Code class implementing an interface for machine instructions (new) |
| Lexer.java | The scanner implementation (same as projectC) |
| Symtab.java | The symbol table implementation (same as projectC) |
| Token.java | The token implementation (same as projectC) |
| tinyc.java | The driver for testing parsing and printing of the syntax tree (modified to now call the code generator) |
| ASTnode.java | The set of classes representing the nodes in the syntax tree (class hierarchy is the same as projectC, but codegen methods have been added) |
| tiny.jflex | JFLEX specification (same as projectC) |
| tiny.cup | Java CUP specification of grammar and actions (same as projectC) |
If you don't use a Makefile, you can compile the flex/bison parser with the following
java -jar java-cup-11a.jar -parser TinyParser - symbols TokenType tiny.cup jflex tiny.jflex javac -classpath .:java-cup-11a.jar Token.java TokenType.java Lexer.java ASTnode.java TinyLexer.java TinyParser.java Symtab.java Code.java tinyc.java