你好我正在将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代码生成中间代码时。我的问题是:为什么?我该如何解决这个问题?
答案 0 :(得分:1)
当解析器收到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 }
因此,这些行为会在语法中产生减少 - 减少冲突。
有两种方法: