Compiler construction 代码生成中的Bison派生问题
你好,我正在使用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->
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 }
因此,这些动作会在语法中产生冲突
有两种方法:
非常感谢,我终于明白了如何解决这个问题,我将重写语法并发布新版本,也许它可以帮助某人。非常感谢,我终于明白了如何解决这个问题,我将重写语法并发布新版本,也许它可以帮助某人。