2010-12-17 32 views
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」,當它發現了「 FIMSE「(這表明該命令是一個簡單的if)在」SENAO「之前(在這種情況下是一個if else命令)它會引發錯誤,這隻發生在我將C代碼生成中間代碼時發生。我的問題是:爲什麼?我怎樣才能解決這個問題?

回答

1

當分析器接收SEexpressao,在增強形式,它則需要立即做出行動來執行它(因爲你問的動作發生在這一點上,沒有註釋的選擇,它可以先推ENTAOcommandos,然後做出決定,以減少。

在本質上,RHS內部的動作被轉換成一個有在端部的動作,與另一非末端。於是

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

是翻譯成

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

因此,這些操作會在語法中產生reduce-reduce衝突。

有兩種方法:

  1. 把動作結尾。
  2. 重構 該語法使動作是 實際上在兩個 替代品中都是相同的。
+0

非常感謝,終於明白瞭如何解決這個問題,我會重寫語法併發布新版本,也許它可以幫助某人。 – Alessandro 2010-12-19 04:07:42