是否可以使用个性化的编程语言转换为其他语言?


13

是否有一种编程语言,您可以在其中设置自己的语法配置,并将代码转换为您选择的语言?

例如,您将选择特定的配置,例如“ Python的索引块”,[a,b,c]初始化数组,^求幂等。脚本会将其转换为您选择的语言的等效语言。


1
我当然希望不会。TIMTOWTDI可以说是不好的,但是“发明任意数量的不兼容方式”肯定会带来100倍的缺点,甚至用处不大。DSL有时是值得的,但是仅仅为了它的

我之所以这样问是因为,特别是我正在使用javascript编程,并且确实希望能够在我的代码上设置一些语法糖,但是该语言不允许这样做。甚至操作员也不可能超载。
多卡特(Dokkat)2012年

2
在某种程度上,您所描述的听起来像预处理器宏。现在,如果我们可以为perl提供类似的功能...
yannis'1

5
@Dokkat:请更新问题以明确声明这与JavaScript有关。所提出的问题是维护和支持的噩梦。向现有语言添加新语法(或使用预处理程序将您的私有语言更改为公共语言)确实很糟糕。然而。如果您列出了特定的 JavaScript语法糖问题,则可能会获得特定的帮助。
S.Lott,2012年

3
这些“个性化编程语言”通常称为“特定领域语言”或DSL。
迈克尔·狄龙

Answers:


14

是的,但可能不是您的思维方式。

Lisp及其亲戚具有强大的宏系统,可让您在源上执行任意转换,因此原则上您可以使用宏(以及字符级别的阅读器宏)来进行您喜欢的任何扩展。串联语言(以及相关领域作者的语言)具有类似的元编程能力。Forth就是一个很好的例子,其中许多语法结构(例如注释)可以由用户定义。对于一个当代的,非深奥的示例,还努力为用户定义的语法提供优于Perl 5的Perl 6支持。


8
以某种方式知道Perl是答案的一部分。我猜想C预处理器宏也符合描述,只是做了很小的扩展。
yannis

同样,C ++中的运算符重载也可以。你好,世界的例子浮现在脑海。cout <<“嗨”;
Tydus勋爵,2012年

@LordTydus:的确,甚至即使运算符重载也可以让您在合理的界面后面做很多魔术。如果C ++具有更通用的重载功能(例如,operator[]多个参数的重载或像Haskell中引入新的运算符),那将是很好的。但是我怀疑委员会是否会解决解析问题。
乔恩·普迪

3

听起来像是概念编程

我不熟悉它,但是XL是专门为它设计的语言。

XL具有程序员可重新配置的语法和语义。编译器插件可用于向语言添加新功能。

Lisp和Forth还支持概念编程,尽管少于XL。我建议使用Lisp,因为它非常实用且有效。最重要的是Lisp提供的清晰灵活的语法(表示法)。


