2013-04-24 51 views
2

我在我的語法如下規則:野牛晃來晃去別的

block:     TLBRACE statements TRBRACE 
         | TLBRACE TRBRACE 
         ; 


statements:    statement 
         | statements statement 
         ; 

statement:    TIF TLPAREN expression TRPAREN TTHEN statement 
         | TIF TLPAREN expression TRPAREN TTHEN statement TELSE statement 
         | TWHILE TLPAREN expression TRPAREN statement 
         | TDO statement TLPAREN expression TRPAREN 
         | TFOR TLPAREN forinits TSEMICOLON expression TSEMICOLON expressions TRPAREN statement 
         | block 
         | declaration TSEMICOLON 
         | expression TSEMICOLON 
         ; 

我知道的晃來晃去別的問題。這就是爲什麼我在語法文件的頂部指定了「%left TELSE」。無論如何,即使我指示Bison優先考慮TELSE標記,也會產生轉換/減少衝突。我也嘗試刪除「%left TELSE」命令(只是爲了查看它是否有任何區別),沒有任何更改。我總是有相同的轉變/減少衝突。

我與--verbose標誌野牛得到的輸出是:

State 117 

    32 statement: "if" "(" expression ")" "then" statement . ["identifier", "string value", "double", "int", "lint", "message", "string", "double value", "int value", "(", "{", "}", "-", "do", "else", "for", "if", "while", "binary not"] 
    33   | "if" "(" expression ")" "then" statement . "else" statement 

    "else" shift and going to state 122 

    "else" [reducing with rule 32 (statement)] 
    $default reducing with rule 32 (statement) 
+0

shift/reduce是一個警告,不是錯誤。 – stark 2013-04-24 13:57:00

+0

如果我指定「%left TELSE」,我希望不會發生轉換/減少衝突。沒有地方寫道有什麼是錯誤的。 – salvo 2013-04-24 13:58:10

+0

使用聲明的生產規則是什麼?看起來你可能會在語法中使用兩次「else」標記。 – Josh 2013-04-24 14:06:34

回答

2

聲明%left TTHEN當我擺脫了衝突。我不能給你一個完整的解釋,但是運算符的優先順序與運算符之後的比較有關。

+0

我認爲你的回答是正確的,因爲我通過擺脫TTHEN令牌來擺脫/減少衝突。謝謝。 – salvo 2013-04-24 14:42:21

1

使用%nonassoc解決此問題的最佳方法。

%nonassoc THEN 

%nonassoc ELSE 

%% 


statement:    TIF TLPAREN expression TRPAREN TTHEN statement %prec THEN 

         | TIF TLPAREN expression TRPAREN TTHEN statement TELSE statement 


%% 

這裏,解析器推動令牌進棧,而當IF表達式推,而下一個標記是ELSE,會有衝突。

解析器應該根據if_statement規則減少IF表達式,或者它應該將下一個ELSE令牌轉換爲堆棧。您必須確定您的規則的優先級,在這種情況下,您必須通過使用%nonassoc%prec,使ELSE令牌的優先級高於if_statement。在ELSE%nonassoc優先級大於THEN,並且通過使用%prec優先級爲if_statment的小於if_else_statment並且衝突得到解決。

+0

謝謝你的回答。你能否補充一些解釋,爲什麼這是最好的方式,它究竟做了什麼? – user5226582 2017-12-28 09:25:49

+1

這裏解析器將令牌推入堆棧,當IF表達式被推入並且下一個標記爲ELSE時會出現衝突,解析器應該根據if_statement規則減少IF expr,或者它應該將下一個標記ELSE移入堆棧。您必須確定規則的優先級,在這種情況下,您必須使用%nonassoc和%prec爲ELSE標記賦予比if_statement更高的優先級。在ELSE的%nonassoc優先級比THEN更多,並且使用if_statment的%prec優先級小於if_else_statment並且不會發生衝突。 – 2017-12-29 20:23:46

+0

謝謝!通過選擇「編輯」將它包含在你的答案中可能不是一個壞主意。我這次爲你推薦了一個。 – user5226582 2018-01-02 08:24:41