編譯器為什麼在一次編譯過程中要儘可能的發現所有錯誤?
01-14
如題~編譯器在編譯的過程中,如果發現一個錯誤為什麼不立即終止退出呢?
看是編譯器前端還是後端的錯誤。
編譯器前端,檢查輸入程序的詞法、語法、語義(類型檢查 / 類型推導、確定性賦值、不可到達的代碼等等)。這些都是跟作為輸入的程序員寫的代碼息息相關的,如果一次只報一個錯的話用戶體驗就不好,用戶就要狂吐槽…或者大家就不用這個編譯器了。
早期的編譯器、或者現代實現得很入門的編譯器,跟現代實現得很成熟、人見人愛的編譯器,差別主要就在這錯誤恢復和報錯信息的體驗上。看C++編譯器中,Clang那麼多人喜歡,主要就在這裡。
順帶放個傳送門:clang編譯器的錯誤提示的精準程度是如何做到的? - C(編程語言)試想一下,您要辦個手續需要準備各種材料,然後跑去個什麼局去審批蓋章。結果每次大老遠跑去那個局之後人家只給您指出一個錯誤,您就又得回家改改改,再跑去又告訴另一個錯誤,再回家改改改,這麼來回很多趟的話您願意么?
當然是那個局一口氣把所有可能的錯誤都告訴您了,這體驗才好,對不對?編譯器後端(這裡籠統把優化器和代碼生成器都叫做後端)只接受前端已經校驗過的輸入,所以假定是輸入的代碼肯定是正確的,接下來就是對它做優化和代碼生成而已。這裡能出的錯就都是編譯器自己的錯了。此時還真的經常就是編譯器跑著跑著突然發現有什麼東西不對了,就直接退出了,不會還試圖做錯誤恢復去繼續編譯。
發現一個錯誤就退出的編譯器是最容易實現的了,但是改一次編一下用戶體驗就不好了,一次列出用戶所有(可能的)錯誤可以減少開發時間說可能的是因為如果發現一個錯誤不退出,繼續往下分析,可能要先想辦法跳過一些代碼,從下一個「正常」代碼繼續編譯,如果代碼前後相關度比較大就不好實現,或報出一些不是錯誤的錯誤比如我做過類似python這樣用縮進表示代碼塊,以及用花括弧表示代碼塊的語言的前端編譯,後者要做全報錯比較容易,詞法階段先分析花括弧,把一個文件分割成多個class和function,然後每個可以獨立編譯,這樣所有錯都能檢測,而前者就要麻煩些,而且出現縮進錯誤時候,你也不知道該怎麼對代碼塊做定界了
最原始的編譯器還真是這樣的,只不過後來慢慢發展,更人性化了,盡量讓程序員一次性修改更多的錯誤。
推薦閱讀:
※你覺得編譯程序中使用的關鍵技術都有哪些應用方向?請詳細說明。
※如果想要寫一個C++或者面向對象的語言的一個簡單的編譯器,應該學習哪些領域的知識?
※Clang裡面真正的前端是什麼?
※gcc編譯器為什麼不直接編譯成機器代碼?
※請問國內有哪些關於clang編譯技術的重要會議或者論壇?
TAG:編譯器 |