探讨Antlr中文文法与英文文法的差异
Antlr是一个很好的词法和语法分析器,而且可以直接生成Tree walker,解决了编译器设计中的大麻烦。最近在利用Antlr开发自己的领域语言(DSL)的时候发现了一个问题,就是中文文法与英文文法的差异问题。
目前在领域语言的设计中,趋向于采用类似于自然语言的设计方式,例如:
I eat apple.
其中I是一个对象,eat 是对象I的方法,apple是传入到eat方法中的参数。这句话转换为面向对象的语言就是:
I.eat(apple);
由于这样的文法非常接近自然语言,可以极大降低软件开发的进入门槛,使得业务专家们可以使用面向各自领域的语言开发软件。目前Ruby语言能够风靡世界,部分原因就是Ruby语法中可以省略括号,使得Ruby编写的代码在一定程度上接近于自然语言了。
类似与上述文法,我们希望基于中文的领域语言可以编写如下的文法:
我吃苹果 --> 我.吃(苹果);
由于近代计算机技术起源于西方国家,编译原理及相关的算法研究均基于英文的词法与语法研究,英文中词语的分割是依赖于空格的,这使得词法分析变得非常简单。而对于中文的词汇没有明显的区分,使得【我吃苹果】的词法分析变得非常困难。利用Antlr进行分析的时候,如果想把【我】分析为一个Token,需要有明显的起止符,如果把语句改写为【我_吃_苹果】,就比较容易分割了,但这又偏离了自然语言。
Antlr采用的是上下文无关的词法、语法分析方式,它不依赖于上下文的相关性,只需要空格即可定义出上述的语法结构。而对上述中文语法,如果想要把【我】分析为一个Token则需要在上下文中查找是否有定义【我】,如
我:人 我吃苹果 |
在分析第二条语句的时候,就可以根据第一句中的定义把【我】作为一个Token来处理了。
根据《The Definitive ANTLR Reference: Building Domain-Specific Languages》书中描述,目前上下文相关的词法分析方式没有完整的算法支撑,所以在这个方向上也没有好的应用。
由于本人刚开始这方面的研究,观点不正确之处请大家批评指正。