2010-03-10 57 views
4

問:
我想下面的代碼:語法高亮(編程語言)
語言:C#或組裝的x86(最好是C#)
平臺:視窗
資格:最有效的實現可能/最專業/像微軟這樣的大公司做的方式
意見反饋:如何以最有效的方式在C#中實現語法突出顯示?


精(隨意跳過 - 不需要回答的問題:)):
我不想只是實現它的任何方式 - 我已經見過幾個。
我想知道的是Microsoft如何在Visual Studio上做得如此出色(無論哪種版本)。

當談到語法高亮時,人們總是試圖重新發明輪子。我不明白爲什麼。
這是否被認爲是一個非常困難的問題?我已經看到只會突出顯示屏幕上顯示的內容的實現,我認爲這是要走的路...(它使用了一些聰明的API來知道文本框的哪些行實際顯示)。
我也見過使用RichTextBox的實現,我認爲這是不是要走的路(也許我在這裏錯了) - 我認爲像在常規文本框上繪製文本並更改它的畫筆的例程子類可能是更好(也許我曾經見過這個地方 - 我懷疑我自己會這樣想)
另外我聽說有人用AST來實現它,就像編譯器會被編碼一樣(我認爲是詞法分析器部分?) - 我希望這是過度的 - 我不認爲這是有效的。 (沒有受過教育的猜測)

如果確實是一個難題,那麼大軍隊總是如何做到這一點?例如,我從來沒有聽說過在Visual Studio中突破語法突出顯示的方法。
但是實現它的任何其他工具都做得很差,或者比大個子差。
什麼是官方的「這是最好的方式和任何其他方式效率較低」的方式呢?

我真的沒有任何證據表明微軟的方式更好,但是看到他們可能比任何其他人更瞭解Windows API,我猜想實現它的方式是最好的(我希望成爲錯誤 - 想象能夠說我的語法突出顯示的實現比MS的更好!)

對不起,脫口而出的闡述。
另外,我還提前道歉,任何假人 - 這是我的第一個問題。語法高亮 - 最有效和最專業的方式

回答

1

我不認爲有一個「這是最好的方式和任何其他方式效率較低」的方式來做到這一點。事實上,我不認爲效率是主要問題。相當複雜。 一個好的語法高亮器基於一個好的解析器。只要你能解析代碼,你可以用你喜歡的任何方式來突出它的每一部分。但是,當代碼格式不正確時會發生什麼?許多語法突出顯示器只是突出顯示關鍵字和一些塊結構來克服此問題。通過這樣做,他們可以使用簡單的正則表達式,而不是具有完整的,語法容錯解析器(這是Visual Studio的功能)。

+0

是的,但看到,不會比微軟做的任何方式效率低很多?所以你認爲微軟很容易,因爲他們擁有語言的解析器(用於編譯),因此他們可以將它用於語法突出顯示並自動100%正確地使用它。 如果是這樣,你能指向那種實現它的代碼嗎? – PeterM 2010-03-10 15:01:35

+0

@Pessimist:你可能想看看這個:http://bit.ly/3w5wK3和這個:http://bit.ly/dxDrkx – 2010-03-10 15:15:19

+0

@Pessimist:但請注意,編譯器本身不能使用時,突出顯示代碼格式不正確。此外,正如你可能已經閱讀了維基百科,正則表達式方法並不是非常有效。 – 2010-03-10 15:16:44

1

最好的方法是重用現有的東西,如ScintillaNET

+0

謝謝。我已經看過以及其他幾個人,但我更感興趣的是如何在更具商業性的IDE中知道它是如何實現的。 – PeterM 2010-03-10 14:59:09

0

與任何代碼一樣....很少有「最佳」方式。做事有多種方式,每種方式都有好處和缺點。

也就是說,某種形式的Interpreter Pattern可能是最常見的方式。根據the GoF book

口譯圖案被廣泛用於與 面向對象的語言實現的編譯器 ,作爲 Smalltalk的編譯器。 SPECTalk 使用該模式來解釋輸入文件格式的描述 。 QOCA約束解決工具包 用它來評估約束。

還繼續談論它的侷限性的適用性部分

  • 的語法很簡單。對於複雜的語法,語法分析器的類層次結構變得很大且不可管理。 解析器生成器等工具是 更好的替代方案,在這種情況下
  • 效率不是關鍵問題。最有效的 口譯員通常是而不是 通過解釋 解析 直接,但首先 翻譯成另一種形式。 例如,經常轉換爲狀態機的正則表達式爲 。 但即使如此,翻譯人員可以通過 執行解釋器 模式,所以模式仍然適用 。

理解這一點,你現在應該知道爲什麼它更好地與它進行很多比賽前先預編譯的可重複使用的正則表達式。如果你不這樣做,那麼每次都必須執行兩個步驟(轉換,解釋),而不是一次構建狀態機,並將其有效地應用幾次。

特別針對您所描述的解釋類型,Microsoft公開Microsoft.VisualStudio命名空間及其作爲Visual Studio SDK的一部分的所有強大功能。您還可以查看System.CodeDOM進行動態代碼生成和編譯。