First you'll run a simple compiler I provide, called c0
,
and you'll re-build it from its source files.
Then you'll evolve c0
into a marginally more capable
compiler, c1
, which can compile larger programs than
c0
, and which has an input syntax compatible with C/C++.
This is just a first step in a progression that will continue all
semester long, ending with c6
in May.
CLASSPATH
to tell it where to
look for Java classes. If you don't set it, only the main system-wide
class library is searched. In order to be able to access the packages
I'm providing, you'll need to put ~max/JavaLib
into your
CLASSPATH
. Furthermore, it will be most convenient if
you make a directory for your own packages and put that in your
CLASSPATH
as well. Assuming you don't have anything else
you want in the CLASSPATH
other than these two, and that
you call your directory JavaLib, you could set your CLASSPATH as
follows:
setenv CLASSPATH ~max/JavaLib setenv CLASSPATH ~/JavaLib:$CLASSPATHYou can do this in a shell window, but you'll find it convenient to put it in your
.login
file so it is done automatically
every time.
CLASSPATH
set, you can run my
c0
as follows. Put an arithmetic expression in a file
(let's say foo
). The expression can use numbers,
parentheses, and the operators +, -, *, /, and %. There can be white
space, but no comments. There shouldn't be anything but the
expression (for example, no semicolon). Now compile foo
into MIPS assembly language, with the result going into
foo.s
, by executing
java edu.gac.max.mcs388.s2000.c0.Main <foo >foo.sNow you can look at
foo.s
, and you can load it into
xspim
and run it.
c0
package into your own JavaLib (or whatever
you've called it). The easiest way is with a shell command like
(cd ~max/JavaLib; tar cf - edu/gac/max/mcs388/s2000/c0) \ | (cd ~/JavaLib; tar xf -)
Now change directory to your edu/gac/max/mcs388/s2000/c0 and rebuild the classes from the source files as follows:
java java_cup.Main <parser.cup
java JLex.Main scanner.lex
javac *.java
CLASSPATH
, as I suggested, you should now wind up running
your own rebuilt c0
if you run c0
again.
package
lines at their tops to reflect the
move, and then evolve the program
The language c1
accepts should allow programs of the
following form:
main(){ print_int(2+(3+4)*5); print_int(7+-2*2); // a comment could be here . . . }(Note that the
gcc
C compiler will also handle these same
programs. For that reason, I suggest you put a .c
extension on the filenames of your test input files, to make it easy to
compare results. Of course, you'll need to link the C version with a
file that provides print_int
.)
The difference from c0
are as follows:
print_int
, parentheses around the expression, and a
semicolon at the end.
main
, empty parentheses, and braces around the
statements.
//
to the end of the line.
Evolving into c1
will require changes in both the
parser (parser.cup)
and the lexical analyzer (scanner.lex).
In understanding what parser.cup
does, you'll need some awareness of the interfaces of two support
classes, Register
and RegisterAllocator,
but you needn't look at their implementations. (The implementations
may well change, and even the interfaces are likely to change in the
course of the semester -- hopefully in upwardly compatible ways.)
If you want to look at the implementations in Register.java
and RegisterAllocator.java,
you can, of course.
Note that if you make any mistakes in the parser.cup or scanner.lex file, you might get an error report when you run java_cup or JLex, but then again, you might find that they just happily produce illegal Java code as their output, leading to error messages when you run javac.
c1
parser and scanner,
highlighting the differences from the code for c0
. You
should also describe the tests you ran, and any problems uncovered.