第4步:改良錯誤訊息
到目前為止,我們做的編譯器在輸入的文法有錯誤時,只能知道有錯誤發生,但不知道在哪裡。這一步我們針對這個問題進行改良。具體來說,要顯示如下較為直覺的錯誤訊息:
要想能顯示這樣的錯誤訊息,必須在錯誤發生時,知道式發生在輸入的第幾個位元才行。為此,我們來把作為輸入程式的文字列存成變數 user_input
,定義一個新的函式可以接受只到其中某一個位置的指標,並顯示錯誤訊息。程式碼如下:
error_at
所接受的指標,會指向指向輸入文字列的某個位置。計算該指標和輸入的開頭的差,就知道錯誤發生的位置,然後就可以在該位置顯示一個醒目的^
符號。
把 argv[1]
存到user_input
變數,然後把程式碼中error("不是數值")
改為 error_at(token->str, "不是數值")
,這一步就完成了。
實用的編譯器也應該要針對輸入有錯誤時的行為寫測試,但現階段,輸出錯誤訊息只是為了幫助除錯,可以暫時不用寫測試沒關係。
參考實作: c6ff1d98a1419e69
小知識:程式碼排版器(formatter)
就像讀自然語言的文章(編註:原文為日文,但一般語言也一樣)時,如果遇上句讀等在基本寫作層級發生錯誤的文章會很難讀下去,程式語言如果在縮排、有無空白等前後沒有一致的話,別說程式的內容了,根本稱不上是漂亮的程式碼。程式碼的排版就是在這些和功能無關的地方,機械化地套用某種規則,注意不要寫出讓人分心、難讀的程式碼。
如果很多人一起開發的時候,得好好商量一下究竟要採用哪種格式,但本書是是一個人在開發,可以在主流的格式中隨意選一個自己喜歡的。
在比較新出現的程式語言裡,為了消除「該選什麼樣的格式」這種只是主觀喜好而非必要的討論,有的語言有提供官方的格式。舉例來說像Go語言就有提供gofmt
這個指令,可以幫忙把程式碼整型變漂亮。gofmt
並沒有選擇格式風格的選項,也就是說只能整成「Go官方格式」這個唯一選擇。因為不給選擇的空間,Go完全解決了「該怎麼處理格式」的問題。
C或C++有 clang-format 這個排版器可以用,但本書並不想推薦要使用這類工具。與其在寫了之後把奇怪的程式碼用排版器整型,不如試著一開始寫的時候就注意寫長相前後一致的程式。
Last updated