2014-06-05 34 views
1

我覺得檸檬語法分析器生成器在非關聯優先級上做錯了。我有一個簡化的語法,展現了我所看到的問題。檸檬是否正確處理非關聯優先?

%nonassoc EQ. 
%left PLUS. 

stmt ::= expr. 

expr ::= expr EQ expr. 
expr ::= expr PLUS expr. 
expr ::= IDENTIFIER. 

產生具有像這樣一個衝突的報告:

State 4: 
     expr ::= expr * EQ expr 
    (1) expr ::= expr EQ expr * 
     expr ::= expr * PLUS expr 

         EQ shift 2 
         EQ reduce 1 ** Parsing conflict ** 
         PLUS shift 1 
       {default} reduce 1 

如果我告訴它相當於是左結合的,問題消失。就好像nonassoc不會將規則放入優先級集合中一樣。與該語法的Bison版本相比,沒有衝突。而任務確實應該是非關聯性的。我寧願不要對此撒謊以解決這個問題。

回答

2

在花費了一些時間仔細研究由檸檬和Bison爲相關語法生成的報告之後,我只能得出結論,檸檬的確處理不合理的優先順序。吸菸槍包含在上面引用的狀態4中,但爲了清晰起見,我應該詳細說明一些細節。

建立到expr EQ的狀態很簡單。您到達狀態2則:

State 2: 
     expr ::= * expr EQ expr 
     expr ::= expr EQ * expr 
     expr ::= * expr PLUS expr 
     expr ::= * IDENTIFIER 

       IDENTIFIER shift 5 
         expr shift 4 

這種狀態包含當前expr EQ項,預計將再接再EXPR。因此,它包含第一個用於expr的集合,這是在狀態中以*開頭的3個條目。如果我們在這個狀態下閱讀一個expr,我們將在狀態4中用一個項目在減少的中途或結束時降落。

expr ::= expr * EQ expr 
expr ::= expr EQ expr * 

如果我們在這種狀態下讀取EQ會發生什麼?我告訴檸檬這個答案。這是一個錯誤,因爲EQ是非關聯的。相反,它會報告一個轉換/減少衝突。在實踐中,它會轉移,這將讓它接受非法解析,如x=y=z

野牛包含這些相同的國家,編號不同,但具有明顯的區別。

state 8 

    2 expr: expr . EQ expr [$end, PLUS] 
    2  | expr EQ expr . [$end, PLUS] 
    3  | expr . PLUS expr 

    EQ error (nonassociative) 

    $default reduce using rule 2 (expr) 

    Conflict between rule 2 and token PLUS resolved as reduce (PLUS < EQ). 
    Conflict between rule 2 and token EQ resolved as an error (%nonassoc EQ). 

Bison知道非關聯手段是什麼,並且如果它在表達式中看到第二個EQ,就會用它來消除假設的不明確性。