Compiler construction 代码生成中的Bison派生问题

Compiler construction 代码生成中的Bison派生问题,compiler-construction,yacc,bison,Compiler Construction,Yacc,Bison,你好,我正在使用bison作为编译器进行研究,我得到了下一个代码: if : if2 | if1; if2: SE expressao {$1 = (struct lbs *) newlblrec(); $1->for_jmp_false = reserve_loc(); $1->label = label; label+=2;} ENTAO comandos SENAO {$1->for_goto = reserve_loc(); back_patch($1->

你好,我正在使用bison作为编译器进行研究,我得到了下一个代码:

if :
if2
|
if1;

if2: 
SE expressao {$1 = (struct lbs *) newlblrec(); $1->for_jmp_false = reserve_loc(); $1->label = label; label+=2;} ENTAO 
comandos
SENAO  {$1->for_goto = reserve_loc(); back_patch($1->for_jmp_false, JMP_FALSE, $1->label);}
comandos
FIMSE  {back_patch($1->for_goto, GOTO, $1->label+1);}
| 
SE expressao error {yyerrok; errors++; yyerror("Entao nao encontrado no se");}
comandos
SENAO 
comandos
FIMSE ;

if1: 
SE expressao {$1 = (struct lbs *) newlblrec(); $1->for_jmp_false = reserve_loc(); $1->label = label++;} ENTAO 
comandos 
FIMSE {back_patch($1->for_jmp_false, JMP_FALSE, $1->label); gen_code(LABEL,$1->label);}
|
SE expressao  error {yyerrok; errors++; yyerror("Entao nao encontrado no se");}
comandos 
FIMSE;

这段代码只生成规则“if2”,当它在“SENAO”之前找到“FIMSE”(这表示该命令是一个简单的if)时(在本例中是一个if-else命令),它会引发一个错误,这只发生在我将C代码放入生成中间代码时。我的问题是:为什么?如何修复此问题?

当解析器以您的增强形式接收到
SE
expressao
时,它需要立即选择要执行的操作(因为你要求动作发生在那一点上。如果没有注释,它可以先推动
ENTAO
commandos
,然后决定减少

本质上,RHS中的一个动作被转化为一个动作在末尾,另一个动作是非终端的

 foo: bar { action1 } foobar
 foo: bar { action2 } baz
翻译成

 foo: helper1 foobar
 foo: helper2 baz
 helper1: bar { action1 }
 helper2: bar { action2 }
因此,这些动作会在语法中产生冲突

有两种方法:

  • 把动作放在最后
  • 重构 修改语法,使动作正确 实际上两者都是一样的 替代品

  • 当解析器收到您的增强形式的
    SE
    expressao
    时,它立即需要选择要执行的操作(因为您要求该操作在该点发生。如果没有注释,它可以首先推送
    ENTAO
    commandos
    ,然后决定减少

    本质上,RHS中的一个动作被转化为一个动作在末尾,另一个动作是非终端的

     foo: bar { action1 } foobar
     foo: bar { action2 } baz
    
    翻译成

     foo: helper1 foobar
     foo: helper2 baz
     helper1: bar { action1 }
     helper2: bar { action2 }
    
    因此,这些动作会在语法中产生冲突

    有两种方法:

  • 把动作放在最后
  • 重构 修改语法,使动作正确 实际上两者都是一样的 替代品

  • 非常感谢,我终于明白了如何解决这个问题,我将重写语法并发布新版本,也许它可以帮助某人。非常感谢,我终于明白了如何解决这个问题,我将重写语法并发布新版本,也许它可以帮助某人。