0

我有以下規則,並在與野牛一起實施時,我會得到5次移位/減少警告。解決GnuWin32 Bison中的Shift/Reduce警告?

規則的部分是:

Type---->  BOOL 
    | INT 
    | CHAR  
    | DOUBLE 
    | ID 
    | INT '['']' 
; 
rule:   VarDec rule 
    | VarDec 
; 
VarDec: Type ID ';' 
; 

Parser.output給我的警告,在這種狀態下:

**state 25**

4 rule: VarDec . rule 
5  | VarDec . 

BOOL  shift, and go to state 3 
INT   shift, and go to state 4 
CHAR  shift, and go to state 5 
DOUBLE  shift, and go to state 6 
ID   shift, and go to state 7 

BOOL  [reduce using rule 5 (rule)] 
INT   [reduce using rule 5 (rule)] 
CHAR  [reduce using rule 5 (rule)] 
DOUBLE  [reduce using rule 5 (rule)] 
ID   [reduce using rule 5 (rule)] 
$default reduce using rule 5 (rule) 

rule   go to state 28 
VarDec   go to state 25 
Type   go to state 27 

誰能幫助我如何解決這個問題,我讀了很多文章,但我無法弄清楚什麼是錯的,並且預先感謝每一個人...... :)

回答

1

上面的例子不足以重現轉換/減少衝突。您可能在其他地方有rule的實例,然後是VarDec或其開頭的令牌。

如果我添加下面的規則,我可以重現的衝突:

decl : rule VarDec; 

這條規則是造成你的問題。

0

衝突發生在分析堆棧頂部存在VarDec的狀態下,並且下一個標記是BOOL,INT,CHAR,DOUBLE或ID。然後,解析器需要至少查看兩個令牌,以確定它是否正在查看另一個VarDec - 在這種情況下,現在正確的操作是預期稍後將以下令牌減少爲「規則」 - 或者是否它正在尋找其他的東西 - 在這種情況下,正確的操作是將當前位於棧頂的VarDec減少到「規則」。

應該可以改變你的「規則」的規則,像這樣來解決這一特殊矛盾:

rule: rule VarDec 
    | VarDec 
; 

,而不是使用右遞歸左遞歸。這也很好,因爲你應該總是使用在Bison規則中使用左遞歸而不是右遞歸。這可以確保您可以使用有限的堆棧空間解析任何輸入。

由Bison確定的實際狀態可能與該更改略有不同,但在可能的情況下,仍然有一個在堆棧頂部有一個VarDec,並且BOOL,INT,CHAR,DOUBLE或ID之一爲下一個標記,將只有一個可能的操作(僅顯示規則):將堆棧上的VarDec減少爲「規則」。沒有其他可能的解析,即使即將到來的令牌後來不會減少到VarDec。