16

您能给想要编写编程或脚本语言的人什么建议?我不担心如何编程或设计编译器,而是担心如何使用工具和代码生成器快速开发编译器。

上次我尝试用 C++ 编写它,状态和语法几乎与编写实际逻辑一样长。我知道以下工具会有所帮助。

我在想我可以生成 c++ 代码并让 gcc 编译它。使用上述工具,您估计编写程序或脚本语言需要多长时间?


早在学习编写编译器时,人们就反复询问过这个问题的变体。这是有关该主题的 SO 资源的不完整列表。

4

10 回答 10

18

估计这样的事情可能需要多长时间取决于许多不同的因素。例如,一个有经验的程序员可以通过单元测试在几个小时内轻松搞定一个简单的算术表达式求值器。但是新手程序员可能必须学习解析技术、递归下降、表达式树的抽象表示、树遍历策略等等。这很容易花费数周或更长时间,仅用于算术表达式。

但是,不要让这让您灰心。正如 Jeff 和 Joel 在最近的 Stack Overflow 播客上与 Eric Sink 讨论的那样,编写编译器是了解编程许多不同方面的绝佳方式。我已经构建了一些编译器,它们是我最难忘的编程项目之一。

一些关于构建编译器的经典书籍是:

于 2009-01-17T19:37:52.043 回答
5

Dave Hanson 与 Chris Fraser 一起花了 10 年时间构建了世界上最精心制作的编译器之一,他曾经告诉我,他从经验中学到的主要内容之一是不要尝试用 C 或 C++ 编写编译器。

如果你想快速开发一些东西,不要生成原生代码;以现有虚拟机为目标,例如 CLR、JVM 或Lua虚拟机。使用最大咀嚼生成代码。

如果您正在编写解释器,另一个不错的选择就是使用底层编程语言的内存管理和其他工具。解析为 AST,然后通过 AST 的 tree walk 进行解释。这将使您快速起步。性能不是最好的,但可以接受。(使用这种技术,我曾经在 Modula-3 中编写了一个 PostScript 解释器。第一个实现花了一周时间,尽管后来它进行了一些性能调整,主要是在词法分析器中,但它从来没有被替换过。)

避免使用 LALR 解析器生成器;使用可以节省您时间的东西,例如 ANTLR 或Elkhound GLR 解析器生成器。

于 2009-01-17T22:34:39.157 回答
3

关于编译器设计的经典书籍是

Alfred V. Aho 和 Jeffrey D. Ullman 的“编译器设计原则”。它已经存在了很长一段时间,它的粉红骑士和绿龙至少为几代 CS 学生所熟知。

还...

“编译器:原理、技术和工具”,Alfred V. Aho、Monica S. Lam、Ravi Sethi、Jeffrey D. Ullman

如果您对编写编译器感兴趣,那么这些无疑是最好的起点。

于 2009-01-17T19:41:42.813 回答
3

作为一个非常了解 C++ 的人,您能给想要编写编程或脚本语言的人提供哪些建议?

不要这样做。(或者至少在你做之前仔细想想!)

如果您正在尝试编写脚本语言来公开某些自定义编写对象的方法/属性,最好在 Java(或 .NET/VB 或所有那些讨厌的 Microsoftisms)中实现这些,然后使用其中一个Bean Scripting Framework语言作为您的脚本语言。(与微软端的任何等价物。)

于 2009-01-17T20:05:23.187 回答
3

任何关于编译器的问题都会在几分钟内得到答案“去读龙书,读那本书,这本书……”。所以我跳过了那部分(就像我一开始所说的那样)。阅读这些书来学习如何使用你想要的工具,与阅读角动量来学习如何骑自行车一样有用。

因此,为了回答您的问题,无需质疑您的意图,我可以轻松地向初学者推荐 antlr 和 antlrworks。您可以轻松生成 AST(我认为真正的魔法发生在哪里)并直观地调试您的语法。它为您生成了一个工作编译器的很大一部分。

如果你知道你的东西并且想要有更多的控制权或者不喜欢 antlr,你可以一起使用柠檬解析器生成器和ragel状态机编译器(对词法分析有特殊的支持)。

如果您不需要太多的性能,并且由于您计划生成 C/C++ 代码,您可以跳过自己进行任何优化,并将这些东西留给您的 C/C++ 编译器。

如果您可以忍受缓慢的运行时,您可以进一步缩短仅进行解释的开发工作,因为以这种方式实现动态功能通常更容易。

于 2009-01-17T20:35:31.800 回答
3

我认为每个人都错过了一个非常重要的观点。

为什么要编写编译器/解释器/解析器等。

这将严重决定你所做的很多事情。

我从事过很多语言实现,有些很奇怪,有些特定于领域,有些只是通过命令环境编写的脚本(通常后来隐藏了命令环境)。每个都需要不同水平的技能。

许多书籍可供选择。我喜欢的是一本 BYTE 书:Threaded Interpreted Languages - 打赌它已经绝版了。

简单的脚本引擎可以通过几个晚上的思考和一些尝试和错误来制作。

但我敢打赌,现在有在线课程可以为您节省大量时间。

于 2012-04-18T16:30:10.600 回答
2

我强烈建议查看现有的字节码解释器。如果您可以使您的语言适合 CIL (.NET) 或 Java(甚至是 Python 或 Parrot 等其他语言),您将省去创建可行支持环境的所有努力,并且可以继续尝试语言概念。

于 2009-01-17T20:06:18.583 回答
1

如果您打算编写解释器或编译器,请不要这样做,因为您想编写下一件大事。写它是因为你已经有了它的目的或学习它。如果你这样做,你可能会发现你不小心写了下一件大事。

于 2009-01-17T20:58:33.750 回答
1

我用于 LALR 的一个好工具是GOLD Parsing System。它是免费的,语法是 Backus-Naur 形式,并且有多个示例,包括用 C#、VB.NET、Java 等编写的引擎。这使您可以编写语法,将语法编译为文件,然后使用引擎解析语法。

如上所述,我建议以某种字节码为目标,例如 IL。这将允许您利用大量现有框架。

祝你好运

于 2009-01-18T00:58:56.387 回答
0

如果您不想编写编译器以将语言简化为汇编/机器,那么您的下一个选择是将编译器编写为字节码语言虚拟机,例如 JVM、PVM 或 .NET。

当然,如果您甚至不想这样做——您只想创建自己的“领域特定语言”,我会在 Common Lisp 中构建它。Lisp 宏提供了一种相当直接的方法来创建您想要的任何语法并将其解析为 Lisp。而且您不必担心字节码或汇编。当然,你需要学习 Lisp。

于 2009-01-18T04:26:45.750 回答