2010-02-13 67 views
2

我有我認爲是我的語法的一個簡單部分這是從yacc獲取錯誤。我知道我需要在某處添加%prec,但不確定其中的位置。yacc shift減少問題

Assignment : Ref '=' Ref 
      | Ref '=' Expression 
      | Ref '=' Value 
      | Ref '=' FunctionCall 
      ; 

Ref : ID 
    | ID '[' Expression ']' 
    ; 

Value : INT 
     | BOOLEAN 
     | CHAR 
     | STRING 
     ; 

錯誤即時得到的是:

warning: rule never reduced because of conflicts: Assignment: Ref '=' Ref 
warning: rule never reduced because of conflicts: Assignment: Ref '=' Value 

所以ID就是一個變量名,編號是一個變量的引用。

+0

'ID'的定義是什麼? – outis 2010-02-13 07:30:16

+0

我們幾乎肯定需要看到Expression,Value和FunctionCall的定義。表達式可能允許ID(或可能是Ref)作爲選項,在這種情況下Ref = Ref規則是冗餘w.r.t Ref =表達式。 – 2010-02-13 07:41:33

回答

1

嗯不知道,FunctionCall,Value和Ref也是表達式嗎?也許如果它表達式被刪除時,它可能暗示表達式包含其中之一...

1

Assignment : Ref '=' Ref的問題是Ref = Ref = Ref是不明確的(其中你可能已經知道);嘗試定義「=」使用%right關鍵字(假設你想「=」是右結合)令牌:

%right '=' 

至於Assignment: Ref '=' Value,我必須看到的定義ID和各種Value雖然將'='定義爲正確的聯想可能就足夠了。

0

看起來解析器不能區分語法中的各種Assignment字符串在其前瞻(相當嚴格)的限制之內。

如果IDValue製作很容易解析我不認爲你會有這個問題。你很可能將所有的產品組合成一個,這樣至少可以更容易地減少這個規則並使問題更加明顯。

1

我們真的需要查看FunctionCall和(特別是)Expression的定義以給出明確的答案,但我的猜測是Expression可以是單個Ref或Value。在這種情況下,它表示它不知道(當然)是否將分配右側的Ref/Value直接解析爲自身,或者將其解析爲簡單表達式。

令人驚訝的是,FunctionCall沒有產生類似的歧義 - 這往往表明您的表達式的定義可能是奇怪的,至少接近有缺陷。

如果我這樣做,我可能會改變分配的定義看起來是這樣的:

%left '-' '+' 
%left '*' '/' 

%% 

Assignment: Ref '=' Expression; 

Expression: Value 
      | FunctionCall 
      | Ref 
      | Expression '+' Expression 
      | Expression '-' Expression 
      | Expression '/' Expression 
      | Expression '*' Expression 
      | '(' Expression ')' 
      ; 

當然,你可能要支持更多運營商帶來了四個基本的,但它很難猜 - 我只是試圖投入足夠的,至少給一個合理的想法。

在任何情況下,採用這種結構,毫無疑問,一個分配的右側有是一種表達,表達可以包括你所列出,加之任意算術運算符的三個基本物品,所以是這樣的:

x[i] = a[2] + 1 + f(3) 

有可能成爲(逐漸):

Ref = Expression 
Ref = Expression '+' Expression 
Ref = Expression '+' Expression '+' Expression 
Ref = Ref '+' Value '+' FunctionCall 
ID '[' ID ']' '=' ID '[' Value ']' '+' Value '+' FunctionCall 

(和FunctionCall可能會進一步降低到類似:ID '(' Value ')'

底線:至少該語法的一部分是基本上不受S/R的衝突 - 有從頂層Assignment爲特定分配單個令牌的明確無誤的路徑。這也有助於減少用戶的混淆,因爲所有表達式都具有相同的語法。