2

是否有任何语言支持轻松扩展编译器以支持新的文字示例,例如 json/xml/yaml/不同的字符串编码/额外的数字类型。我知道你总是可以分叉编译器,写一个 dsl,但这并不是我要问的。我知道诸如 smalltalk 和 lisp 之类的一些语言非常灵活,但我并不是在寻找可以由一个团队相当简单地完成的东西,而是试图将其引入整个语言并使其成为常见做法的东西. 您还可以分享任何关于类似想法的研究。

或者,是否有任何语言通过带有字符串参数 alla 的对象中的特殊方法支持文字(在这种情况下,“”表示要传递给 Xml.newFromTripleString(String a) 的字符串的开头和结尾。

Xml exapmleXml=""" #{name} #{title} """ 我知道许多语言通过执行类似 XMl exapmleXml= Xml.newFromTripleString(" " + "\n" " + "\n " + " #{name} + "\n" + " #{title} + "\n" + "") 但是有没有任何语言试图通过隐式转换来简化这一点?对这些技术有研究吗?

任何关于如何在语言中引入更灵活的文字或类似文字的支持的其他想法的链接和解释也很好。

4

3 回答 3

3

约克

Ioke 允许覆盖文字,但不允许新的定义。其工作方式是将文字简单地转换为消息发送,然后您可以像其他任何方法一样覆盖相应的方法。

例如,这是Dict具有两个条目的 a 的“文字语法”,一个映射 aSymbol到 a Text,另一个映射 aSymbol到 a Number

{ :name => "Jörg", :age => 31 }

这实际上被转换为消息发送,对于名为{}(顺便说一句:列表的工作方式相同,它们对应的消息是[])的消息。它完全等同于(如果你愿意,可以这样写):

{}(:name => "Jörg", :age => 31)

现在,=>实际上只是一个为几乎所有对象定义的运算符,它简单地返回 a Pair,键(第一个元素)是接收者,值是参数。现在,运营商只是消息发送,所以这相当于:

{}(:name =>("Jörg"), :age =>(31))

表示文字符号的:印记也被翻译成消息发送:

{}(:("name") =>("Jörg"), :("age") =>(31))

文本文字被翻译成发送internal:createText消息:

{}(:("name") =>(internal:createText("Jörg")), :("age") =>(31))

【注:很明显,这里的写法会导致无限递归。事实是,参数internal:createText显然不是 Ioke Text,而是平台字符串。即ikj,对于 Ioke 的 JVM 实现,它实际上是一个java.lang.String,对于ikcCIL 实现,它是一个System.String. 我在这里用三引号表达了这一点。]

{}(:("name") =>(internal:createText("""Jörg""")), :("age") =>(31))

这只是给我们留下了号码,你猜对了,它也是一个消息发送:

{}(:("name") =>(internal:createText("""Jörg""")),
   :("age") =>(internal:createNumber("""31""")))

由于一切都是消息发送,因此您可以随意自定义字面量的行为,只需实现相应的方法即可。这是交互式 Ioke REPL 的简短记录iik

iik> "Hello"
+> "Hello"

iik> internal:createText = method(raw, super(raw) upper)

iik> "Hello"
+> "HELLO"

收敛

Converge 允许强大的编译时元编程,包括称为DSL Blocks的功能。DSL 块是不使用 Converge 语法的代码块。DSL 块如下所示:

$<<xml>>:
    <xml>
      <literal>here</literal>
    </xml>

$<<其工作方式是和之间的字符串是一个函数的名称,该函数在编译时>>被调用并作为字符串传递整个 DSL 块(以及一些源代码元数据,如行号、文件名等.) 并返回 Converge Abstract Syntax Tree 的片段。因此,在这种特殊情况下,会有这样的函数:

func xml(dsl_block, src_infos):
    // implement an XML parser here ...
    return ast

因素

因子允许定义解析词,这些词是影响同一范围内其他词的解析方式的词。Factor 实际上有一个XML 库实现,它使用解析词来获取看起来很像 Scala 的 XML 文字但只是普通的 Factor 代码的语法:

: feed>xml ( feed -- xml )
    [ title>> ]
    [ url>> present ]
    [ entries>> [ entry>xml ] map ] tri
    <XML
        <feed xmlns="http://www.w3.org/2005/Atom">
            <title><-></title>
            <link href=<-> />
            <->
        </feed> 
    XML> ;

[Factor 简介::定义一个新词,即第一行定义一个名为的词feed>xml,它接受一个参数并产生一个结果。单词的前三行从提要对象中提取标题、URI 和条目,并将它们放在堆栈中。<XML是打开 XML 模式并XML>再次关闭它的解析词。在 XML 代码中,<->从堆栈中获取一个值并将其插入 XML。]

通用 Lisp

Common Lisp Reader Macros允许您进入阅读阶段,即接受字符串并生成嵌套列表然后将它们交给编译器/评估器的阶段。它们要求您选择一个唯一的一或两个字符前缀,并且它们是全局的。第一个问题不大,因为我们可以简单地选择<字符作为前缀,让它看起来很自然。

Perl 6

Perl 6 应该允许您在程序运行时更改语法。Perl 6 具有动态可变语法,这意味着代码在执行时被解析,并且可以更改语法,以便文件中更靠后的其他代码使用新语法进行解析。

奥美达/可乐

在Ian Piumarta 的 COLA 系统之上运行的 Alessandro Warth 的 OMeta 语言允许他们所谓的“特定于情绪的语言”。即,其规范和实现非常轻量级的语言,您可以将它们用于程序中间的一行,然后再次切换到不同的语法。

它被用于Alan Kay 的观点研究所的发明基本新计算技术。一个示例用法是通过设计一种语法与 IETF RfC 中使用的 ASCII 艺术图和另一种用于编写网络协议状态机的语言相同的语言,仅用 200 行代码实现整个 TCP/IP 网络堆栈。然后,网络堆栈的实现简单地包括从 RfC 复制和粘贴 ASCII 图,并将英语状态机描述从 RfC 转换为状态机语言。

(哦,如果您想知道:这 200 行不只是用于 ASCII 图和状态机。它还包括两种语言的解析器和编译器。)

π

π 编程语言可能也很有趣。

于 2010-06-29T17:41:01.747 回答
2

听起来C++ 0x中的用户定义文字(第 2.14.8 节) (警告:大 PDF)非常接近(或者可能完全是)您正在寻找的内容。

于 2010-06-29T03:57:34.517 回答
1

D 编程语言具有在编译时将包含 JSON 的字符串文字转换为相应的 object/struct/arrays 所需的结构。它甚至可以在编译时从外部文件加载字符串。我不知道有任何代码可以做到这一点,但编写起来并不是特别难。

如果您在运行时想要同样的东西,D 具有关联数组动态数组以及标准的 OO 功能集,因此构建遗传 JSON DOM 模型应该不难。

我不知道任何其他编码,但如果它们比 JSON 更成问题,我会感到惊讶。

简短的回答: D 本身不支持它,但让它工作一点也不难。

于 2010-06-29T05:27:20.423 回答