Useful Links

How I will run your code

Save your program in a file called in folders called proj1 and proj2 respectively for phases 1 and 2 of your project.

I will test your code in the same environment as the lab machines in MI 302, using the command


Phase 2 Assignment

For phase 2 of your project, you will write a compiler from a highly simplified subset of the C programming language to brainfuck code. You will not submit brainfuck code for this part, but rather a parser and scanner generator using flex and bison, in two files called proj.lpp and proj.ypp.


I will compile your code to the executable compiler proj as follows:

flex -o proj.yy.cpp proj.lpp
bison -d proj.ypp
g++ -o proj proj.yy.cpp

Then, if test.c contains a program in the C subset described below, I will test your compiler as follows:

./proj < test.c >

Of course, the result of the second command should be the same as if I had compiled the test.c program using gcc and run the resulting executable.

Now don't worry, the subset of C that we are going to compile from is going to be very restricted. Specifically, our C subset has the following properties:


I suggest you write your program in the following steps. Of course you are free to develop however you wish. As always, you are encouraged to submit every time you get some small step of the program working.

  1. First get your simplified C++ scanner and parser working, and doing nothing. This should be very easy for you by now in this course! As a comment, you may be tempted to make a token called OP for all the operators, but I advise against this. Ultimately your parser is going to have to be writing brainfuck code, and this code will be very different for something like 5 + 2 compared to 5 == 2. So it might make your job easier to just have every operator be a different token.
  2. Now start building your compiler, from the very very basics. Start with variable declarations. Where should variables be stored in the brainfuck program? What does your parser have to remember to facilitate this? (Hint: you will need a symbol table.)
  3. After you get variable declarations, the input and output commands shouldn't be too much trouble. Then venture into some of the operators, adding in their functionality one at a time. For each one, think about how you would actually write the brainfuck program to do that operation. Then get your parser to write that code in a way that won't interfere with anything else. Test after you add each operation, and don't try to do everything at once.


So for instance, given the following C program:

#include <stdio.h>

int main() {
  int x = 5;
  int y;
  y = getchar();
  x = x + y;
  return 0;
your program might produce (written to standard out) the brainfuck program

Of course your actual program might differ from this one. As long as they behave identically, it's fine.