CS230
Compiler Design
Project Assignment #5
Symbol Table and Code Generation
There are two parts to this assignment. The first is relatively
simple; the second requires quite a bit of work.
-
Add a symbol table to your program. Define it as an abstract data
type and add a compiler switch to allow the "dump" of the symbol table
after compilation (first print the AST, then the symbol table). Keep it
simple (!), since its structure is not going to be extremely important
for the primitive type of code generation you will do.
-
Write a simple code generator for the Pascal subset you have implemented.
The goal is to produce assembly code for the language as it existed in
assignment 3 (see below for possible further enhancements). You MUST translate
from the intermediate representation (the AST). The preferred target language
is MIPS. But you may translate into
any assembly language, provided you can demonstrate that the code runs.
Note that you can get by with a very small instruction set for this (about
20 operations, tops). You don't have to be an ace assembly language programmer
to do this; you don't even need to have any prior experience programming
in assembler. Click here for some tips which, I hope, will convince you of
this.
Basic techniques for generating code will be discussed in class. A
good strategy for this problem is to start by generating code for assignment
statements, adding other constructs one at a time. As always, do not attempt
to generate code for more complicated constructs until the simpler ones
are working. If you only get as far as a single assignment statement, that's
already a significant achievement. A simple working code generator is
far better than an elaborate non-working one!
Run your compiler on various programs, I will post more sources on
this page shortly. Output should be the assembly language code.
Test it by running it with a simulator/debugger, such as SPIM;
it is not necessary to implement the input and output procedures "readln"
and "writeln", although some rudimentary output is quite easy to
implement and is highly desirable. Note the simplicity of the system
calls for output in the sample MIPS code given here.
Options
There is much room for extra work, all of which will be suitably
rewarded. For example (in increasing order of difficulty):
-
Enhance your program so that it is capable of parsing programs with arrays.
The grammar for this is all in the book, in appendix A, pages 746 to 748.
So this part has two steps:
-
Write down a BNF grammar for the part of the language for declaring AND
using arrays (1-dimensional only; save multi-dimensional arrays for another
day). Be sure to adhere to the language "standard" as much as possible.
-
Implement the parser, ignoring the abstract syntax tree. Then put in the
syntax tree. Enhance the symbol table part of your program so that it can
handle arrays.
-
A code generator that compiles programs with 1-dimensional arrays might
actually be useful. You could feed it some simple sorting algorithms.
-
Do some simple register allocation. (The code you generate otherwise will
be extremely inefficient). A basic strategy for register allocation will
be discussed in class.
-
Translate programs with procedures and functions; this will require more
work on the parser, of course.
Here are a couple of source programs that you can try your compilers on:
program monsterExpr (input, output);
var a, b, c, d, e, f, g, h, x : integer;
begin
a := 1; b := 2; c := 3;
d := 4; e := 5; f := 6;
g := 7; h := 8;
x := 9;
x := ((a + b + c + d + e + f + g + h)*(a - b + c - d + e - f + g - h)
mod g)*(x*(a + b + c + d + e + f + g + h)
*(a - b + c - d + e - f + g - h) div b)
*x*(a + b*(a + b + c + d + e + f + g + h)
+ c + d + e + f + g + h);
end.
program primeTester (input, output);
var x, divisor : integer;
prime : boolean;
begin
x := 121;
divisor := 2;
prime := true;
while (divisor < x) and prime do
if ((x mod divisor) = 0) then
prime := false
else
divisor := divisor + 1
end.
Back to CS 230 Home Page