0

我正在用 C++ 编写一个简单的程序解释器。当我构建程序的内部表示并得到一个 break 语句时,我如何确定包含循环的目标位置?

void Imp::whilestmt()
{
    Expr *pExpr;
    accept(Token::WHILE);
    expr(pExpr);
    WhileStmt *pwhilestmt = new WhileStmt(pExpr,vm.getLocationCounter);
    vm.add(pwhilestmt);
    accept(Token::LOOP);
    stmtlist();
    pwhilestmt->setTarget(vm.getLocationCounter);
    accept(Token::END);
    accept(Token::LOOP);
    vm.add(new EndLoopStmt);
}

我的 break 语句对象将 while 语句的目标作为参数,我该如何确定呢?

4

3 回答 3

3

我会考虑建立一种执行树/管道。每个 LOOP/WHILE 都将是一个新分支(类似于每个函数),因此当您遇到 END/BREAK 指令时,您只需恢复到分支原点并继续下一行。

于 2013-05-18T08:15:21.743 回答
2

我认为解决方案是添加一个前向引用,当该循环级别的所有代码都已生成时,该引用已被解析(通过查找循环结束的位置)。

换句话说,当为循环生成代码时,你需要形成一个“跳转”指令,它的目标设置到你还不知道它在哪里的地方。解决方案是使用未知目的地进行跳转(将“​​目的地”设置为指令 0 或 -1 或 0xdeaddead 或其他可以在以后轻松识别以用于调试目的的东西 - 因为避免出现“我没有”错误的最佳方法't fix it up proper' 是为了便于识别这些地方 - 错误只发生在难以识别的事物中,就像你带着雨伞从不下雨一样),并保留此类跳跃的修复列表,直到你已经生成了整个循环,然后通过该修复列表工作,并填写您现在知道的相关地址“这里” (循环后的下一条指令)。我怀疑对于循环本身的条件,您还需要类似的东西 - 如果这是错误的,那么您需要在循环“之后”继续。

于 2013-05-18T08:07:47.080 回答
0

我添加了 setTarget 作为 Stmt 的一个虚函数。

我将开始位置存储在处理 if 语句的部分中,然后检查从开始位置到当前位置是否有任何中断 stmts,如果有,我将目标设置为当前位置。

这样做真的很混乱,但它现在有效

于 2013-05-18T08:48:30.607 回答