[英]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 t3
或t1 t3 t2
,在這種情況下, TOK3
的序列將稍后出現,或者它可以假設輸入是t3 t1 t2
空t3
,其中它必須在繼續解析之前對空t3
執行操作。 選擇 shift 意味着拒絕在輸入開始時出現空t3
的可能性。
在這種特殊情況下,默認班次可能不會引起問題。 這意味着僅由TOK1
和TOK2
組成的輸入將始終在最后解析為空的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.