Date Assigned: 3/19/07
Date Due: 4/9/07
Points: 50 pts
It is now time to make a few more modifications to your compiler and begin adding some semantic actions to your top-down parser. These actions will, among other things, do all of the symbol table handling for variable and function declarations. The actions are described more fully below.
Once again, the scanner must be modified. Currently, when the scanner recognizes an identifier, it only checks if the identifier is a reserved word. If the identifier is not a reserved word, its class is identifier and its value is NULL. You must modify the scanner so that the value of an identifier is a pointer to the symbol table entry if the entry is found, or NULL if it is not found.
The following semantic actions must be performed:
1) Add entries to the symbol table. No entry may be added until the information is available to fill in all relevant fields. Attempts to add duplicate entries at the same level must generate the appropriate error message. You will have to keep track of levels as well as stack offsets (for globals) and activation record offsets (for locals and parameters). Entries to be added will be of the following types which exists in pcc07defines.h:
//*****************************************************************************
// symbol table entry types
//*****************************************************************************
typedef enum SymbolTableType { RSRVWRD = 0,
INTEGER,
INTEGER_ARRAY,
POINTER_ARRAY,
POINTER,
FUNCNAME,
POINTER_TO_POINTER } SymbolTableType ;
//***************************************************************************** // symbol table entry levels //***************************************************************************** typedef enum SymbolTableLevel { RSRVWRD_LEVEL = 0, GLOBAL_LEVEL, LOCAL_LEVEL } SymbolTableLevel;2) Generate the following quads. Don't forget to place a level in each quad!!
a) Program begin and end quads - global level. These mark the start and end of the quads in the quadfile.
b) Function begin and return quads - local level. The function begin quad may be generated before all operands are known. It will then have to be backpatched. When a function begins, the level must be incremented. When a function ends, the level must be decremented and all symbol table entries on that level must be deleted.
c) Perform the following semantic error checks (in addition to the duplicate id check mentioned above):
(1) Check to insure that the number of parameters in the formal parameter list equals the number of parameters declared. If it does not, generate an error message.
(2) Check to insure that the parameter names in the formal parameter list equal the names in the parameter declarations and that they are in the same order. Generate an error messge if there are any discrepancies.
When the parse is complete, create the quad file that the interpreter will read. The format for this file is given in the interpreter specifications. It is time to study that closely and begin to develop for those specifications.
When a test program is run through this stage of your compiler, your driver must do the following:
1) Place the symbol table routines in debug mode ala the ST assignment. Print out the entire ST, alphabetically increasing, just prior to leaving each function and before you delete symbols on the current level.
2) Add all reserved words to the ST.
3) Call the parser.
4) Dump the quad file, constant table, ST, and runtime stack at the very end. Make sure that this information follows the exact printout below.
5) Dump any error messages produced by any module.
Consider the following program:
int a; int b(c,d) int c,d; { int h,i; } int e() { } main() { int f; int g[5]; }The following is the output right before leaving function b:
123456789012345678901234567890123456789012345678901234567890123456789012345678 Deleting a level - ST before leaving function b: S Y M B O L T A B L E Identifier Level Type Address Other ------------------------------------------------------------------------------ a 1 1 1 -1 b 1 5 1 2 c 2 1 -3 -1 d 2 1 -4 -1 else 0 0 4 -1 for 0 0 6 -1 h 2 1 1 -1 i 2 1 2 -1 if 0 0 3 -1 input 0 0 7 -1 int 0 0 2 -1 main 0 0 1 -1 output 0 0 8 -1 return 0 0 5 -1 Deleting a level - ST before leaving function e: S Y M B O L T A B L E Identifier Level Type Address Other ------------------------------------------------------------------------------ a 1 1 1 -1 b 1 5 1 2 e 1 5 3 0 else 0 0 4 -1 for 0 0 6 -1 if 0 0 3 -1 input 0 0 7 -1 int 0 0 2 -1 main 0 0 1 -1 output 0 0 8 -1 return 0 0 5 -1 Deleting a level - ST before leaving function main: S Y M B O L T A B L E Identifier Level Type Address Other ------------------------------------------------------------------------------ a 1 1 1 -1 b 1 5 1 2 e 1 5 3 0 else 0 0 4 -1 f 2 1 1 -1 for 0 0 6 -1 g 2 2 2 5 if 0 0 3 -1 input 0 0 7 -1 int 0 0 2 -1 main 0 0 5 -1 output 0 0 8 -1 return 0 0 5 -1 CONSTANT TABLE CONSTANT VALUE RUNTIME STACK ADDRESS -------------- --------------------- 5 2 RUNTIME STACK ADDRESS VALUE ------- ----- 0 -1 1 0 2 5 3 -1 Quad File --------- 1 27 0 0 0 0 0 0 2 22 0 2 0 0 0 0 2 23 0 0 0 0 0 0 2 22 0 0 0 0 0 0 2 23 0 0 0 0 0 0 2 22 0 6 0 0 0 0 2 23 0 0 0 0 0 0 1 28 0 0 0 0 0 0 3 0 0 5 0 Errors
Note1: Assume that we are compiling a program called t1.c. You must generate a subsequent quad file called t1.q. In general, a source program called source.c will generate a quad file called source.q that can then be run through the interpreter. This will be true for all subsequent assignments.
Note2: I will begin testing your compiler for errors. If a program compiles with no errors, then print 0 Errors; otherwise, print one error per line as follows:line xxx: Error description
as an example,
line 017: Error: Constant Too Long.
Note3: Remember, your compiler is to be in a directory called yourlastname. In that directory there is to be a makefile that I simply use to compile your project creating the executable pcc. Continue creating subdirectories within yourlastname directory as needed. Also, continue to use subversion more than ever as we go back and modify existing code.
Note4: Use the submit script to submit your solution: zeus$ submit cs480s07 user.tar.gz
Note5: On the day the program is due, turn in a colored hard copy of the source code in this order:
1. makefile
2. main .h/.c
3. td .h/.c
4. lex .h/.c
5. bu .h/.c
6. any new .h/.c source file combinations
7. all older .h/.c source file combinations