$24
REQUIRMENT:
All assignments must compile and run on the Eustis3 server. Please see course website for details concerning use of Eustis3.
Objective:
In this assignment, you must implement a Recursive Descent Parser and Intermediate Code Generator for PL/0. In addition, you must create a compiler driver to combine all the compiler parts into one single program.
Component Descriptions:
The compiler driver is a program that manages the parts of the compiler. It handles the input, output, and execution of the Scanner (HW2), the Parser (HW3), the Intermediate Code Generator (HW3) and the Virtual Machine (HW1). The compiler driver has been provided for you. Additionally, compiled implementations of HW1 and HW2 have been provided, so you can focus on the programs for this assignment, but you will have to correct them for HW4.
The Parser is a program that reads in the output of the Scanner (HW2) and parses the tokens. It must be capable of reading in the tokens produced by your Scanner (HW2) and produce, as output, if the program does not follow the grammar, a message indicating the type of error present and it must be printed (reminder: if the scanner detects an error the compilation process must stop and the error must be indicated, the compilation process must stop). A list of the errors that must be considered can be found in Appendix C. In addition, the Parser must fill out the Symbol Table, which contains all of the variables, procedure and constants names within the PL/0 program. See Appendix E for more information regarding the Symbol Table. If the program is syntactically correct and the Symbol Table is created without error, the execution of the compiler continues with intermediate code generation. (See Appendix D for parser pseudocode)
The Intermediate Code Generator uses the Symbol Table and Token List to translate the program into instructions for the VM. As output, it produces the assembly language for your Virtual Machine (HW1). Once the code has been generated for your Virtual Machine, the execution of the compiler driver continues by executing the generated assembly code on your Virtual Machine
The compiler driver supports the following compiler directives:
-l : print the list and table of lexemes/tokens (HW2 output) to the screen
-s : print the symbol table
-a : print the generated assembly code (parser/codegen output) to the screen
-v : print virtual machine execution trace (HW1 output) to the screen
<filename>.txt : input file name, for e.g. input.txt
Example commands:
./a.out input.txt –l –a –v Print all types of output to the console
./a.out input.txt –v Print only the VM execution trace to the console
./a.out input.txt Print nothing to the console except for program read and write instructions.
Notes on Implementation
Our policy in grading is this: if it works and you didn’t cheat, we don’t care how you did it. If you choose to alter the provided files or submit your own lex.c vm.c instead of using the .o files or even include additional c files, you can! Just make sure to leave an explanation in your readme and the comment on your submission. There are many ways to implement this assignment. In the pseudocode in Appendix D, we’ve taken the interleaved approach (combining parser and code gen), but you can implement them separately if desired.
Error Handling
When your program encounters an error, it should print out an error message and stop executing immediately.
We will be using a bash script to test your programs. We’ve included printing functions for you to use; if you choose to alter them, you won’t lose points as long as you output the necessary information, but you will delay the grading process. We use diff -w -B for evaluation.
Submission Instructions:
Submit via WebCourses:
1. Source code of the tiny- PL/0 compiler. Because we’ve outlined an approach using one file, we assume you will only submit parser.c, but you may have as many source code files as you desire. It is essential that you leave a note in your readme and as a comment on your submission if you submit more c files or you alter the provided files; you may lose points if you don’t.
2. A text file with instructions on how to use your program entitled readme.txt.
3. Please don’t compress your files
4. Late policy is the same as HW1 and HW2: 10 points for one day, 20 for two
5. Only one submission per team: the name of all team members must be written in all source code header files, in a comment on the submission, and in the readme.
6. Include comments in your program
What we’re giving you:
• parser.c – this is a skeleton with the print functions implemented and some global variables; to print an error message pass the error number from Appendix C, you should always print error messages if they occur, after printing an error, the function will free the code array and symbol table for you, and you should return null to the driver; make sure that you only call the print code function or print symbol table functions IF their respective flags are true There is a line commented out in parser which marks the end of the code array. YOU MUST UNCOMMENT IT IN ORDER FOR vm.o TO FUNCTION. IT WILL SEGFAULT IF YOU DON’T
• driver.c – we’ve left this uncompiled in case you want to understand how it works, but you shouldn’t need to alter it. It reads the input into a string from a file whose name is given as a command line argument. It reads in the compiler directives which are given as command line arguments. Then it calls the lexanalyzer function by passing the input string and a flag variable indicating whether output should be printed. If there were errors, it stops; otherwise, it calls the parse function by passing the lexeme list returned by the lexanalyzer and some flag variables. If there were errors, it stops; otherwise, it calls the vm function by passing the code returned by the parse and some flag variables. Then it frees everything and stops
You shouldn’t have to write ANY free calls; they have all been implemented for you.
• lex.o and vm.o – these are compiled implementations of HW2 and HW1 respectively. They are correct. If you discover any bugs, please email TA Elle. They were compiled on Eustis3, so they will only run properly on Eustis3.
• Makefile – this will compile the program. It runs the command “gcc parser.c driver.c lex.o vm.o -lm”, you can run the makefile with command “make”
• compiler.h – this is the most important bit. It allows the separate files to call each other’s functions. You shouldn’t need to alter it at all. If you do, leave a note.
• tester.sh – this is a sample bash script, similar to the one we use in grading. You can run it with the command “bash tester.sh” It tries to compile your program and stops if it doesn’t. Then it runs each test case, dumps the output to a file and then compares that file to the correct output using diff -w -B before printing out the results. If you’re not passing because of a formatting difference, you won’t lose points, but it will cause a delay in grading.
• Some test cases. They don’t cover everything, and we will use completely different ones during grading, so you should make up your own test cases to try.
Rubric
15 – Compiles
20 – Produces some instructions before segfaulting or looping infinitely, not necessarily correct, but enough to demonstrate that your program is doing something.
05 – README.txt containing author names and a description of alterations to the provided documents if present
20 – all errors are implemented correctly
10 – correctly parses symbol table
05 – correctly implements while structure
05 – correctly implements if structure
05 – correctly implements read and write instructions
05 – correctly implements arithmetic expressions
10 – correctly implements procedures (load, store, call, rtn, inc)