WEB开发网      婵犵數濮烽弫鍛婃叏閻戣棄鏋侀柛娑橈功缁犻箖鏌嶈閸撴氨鎹㈠☉娆愬闁告劕寮堕幖鎰棯閸撗勫殌闁宠鍨块幃鈺冣偓鍦Т椤ユ繈姊哄Ч鍥р偓妤呭磻閹捐桅闁告洦鍨扮粻娑㈡煕椤愶絾绀冩い搴$Ч濮婅櫣绮欏▎鎯у壋闂佸摜濮甸崝娆愪繆閻㈢ǹ绀嬫い鏍ㄨ壘閸炪劑姊洪棃娴ゆ稒鎷呴幓鎺嶅闂佸湱鍎ら〃鍡涘煕閹烘鐓曢柡鍥ュ妼娴滄粍銇勮箛锝呭籍闁哄备鈧磭鏆嗛悗锝庡墰閺嗙娀鏌ф导娆戝埌闁靛棙甯掗~婵嬫偂鎼达絼鐢荤紓浣诡殕閸ㄥ灝顫忕紒妯诲缂佹稑顑呭▓顓炩攽椤旀枻鍏紒鐘虫崌閵嗕礁顫濋幇浣光枌婵犵數濮崑鎾趁归敐鍥┿€婇柡鈧禒瀣厽婵☆垱顑欓崵瀣偓瑙勬偠閸庤精鐏冮梺缁樏鍫曞疮閻愮數纾奸柛灞炬皑鏁堥悗瑙勬礃缁繘藝鐎靛摜妫柟顖嗕礁浠悗娈垮枛閻栫厧鐣烽悡搴樻婵☆垯璀﹂悗宕囩磽閸屾瑧鍔嶆い銊ユ閻f繈骞栨担姝屾憰闂佺粯妫冮ˉ鎾诲汲鐎n喗鐓熸俊銈傚亾闁绘妫楅埢鎾澄旈崨顔规嫼闁荤姴娲犻埀顒冩珪閻忊偓闂備礁鎼幊鎰叏閹绢喗鍋╅柣銈庡灛娴滃綊鏌熼悜妯肩畺闁哄懏绻堝娲濞戞艾顣哄┑鈽嗗亝閻熲晠銆佸▎鎺旂杸闁哄啫鍊婚惁鍫ユ⒑濮瑰洤鐏叉繛浣冲嫮顩烽柨鏇炲€归悡鏇㈡煏婵炲灝鍔ら柛鈺嬬稻椤ㄣ儵鎮欓弶鎴濐潚濡ょ姷鍋為敃銏ゃ€佸▎鎾村殐闁冲搫顑囬獮銏ゆ⒒閸屾瑦绁版い顐㈩槸閻e嘲螣閼测晝鐓嬪銈嗘閿熴儲绂嶈ぐ鎺撶厵闁绘垶蓱鐏忣厼霉濠婂啰绉烘慨濠呮缁辨帒螣閾忛€涙闂備焦瀵уú宥夊疾濞戞粎浜遍梻浣告啞濞诧箓宕归柆宥呯厱闁硅揪闄勯悡娆撴煠濞村娅呭ù鐘崇矊閳规垿鍨鹃悙钘変划闂佽鍠楅〃鍛村煡婢舵劕绠抽柟鎯ь嚟瑜板洨绱撻崒娆戣窗闁哥姵鐗犻、鏍川閹碱厽鏅i梺绋跨箳閸樠呮閻愮繝绻嗘い鏍ㄧ矌鐢稒绻涢崨顓熷枠婵﹦绮幏鍛存偡闁箑娈濈紓鍌欐祰椤曆囧磹閸噮鍤曠紓浣贯缚缁♀偓闂佹悶鍎崝宥呪枍閸ヮ剚鈷戠紒瀣濠€鎵磼鐎n偅宕岀€规洏鍨介幃浠嬪川婵犲嫬骞楅梺鐟板悑閻n亪宕规繝姘厐闁哄洢鍨洪悡銉︽叏濡灝鐓愰柣鎾跺枛閻擃偊宕堕妷銉ュБ缂備礁顑堝畷鐢垫閹烘梻纾兼俊顖濆亹閻h櫣绱撴担铏瑰笡缂佽鐗嗛悾宄邦潨閳ь剚淇婂宀婃Ш缂備浇椴哥换鍫濐潖缂佹ɑ濯寸紒娑橆儏濞堟劙姊洪幖鐐插闁告鍟块悾鐑筋敍閻愯尙楠囬梺鐟邦嚟婵潧鈻撴ィ鍐┾拺缂備焦蓱閳锋帡鏌嶅畡鎵ⅵ鐎殿噮鍋婂畷鎺楁倷鐎电ǹ骞堥梻浣瑰▕閺侇噣宕戦幘缁樼厸闁告侗鍠氶幊鍛繆閸欏濮囬摶锝夋偠濞戞帒澧查柡鍌楀亾闂傚倷鑳剁划顖炲礉閺囩倣鐔哥節閸パ冩優闂佺粯鏌ㄩ惃婵嬪绩閼恒儯浜滈柡鍐ㄦ处椤ュ鏌涢弬璇测偓婵嬪箺閸洘鍊烽柣鎴炨缚閸橀亶姊洪崫鍕偍闁告柨鏈弲鍫曨敍閻愬鍘卞┑鐐叉缁绘帞绮绘繝姘厸閻忕偟鏅晥閻庤娲﹂崑濠傜暦閻旂⒈鏁嗛柍褜鍓欓埢宥夋晲閸モ晝锛濇繛杈剧稻瑜板啯绂嶉悙顒傜瘈闁靛骏绲剧涵鐐亜閹存繃宸濈紒顔剧帛閵堬綁宕橀埡鍐ㄥ箥闂佽瀛╃粙鎺戠幓鐠恒劎涓嶆慨妞诲亾闁哄被鍔岄埥澶娢熸径鐧哥稻閵囧嫰濡搁敐鍛Е闂佽鍠楅悷鈺呫€侀弮鍫濈妞ゆ挻绻勭粈鍕⒒閸屾瑦绁版い鏇熺墵瀹曚即寮介銈囶槸婵犵數濮撮崐濠氬汲閿曞倹鐓欐い鏍仜娴滅増淇婇懠棰濆殭闁宠鍨块崺鍕礃閵娧呫偡婵$偑鍊ら崢楣冨礂濡警鍤曢悹鍥ㄧゴ濡插牓鏌曡箛鏇烆潔闁冲搫鎳忛悡蹇擃熆鐠鸿櫣澧曢柛鏃€鎸抽弻娑㈠棘濞嗙偓楔缂備浇椴搁幐濠氬箯閸涱垳鐭欓幖瀛樻尭娴滈箖鏌涘┑鍕姢闁活厽鎸鹃幉鎼佹偋閸繄鐟ㄩ梺鍝勵儎缁舵岸寮婚悢鐓庣鐟滃繒鏁☉銏$厸闁告侗鍠楅崐鎰版煛鐏炶濮傞柟顔哄€濆畷鎺戔槈濮楀棔绱� ---闂傚倸鍊搁崐鎼佸磹閹间礁纾归柣鎴eГ閸婂潡鏌ㄩ弮鍫熸殰闁稿鎸剧划顓炩槈濡搫绠诲┑鐐叉▕娴滄粓鎮″☉銏$厱婵炴垵宕獮妯汇亜閺傛寧顥㈡慨濠呮閹瑰嫰濡搁妷锔惧綒闂備胶鎳撻崵鏍箯閿燂拷
开发学院软件开发Java 基于 JFace Text Framework 构建全功能代码编辑器... 阅读

