代码生成的 Bison 推导问题

发布于 2024-10-07 23:31:54 字数 977 浏览 5 评论 0原文

您好,我正在使用 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;

此代码仅在“”之前找到“FIMSE”(这表明该命令是一个简单的 if)时生成规则“if2” SENAO”(在本例中是 if else 命令)它会引发错误,只有当我输入 C 代码来生成中间代码时才会发生这种情况。我的问题是:为什么?我该如何解决这个问题?

Hello I'm using bison for a compiler for study purposes, i got the next code:

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;

This code only generates the rule 'if2', when it found the "FIMSE" (this indicates that the command is a simple if) before the "SENAO" (in this case is a if else command) it's raises an error, this only happen when i put the C code to generate the intermediate code. My question is: Why? How can i fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

中二柚 2024-10-14 23:31:54

当解析器以增强形式接收 SEexpressao 时,它立即需要选择要执行的操作(因为您要求该操作在该点发生)如果没有注解,它可以先推送ENTAOcommandos,然后做出减少的决定。

本质上,RHS内部的一个动作被翻译成具有以下内容的动作 。动作放在最后,与另一个非终结符 So

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

被翻译成

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

结果,这些动作在你的语法中产生了减少-减少冲突。

有两种方法:

  1. 动作放在最后。

  2. 语法使得动作是
    实际上两者都是同一个
    替代方案。

When the parser receives SE and expressao, in your augmented form, it then immediately needs to make a choice which action to perform (because you asked that the action happens at that point. Without the annotation, it can first push ENTAO and commandos, and then make a decision to reduce.

In essence, an action inside the RHS is translated into one that has the action at the end, with another non-terminal. So

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

is translated into

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

As a consequence, these actions produce a reduce-reduce conflict in your grammar.

There are two approaches:

  1. put the action at the end.
  2. refactor
    the grammar so that the action is
    actually the same one in both
    alternatives.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文