编写 C 编译器时应该如何解析关键字?

How should I parse keywords when writing a C Compiler?

我目前正在编写一个 C 到汇编的编译器,这不是为了实用,但我想这样做是为了教育价值。我想知道当我测试关键字时,有没有更有效的方法,而不是仅仅读取文件中的下一个单词,然后通过一堆测试关键字的嵌套 if 语句 运行 它。有没有更好的方法?

你的问题其实很具体。您问的是如何构建词法分析器(也称为扫描器)以及如何高效便捷地识别关键字。扫描器是典型编译器的第一阶段,它将源代码(字符序列)转换为标记序列,其中标记是一个单元,例如数字、运算符或关键字。

由于关键字匹配一般标识符的模式,一个常见的技巧是将所有关键字放在符号 table 中,连同它是关键字的信息。然后,当扫描仪找到一个标识符时,它会像往常一样搜索符号 table 以查看该标识符以前是否已被看到。如果此标识符是关键字,则会找到它以及有关它是哪个关键字的信息。

你这样做是为了 class 的一部分吗?如果是这样,应该有关于解析和词法分析的指南。否则,您将面临大量工作!

编写一个实际的编译器比仅仅通过一堆 if 语句要复杂得多,因为您需要跟踪环境。您需要考虑如何允许 classes、函数、函数调用、class 实例化、递归函数...等等。

查看加州大学伯克利分校有关该主题的课程讲座,即解析、词法分析、代码生成以及您需要的工具:

http://www-inst.eecs.berkeley.edu/~cs164/fa13/

请注意,本课程特别使用 C++ 编写 Python2.5 汇编编译器,但讲座和阅读中的概念以及一些工具不受语言限制。

关键字(而不是一般的标记)是一个封闭集,生成无冲突哈希函数是实用的。因为集合很小,所以连最小散列函数都没有必要。

您可以使用一堆 if - else if 语句和 strcmp() 来完成。但是,为所有关键字编写语句很快就会变得烦人。您最好使用散列 table - 在编译开始时,您将所有关键字放在 table 中,然后根据需要进行查找。这样做的缺点是,如果您必须使用 C,您还必须编写自己的散列 table(或使用库中的散列)。但是,如果可以使用 C++,则可以使用 STL 中的映射或 unordered_map。无论如何,如果你担心性能,就像其他人提到的那样,那不会是瓶颈。