寫一個你自己的編輯器 - 第2章:語法着色(上)

·1 目的

      無論是Visual stuio還是Eclipse等衆多IDE,映入我們眼簾最直觀的就是各種語法着色,關鍵字如“int”,字符串如"ddd",註釋如“com.bbe”。

      今天我們學習如何讓你的編輯器支持語法着色。

 

·2 定義

      我們首先從思想上定義哪些輸入串將被語法着色,以及它們的顏色和字體類型,我們有如下三種模式將被語法着色:

Ø       關鍵字

關鍵字包括SELECT, FROMWHERE

n         顏色:RGB(127, 0, 85)

n         styleSWT.BOLD

n         示例:CREATE

Ø       字符串

n         顏色:RGB(42, 0, 255)

n         style:默認

n         示例:"String"

Ø       註釋

n         顏色:RGB(63, 95, 191)

n         style:默認

n         示例:/*Zero Bobo Resource Manager */

是的,正如你所見,我們使用的是Eclipse的默認語法顏色。

 

·3 分析

·31 如何讓編輯器着色

      想想,怎麼才能讓編輯器語法着色?

Ø       我們必須有一個語法(詞法)掃描器(Scanner),它能夠分解出輸入中的單詞(Token),並且根據某種模式判斷出單詞的類型,是關鍵字、字符串還是數字?在此前我們已經定義了各種Token類型對應的語法顏色和字體類型(如·2定義中描述)。

Ø       AbstractDecoratedTextEditor上有一個SourceViewerSourceViewer屬於JFace,它封裝了StyledText。我們還必須爲SourceViewer設置一個Configuration以支持對SourceViewer提供各種增加功能(add-ons),由它支持對SourceViewer進行語法着色。

     

·32 Eclipse的策略

針對我們上面的考慮,Eclipse中有對應的類實現它們:

org.eclipse.jface.text.rules.RuleBasedScanner

爲了支持語法着色功能,就必須使用某種掃描器對輸入進行語法分析,將輸入分解爲一個個的記號(Token),同時還要確定這些Token屬於什麼類型,是關鍵字還是字符串。

定位於org.eclipse.jface.text.rules下的RuleBasedScanner類提供了掃描器的功能,該類可設置多個Rule(規則),對於輸入按序執行這些rule,當某個Rule能夠成功evaluate一個輸入,就返回一個定義好的Token。如果一個rule返回了一個UN_DEFINETOKEN,就繼續讓下一個Rule來解析。如果沒有Rule能夠返回定義的token,則Scanner返回一個特定的Token,對該token調用isOther()將返回true。如果遇到了文件的結尾,則對Scanner返回的Token調用isEOF返回true

我們自己定義一個ZSqlScanner類繼承RuleBasedScanner,並在構造中設置需要的rule

關於Rule主要有如下幾種(Rule均實現IRule接口):

a)                 WordRule實現IRule:該規則可以發現一個完整的字,比如JavaSQL的關鍵字,他們的語法組成是固定的,int就是intlong就是long,通過這個規則可以發現這些關鍵字。WordRule需要一個IWordDetector接口的實例來輔助分析(實際上WordRule有點小問題,在後面介紹)。

b)                 WhitespaceRule實現IRule:顧名思義,發現輸入中的空白字符。WhitespaceRule需要一個IWhitespaceDetector接口的實例來輔助分析

c)                 SingleLineRule繼承PatternRule:根據某種模式匹配規則,比如字符串由“”開始和結束。但SingleLineRule要求字符序列必須在單行上匹配模式。

d)                 MultiLineRuleSingleLineRule類似,不同在於MultiLineRule允許字符序列在多行上匹配模式(比如多行註釋/*  */可用這種規則)。

e)                 EndOfLineRule繼承自SingleLineRule,它開始於某種指定的模式,結束一定是一個換行符(line delimiter),比如單行註釋“//abcd”就可使用這種規則。

     

