Hello! 2015-12-25 2:50 GMT-08:00 Ming: > > 看春哥2016年的计划,里面提到有Edge、ORSQL、Y这些自己的小语言;听春哥OpenResty大会上面的分享,也多次提到要用最符合业务的语言来描述业务本身,而不是用程序语言来描述。 > 所以想请教下大家,正确的发明一个小语言,需要具备什么样的技术栈? 需要编译器构造方面的基础知识,但不用很深入,因为我们这里通常实现的是所谓的 source-to-source translator,编译器的一个类别。 > 最简单、最不灵活的是用正则表达式来字符串匹配,看上去自己写一个parser才是正途。 是的,需要一个像样的 parser. 一般递归下降的 parser 最容易构造,也最灵活(比如可以和 lexer 融合在一起,同时可以灵活地对文法作消歧)。 > 怎么自己写parser呢?借助haskell的parsec以及其他语言的变种?还是需要自己完整的学习《编译原理》? 一般使用某种分析器生成器, 或者 PEG 这样的分析器构造器。经典的 yacc/bison 工具就属于前者,面向 C 语言,而 Lua 的 lpeg 则属于后者。 不考虑语言的话,我最喜欢 Perl 的 Pegex 分析器生成框架: https://metacpan.org/pod/distribution/Pegex/lib/Pegex.pod 当然,Pegex 是相对比较新的东西,在此之前,我最喜欢 Perl 的 Parse::RecDescent 框架,这个东西的文档也写得很赞: https://metacpan.org/pod/Parse::RecDescent 这个和 Pegex 是类似的东西,但性能远不及 Pegex. 当然,其实 parser 的构造在一个像样的编译器中只占很小的比重。大部分时间都花在抽象语法树(AST)的设计 [1]、优化器和类型检查的实现,还有代码生成器。 编译器涉及的理论和工程细节比较多比较广,但幸运的是,相关的技术和算法还是比较成熟和现成的,属于可能熟能生巧的事情。这样我们其实可以把主要力量放在小语言本身的设计以及有趣的优化算法上面了。 作为一个参考,使用合适的工具,构造一个生产级别的小语言的优化编译器也不需要太多的代码。比我在几年前为淘宝量子统计的数据接口平台设计的 LZSQL 语言的优化编译器,总共也不过 4000 多行 Perl 代码而已,虽然它的复杂度非常高。 Best regards, -agentzh [1] 对于 source-to-source translator 来说,AST 应该是最合适的中间语言(IR),而像 SSA 这样的线性 IR 对于经典的针对机器语言目标的编译器更为合适,当然,混合使用多种 IR 格式的情况也是有的。所以在 source-to-source translator 中最常见的操作是对 AST 进行遍历和各种变换。