在Java中编写针对特定于域的语言的解析器

时间:2010-03-08 11:28:38

标签: java parsing dsl

我们希望设计一种简单的特定于域的语言来编写测试脚本,以自动测试我们其中一个应用程序的基于XML的界面。样本测试将是:

  • 从网络共享文件夹或subversion存储库获取输入XML文件
  • 使用界面
  • 导入XML文件
  • 检查导入结果消息是否成功
  • 使用界面导出与刚导入的对象对应的XML,并检查其是否正确。

如果特定于域的语言可以是声明性的,并且其语句看起来尽可能接近上面示例中的句子,那么它将非常棒,因为人们不一定非必须是程序员来理解/编写/维护测试。类似的东西:

newObject = GET FILE "http://svn/repos/template1.xml"
reponseMessage = IMPORT newObject
newObjectID = GET PROPERTY '/object/id/' FROM responseMessage
(..)

但后来我不确定如何在Java中为该languange实现一个简单的解析器。回到学校,10年前,我使用LexYacc为C语言编写了语言解析器。也许一种方法是使用Java的等价物?

或者,我可以放弃使用声明性语言并选择基于XML的语言的想法,这可能更容易为其创建解析器?你会推荐什么方法?

7 个答案:

答案 0 :(得分:6)

您可以尝试JavaCCAntlr为您的特定于域的语言创建解析器。如果该文件的编辑器不是程序员,我宁愿这种方法优于XML。

答案 1 :(得分:5)

看看Xtext - 它将采用语法定义并生成一个解析器以及一个功能齐全的eclipse编辑器,其中包含语法高亮和检查。

答案 2 :(得分:4)

ANTLR应该足够了

  

ANTLR,另一种语言识别工具,是一种语言工具,它提供了一个框架,用于从包含各种目标语言中的动作的语法描述构建识别器,解释器,编译器和翻译器。 ANTLR为树构造,树行走,转换,错误恢复和错误报告提供了出色的支持。

答案 3 :(得分:2)

看看Antlr库。您必须使用EBNF语法来描述您的语言,然后使用Antlr从您的语法中创建java类。

答案 4 :(得分:2)

看看Cucumber如何定义测试用例:

alt text http://cukes.info/images/feature.png

http://cukes.info/ - 可以在JRuby中运行。

答案 5 :(得分:1)

  

或者,我可以放弃使用声明性语言的想法   选择基于XML的语言,   这可能会更容易   为...创建解析器?什么方法   你会推荐吗?

  1. 使用XML来描述您的测试场景可以轻松完成。

    < GETFILE对象=“newObject”file =“http://svn/repos/template1.xml”/>

  2. 由于您的语法示例非常简单,因此还应该可以简单地使用StringTokenizer来标记和解析这些类型的脚本。

  3. 如果您想引入更复杂的表达式或控制结构,最好选择ANTLR

答案 6 :(得分:0)

我意识到这个帖子已经有3年了,但仍然觉得有提示我提出这个问题。提问者询问是否可以使用Java来尽可能地使用DSL,如

Get an input XML file from network shared folder or subversion repository
Import the XML file using the interface
Check if the import result message was successfull
Export the XML corresponding to the object that was just imported
   using the interface and check if it correct.

答案是肯定的,可以做到,并且已经完成了类似的需求。许多年前,我构建了一个Java DSL框架 - 通过简单的自定义 - 可以允许以下语法用于可编译的可运行代码:

file InputFile
message Message

get InputFile from http://<....>
import Message from InputFile
if validate Message export Message
else
begin
   ! Signal an error
end

在上文中,关键字filemessagegetimportvalidateexport都是自定义关键字,每个关键字都是一个需要两个简单的类,少于一页代码来实现他们的编译器和运行时函数。随着每项功能的完成,它将被放入框架中,可立即用于完成其工作。

请注意,这只是一种可能的形式;实现者可以自由选择确切的语法。该系统实际上是一种DIY高级汇编语言,使用预先编写的Java类来执行所有功能块,包括编译和运行时。该框架定义了必须放置这些功能的位置,并提供了必要的抽象类和接口。

系统满足清晰度的主要需求,非程序员可以轻松查看正在发生的事情。可以快速进行更改并立即运行,因为编译几乎是即时的。

完整(开放)源代码可根据要求提供。有一个通用的Java版本,也有一个用于Android。