基于 JFace Text Framework 构建全功能代码编辑器: 第 1 部分:引言

 2010-03-18 00:00:00 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣椤愯姤鎱ㄥ鍡楀幊缂傚倹姘ㄩ幉绋款吋閸澀缃曢梻鍌欑濠€閬嶆惞鎼淬劌绐楅柡宥庡亞娑撳秵銇勯弽顐沪闁绘挶鍎甸弻锝夊即閻愭祴鍋撻崷顓涘亾濮樼偓瀚�闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣捣閻棗銆掑锝呬壕濡ょ姷鍋涢ˇ鐢稿极閹剧粯鍋愰柟缁樺笧閳ь剦鍙冨鍝勑ч崶褏浠奸梺璇茬箲閼归箖鎮鹃悜钘夎摕闁靛濡囬崢鐢告⒑鐟欏嫷鍟忛柛鐘崇墵閵嗗倹绺介崨濠勫幈闁硅壈鎻槐鏇熺墡闂備線娼уú銈団偓姘嵆閻涱噣骞掑Δ鈧粻锝嗙節闂堟稑鏆欏ù婊堢畺閺岋綁濮€閳惰泛婀辨竟鏇熺節濮橆厾鍘甸梺缁樺姦閸撴岸鎮樻潏銊ょ箚闁圭粯甯炴晶娑氱磼缂佹ḿ娲寸€规洖宕灃闁告劕鍟犻崜婵堟崲濞戞ḿ鏆嗗┑鐘辫兌閺佹牜绱撴担浠嬪摵闁圭懓娲ら悾鐑藉箳閹搭厽鍍甸梺鐟板悁閻掞箓鎮楅幖浣光拻濞达絿鍎ら崵鈧梺鎼炲€栭悧鐘荤嵁韫囨稒鏅搁柨鐕傛嫹婵犵數濮烽弫鍛婃叏閻戣棄鏋侀柛娑橈攻閸欏繑銇勯幘鍗炵仼缂佺媭鍨堕弻娑㈠箛闂堟稒鐏堥悗鐟版啞缁诲啴濡甸崟顖氱閻庨潧鎽滈悾濂告⒑绾拋娼愭繛鑼枎椤繒绱掑Ο鑲╂嚌闂侀€炲苯澧畝锝堝劵椤︽煡鎮¢妶澶嬬厪闁割偅绻冮崑顏呯箾瀹割喕绨婚幆鐔兼⒑鐎圭姵銆冮柤鍐茬埣瀹曟繈鏁冮埀顒勨€旈崘顔嘉ч柛鈩冾殘閻熸劙姊洪悡搴℃毐闁绘牕銈稿畷鐑樼節閸パ冨祮闂侀潧楠忕槐鏇㈠储椤忓牊鈷戦柟鑲╁仜閸旀鏌¢崨顔锯姇缂佸倹甯熼ˇ瀵哥磼鏉堛劌绗氭繛鐓庣箻閸┾剝鎷呴柨瀣垫綗闂傚倷娴囧銊╂倿閿曞倸绠查柛銉墮閺嬩線鏌熼崜褏甯涢柡鍛倐閺屻劑鎮ら崒娑橆伓闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣椤愯姤鎱ㄥ鍡楀幊缂傚倹姘ㄩ幉绋款吋閸澀缃曢梻鍌欑濠€閬嶆惞鎼淬劌绐楅柡宥庡亞娑撳秵銇勯弽顐沪闁绘挶鍎甸弻锝夊即閻愭祴鍋撻崷顓涘亾濮樼偓瀚�  闂傚倸鍊搁崐鎼佸磹閹间礁纾归柣鎴eГ閸ゅ嫰鏌ら崫銉︽毄濞寸姵姘ㄧ槐鎾诲磼濞嗘帒鍘$紓渚囧櫘閸ㄥ爼濡撮崘顔煎窛闁哄鍨归崢娲倵楠炲灝鍔氭い锔诲灦瀹曪繝骞庨懞銉у帾闂婎偄娲﹀ú鏍ㄧ墡闂備浇顕х€垫帡宕滈悢濂夋綎闁惧繐婀辩壕鍏间繆椤栨碍鎯堟い顐㈢焸濮婃椽宕烽娑欏珱闂佺ǹ顑呭Λ婵嬪箚閳ь剚銇勮箛鎾寸ォ婵☆垰瀚板娲传閸曨剚鎷卞┑鐐插级宀e潡骞戦姀鐘斀濠电姴瀚弶鎼佹⒑閸濆嫭宸濆┑顔惧厴閹即濡烽埡鍌楁嫽婵炶揪绲介幖顐ゆ暜鐠轰警鐔嗛柣鐔峰簻閺€鑽ょ磼閸屾氨孝妤楊亙鍗冲畷鐓庮潩閿濆懍澹曢梺鍝勫暙閻楀棛绮堥崘鈹夸簻闊洤娴烽ˇ锕€霉濠婂牏鐣洪柡灞诲妼閳规垿宕卞☉鎵佸亾濡も偓椤儻顧侀柛鐘崇墵濠€渚€姊虹紒妯曟垿鎮烽妷褉鍋撳鐓庢灓缂侇喚绮妶锝夊礃閳哄啫骞堟俊鐐€栭崝鎴﹀磹閺囥垹鍑犻幖娣妽閻撶喖鐓崶褜鍎忛柛鏃€绮撻弻鏇㈠炊瑜嶉顓犫偓娈垮枟濞兼瑨鐏掗梺鍛婄箓鐎氼剝顤傛繝纰夌磿閸嬫垿宕愰幋锕€鍨傛繛宸簼閸嬶繝鏌嶉崫鍕櫣缂佺姵鐗犻弻宥夊煛娴e憡娈查梺绋挎捣閸犳牠寮婚弴銏犵倞鐟滃秶鑺辨繝姘厵闁告垯鍊栫€氾拷
