代码生成的野牛派生问题

时间:2010-12-17 13:15:43

标签: 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->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代码生成中间代码时。我的问题是:为什么?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

当解析器收到SEexpressao时,在您的扩充形式中,它立即需要选择要执行的操作(因为您要求该操作在该点发生。注释,它可以先推ENTAOcommandos,然后做出减少的决定。

本质上,RHS内部的一个动作被翻译成一个动作在最后,另一个非终端动作。所以

 foo: bar { action1 } foobar
 foo: bar { action2 } baz

被翻译成

 foo: helper1 foobar
 foo: helper2 baz
 helper1: bar { action1 }
 helper2: bar { action2 }

因此,这些行为会在语法中产生减少 - 减少冲突。

有两种方法:

  1. 将行动放在最后。
  2. 重构 语法,以便行动 实际上两者都是一样的 的替代品。
相关问题