2009-11-18 32 views
0

我在yacc中使用了-v選項來生成y.output文件。在文件的頂部,它說這個yacc解析器中的衝突是什麼?

州98個矛盾:1個轉變/減少

在文件中再往下是:

state 98 

    30 selection_stmt: IF '(' expression ')' statement . 
    31    | IF '(' expression ')' statement . ELSE statement 

    ELSE shift, and go to state 101 

    ELSE  [reduce using rule 30 (selection_stmt)] 
    $default reduce using rule 30 (selection_stmt) 

什麼衝突,這怎麼能固定?

+0

[如何在此yacc文件中找到移位/減少衝突?](http://stackoverflow.com/questions/1737460/how-to-find-shift-reduce-conflict-in-this-yacc -文件) – Flexo 2013-01-12 12:29:32

回答

0

嘗試這樣:

election_stmt: IF '(' expression ')' statement . selection_stmt_else_part; 
selection_stmt_else_part: ELSE statement 
         | 
         ; 
1

剛想移位/減少誤差if/then/else語句是臭名昭著的dangling else問題。

有了這個代碼段:

if (f1): 
    if (f2): 
     c1 
    else: 
     c2 

(和Python,由於它的奇怪的縮進規則)知道哪個ifelse屬於,但解析器是不高明。

它不能分辨else屬於第一個還是第二個if

This link顯示瞭如何將LR(n)轉換爲應該解決問題的LR(1)等價物。

另一種方法是改變你的基礎語言定義(如果可能的話),這樣的模糊性消失:

: IF '(' cond ')' THEN statement ENDIF 
| IF '(' cond ')' THEN statement ELSE statement ENDIF 
0

咳咳,正確回答這個問題通常是:無能爲力

移位/減少衝突是預期與歧義文法。他們不是錯誤,他們是衝突

衝突將通過寧願轉移減少來解決,這恰好解決了典型的懸擺問題。

野牛甚至有一個%預計ň語句,這樣,當有確切ň衝突,你沒有得到一個S/R衝突警告。