核心提示:JFace Text Framework(JFace 文本框架,后面直接简称为 JTF)是 Eclipse 中重要的框架,是其它开发工具的基石之一,基于 JFace Text Framework 构建全功能代码编辑器: 第 1 部分:引言,比如 JDT (Java Development Tool) 中的 Java 源

JFace Text Framework(JFace 文本框架,后面直接简称为 JTF)是 Eclipse 中重要的框架,是其它开发工具的基石之一,比如 JDT (Java Development Tool) 中的 Java 源代码编辑器就是基于它开发的。相信用过 JDT 的人都会对它的源代码编辑器有深刻印象,因为它的很多功能可以让我们很方便的编辑 Java 源代码,比如语法高亮和内容提示等等。所有这些功能都是在 JTF 架的基础上实现的,所以学会使用这个框架对于开发某种语言的编辑工具是至关重要的。即使不是为了这个目的,学习这个框架也有助于提高对 Eclipse 整体的认识。但是JTF本身也确实是一个复杂的框架,非几句话能解释清楚。本系列文章以 JTF 的特性为中心,逐个介绍某个特性的相关概念以及实现方式,并且会给出相应的示例程序。因此随着系列的进行,示例程序会发展成一个全功能的编辑器。本文是此系列文章的第一篇,列举了 JTF 的一些特性,并且简略的介绍了 ANTLR 的相关技术,为后续的文章做好了铺垫。本系列的所有代码都是在 Eclipse 3.3 上调试运行的。

