"The code generation phase translates the intermediate representation into "code". "
"The preparation for code generation phase decides how to allocate registers and memory.
The code generation phase translates the intermediate representation to assembly language using these registers and memory assignments."
---Professor Karen Lemone.
The Javacc doesn't generate code. By using Javacc to generate scanner, parser, and semantic analyzer,
we can finish front end of the compiler. We got a AST and a symbol table from the front end of
the compiler. we can use the AST and symbol table to generate the code.
In this example, I write a new class, CodeG, to generator assembly-like code. Because in calculator there is no variable, so I only pass the AST to
the code generator.
Note: In our whole example, we only handle integer number. We may get the different result with the real calculator if the expression includes divide operator.
We need the following files for our exmple: cal.jjt file.There is only a little difference from our last example. CodeC.java This class is used to generate assembly-like code. REG.java This is the register class. I use it to record register info. SimpleNode.java This class is the same as in the last example.
There are two test file (You can write your own expression as the test):
test1.txt (we use this test in previous examples)
6*(11-7)/3+100
test2.txt
(6 + 7)*(8+9)/(4+3)
To generate the code you need to run:
>jjtree cal.jjt
>javacc cal.jj
>javac cal.java
>java cal test1.txt
(or)>java cal test2.txt
The output of test1 will be like this:(Printing out AST is helpful for us to understand the code)
calculator
add_op(+)
mult_op(/)
mult_op(*)
number(6)
add_op(-)
number(11)
number(7)
number(3)
number(100)
Assembly-like Code:
BEGIN
SUB 11 7 r1 //r1 = 4
MULT 6 r1 r1 //r1 = 24
DIV r1 3 r1 //r1 = 8
ADD r1 100 r1 //r1 = 108
END
The result is ====> 108
The output of test2 will be like this:
calculator
mult_op(/)
mult_op(*)
add_op(+)
number(6)
number(7)
add_op(+)
number(8)
number(9)
add_op(+)
number(4)
number(3)
BEGIN
ADD 6 7 r1 //r1 = 13
ADD 8 9 r2 //r2 = 17
MULT r1 r2 r1 //r1 = 221
ADD 4 3 r2 //r2 = 7
DIV r1 r2 r1 //r1 = 31
END
The result is ====> 31
Note that when we translated to assembler that we also interpreted (executed the code). The
part that translates is a complier. The part that computes is an interpreter.