0

我想實現一個簡單的Java像sablecc語言解析器,雖然我實施ifwhileblock報表時不斷運行到shift-reduce/reduce-reduce問題。創建移降低/減少,減少無關文法

舉例來說,我已經考慮了以下幾點:

stmts = stmt*;

stmt = if_stmt | block_stmt | while_stmt;

block_stmt = { stmts } | ;;

while_stmt = while(predicate){stmts} | while(predicate);

這個語法,將,例如,導致問題,當你有形式

while (true) ; 

的東西解析器將無法知道是否減少只是;(來自block_stmt)或完整的while (true);(來自while_stmt)。

我一直在閱讀各地的原因shift-reduce/reduce-reduce問題,我想我理解他們。但有一點是要知道是什麼引起了他們,而另一個完全不同的是知道如何構建語法,以避免它們。我嘗試過以不同的方式實現語法,然而我最終遇到了問題。

我想,不是試圖從一個特定的問題運行,而是必須採取一種模式來避免這種問題?我相信我的方式來解決問題必須是完全錯誤的:(

任何資源如何從頭開始構建一個語法,而不會陷入所有這些陷阱?在這個問題上的資源往往要麼很容易(說明明顯if then else問題),或者完全標記語法,這是一種令人費解的。

回答

2

的問題是,指定你的語法使得例如分號可以解釋無論是作爲while_stmt的分號或block_stmt的...沒有遺憾不是,但不知何故,語法是多餘的,因爲{stmt}在RHS上出現兩次。通常你會做

stmts ::= stmt | stmts stmt 
block_stmt ::= { stmts } 
stmt ::= ... | block_stmt | ;  // empty 
while_stmt ::= while ... stmt