JFace Text Framework(JFace 文本框架,后面直接简称为 JTF)是 Eclipse 中重要的框架,是其它 开发工具的基石之一,比如 JDT (Java Development Tool) 中的 Java 源代码编辑器就是基于它开发的。 相信用过 JDT 的人都会对它的源代码编辑器有深刻印象,因为它的很多功能可以让我们很方便的编辑 Java 源代码,比如语法高亮和内容提示等等。所有这些功能都是在 JTF 架的基础上实现的,所以学会 使用这个框架对于开发某种语言的编辑工具是至关重要的。即使不是为了这个目的,学习这个框架也 有助于提高对 Eclipse 整体的认识。但是JTF本身也确实是一个复杂的框架,非几句话能解释清楚。 本系列文章以 JTF 的特性为中心,逐个介绍某个特性的相关概念以及实现方式,并且会给出相应的示 例程序。因此随着系列的进行,示例程序会发展成一个全功能的编辑器。本文是此系列文章的第一篇, 列举了 JTF 的一些特性,并且简略的介绍了 ANTLR 的相关技术,为后续的文章做好了铺垫。本系列的所有 代码都是在 Eclipse 3.3 上调试运行的。

JFace 文本框架特性一览

JFace 本身是一个更高级的 UI 库,文本框架只是其中的一部分。JFace 本身是基于 SWT 的,所以文本框架 的功能也是受制于 SWT 的,具体的说,是受制于 SWT 中 StyledText 的能力。如果要简单的概括一下 JTF 是 什么,可以说 JTF 只不过是把 StyledText 的一些功能包装的很方便让你来用罢了。所以对 JTF的功能不 要感到很神奇,所有的特性都可以在SWT中找到它的根据。目前,JTF支持以下特性:

