簡體   English   中英

在 Java Cup 狀態中發現 Shift/Reduce 沖突

[英]Shift/Reduce conflict found in state in Java Cup

我正在嘗試在 java cup 中編寫解析,但我遇到了沖突

start with prog;

prog ::= header;
header ::= t1 t3 t2 | t3 t1 t2 | t2 t3 t1 | t1 t2 t3 | t2 t1 t3 | t3 t2 t1;

t1 ::= TOK1;
t2 ::= TOK2 | TOK2 TOK2 ;
t3 ::= | t3 TOK3;

我收到了這個錯誤;

Warning : *** Shift/Reduce conflict found in state #3
  between t3 ::= (*) 
  and     t1 ::= (*) TOK1 
  under symbol TOK1
  Resolved in favor of shifting.

有人可以解釋我在哪里做錯了嗎?

t3可以為空(它匹配零個或多個TOK3標記的序列)。 這造成了歧義,因為沒有TOK3的輸入可以匹配多個header的替代方案。

盡管所有的可能性都歸約到同一個非終結符,但這是模棱兩可的,因為每個產生式都有不同的歸約動作,而且語法無法知道要執行哪個動作。 正如沖突報告中所指出的,解析器將移動而不是減少。 例如,如果第一個輸入是TOK1 ,解析器可以假設輸入將匹配t1 t2 t3t1 t3 t2 ,在這種情況下, TOK3的序列將稍后出現,或者它可以假設輸入是t3 t1 t2t3 ,其中它必須在繼續解析之前對空t3執行操作。 選擇 shift 意味着拒絕在輸入開始時出現空t3的可能性。

在這種特殊情況下,默認班次可能不會引起問題。 這意味着僅由TOK1TOK2組成的輸入將始終在最后解析為空的t3 ,但如果沒問題,那么您可以隨意忽略警告。

所謂的“可空非終結符”通常正是這種形式的移位歸約沖突的原因。 避免它們通常很有用; 與創建可能為空的列表不同,更好的解決方案通常是使列表非終結符匹配一個或多個元素,然后通過添加列表不存在的產生式使其可選。 換句話說,而不是

header: t3 t1 t2
t3    :  
      | t3 TOK3

采用

header: t3 t1 t2
      |    t1 t2
t3    : TOK3
      | t3 TOK3

該解決方案可能會導致不受歡迎的代碼重復,但它是解決由於可空非終結符引起的 shift-reduce 沖突的簡單方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM