"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.