我正在开发一个简单的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);
}
答案 0 :(得分:3)
创建DSL以定义应用程序的某些行为。我的想法是创建一个非常干净的语言,类似于Ruby,但实际上是在C中运行。
C不是嵌入式语言的好主机。它是语言运行时的一种很好的实现语言,因此如果您想编写应用程序脚本,请考虑执行其他人的操作,并将高级语言链接到您的应用程序。
Lua等语言专为此目的而设计 - 比C语言更容易编写;但是用C语言简单嵌入你也可以用Ruby或Python或者Haskell等来调用C.
重用现有语言是一个好主意,因为其他人已经完成了艰苦的工作。您也可以重用库。
答案 1 :(得分:1)
我认为,如果你想创造一种优秀的语言,你就不能只依赖正则表达,因为它的表现力很差。
编写正则表达式以匹配复杂模式也很困难。
如果您只想隐藏C语言的一些冗长,可以使用C MACRO
答案 2 :(得分:1)
定义好的DSL语法很难;你必须要了解你想要解决的问题(以及你不想解决的问题,否则它最终会包含所有内容,包括厨房水槽),你必须弄清楚如何将其翻译成目标语言(或在飞行中解释它。
在这两种情况下,您都需要一个解析器,并且有趣的DSL语法通常不适用于使用正则表达式进行解析。所以你需要一个真正的解析器生成器。如果要解决像Ruby这样的问题,你需要一个强大的解析器生成器!
然后,您需要捕获解析的结果,作为一些数据结构,通常是树。然后,您需要分析DSL代码以了解特殊情况,优化以及如何生成代码。这一切意味着解析器通常是不够的。请参阅我对Life After Parsing的扩展讨论。
答案 3 :(得分:1)
我正在开发一个简单的C应用程序,我想创建一个DSL来定义应用程序的一些行为。我的想法是创建一种非常干净的语言......实际上是用C语言运行的。
你并不是第一个有这个想法的人。 John Ousterhout使这个想法受到Tcl/Tk的欢迎。不幸的是,这种语言不是很干净。
今天可用的最清晰的实现是嵌入式语言Lua。它设计得非常好,我非常推荐它。构建自己的(而不是使用Lua)的唯一原因是因为您想学习如何实现嵌入式编程语言。在这种情况下,你可以通过研究Lua的设计仍然学到很多东西。
我知道lex和yacc,但我认为他们对我正在尝试做的事情有点过分。是不是有更简单的东西?
用手写lexer比使用lex几乎总是更简单。
Yacc是另一个故事 - 下面没有任何根本简单的东西,因为你真的必须处理无上下文语言的全部功能。但是你可以在其他软件包中找到这种先进的技术(Lex和yacc是20世纪70年代为20世纪70年代硬件设计而设计的技术,它们提供了糟糕的人机界面。)
如果您知道如何设计LL(1)语法,那么手写递归下降解析器的编写非常简单,并且不需要额外的技术。但是知识并不容易获得,用C编写这些东西并不是很有趣。
如果你想学习,Niklaus Wirth的书中有很好的例子。 LL(1)和网上递归下降也可能有教程。
您可能会发现使用更现代的解析器生成器更简单,不仅限于LALR(1)语法。例如,也许是Elkhound解析器生成器。但这也不简单。