Save your program in a file called proj.bf
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
/usr/bin/beef proj.bf
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.tab.cpp 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 > test.bf /usr/bin/beef test.bf
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:
#
character is ignored
by your compiler.int main() {
function.
There must be no function prototypes or global variables. This main function
must end with a return 0;
statement, which is ignored by your
compiler.
main
.int
, but may never store any
integer larger than 127.int x,y;
is not allowed.int x = 5;
is OK, but int x = 5 + 2
is not.
VAR = ANY OP ANY;
.
Here ANY
is either a variable name or an integer in the range
0-127, and VAR
must be a variable name. OP
can be any of the following: +
, -
,
>
, <
, ==
.
Addition and subtraction work as usual, and the comparison operators set
the variable to 1 if the statement is true, and to 0 if it is false.
VAR = getchar();
,
and an output statement has the form putchar(ANY);
.
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.
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.
So for instance, given the following C program:
#include <stdio.h> int main() { int x = 5; int y; y = getchar(); x = x + y; putchar(x); 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.