RIGUZ Lee

使用 Antlr 解析配置文件

2018-05-09 / Programing / Java

在纠结了一阵子 yml,ini,xml甚至 lua 等等 配置文件的格式后,还是决定使用antlr实现了一种我自定义的格式的解析。 这个格式是这个样子的:

其实是一个k-v形式的文本文件,支持的基本类型有:字符串、布尔值、整数、小数、数组。定义的方法类似于Java或者C语言, string _baseUrl = "http://localhost:8080" 前面会限定数据类型。如果要定义数组,则用 bool sslArray = [true, false]; 这种形式。

然后使用scope区分不同的配置块。因为可能有些相同的配置会重名,这样我们利用不同的scope去区分就好了。考虑到有些配置中需要共同的变量的使用,所以定义了一个shared的scope,这个是写死的scope,其他scope中只能引用shared scope中的变量。

字符串连接使用..操作符。这样可以组装字符串。详细的实现可以在forks的子项目config中找到。

另外还实现了一个类似Play! Framework的路由定义文件的解析,长这个样子的:

这个文件的解析也在上面的git中可以找到实现。通过Antlr可以很方便的把类似这样的文件解析出来,你甚至可以实现自己的领域语言。在实现过程中,遇到过一些问题,来说下问题吧。

首先是Antlr提供了Listener和Visitor两种方式,起初使用Listener来实现但是感觉比较麻烦,而使用Visitor则可以直接通过返回值来取得AST解析结果。我们解析一个文件的时候,是自顶向下的,一个个的去解析的,比如我们的配置文件的antlr语法定义如下:

其中shared又是这样的

也就是说 shared { k=v...} ;这样的形式,然后又开始到了property:

这样层层往下来看。然后解析的时候也是一样,我们首先有一个顶层的解析器:

这个Visitor负责解析语法文件中定义的script块,然后解析里面的scope:

这样又实现一个ScopeVisitor去解析scope就好了。详细的实现就不多贴代码了。

另外一个问题是,对于错误的处理,我们在哪一步做?比如bool s = "123";这是错误的,我们其实可以在定义grammar的时候就避免这种错误来,但写起来会麻烦一些。目前的实现是在Visitor中去对逻辑进行判断的,前面只做语法检查就可以了。

参考:

  • http://jakubdziworski.github.io/java/2016/04/01/antlr_visitor_vs_listener.html