Assignment #2
Due: Monday, Feb 11, 2019
GOAL: Modify the translator in InToPostfix to produce stack machine code as output and expand the grammar to include certain statements. In particular, your new translator should process statements which are defined by the following grammar (the productions for expr are the ones InToPostfix currently uses):
stmt → id := expr
| if expr then stmt
| while expr do stmt
| begin stmt_list end
stmt_list → stmt_list ; stmt
| stmt
[ As we discussed in class, the productions given for stmt_list won’t work with a predictive parser. Here’s a set that will:
stmt_list → stmt stmt_rest
stmt_rest → ; stmt stmt_rest
| ε
]
Note, your program should now read a series of statements, not a series of expressions. So, input like 3+4 will no longer be valid. You would need to say something like
x := 3+4
STACK MACHINE: We will generate code for a pretend stack machine whose machine language is describe here. This machine is based on one from the Aho, Sethi, and Ullman book.
The basic stack manipulation instructions are:
push num push numeric constant num onto the stack
rvalue addr push contents of data location addr
lvalue addr push address of data location addr
pop throw away value on the top of the stack
store the r-value on top is placed in the l-value below
it and both are popped
copy push a copy of the top value on the stack
We assume there is a machine instruction for each arithmetic operator. These instructions pop the top two values off of the stack, perform the operation and push the result back onto the stack.
Data locations (addr) are simply identified by symbolic names like “x” or “day” rather than numeric addresses.
We also have the following control flow instructions:
label L target of jumps to L ; has no other effect
goto L next instruction is taken from statement with label L
gofalse L pop the top value; jump if it is zero
gotrue L pop the top value; jump if it is nonzero
For example, the input statement:
day := (1461*y) div 4 + (153*m + 2) div 5 + d
should produce the code:
lvalue day push 2
push 1461 +
rvalue y push 5
* div
push 4 +
div rvalue d
push 153 +
rvalue m store
*
METHOD: You will need to create new tokens for the additional keywords (in Lexan). The assignment
operator “:=” should be treated as one token (representing the store operation in machine code).
In order to generate the correct code for the statements, you need to decide what that code should look like. For instance, a semantic action for the if statement might be something like:
stmt → if expr then stmt1 { out := newlabel();
stmt.code := expr.code ||
‘gofalse’ out ||
stmt1.code ||
‘label’ out }
where the symbol “||” means to concatenate code fragments and newlabel() is a method which returns a label value that hasn’t been used before. This could be a routine with a simple counter. The labels could be simply numbers or strings like “L5”, “L14”.
This could be implemented using the following translation scheme:
stmt → if
expr {out := newlabel(); emit(‘gofalse’, out); }
then
stmt1 { emit(‘label’, out); }
You should work out similar schemes for the while and begin-end statements.
HAND-IN: Submit the code (.java files) for your modified translator using D2L by 11:59PM Monday. Be sure to include comments saying who wrote the code and why.