org.eclipse.jface.text.source.SourceViewerConfiguration

在前言中我們已經瞭解,SourceViewer通過SourceViewerConfiguration類來控制其各種增件配置,如代碼着色,自動提示等。爲了支持語法着色,我們必須提供自己的SourceViewerConfiguration類:ZSqlSourceViewerConfiguration,並且重寫getPresentationReconciler方法。

IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer)方法,返回一個IPresentationReconciler接口的實例,該實例上註冊了了一個毀壞器(damager)和一個修復器(repairer)。

damager負責計算文檔被修改的區域

repairer負責重新構建文檔被修改區域的表現形式(着色)

 

 

·4 源代碼

      通過分析,我們的思想已經有了,下面就來看源代碼。由於篇幅關係,我們不在這裏介紹所有的源代碼,只介紹增加的和重要的代碼。介紹的順序按照執行的流程。

 

·41 擴展父類的initializeEditor()方法,並如下實現:

       super.initializeEditor();

this.setSourceViewerConfiguration(new

ZSqlSourceViewerConfiguration());

    initializeEditor()方法會在ZSqlEditor的構造方法前執行,因爲在AbstractDecoratedTextEditor類的構造中調用了initializeEditor()方法,此時ZSqlEditor的構造方法還沒有執行(請參考我的另一篇文章,Java對象的構造順序-讓代碼在構造方法前執行)。

你也許會問,此時我們的SourceViewer還沒有創建,怎麼能夠設置Configuration,實際上AbstractTextEditor會爲你保持Configuration對象,並在其createPartControl()方法中將其配置到SourceViewer上。ZSqlEditor.intializeEditor()ZSqlEditor的構造方法之前執行(因爲它在父類AbstractDecoratedTextEditor的構造方法中被調用)因此我們在這裏設置Configuration。而在AbstractTextEditor.createPartControl()方法中,將調用createSourceViewer()方法創建SourceViewer的實例,併爲SourceViewer配置Configuration(使用我們設置的configuration)。而一旦爲SourceViewer設置了Configuration,就不能重新配置,否則會出現IllegalStateException異常(因此,你實際上可以在ZSqlEditorinitializeEditor(), constructor(), init()方法,包括createPartControl()方法(調用super.createPartControl()方法之前)調用setSourceViewerConfiguration()方法)。

       

·42 增加類ZSqlSourceViewerConfiguration

extends SourceViewerConfiguration

重寫public IPresentationReconciler getPresentationReconciler(

                                       ISourceViewer sourceViewer)方法

 

·43 增加類ZSqlScanner extends RuleBasedScanner

     

·44 增加類ZSqlWhiteSpaceDetector, ZSqlWordDetector

      這兩個類均爲Rule的輔助類,負責發現空白字符和關鍵字。

 

·45 增加接口ZISqlSyntax

    這個接口用來提供各種字符串數組,當前僅提供關鍵字字符串數組。ZSqlWordDetector根據這些來判斷某個模式是否關鍵字。

 

·5 運行

      點擊下載(http://www.sinadisk.com/pick.aspx?code=com.bbebfe.sql_source_highlight源代碼工程和插件Jar包。

      下載完成後你可以選擇導入源代碼工程或者直接將Jar包拷貝到Eclipseplugins目錄下。通過File -> open file打開任意.sql後綴就可以激活編輯器。運行效果如下:

·6 總結

      在本章我們學習瞭如何讓我們的編輯器支持語法着色,雖然我們只定義了最簡單的幾種模式,但你完全可以以此推導出其他的多種模式。不過目前編輯器在代碼着色方面仍然有些小問題,將在下一章介紹並解決。

 

·7 參考文獻

      []Jim D’Anjou等,《Eclipse權威開發指南》,清華大學出版社

      Eclipse示例:org.eclipse.ui.examples.javaeditor

 

發佈了43 篇原創文章 · 獲贊 29 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章