我正在编写一个编译器,并且我有处理无限嵌套if语句的工作代码,但它有点像黑客。我不知道这样做是否安全?
con_statement:
IF exp DO
{
$1 = ifNum++;
if($2 == BOOLEAN_TYPE || $2 == INTEGER_TYPE)
{
utstring_printf(code, "\tpop\teax\n");
utstring_printf(code, "\tcmp\teax, 0\n");
utstring_printf(code, "\tje\tIF_END_%d\n", $1);
}
if($2 == FLOAT_TYPE)
{
utstring_printf(code, "\tnop\n");
}
}
program FI
{
utstring_printf(code, "IF_END_%d:\n", $1);
}
;
答案 0 :(得分:1)
这样可以正常使用,但使用$$ / $ 4会更加清晰:
con_statement:
IF exp DO
{
$$ = ifNum++;
if($2 == BOOLEAN_TYPE || $2 == INTEGER_TYPE)
{
utstring_printf(code, "\tpop\teax\n");
utstring_printf(code, "\tcmp\teax, 0\n");
utstring_printf(code, "\tje\tIF_END_%d\n", $$);
}
if($2 == FLOAT_TYPE)
{
utstring_printf(code, "\tnop\n");
}
}
program FI
{
utstring_printf(code, "IF_END_%d:\n", $4);
}
;
第一个操作是生成一个值(它放入$$
),然后以后的操作可以访问该值。
或者(特别是如果您想支持ELSE),将此初始操作拆分为单独的生产可能是有意义的:
con_statement:
if_head program FI
{ utstring_printf(code, "IF_FALSE_%d:\n", $1); }
| if_head program ELSE
{ utstring_printf(code, "\tjmp\tIF_END_%d\n", $1);
utstring_printf(code, "IF_FALSE_%d:\n", $1); }
program FI
{ utstring_printf(code, "IF_END_%d:\n", $1); }
;
if_head:
IF exp DO
{ $$ = ifNum++;
:
;
这允许对plain if和if / else使用相同的操作,避免语法冲突,因为在解析IF..DO
时你不知道是否会有ELSE
或不。