关于您的项目的信息很少,处理条件问题的方法很大程度上取决于上下文。
例如,如果你的程序正在为目标机器编译代码,比如 JVM 字节码,你会做这样的事情:
void conditional(): {
ForwardJump jump, savedJump;
} {
<IF> condition() { jump = generateJumpIfFalse(); } block()
[<ELSE> {
savedJump = jump;
jump = generateJump();
fixForwardJump(savedJump);
} block()] {
fixForwardJump(jump);
} <FI>
}
这假定condition() 将生成计算布尔值的代码,然后将该布尔值推入堆栈。 generateJumpIfFalse() 生成一个条件跳转,从堆栈中弹出一个布尔值并跳转到一个未知的位置,因为后面的块尚未编译。一旦知道这个位置,就必须更新前跳。这就是fixForwardJump 所做的。
现在,如果您的程序是解释器,您希望解析器生成一些结构,然后您的 java 代码可以执行。
在本例中,您操作两种基本类型的结构:Statements 和 Expression。它们可能是同一个东西,但区别在于Expression 在执行时返回一个值,而Statement 没有。
对于解释器,您通常希望句法方法返回整个输入程序的某些子结构;所以你会有这样的事情:
Statement conditional(): {
Expression cond;
Statement ifBlock;
Statement elseBlock = null;
} {
<IF> cond=condition() ifBlock=block()
[<ELSE> elseBlock=block()] <FI>
{
return new ConditionalStatement(cond, ifBlock, elseBlock);
}
}
假设Statement 和Expression 是以下类型的接口:
public interface Statement {
public void execute(MachineState state);
}
public interface Expression {
public Object evaluate(MachineState state);
}
ConditionalStatement 类当然必须实现 Statement 接口。它看起来像这样:
public class ConditionalStatement implements Statement {
private final Expression cond;
private final Statement ifStatement;
private final Statement elseStatement;
public ConditionalStatement(Expression cond, Statement ifStatement, Statement elseStatement) {
this.cond = cond;
this.ifStatement = ifStatement;
this.elseStatement = elseStatement;
}
@Override
public void execute(MachineState state) {
Object value = cond.evaluate(state);
if (value == Boolean.TRUE) {
ifBlock.execute(state);
} else if (elseBlock != null) {
elseBlock.execute(state);
}
}
}
当然,它可以变得比这复杂得多。