4

我正在开发一个简单的 C 应用程序,并且我想创建一个 DSL 来定义应用程序的一些行为。这个想法是创建一种非常干净的语言,类似于 Ruby,但它实际上是在 C 中运行的。所有的函数都在 C 中定义,DSL 只是......好吧,一个“隐藏”C 的冗长语法的别名.

我知道 lex 和 yacc,但我认为它们对于我正在尝试做的事情来说太过分了。没有更简单的吗?我考虑过正则表达式,但这样做我会觉得很脏。也许有更好的东西!

一个例子:

if a = b
    myFunctionInC()

get 'mydata' then
    puts 'Hello!'

很容易翻译成:

if (a == b) {
    myFunctionInC();
}

void get(string test)
{
    printf('Hello! %s', test);
}
4

4 回答 4

3

创建一个 DSL 来定义应用程序的一些行为。这个想法是创建一种非常干净的语言,类似于 Ruby,但它实际上是在 C 中运行的。

C 不是嵌入式语言的好宿主。它是语言运行时的一种很好的实现语言,因此如果您想编写应用程序脚本,请考虑做其他人所做的事情,并将高级语言链接到您的应用程序。

Lua 等语言就是为此目的而设计的——比 C 更容易编写;但是在 C 中简单嵌入。您也可以从 Ruby 或 Python 或 Haskell 或其他任何方式调用 C。

重用现有语言是个好主意,因为其他人已经完成了艰苦的工作。您也可以重用库。

于 2012-05-08T20:09:38.783 回答
1

我认为,如果你想创建一种好的语言,你不能只依赖正则表达式,因为它们的表达能力很差。

编写正则表达式来匹配复杂的模式也很困难。

如果你只是想隐藏一些 C 语言的冗长,你可以使用 C MACRO

于 2012-05-08T18:47:36.870 回答
1

定义一个好的 DSL 语法很难;您必须了解您希望它解决哪些问题(以及您不想解决哪些问题,否则最终会出现包括厨房水槽在内的所有问题),并且您必须弄清楚如何将其翻译成目标语言(或即时解释它)。

在这两种情况下,您都需要一个解析器,而有趣的 DSL 语法通常不适用于使用正则表达式进行解析。所以你需要一个真正的解析器生成器。如果你要处理像 Ruby 这样的东西,你需要一个强大的解析器生成器!

然后你需要捕获解析的结果,作为一些数据结构,通常是一棵树。然后,您需要分析您的 DSL 代码以了解特殊情况、优化以及如何生成代码。这一切意味着解析器通常是不够的。请参阅我对解析后的生活的扩展讨论。

于 2012-05-08T20:12:35.677 回答
1

我正在开发一个简单的 C 应用程序,我想创建一个 DSL 来定义应用程序的一些行为。这个想法是创建一种非常干净的语言……实际上是在 C 中运行的。

你不是第一个有这个想法的人。John Ousterhout 使这个想法在Tcl/Tk中流行起来。不幸的是,这种语言不是很干净。

今天最清楚地实现这一想法的是嵌入式语言Lua。它的设计非常好,我非常推荐它。构建自己的(而不是使用 Lua)的唯一原因是因为您想学习如何实现嵌入式编程语言。在那种情况下,你仍然 可以通过学习 Lua 的设计来学​​到很多东西。

我知道 lex 和 yacc,但我认为它们对于我正在尝试做的事情来说太过分了。没有更简单的吗?

手工编写词法分析器几乎总是比使用 lex 更简单。

Yacc 是另一回事——实际上并没有什么从根本上更简单的东西,因为您确实必须处理上下文无关语言的全部功能。但是您可以在其他软件包中找到这种复杂的技术(Lex 和 yacc 是 1970 年代的技术,专为 1970 年代的硬件限制而设计,它们呈现出糟糕的人机界面。)

  • 如果您知道如何设计 LL(1) 语法,那么手写递归下降解析器编写起来非常简单,并且不需要额外的技术。但是知识并不是那么容易获得的,用 C 编写这些东西也不是很有趣。

    如果你想学习,Niklaus Wirth 的书中有很好的例子。也可能有 LL(1) 和在线递归下降的教程。

  • 您可能会发现使用更现代的解析器生成器更简单,不仅限于 LALR(1) 语法。例如,也许是Elkhound解析器生成器。但这也不简单。

于 2012-05-09T01:13:34.430 回答