2012-04-15 49 views
4

幾乎所有的編譯器都會返回一個行號和錯誤消息。我想知道在編譯器設計的角度來看,編譯器如何根據不同的階段處理行號消息?謝謝。編譯器如何處理運行時錯誤消息中的行號

  • 掃描儀
  • 分析器
  • AST數據結構
  • 代碼生成

在附加:

  • 運行時環境
  • 機解釋
+0

運行時和機器解釋器不是編譯器的組成部分。 – 2012-04-15 15:10:41

+0

謝謝。我編輯了一些問題。 – 2012-04-15 15:12:42

回答

1

我已經爲我的類分配實現了一個相當簡單的編譯器。這是Pascal的一個子集,還有其他一些限制。

編譯器是一種將一種語言翻譯爲另一種語言的工具。它通過執行錯誤檢查然後生成輸出代碼(如果可能)。通常,編譯器的管道是大致等效於:

輸入代碼 - >詞法分析器(掃描儀) - >語法分析器 - >語義 分析器 - >代碼生成器 - >輸出代碼*

因爲我的語言很簡單,所以我可以做一些假設,例如一條指令將只在一行中。我的Lexer使用正則表達式來檢查不應該存在的字符,例如「不是數字,字母」的字符(「」,「,」「。」等等。「我將文件讀入字符串列表中,其中每個字符串都是下一行,所以如果我掃描一行並發現錯誤,則返回索引+ 1,其是行的數目。

隨着其檢查例如該算法是類似的「如果一個變量名稱以字母開頭的」語法分析器(解析器)。

當我延伸解析器我將代碼中的代碼與代碼中的行相關聯,以便在發生錯誤時將其返回。

我不知道現代編譯器如何解決此問題,但我可以猜測這也是某種AST和行號的關聯記住一個AST可能在幾行(好,這是語言的依賴)。

使用代碼生成編譯器知道代碼是正確的(就他們的知識而言),並且返回錯誤不是關於代碼,而是編譯器或進程存在問題(錯誤,內存不足,不能寫入位置等)。

運行環境和機器解釋也可以有編譯器,例如, JIT,但錯誤消息返回通常表示編譯器或運行時錯誤,而不是代碼。

*請注意,這是3道次的非常簡單的模型。 Modern compilers have a lot more

編輯:我發現AST有一個字段,指示行號和文件的錯誤(每個節點)。

0

大多數詞法分析器和分析器生成器將生成具有錯誤報告方法的代碼,這些方法在發生匹配錯誤時被調用。你可以重寫該方法,並做你喜歡的事情。

如前所述,在詞法分析器規範中,將行和字符號與標識符或字符串/ char/integer /布爾文字相關聯是很常見的。通常詞法分析器會提供一個yyline()方法來執行此操作。而不是讓詞法分析器返回一個原始標記(例如字符串)值,讓它返回一個包含字符串值,字符和行號的對象。例如,快速瀏覽this詞法分析器規範。

private Symbol symbol(int type) { 
    return new Symbol(type, yyline, yycolumn); 
} 

解析器將在解析過程中收到符號,並應將位置信息和令牌值一起插入AST節點。這些信息最終應該在符號表中找到。在類型分析過程中,每個葉節點都會綁定位置信息。這應該是您需要提供相當好的錯誤診斷的全部內容。