2017-11-04 110 views
0

我目前正在實施Decaf(編程語言)語法的一部分。這裏是野牛代碼中的相關片段:無法解決以下reduce-reduce錯誤(LALR解析)

type: 
    INT 
    | ID 
    | type LS RS 
    ; 

local_var_decl: 
    type ID SEMICOLON 
    ; 

name: 
    THIS 
    | ID 
    | name DOT ID 
    | name LS expression RS 
    ; 

然而,當我開始產生式規則的工作,我的解析器給出了減少,減少警告。

這裏什麼它是.OUTPUT文件(野牛生成)內:

State 84 

    23 type: ID . 
    61 name: ID . 

    ID  reduce using rule 23 (type) 
    LS  reduce using rule 23 (type) 
    LS  [reduce using rule 61 (name)] 
    $default reduce using rule 61 (name) 

所以,如果我們給下面的輸入{ abc[1] = abc; },它說,syntax error, unexpected NUMBER, expected RSNUMBER來自表達式規則(基本上,它是如何解析它的),儘管它試圖通過local_var_decl規則解析它。

您認爲應該改變以解決這個問題?花了大約2小時,嘗試了不同的東西,沒有工作。

謝謝!

PS。這裏是link到完整.y源代碼

回答

1

這是一個常見問題的特定實例,其中解析器被迫在它有足夠的信息之前做出決定。在某些情況下,比如這種情況,所需的信息並不遙遠,如果可能的話,增加預見性就足夠了。 (不幸的是,很少有解析器生成器生成LR(k)解析器,並且bison也不例外。)通常的解決方案是簡單地讓解析繼續進行而不必做出決定。另一種解決方案是bison(但只能在C模式下)是要求%glr-parser,這對於何時需要額外處理時間來解決縮減問題要靈活得多。

在這種情況下,上下文允許使用一個typename,兩者都可以用ID後跟一個[LS)啓動。在name的情況下,[後面必須跟一個數字;在type的情況下,[後面必須跟着]。所以如果我們可以在ID之後看到第二個標記,我們可以立即做出決定。

但是我們只能看到一個令牌,即]。語法堅持我們能夠立即作出決定,因爲在一種情況下,我們必須將ID減少到name,在另一種情況下,減少到type。所以我們有一個reduce-reduce的衝突,這個野牛通過總是使用語法文件中的第一個減少來解決這個衝突。

一個解決方案是避免強制執行此選擇,但要以複製作品爲代價。例如:

type_other: 
    INT 
    | ID LS RS 
    | type_other LS RS 
    ; 
type: ID 
    | type_other 
    ; 

name_other: 
    THIS 
    | ID LS expression RS 
    | name_other DOT ID 
    | name_other LS expression RS 
    ; 
name: ID 
    | name_other 
    ; 
+0

感謝您的幫助!這工作完美。 – oneturkmen