Syntax Highlight(语法高亮)

Double Click (鼠标双击)

Content Assistant (内容提示)

Text Decoration (文本装饰)

Text Hover (文本悬浮帮助)

Annotation Hover (标注悬浮帮助)

Quick Assistant (快速帮助)

Hyperlink (超链接)

Template (模版)

Text Formatting (文本格式化)

Text Folding (文本折叠)

本系列将介绍所有这些特性,至于这些特性的具体概念会在以后的文章中一一介绍,而且还会顺带介绍一些 JTF 本身并不支持的特性,比如 Triple Click (鼠标三击) 。由于 JFace 和 SWT 都在不断发展中,所以也有可能提到一些上面没有列出的特性。但是JTF本身是一个复杂的框架,所以我不打算一一讲解每一行示例代码的含义,只会关注基本概念和架构以及核心代码,同时为了尽量保持示例代码的简洁,我也不考虑性能等诸多因素。

ANTLR

对于编写自定义的源代码编辑器来说,有一个源代码的解析器是很重要的。现在有很多这样的工具,比如 JavaCC, Antlr,bison 等等,我们将使用 Antlr 来构造我们的语言解析器。如果你不熟 Antlr 也没有关系,这并不是本文的重点,我会稍微介绍一下 Antlr 的基本概念,你只要了解我用 Antlr 做了什么事就可以了。

Antlr 是一个解析器生成器,可以根据你书写的文法自动生成解析器代码,并且可以生成语法树。之所以需要一个解析器是因为我们要在本系列中一步步实现一个源代码编辑器,很多情况下我们需要一颗语法树来帮助我们获得一些信息。我们可以通过遍历这棵语法树查询我们想要的信息,然后决定我们的程序逻辑。

我将自定义一种简单的语言,然后实现这种语言的编辑器,可以称这种语言为数学表达式语言,在这种语言里,我们仅支持变量声明和四则运算,并且只支持整数类型。看下面的例子:

清单1. 非常简单的假想语言:数学表达式语言

        a = 3; 
b = (1 + 2) * 3; 
a / 2 + b * 5; 

从例子中可以看出,我定义的这种语言以分号作为行的结尾,变量声明采用等号作为操作符,变量声明了之后,可以参与到四则运算中,或者直接使用数字常量。这就是全部的语法了。下面是对这种简单语言的一个总结:

操作符: +, -, *, /, (, ), =

变量名: 任意长度,仅能由字母组成

每条语句以分号结尾

我为这种语言定义了 Antlr 的文法,由于并非本文主题,这里不列举其代码,下面是一个与之相关的文件清单,大家可以在示例代码中找到它们:

表 1. ANTLR 相关文件说明

文件名说明
Expr.g语言的ANTLR语法描述
Expr__.gANTLR自动从Expr.g生成的词法分析器文法描述
Expr.tokensANTLR自动生成的所有符号的列表
ExprLexer.java语言的词法分析器
ExprParser.java语言的语法分析器
TokenList.java符号列表,可以通过它得到指定偏移位置的符号以及得到某个符号的下一个符号
TokenManager.java符号管理器,维护 IDocument 实例到符号列表的映射,每次 IDocument 实例发生变化时,符号列表缓存将被清空,这样下次会得到一个重新生成的符号列表
TreeManager.java语法树管理器,维护 IDocument 实例到语法树的映射,每次 IDocument 实例发生变化时,语法树的缓存将被清空,这样下次会得到一个重新生成的语法树
TreeHelper.java这个方法定义了一些和语法树相关的方法,可以从语法树中抽取一些信息
IExprTokens.java这个接口定义了语言中可能出现的所有符号
SharedParser.java为了稍微提高一点性能,维护了词法分析器和语法分析器的单一实例

