If statement 这对野牛来说安全吗?

If statement 这对野牛来说安全吗?,if-statement,bison,yacc,If Statement,Bison,Yacc,我正在编写一个编译器,我有处理无限嵌套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"); utst

我正在编写一个编译器,我有处理无限嵌套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);
}
;

这很好,但使用$$/$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);
}
;
第一个操作是生成一个值(它将该值放入
$
),然后后面的操作可以访问该值

或者(特别是如果您想支持其他操作),将此初始操作拆分为单独的产品可能是有意义的:

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++;
          :
;

这允许对普通if和if/else使用相同的操作,避免语法冲突,因为在解析
if..DO
时,您不知道是否会有
else

您关心什么?标签的产生?代码生成?
程序是规则的一部分吗?现在还不清楚如何处理ELSE子句……也许这并不重要,但通常都是这样。说$1=LABELNUM并键入一个终端对我来说似乎是一个糟糕的难题?抱歉,我忘记完成键入,因为默认操作是设置
$$=$1,像这样用
$1
下注可能会在上游产生影响,但它不应该影响Yacc代码-只是查看
con_语句返回的值的任何操作。我认为更传统的做法是创建一种机制,将标签号与当前构造相关联。我认为你所做的是常规的。它认为这可能会对你以后产生影响。但我不认为它破坏了Yacc本身。