2013-07-11 77 views
5

我是新來Bison和我遇到麻煩轉變/減少衝突......我試圖從文件加載到array data[]移位/減少衝突野牛

struct _data 
{ 
    char name[50]; 
    char surname[50]; 
    int year; 
} data[1000]; 

下面是部分我的野牛代碼:

%token ID NUM NL EOF 

%% 

File : List EOF 
     ; 
List : Record 
     | List Record 
     ; 
Record : Name Surname Year NL { count++; } 
     | NL     { count++; } 
     | /*empty*/ 
     ; 
Name : ID     { strcpy(data[count].name, yytext); } 
     ; 
Surname: ID     { strcpy(data[count].surname, yytext); } 
     ; 
Year : NUM     { data[count].year= atoi(yytext); } 
     ; 

%%    

我得到這個錯誤:

conflicts: 5 shift/reduce 

任何想法,我在哪裏呢?

回答

11

可以使用-v選項來獲得bison產生的.output文件,其中包含了很多的更多信息,可以幫助您診斷轉變/減少衝突。特別是,它會向您顯示每個解析器狀態,包括項目列表,並指出哪些狀態存在衝突。

但在這種情況下,問題很簡單。剝去其要領你有:

List: Record 
    | List Record 
    ; 

Record: Something 
     | /* Nothing */ 
     ; 

忽略的Something的定義是什麼,問題是List可以由任意數量的Records,此起彼伏的,並且Record可以爲空。這意味着什麼都不能解析爲任何數量的空Records,這是完全不明確的。輸入中的任何兩個連續的Somethings可以用0,1,2,42或273空的Records分開。由於解析器不知道是否開始解析新的Something(shift)或發出空的Record(減少),它抱怨存在移位/減少衝突。

在這種情況下,解決方案非常簡單。我們可以看到非空的Something必須以NL結尾;大概意圖是File由任意數量的Records組成,每個都在其自己的行上。所以我們可以改寫:

File: List EOF 
    ; 

List: Record 
    | List NL Record 
    ; 

Record: Name Surname Year 
     | /* Empty */ 
     ; 

現在Record,空與否,必須跟隨一個EOFNL。不能直接跟着另一個Record