的字节码我有一个包含这样的规则语法:如何产生循环指令
stmt -> ID := expr
| print(expr)
| if(expr) then (stmt) [ else stmt ]?
| while(expr) do stmt
| begin stmt [ ; stmt ]* end
我不知道如何将规则翻译WHILE字节码。现在,我写了这个:
stmt
: ID ':''=' expr
{
if(st.lookupType($ID.text) != $expr.type) {
throw new IllegalArgumentException("Type error on variable: " + $ID.text + ".");
}
int var = st.lookupAddress($ID.text);
code.emit(Opcode.ISTORE, var);
}
| 'print' '(' expr ')'
{
if($expr.type == Type.INTEGER) {
code.emit(Opcode.PRINT);
}
if($expr.type == Type.BOOLEAN) {
code.emit(Opcode.BPRINT);
}
}
| 'if' expr
{
if($expr.type != Type.BOOLEAN)
throw new IllegalArgumentException("Type error in '(expr)': expr is not a boolean.");
int ltrue = code.newLabel();
}
'then'
{
code.emit(Opcode.LABEL, ltrue);
}
s1 = stmt ('else' s2 = stmt)?
| 'while' expr
{
if($expr.type != Type.BOOLEAN)
throw new IllegalArgumentException("Type error in '(expr)': expr is not a boolean.");
//Bytecode generator
// CODE...
}
'do'
(
s1 = stmt
{
int ltrue = code.newLabel();
}
)*
| 'begin' s1 = stmt (';' s2 = stmt)* 'end'
;
st
是一个符号表,也就是包含某个特定变量的类型的表。
在我的语法中只能有两种类型:INTEGER或BOOLEAN。
方法newLabel()
只不过是创建一个新的标签,如L1,L2,L3等字符串,只需递增一个计数器即可。
code
是CodeGenerator的一个实例,它是一个数据结构(Vector <Instruction>
),它存储在解析程序期间生成的字节码指令。
Instruction
类由两个字段(opcode
和operand
)组成,代表单字节代码指令。
如何生成循环的字节码,如WHILE? 由于
修改后的代码:
'while'
{
int lloop = code.newLabel(); //label for loop
int ldone = code.newLabel(); //laber for done
code.emit(Opcode.LABEL, lloop);
}
expr
{
if($expr.type != Type.BOOLEAN)
throw new IllegalArgumentException("Type error in '(expr)': expr is not a boolean.");
code.emit(Opcode.GOTO, ldone);
}
'do' (stmt)*
code.emit(Opcode.GOTO, lloop);
code.emit(Opcode.LABEL, ldone);
}
这是一个很模糊的问题,我很害怕。我们甚至不知道你的指令集是什么样的,所以我们如何告诉你如何从while循环生成代码? –
@TheantLRGuy谢谢你的回答,有什么不清楚的?我可以详细说明问题。 – user3602008
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html – Holger