DSL——基础知识

外部DSL是一门需要编译或者解释运行的编程语言,而内部DSL则构建于一门通用编程语言(general-purpose programming language)之内。实际上,内部DSL对于其宿主通用编程语言来说,就是它的一套层次非常高的API。Martin Flower的原文描述

当然,并非我们关注的领域都有现成的DSL,这时候我们有三个选择:

  1. 使用通用语言描述该领域的问题(non-DSL)
  2. 发明一门全新的语言描述该领域的问题(External DSL
  3. 在一门现成语言内实现针对领域问题的描述(Internal DSL
例如说,我们现在要描述一个很简单的金融领域问题,“我在花旗银行存款$200”这样一句话对应的三种法写法可能是:(假设已经存在I和CitiBank两个实体实例)
  1. I.DepositTo(new USD(200), CitiBank); /* C# */
  2. I deposit 200USD to CitiBank /* E-DSL */
  3. I.deposit(200.USD()).to(CitiBank); /* I-DSL */
第1种做法的成本最低,你只需要有OO的思想就可以了,你总能把实体类设计出来,但可能和人类描述此领域问题的思维方式有一定偏差(为什么USD可以new?为什么不是deposit [something] to [somewhere]?)。

第2种做法的成本最高,你需要写一个全新的解释器,至少是写一组全新的规则,然后让YACC这类工具帮你生成一个解释器,但这样出来的语法最贴近人类思维方式,甚至就如同自然语言一样流畅。

第3种做法术语上述两者的折中方案,如果语法不太复杂可以使用Builder模式实现语法分析,写出来的语法相当贴近自然语言,但还是有学习门槛。由于脚本语言有相当的灵活性,所以现在很多人倾向于选择在脚本语言内实现Internal DSL。

如何构造Internal DSL?

常见的两种Internal DSL实现方法是Method ChainingFunction Sequence

不错的实例
基于DSL的Lambda   Code

DSL Tools生成代码器

原文地址:https://www.cnblogs.com/mingle/p/1614053.html