我最近对DSL很感兴趣,特别是如何在Lisp中实现它们, 因为与替代品相比,它看起来像小菜一碟。
寻找信息我在互联网上的Lisp中找不到任何非lisp DSEL的证据。
所以我的问题是:
这是如何实现的?
lisp的读者可以用自定义阅读器替换,将代码翻译成lisp结构吗?
答案 0 :(得分:7)
如何实现编程语言的表面语言?您编写解析器或使用解析器生成器。你也可以在Lisp中做到这一点。
有许多用Lisp编写的通用和领域特定语言的例子 - 不使用s表达式语法。
历史上第一个ML(定理证明器的扩展语言)是用Lisp编写的。 Macsyma(计算机代数的一种语言)是用Lisp编写的。在许多情况下,存在某种“最终用户”,需要为其编写/支持非s表达式语言。有时存在并且需要支持的语言。
使用宏和读取宏可以实现某些语言或扩展Lisp语言。例如,使用读取宏很容易将JSON语法添加到Lisp。还有某种infix syntax。 XML(例如:XMLisp)。
答案 1 :(得分:7)
简短版本:Racket执行此操作。
更详细地说:Racket是Scheme的后代,在这里有一个经过深思熟虑的故事。 Racket模块/文件可以以语言声明开头,例如
#lang algol60
...然后文件的其余部分可以用给定的语言编写。 (是的,algol60 is built in。)
为了开发自己的语言,您需要编写一个语言规范包,该包展示了如何将该语言的语法扩展为基础语言的语法(在本例中为Racket)。任何人都可以编写这样的包,然后分发它们以允许其他人用这种语言编写程序。 Racket中包含这样的语言规范的例子,例如前面提到的algol 60例子。
我认为这正是你所要求的?
ObDisclaimer:是的,我是一名球拍开发者。
答案 2 :(得分:1)
在Lisp中支持非Lisp语法DSL没有问题。您需要使用Rainer提到的一些解析器/解析器生成器库。一个很好的例子是esrap用于解析降价(请参阅3bmd)以及pgloader command language,它只是您要询问的外部DSL的一个示例。< / p>
答案 3 :(得分:1)
从 Let Over Lambda ,有一个Perl样式正则表达式的实现:http://letoverlambda.com/index.cl/guest/chap4.html#sec_4。
此外,有几次尝试制作Lisp的“非lispy”版本,主要的是可读Lisp S表达式项目:http://readable.sourceforge.net/。
答案 4 :(得分:0)
突出显示的一个特定于实现的解决方案(如果您想使用Scheme而不是CL)是Gambit Scheme's内置支持通过其SIX-script扩展名的中缀语法。
这提供了一组丰富的类似C的松散运算符和语法形式,可以开箱即用,以类似C的方式编写代码,或者重新定义为任何你想要的东西(你可以如果你不是type name(args) {}
的粉丝,可以轻松重新定义例如函数定义格式。 for
,case
,:=
等等(偶数goto
)已经存在并准备好表达您需要的任何内容。
语法的实际核心(运算符优先级,表达式与语句)是固定的,但您可以将类似Scheme绑定构造的内容分配给运算符生成的s表达式,以获得相当大的自由度。
a = b * c;
由读者翻译成
(six.x=y (six.identifier a) (six.x*y (six.identifier b) (six.identifier c)))
然后,您可以使用自己的宏覆盖这些宏的定义,以使语法执行您想要的任何操作。将C风格的基础变成看起来像Haskell的函数式语言并不太难(从战略上重新定义=
和->
并且你在那里中途......)。