需要强调的是:上述这些类对于实现一个完整的代码编辑器是非常重要的。对于文本来说,我们没有篇幅去仔细了解它们是怎么实现的,只需要明白它们能够做什么就可以了。对于 ANTLR 的具体使用和解析器相关的内容,值得花一本书的篇幅来介绍,对此有兴趣的读者可以阅读最后的参考文献。我们不做详细阐述,但是下面会介绍一些ANTLR的基本概念:

符号(Token): 可以认为符号是一个具有特定意义的词法单元,比如一个英文单词,一个数字都是一个符号,比如语句”a = 3;”,它包含了 6 个符号:a, 空格,等于号,空格,3,分号。当然具体哪些部分能构成一个符号是由你写的文法来规定的。符号可以有很多属性,比如符号的类型、起始位置、结束位置等等

词法分析器(Lexer): 词法分析器把一个字符流解析成为一个符号流。词法分析器一般要和一个语法分析器结合起来使用。词法分析器的输出就是语法分析器的输入

语法分析器(Parser)和语法树(Tree):语法分析器把一个符号流解析成其它的格式,可以是一棵树或者其它什么东西。比如3 + 4可以变为如下图所示的结构:

图1. 语法树


加号变成了一颗树的根节点,而3和4成为了它的孩子节点。在这样的树结构里,包含了一定的语义信息。我们通过遍历这颗树,得到数学表达式的结果或者进行其它操作。语法树的好处是可以重复的遍历它而不是每次都去把表达式解析一次。语法树实际上是一种中间格式。

文法(Grammar):ANTLR中可以编写很多文法:比如词法分析器的文法,语法解析器的文法,语法树文法等。ANTLR 的文法文件的扩展名是”.g”, 根据你的文法类型,ANTLR会生成不同的源代码文件

一旦我们拥有了处理我们语言源代码的能力,并能够方便的管理源代码的词法语法信息,就相当于大楼有了牢固的地基一样,事情已经成功了一半了。后面的文章将告诉大家如何完成另外一半的工作。

初始示例代码

为了提供文本编辑和源代码编辑的能力,JTF 提供了 TextViewer 和 SourceViewer。TextViewer 仅仅面向纯文本的编辑,而 SourceViewer 提供了一个代码编辑器所需要的特性。代码编辑相对纯文本编辑来说复杂很多,需要很多附加功能,比如前面提到的 JTF 的所有特性,SourceViewer 都是做了一定的包装的。为了方便自定义,SourceViewer 通过一个 SourceViewerConfiguration 来控制这些特性的行为。缺省的实现基本上就和纯文本编辑器一样,所以我们从扩展 SourceViewer 以及 SourceViewerConfiguration 开始,一步步来完成我们自己的代码编辑器。本文附带的例子是一个起点,虽然有 ExprViewer 和 ExprConfiguation,但是还没有任何自定义代码。

在初始示例代码里,我们为 Eclipse 工具条添加了一个按钮,点击之后会出来一个对话框,我们的自定义编辑器就放在对话框里。之所以没有用 Eclipse 标准的 org.eclipse.ui.editors 扩展点,是因为 editor 本质上也是包装了一个 SourceViewer, 它为我们隐藏了一些东西。所以为了更清楚的说明问题,我们从一个较为原始的状态开始。

结束语

JTF 是一个比较成熟的文本编辑框架,通过 JTF 我们可以实现自己的代码编辑器。我的目的是对JTF的每个特性进行详细的解说,最终能够构建出一个可以达到和 Java Editor 相同水平的代码编辑器。本系列的每一篇都会附带一个阶段性的代码示例,以便读者对照代码更好的理解 JTF 的架构和细节。

本文示例源代码或素材下载

Tags:基于 JFace Text

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接