0

我想练习 C,所以我决定本着 Python 解释器的精神写一个 C 解释器。我有一些 C 知识,但我一直是一个边做边学的程序员。

到目前为止,我所拥有的非常简单。只需解析用户的输入,一次一行,并区分以下声明:

int x = 10;
char c = 'a';

我在其中创建了一个结构,该结构表示变量的类型、名称和 int 值的 ivalue,以及 char 值的 cvalue。还有很多事情要做,但一步一步。

我还可以解析函数调用,例如:

printf("value of x = %d\n, x);

我在其中提取函数的名称,并将 args 存储在 char** args 中。

这听起来很傻,但我想避免为每个标准 c 库函数编写映射器,以便执行对 printf、strstr 或 strcpy 之类的调用。无论如何,如果没有这种方法,是否可以动态调用标准 c 函数?

此外,非常欢迎对这个东西的设计提出建议。

4

2 回答 2

1

您不能(如我所想)编写 C 解释器。
我猜你会遇到编写 C 解释器非常困难的事情。您可能必须编写一个编译器。
当然,您可以即时“剖析”该语言,并在您进行时解析代码。
真正的问题(如我所见)是处理外部引用。

import在 Python 中,您使用关键字处理外部引用。
如您所知,某些库可能有冲突的方法(例如lxmllibxml2)。
这个冲突可以通过import正确的库来解决。
您当然可以考虑某种机制来有效地“链接”或导入所有需要的外部引用。
这可能会有某些非常具体的假设。
就这样,当你遇到#include <stdlib.h>你的时候,其实import它。
就此而言,导入它可能意味着加载stdlib使用类似LoadLibrary()LoadLibraryEx在 windows 下的 dll。
全部加载后#include's你遇到,如果你没有找到引用的定义,那么你可能会遍历本地目录'以获取其他 C 文件,直到遇到寻求的引用,此时我不确定应该做什么。
那是关于链接问题(老实说,如果没有适当的编译,我真的看不出你将如何克服)。

另一部分实际上也非常困难。你需要写一个词法分析器。
那就是解析所有这些 C 代码行的小恶魔。
我假设您已经摆弄过 Scheme/List 解释器的编写,或者甚至可能是一些更复杂的解析器。
谨防!C不是Scheme!
它是一种高度复杂的解析语言。它的描述文件跨越数百页。
编写 C 词法分析器不是编写解释器的练习。
C 有一些令人讨厌的与上下文相关的解析——这基本上意味着它不是 CFL(上下文无关语言)——这意味着你不能编写一个好的有限自动机来解析它。

我将以一个取自Eli Bendersky精彩博客的示例作为结尾。

typedef int AA;
void foo()
{
    AA aa;       /* OK - define variable aa of type AA */
    float AA;    /* OK - define variable AA of type float */
}

这只是表明上下文相关的语法是多么棘手。

于 2013-08-05T00:08:56.070 回答
0

除了解析 C 语法的麻烦之外,它实际上非常适合解释,因为它被设计为一次性处理,以解决 1970 年代设备的内存限制。

事实上,Herbert Schildt 的C: The Complete Reference, Fourth Edition的第 6 部分 (p. 713-787) 致力于通过引导您编写这样的解释器来将本书其余部分的所有内容联系在一起。

我没有查过书中的版本是否有任何修改,但他的“小C”是在1989年8月的Dr. Dobb's Journal上首次向世界展示的。

此外,这个问题有一堆列出现有 C 解释器的答案。

至于动态调用 C 函数,在 POSIX 平台上比在 Windows 上更容易,因为您可能需要.lib文件来解析.dlls 中的符号,而.so文件没有等价物。

对于.so文件,您只是dlopen库的路径,并用于dlsym按名称检索函数指针。

可以在 dlopen 的 Linux 联机帮助页中找到这样做的示例,方法是运行man dlopen.

于 2021-10-02T03:41:37.517 回答