Schliemann:在NetBeans6.0中集成脚本语言

来源:互联网 发布:淘宝的diy u盘 编辑:程序博客网 时间:2024/05/16 11:41

过去,将语法颜色标记、代码完成和其他编辑器功能集成到 IDE 需要大量的工作。现在终于解脱了!您可以轻松完成这一切!本文将介绍一个名叫 Heinrich Schliemann 十九世纪探险家如何鼓舞着 IDE 自如运用多种语言。

 

过去,在为 IDE 中的新编程语言提供编辑器支持时,必须实现许多不同的 NetBeans API。对于“编辑器支持”,我们通常是指由 IDE Navigator 提供的语法颜色标记、代码完成和其他的源导航功能。其他示例还包括代码缩进和括号匹配。NetBeans IDE 为几种语言和技术提供了即装即用的功能,例如:Java(这个毫无疑问)、JSP HTML

人们需要实现许多 NetBeans API 才能为编程语言提供编辑器支持。这有两个原因。首先,语言编程人员通常能够提供的域知识是语言本身,而不能提供实现必要功能所需的多种 NetBeans API 知识。其次,编辑器支持的底层基础架构对所有语言来说都是一样的。例如,用于 JAVA Navigator和用于 HTML Navigator 的唯一区别是实际代码的区别,而不是容器的区别。因此,语言编程人员应该只需标记(token的形式提供语言的内容,这些标记使用正则表达式通信。而无需提供任何其他内容

给定标记和应当使用标记的位置之后,NetBeans 平台应该能够计算出如何与标记挂钩以支持功能。这种方法不仅简化了将新语言集成到 IDE 中的过程,而且它还利用了语言编程人员现有的知识 — 而不需要陡峭的学习曲线使编程人员甚至在开始编码之前就学习那些新知识。

走进 Schliemann

总的来说,这就是新的 Schliemann 项目 (languages. netbeans.org) 所关注的。那么为什么将它称作 Schliemann 呢?Heinrich Schliemann 是十九世纪一个很有语言天赋的探险家。他在环球旅行的时候总是能用他所到的国家的语言来写日记。在 Schliemann 精神的鼓舞下,NetBeans 平台的 6.0 版本将 IDE 设想为 Schliemannesque,希望它能够快速地学会各种语言,然后用这些语言自如地交流。

这个项目主要倾向于脚本语言一是因为 Schliemann 项目不提供编译支持,而脚本语言不需要编译支持 -另一个原因是脚本语言在如今日益流行。在本文中,我们将探讨 Schliemann 项目的主要方面,并将它与传统的用 NetBeans API 提供编辑器支持功能的方法进行了比较。

只需一个文件!

传统的 API 方法和 Schliemann 方法之间的一个最主要的区别就是:后者允许您在一个文件中通过声明指定所有编辑功能。这个文件具有 .NBS  文件扩展名,它代表 NetBeans 脚本。为了快速了解 NBS 文件的一些典型内容,我们来看一个代码片段列表 1

列表 1. NBS 文件代码片段


#
# NBS Template
#

# definition of tokens
TOKEN:keyword:( “while” | “if” | “else”)
TOKEN:operator:( “{“ | “}” | “(“ | “)” )
TOKEN:identifier:( [“a”-”z”] [“a”-”z” “0”-”9”]* )
TOKEN:whitespace:( [“ “ “/t” “/n” “/r”]+ )

# parser should ignore whitespaces
SKIP:whitespace

# definition of grammar
S = (Statement)*;
Statement = WhileStatement | IfStatement | ExpressionStatement;
WhileStatement = “while” “(“ ConditionalExpression “)” Block;
IfStatement = “if” “(“ ConditionalExpression “)” Block;
Block = “{“ (Statement)* “}”;
ConditionalExpression = ;
ExpressionStatement = ;

# code folding
FOLD:Block

# navigator support
NAVIGATOR:WhileStatement:”{$ConditionalExpression}”

# brace completion
COMPLETE “{:}”
COMPLETE “(:)”

# indentation support
INDENT “{:}”
INDENT “(:)”
INDENT “//s*(((if|while)//s*//(|else//s*|else//s+if//s*//(|for//s*//(.*//))[^{;]*)”b

 

这个模板是使用 Generic Languages Framework 向导时得到的,该向导是 NetBeans IDE 6.0的一部分。它提供了一个带有样例内容的 NBS 文件,它以四个标记定义开始。这些标记分别被命名为“keyword”“operator”“identifier”“whitespace”。在与标记名称同一行的括号内,用一个正则表达式定义这些名称。

马上就会有人发现这个语言支持新方法的好处:使用正则表达式语言来定义标记而不是使用 java 来定义标记。因此,JAVA 系统外部的编程人员可以将他们的编程语言集成到 NetBeans IDE 中。不需要了解 Java Schliemann 项目的一个重要优点,至少对于较简单的语言集成来说是这样。

一旦定义了标记,您就可以开始分配功能。例如,下面这个声明将会使用“keyword”标记提供的值来填充 Navigator

NAVIGATOR:keyword

熟悉 NetBeans Navigator API 的读者将对这种简化的程度感到不可思议!然而,通常您会喜欢对某种语言更健壮的支持,并且会希望除标记之外还提供语法。Schliemann 方法要求的语法也相当简单,可以与 JavaCC 或者 AntLR 相媲美。理想情况下,大家期望 JAVACC AntLR 提供的语法能够直接集成到 NetBeans IDE 中。然而不幸的是,这些语法不是针对在 IDE 中的使用而定制的。因此,需要一个转换过程,将其从 AntLR 或者 JavaCC(或者是类似方法)转换到 Schliemann NBS 格式。

以前的实验表明,这个过程的手动和自动解决方案都是可行的。然而,就 Schliemann 项目而言,无疑要在这方面完成大量工作。为了使 Schliemann 项目发挥其全部潜能,需要有一种统一简单的方法来整合 AntLRJavaCC 和类似的方法所提供的语法。

在前面显示的 NBS 代码中,除了标记以外,您还可以看到形成 Navigator 实现和代码折叠实现的语法。对于代码折叠这种情况,Block 语法定义确定了每个代码折叠,而 Navigator 是由符合 WhileStatement 定义的值所填充的。

最后,请注意,代码还显示了括号完成和缩进的定义方式,所有内容都在同一文件中,并且能够通过指定解析器应跳过空格进一步调优功能。

因此,当列表 1 中的 NBS 文件与 MIME 类型相关联的时候,相应 MIME 类型的文档将立即拥有以下功能:

·                                 语法颜色标记

·                                 Navigator

·                                 代码折叠

·                                 括号匹配

·                                 缩进

使用类似方法,可以创建许多其他语言支持功能,其中包括代码完成,它是语言编程人员最希望得到的支持功能之一。

入门

现在我们对 Schliemann 方法已经有了一个大致的了解,让我们把它应用到实践中,并创建一个用于 Java Manifests NBS 文件。正如您所知,Manifests 是由键/值对构造而成的。在 IDE 中,没有针对 Manifests 的语言支持,甚至没有语法颜色标记支持。让我们提供这些支持以及其他更多支持。

我们从大家为 IDE 创建插件时通常要做的工作开始:首先创建一个新模块项目。接下来,在New Project 向导中,把项目命名为“ManifestEditorFeatures”并指定“org.netbeans.modules.manifesteditorfeatures”作为 Code Name Base。在向导结束时,单击 Finish然后,您会看到 IDE 已经创建了一个基本的源结构,就像它为每个 NetBeans 模块所做的一样

 

接下来,我们可以用 Generic Languages Framework 向导生成一个在前面部分已经讨论过的 NBS 模板。这个模板位于 New File 向导的 NetBeans Module Development 部分。完成向导之后,就会得到一个新文件,我们将在这个文件中完成这个模块的所有编码工作。

 

 

现在,让我们正式开始!与前面的部分不同,我们在这里处理的语法有状态概念。所谓状态,我们指的是:如果知道自己在哪一个标记中,就始终能够知道自己将在什么位置与其他标记相关联。所以,如果我们在 Manifest 中键/值语句的“键”部分,那么,我们就知道当遇到冒号时,我们正在进入语句的“值”部分。因此,可以在它们的状态上下文中定义标记。下面您将会看到这一切是如何完成的。如果您对正则表达式很熟悉的话,那么这些内容对您来说应该不会很陌生:

TOKEN:key:( [^”#”] [^ “:” “/n” “/r”]* ):
{
TOKEN:whitespace:( [“/n” “/r”]+ ):
TOKEN:operator:( “:” ):
}
{

TOKEN:whitespace:( [“/n” “/r”]+ ):
TOKEN:value:( [^ “/n” “/r”]* )
}

请注意,开始说明如果第一个字符不是哈希字符(#),则不在键中。事实上,在这种情况下,是在注释中。如果能为注释提供一个特定的语法颜色标记很有好处,所以让我们来为注释定义一个标记:

TOKEN:comment:( “#” [^ “/n” “/r”]* [“/n” “/r”]+ )  

现在,如果没有进一步的操作,就可以分配颜色了。再次以声明方式执行这个操作:

foreground_color: “blue”;
COLOR:operator: {
foreground_color: “black”;
}
COLOR:value: {
foreground_color: “magenta”;
}

除了前景色以外,还可以为标记设置许多其他属性,例如:风格和背景色。如果没有进一步的操作,就可以安装模块,并使用语法颜色标记功能了。这真是再简单不过了!但是,在执行这些操作之前,需要创建一个 MIME 类型解析器,它是一个 XML 小文件,用于指定要处理文件的扩展名。

如果使用了 New File Type 导,可以让 IDE 生成这样一个 MIME 类型解析器。然后,在 XML 层文件中注册解析器和 NBS 文件,并且在 Generic Languages Framework API 声明依赖关系。最终,Generic Languages Framework 会为您完成这一切。

安装完模块后,可以进行进一步的开发。NetBeans 6.0 提供了许多开发工具来帮助您,例如新的 AST 窗口这个工具允许您根据分配到文件的 MIME 类型的标记来分析文件。最终,您可以为 Manifests 创建一个非常详细的 Navigator,当然还可以为最终用户提供了一些其他有用的功能。

 

 

小结

希望这个介绍能使您大致地了解 NetBeans 6.0 对脚本语言提供的支持功能。语言开发人员将能够快速轻松地将他们最喜欢的脚本语言集成到 IDE 中,从而越来越多地将 NetBeans 转变成他们自己自定义的开发环境。一句话,就像 Heinrich Schliemann 一样,NetBeans IDE 将能够学会更多新的语言,在越来越多的开发社区中得到广泛使用。