用标准C或C++编写的解释器

7
有哪些可扩展的解释型编程语言是用标准、独立于平台的C或C++编写的?
我希望能够将所有源文件放在一个目录中,在任何符合标准的C或C++编译器下编译这些源文件,并生成一个可执行文件,该可执行文件可以读取和解释指定脚本语言的脚本文件。
许多“用C编写”的编程语言似乎都包含了很多依赖于它们所在的平台的特性,因此需要一些配置程序来根据目标系统运行(例如Autoconf),这使得事情变得复杂并限制了跨平台兼容性。
提问原因:
我对编程语言设计很感兴趣。在按照yacc、lex和llvm的教程后,我曾尝试使用一些玩具级别的编程语言。然而,最近我对研究用可移植的C/C++编写的编程语言产生了兴趣,因为这样,我可以在支持标准C或C++编译器的任何机器上研究程序和代码,并且仍然有一个相对统一的体验。
由于这只是为了教育目的,脚本语言不需要支持像C那样的超低级别特性,也不必像Java那样具有GUI(我认为你不能像标准C/C++一样编写任何类型的GUI),甚至不需要进行任何复杂的I/O操作。但是,我希望该语言足够完整,以便在语言中编写一些有用的程序是可行的(例如,应该可以使用C/C++扩展语言,以便在tty上像shell一样使用它)。
谢谢。
编辑:
@AndréCaron 我更喜欢至少语言核心是100%独立于平台的。如果语言包括大量依赖于其他库使其“更有用”的标准库,那也没关系,但是,如果我想要,我希望能够剥离标准库并仅使用语言的核心(可能是自定义手写库)。

这个问题最好在程序员网站上提问。 - the Tin Man
2
这怎么算是离题了?看起来很符合程序员.SE排除的主题 - Ben Voigt
“将库源代码嵌入我的源代码树”并不是在iOS平台之外将库包含到项目中的常见方式。如果您打算使用C语言,您应该考虑将“使用第三方库”和“处理自动工具”添加到您的学习目标中。 - millimoose
您是否需要100%的平台无关性,或者只要在所有平台上都可以编译即可?如果不使用任何语言/库扩展,编写任何有用的编译器/解释器都非常困难。 - André Caron
2
话虽如此,您可能想看看Lua。 "易于嵌入其他软件"是他们的主要目标之一,因此他们可能支持您所需的场景。(作为奖励,它是一种非常小的语言和实现,因此应该很容易理解,并且可能可行删除与操作系统相关的代码。) - millimoose
这里有很多有趣的阅读内容:学习编写编译器 - Stephen Quan
4个回答

9

也许使用嵌入式Lua

实际上,核心Lua本身可能更好。乍一看,我认为eLua声称在许多不同的系统上运行意味着它非常便携,但实际上它采用了核心Lua并添加了一堆硬件驱动程序,这显然不是很便携。

Ocaml将是另一个绝佳的选择。它声称{{link4:“基于字节码的系统目前在任何符合POSIX标准的具有ANSI兼容C编译器的操作系统上运行”}}而且Caml Light特别适合学习。“运行时系统和字节码解释器是用标准C编写的,因此Caml Light易于移植到几乎任何32位或64位平台。”


很遗憾,否定回答。来自http://www.eluaproject.net/doc/master/en_building.html的内容: "eLua拥有非常灵活的构建系统[...]。要使用它,您需要编辑位于特定平台目录(src/platform/<platform_name>/platform_conf.h)中的单个配置文件(platform_conf.h)"。 - ruakh
4
嗯,它并不完美 - 但我认为没有跨平台的平台无关的任何东西。如果有,那么所有平台都将保持一致,就不会存在跨平台问题,对吧?一切都将是平台无关的。Lua的价值在于所需更改很小,并且仅在一个文件中,他们已经完成了使代码平台无关的工作。我的理解是,你只是在微调构建,而不是解释器。 - Matt
@Matt:我认为重点在于 C(和 C++)运行时库应该抽象化(几乎)所有平台差异。但是,C 标准 API 仍然需要应用程序使用特定于平台的数据,例如文件名。 - Ben Voigt
@Matt 实际上,你可以进一步采纳BenVoigt的建议,要求通过参数传递大量特定于平台的数据,或保存到另一个文件中。不过,我想这可能是构建工具一开始就要做的事情。 - math4tots

7

Lua是你最好的选择。核心Lua解释器非常简单。发行版包括一个makefile,但它非常基本。甚至有一些说明,解释了哪些文件是构建核心语言所需的,哪些是Lua标准库,哪些是命令行解释器。

核心语言本身不涉及任何特定于平台的API或标头。标准库确实涉及,但只是以最小的方式。如果你不想,你甚至不需要构建标准库。

有一些#define可以用来配置构建,但这主要是为了DLL构建之类的事情。

注意:autotools和其他特定于平台的构建配置实用程序的目的是允许库有效地将特定于平台的东西包装在平台中立的接口内。在大多数平台上,你不能使用纯平台中立的C或C++标准库访问目录树并搜索文件,更不用说像打开窗口这样真正有用的东西了。对于简单的stdin/stdout应用程序,可能足够了。但对于绝大多数情况来说,这是不够的。

我的建议是,你要习惯为特定平台配置构建。除非你的领域是科学应用(有些情况下也不是),否则通用平台编程对你来说没有多大帮助。你需要学会使用这些库。
在库方面,Lua是一个例外。大多数库不是可以随意将文件列表放入目录并进行编译的。你越早学会如何使用库所使用的工具,你就会越好。

1

几乎所有最近的脚本语言都是用CC++编写的:Perl、bash、csh、PHP、html、Javascript、make、vim、tcl等等。

构建它们需要配置并不是解释器的特性,而更多地是为了在多个平台上构建而进行的适应——通常被认为是一件好事。

它们都是可扩展的,你可以编写函数来创建新的功能。


0

LUA和TCL是两种最简单的解释型语言,因此获取这两种语言的源代码并进行检查。然而,我认为你的问题更与静态链接与共享链接有关。静态链接的程序除了内核接口外没有系统依赖性,但动态链接的程序需要安装正确的共享库集。

对于像Python这样的语言,您需要担心Python自己的库(称为模块)以及任何二进制共享库所依赖的内容。Python本身通常使用共享库构建,但它也可以静态构建。此外,我已经构建了一个Python二进制文件使用Linux共享库RUNPATH功能,以便将所有二进制依赖项捆绑到Python中的自己的文件夹层次结构中。

如果您的问题更多地涉及链接,请查看StaticPython与标准动态Python以及使用RUNPATH的Pybuild构建脚本之间的差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接