編程時IDE里的Intellisence好像是個編譯器前端一樣,什麼都知道.這是怎麼實現的?
比如VS的,有什麼都給我們立即找出來.
其實我是想問:Intellisence難道保存了函數簽名之類的信息嗎??Intellisence是怎麼準確獲取一個函數的簽名信息的?(比如用模板生成的)
通常大家寫編譯器都是pull模型的,就是我已經準備好字元串了,我來讀,讀到哪裡類型算到哪裡。你現在把它改成push的,意思就是,我字元串已經準備好了,但是我要你算哪裡你就算哪裡,我不要的隨便。當然這種寫法很痛苦,比寫普通的編譯器麻煩很多,不過你做出來了,你的intellisense也就完成了。
如果你覺得糊塗的話,.net的IEnumerable就是pull的(主動計算),IObservable就是push的(被動計算),大概就是則個意思。他們都長得差不多,都能用linq,演算法表達出來代碼的樣子完全一致,但是就是一個push一個pull。
一個演算法可以計算很多個結果。pull的意思就是由乙方來決定多個結果之間要如何決定計算的順序(從而寫起來方便)。push的意思就是由甲方來決定多個結果之間要如何決定計算的順序(從而運行起來不浪費多餘的能量,譬如說我輸入一個點要彈列表,你去算100行以前以後的東西,大多數都是無用功)。
學習編程的時候,不僅什麼演算法數據結構、設計模式、MVVM、IoC、各種套路你都要學,還要背誦語法和函數名,更重要的,push和pull之間的相互轉換你也要熟練掌握。你不需要深入研究到我可以寫一個程序來替我轉完了還是一個非常高效的演算法(目前沒解決),你只要能夠人肉做出來就可以了。
事實上絕大多數的問題,都是pull和push相互轉換的問題,包括一些設計模式也是。如果你已經會寫正常的類型推導程序了,同時你也知道如何把一個大規模的程序在pull和push之間互相轉換,那做intellisense不就成為一件苦力了嘛。
當然了,這只是把事情做得能運行,至於如何優秀地運行,像VS一樣,還是要花點心思的。
舉個例子,以前VS的intellisence用的自己寫的解析,出來很多問題。intellisence說可以,編譯器說不行。intellisence說有這個,編譯器說沒這個。種種。後來調用了msvc的前端,就沒那麼多麻煩事了。
其他很多IDE,都用libclang做前端,如果編譯器也是用的clang,那就完全一致。不是「好像」,而是「是」。
準確的說,你的問題是編程語言如何支持 Intellisense/Autocomplete(作為 IDE 其實主要就是負責界面和交互)。
和寫編譯器差異不算大,不過有一個側重點就是用於 Intellisense 的 parser 一定要是 Error Tolerant,因為你書寫的代碼在大部分時候都不是完整的,比如
function foo() {
bar
function bar() {
}
Parser 不能因為 foo 函數定義的 closing bracket 沒有,就不認為 bar 是一個函數並不提供提示。然而圖省事的話,做編譯器則大可不必考慮這麼多(雖然他們經常容錯都做得挺好的)。
很多 ide 和編輯器的補全就是直接拿編譯器驅動的啊,比如 ycm 就是直接接 clang
VS的intellisense是買的EDG公司的前端
這個公司是C++前端做的最牛逼的公司,沒有之一
CLion的智能提示前端之前說是用C++翻譯到Java做的,現在不知道重寫了沒有
IDE的intellisense就是一個編譯器前端. 不同語言的實現不同, 但是做的事情: parsing 和 type checking, 都屬於編譯器前端的範疇.
Intellisence難道保存了函數簽名之類的信息嗎
一般而言, 是的. 交互性的編譯器都會做緩存,才能在用戶可接受的時間範圍內(&< 1000ms)返回補全結果.
Intellisence是怎麼準確獲取一個函數的簽名信息的?
和編譯器前端一樣,首先把用戶輸入的字元串解析成AST, 得到AST之後再進行類型檢查. 在用戶編輯時,把游標所在的位置轉換成AST的節點,反查該節點下有哪些符號存在,並轉化為補全信息.
事實上,對於現代編譯器前端而言,解析語法已經不是大頭.重要的是怎麼支持在各種環境下編譯器的介面,包括且不限於: IDE智能補全, REPL交互, 增量編譯, 第三方工具API.
不過對於現在大多數(非微軟出品)的語言(尤其是腳本語言), 把解釋器/編譯器做正確做強健已經算很好了,上面提的延伸場景鮮有人考慮,或者考慮了仍然實現不好. (為什麼這些語言寫不好就不展開了,已經偏題太多....)
將文本框內的代碼推到編譯器前端,獲取返回字元串,然後解析結果,反饋到文本框顯示出來。
這就是一個簡單的山寨實現。如何評價微軟的Language Server Protocol?
https://channel9.msdn.com/Blogs/Seth-Juarez/Anders-Hejlsberg-on-Modern-Compiler-Construction
推薦閱讀:
※程序員怎樣避免高強度的工作?
※【C語言】關於C裡面數組批量初始化?
※c++程序哪些應該放在頭文件裡面,哪些應該放在源文件裡面?
※編譯器生成的彙編語句執行順序為什麼與C代碼順序不同?
※編譯器能否對如下場景優化,以及如何檢查不同編譯器對此是否做了優化?
TAG:編程 | MicrosoftVisualStudio | CC |