例如,您将选择特定的配置,例如“ Python的索引块”,“ [[a,b,c]””初始化数组,“ ^”表示求幂等。

您可能对Haskell这样的语言感兴趣,该语言具有非常灵活但统一的语法。


这就是我想要的。
多卡特(Dokkat)

2

据我所知。

我也不认为这是一个特别好的主意-标准语言语法的主要好处之一就是很多人都可以阅读它,而且如果每个人都发明了自己的语法,那么没人会理解其他人的代码。 ....因此,这种语言对于业余爱好者可能很有趣,但对于任何实际的用途却没有太多用处。

现有的最接近的东西可能是Lisp,宏系统允许您以非常灵活的方式编写自己的新语言结构。通常,您仍然会坚持使用Lisp语法,但是如果您确实愿意的话,可以有效地重新定义所有内容。

结果,Lisps在实现DSL方面特别受欢迎。一个很好的例子是Clojure(Korma)中的数据访问DSL,它负责数据库访问所需的所有样板代码。


2

Scala通常以这种方式用于创建DSL(特定领域语言)。

这主要是因为Scala没有运算符,并且Scala方法调用语法可以缩写。例如:

5是一个整数对象。要计算5加7,您可以编写

val ans = 5.add(7),不同之处在于加法方法实际上被命名为“ +”,因此您将编写:

val ans = 5。+(7),但在Scala中,不需要包括“。”。在方法调用中或在参数周围加上括号“()”,以便在对象5上调用+方法,您将编写

val ans = 5 + 7,因为Scala没有运算符来干扰您的聪明方法命名方案,所以效果很好。现在将该思想扩展到您自己的类和对象,包括以下事实:您可以“覆盖” +之类的方法,也可以创建自己的名为>>>或::的方法!或@ * @或仅纯文本名称(例如fancify)。


这太棒了。我来看看scala。
多卡特(Dokkat)

1

并不是说您应该使用它,因为它仍然主要是实验性的,但是最近一个有趣的编程范例是面向语言的编程(LOP)。

面向语言编程的概念采用这种方法来捕获用户术语中的需求,然后尝试创建一种与用户描述尽可能同构的实现语言,以便需求与实现之间的映射尽可能直接。

谢尔盖·德米特里耶夫(Sergey Dmitriev)更详细地说明了这一点

那是它的意识形态,但实际上归结为它支持您所要求的行为。您可以:

  • 扩展现有语言。
  • 撰写不同的语言。
  • 使用现有的“转换语言”将新定义的关键字转换为基本语言。

我知道遵循此范例的最活跃的编程环境是JetBrains提供的免费元编程系统(MPS)。

实际上,它也已经开始在商业软件中使用,因此也许已经摆脱了“实验”阶段:

  • Realaxy是一个完全基于MPS构建的动作脚本编辑器。借助LOP的强大功能,他们能够实现AS3的关闭。
  • mbeddr C是基于MPS的可扩展C语言。

1

特定领域的语言在Tcl社区中非常普遍。例如,看到一个同时包含C和SQL作为嵌入式DSL(通过Critcl和Sqlite软件包)的Tcl程序并不少见。关于嵌入式DSL的唯一限制是,如果嵌入式语言平衡其大括号,那就更好了,这实际上在实践中是一项真正的繁重要求!

另一种使DSL变得容易的语言是Standard ML,它使您可以从通用系统令牌生成器(从将标识符转换为关键字的那一刻之前)访问原始令牌。这使得编写各种DSL变得容易,只要它们遵守SML的一些基本语法规则,尤其是与注释,字符串和令牌边界有关的规则,并且实际上已在该语言的许多关键驱动应用中大量使用(定理证明等)

并非所有语言都使此操作如此容易。特别是,自动解析括号项(其中很多!)的内容的语言无法做到这一点,因此它们要求DSL必须由优先级较高的运算符通过将子语言放在字符串中来构建,或者通过使用预处理器将DSL重写为可以在宿主语言中处理的东西。


0

在AFAIU中,您正在寻找可以帮助您编写自己的DSL(特定于域的语言)的语言。有很多好的候选人。我个人建议使用Ruby或Io,因为它们提供1)轻松的操作符重载,2)元编程和3)method_missing可用于创建自己的API的后备机制。例如,看一下sqldsl,这是一种用Ruby编写的DSL,它通过读取Ruby代码生成SQL。


0

我本身并没有真正使用过它,但是如果我没记错的话,TXL是专门为翻译源代码而设计的。因此,您应该能够使用它来指定如何从您的语言和/或语言扩展名转换为任何目标真实语言。

它确实具有可用于Javascript 的语法。但是,我以前没有使用过它,所以我不确定这对您有什么帮助。


0

有一个很好的预处理器叫做PPWizard,功能很强大。一旦了解了它的语法,就可以创建针对不同语言的宏定义-并不是说它是万无一失的或有趣的,但是它是一个有用的工具。


这里有一些链接:PPWIZARD目录(官方文档),PPWizard-EDM2(外部参考)。该工具功能强大,但是其文档不容易阅读(可能是由于其功能强大)。


0

部分个性化编程语言的一种常见方式是使用宏预处理器。例如,您可以通过C预处理程序运行“ dokkat-lang”,然后再将结果放置在某些javascript环境下载该结果的位置。

您能做多少取决于预处理器的复杂程度。请注意,C ++的早期版本,Objective C和各种实验语言是通过在对原始C编译器工具链进行馈送之前对源代码进行预处理而完成的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.