2011-09-15 42 views
1

我正在爲C++編寫遞歸下降解析器。我不知道如何選擇合適的生產有如下情況:在遞歸下降解析器中使用第一集

statement: labeled-statement | compound-statement | expression-statement | selection-statement | iteration-statement | jump-statement 

我讀到了「第一」 -set與可能的終端超前令牌/焦炭這是第一位的作品進行比較。目前我堅持在遞歸下降解析器中使用第一套,因爲我只有一個函數,沒有別的東西,每個規則都沒有對象,或者其他任何可以識別規則/生產的東西。

+1

你的換檔鍵有什麼問題嗎? –

+0

不,謝謝。下次我會用它:) – dcast

+0

謝謝!它只是讓這個地方看起來整潔,對於那些願意幫助你的人來說,這是一個小小的禮節。 –

回答

1

你的語法是遞歸下降解析器無效的,因爲它的左側含糊:

  • labeled-statement啓動標識爲
  • compound-statement開始用{(這是罰款)
  • expression-statement打頭一個標識符或一個數字(或(

可以在這裏停止,你在標籤語句和表達語句之間發生衝突。你需要改變你的語法來消除左邊的歧義(通過臨時語法節點來包含公共部分,所以當你分支時,你可以只使用預見來確定要去哪個分支)。

+0

mhh聽起來不錯,但怎麼樣嘗試一個並且不包括這些,這與它的「第一」集合(爲了提高性能)不匹配。如果任何生產失敗,我可以回溯到最後的生產或最後的有效狀態? 順便說一句:在我消除了左側的歧義之後,我仍然不知道要選擇哪種產品,因爲我仍然沒有第一次與前瞻比較。還有什麼好的解決方案? – dcast

+0

回溯編譯器將永遠不會工作,因爲即使是很小的輸入文件,其性能仍然非常低。假設你真的消除了左邊的歧義,那麼構建第一套很容易(如果單調乏味):只要下載每個分支的產品並構建一組可能的第一個字母。例如,'statement'的第一個集合是'identifier'(來自表達式和標籤),'{'(來自複合語句),'number'(表達式),'goto','for','if'等等。在你的遞歸函數中,你只需對每個分支的第一組進行檢查。 – Blindy

+0

如果不是很明顯,單個生產的分支之間有*任何*重疊意味着您的語法不明確。另外epsilon製作在遞歸下降語法分析器的語法中沒有位置,如果有的話,你必須擺脫它們。 – Blindy