2011-01-14 55 views
3

我一直在試圖解決看似簡單的轉換/減少衝突無濟於事。當然,如果我只是忽略衝突,分析器工作正常,但如果我重新組織規則,我會感覺更安全。在這裏,我已經簡化一個比較複雜的語法的單衝突:由於先行令牌限制,在yacc中移位/減少衝突?

statement_list 
    : statement_list statement 
    | 
    ; 

statement 
    : lvalue '=' expression 
    | function 
    ; 

lvalue 
    : IDENTIFIER 
    | '(' expression ')' 
    ; 

expression 
    : lvalue 
    | function 
    ; 

function 
    : IDENTIFIER '(' ')' 
    ; 

隨着yacc的詳細選項,我得到的描述與衝突提到的狀態此輸出文件:

state 2 

    lvalue -> IDENTIFIER . (rule 5) 
    function -> IDENTIFIER . '(' ')' (rule 9) 

    '(' shift, and go to state 7 

    '(' [reduce using rule 5 (lvalue)] 
    $default reduce using rule 5 (lvalue) 

謝謝你的任何幫助。

回答

5

問題是,這需要2令牌前瞻來知道它何時到達語句的結尾。如果你有以下形式的輸入:

ID = ID (ID) = ID 

分析器之後移位第二ID(前瞻是(),它不知道這是否是第一個發言的一端((是第二語句的開始),或者這是一個功能。所以它轉移(繼續解析一個函數),這與上面的示例輸入是錯誤的。

如果擴展function允許括號和expression內的參數,讓實際的表情,事情變得更糟,因爲需要先行是無界 - 解析器需要一路到達第二=來確定這不是函數調用。

這裏的基本問題是,沒有幫助標點符號來幫助解析器找到語句的結尾。由於有效語句開始的文本也可能出現在有效語句的中間,因此查找語句邊界很困難。

+0

我沒有考慮過這樣的輸入。那麼,我解析的語言需要這種模糊性,所以我想我會忽略這個衝突。 – Skyler 2011-01-15 09:07:42