在编译的哪个阶段可以识别编程语言的关键字?
我有点困惑
- 词法分析。
- 程序的解析。
我曾经使用正则表达式在 C 中编写了一个词法分析器,但它也将main()
in识别int main(void)
为关键字。
在这些方面,我认为我们必须构建一个解析树来识别关键字。
在编译的哪个阶段可以识别编程语言的关键字?
我有点困惑
我曾经使用正则表达式在 C 中编写了一个词法分析器,但它也将main()
in识别int main(void)
为关键字。
在这些方面,我认为我们必须构建一个解析树来识别关键字。
通常,编译的词法分析阶段将输入文本分解为词位序列,每个词位都属于某些特定的标记类型,在以后的分析中很有用。因此,通常在词法分析期间首先识别关键字,以使解析更容易。由于解析器倾向于通过编写标记的上下文无关文法而不是词位(即词位的类别而不是词位的内容)来实现,因此在词法分析期间标记关键字时构建解析器要容易得多. 例如,如果我想要一个将“if”视为关键字的解析器,那么我可能想要一个在我的 CFG 中看起来像这样的规则:
Statement ::= 'IF' Expr 'THEN' Expr
如果我不将它们分类IF
并THEN
归入它们自己的标记类型,那么我的解析器就无法编写像上面这样的语句。
今年我不得不构建一个简单的编译器作为我使用 Java 的项目。关键词的识别是在词法分析的基础上进行的。在那个阶段,我会读取输入语言并创建一个带有类型(对于关键字类型是 variable_declaration )及其值的标记。对于每种情况,我也有不同的类型,例如标识符,常量,乘法运算,加法运算等。然后传递这些标记到一个队列,然后进入一个解析器,该解析器将检查语法并创建一个二叉树,然后用于创建输出语言。
那将是词法分析。
某些语言具有“特殊”标识符以及关键字。这些通常在解析开始之前添加到标识符表中并分配已知的常量 ID 值,以便可以轻松发现它们。但是,这些通常对解析器没有特殊含义 - 它们应该在解析后在抽象语法树 (AST) 中检测到。
例如,看看 Oberon 语言报告...
http://www-old.oberon.ethz.ch/oreport.html
不是语言推荐 - 只是一个易于获得且简单的语言规范(非常 Wirths 风格)。
无论如何,“词汇和表示”部分包括一个“运算符和分隔符”列表,包括大多数人认为是关键字的内容。这些将被词法分析器识别。
在“声明和范围规则”部分,有一个预定义标识符列表,例如“ABS”和“BOOLEAN”。我对 Oberon 不够熟悉,无法确定,但如果我要编写一个编译器,我很有可能只是预初始化普通标识符表以包含这些预定义的标识符。
在 C 中,“main”在大多数情况下只是另一个函数。编译器可能会将其视为特殊的,也可能不会。可能唯一的“特殊”事情是链接到最终可执行文件的启动代码会调用该函数。
这在很大程度上取决于定义,特别是在扫描仪、标记器、词法分析器和解析器之间画线的位置。因为这是家庭作业,只有你的教授才是正确的。说它是正确的:看看你的阅读材料中提供的定义。
关于 main():你可以肯定地说 main() 和所有其他函数一样,不是关键字,而是一个标记。标记器识别子串“main”是一个标记,解析器将其设置为与其“(...)”和“{...}”部分相关。此外,对于 main(),解析器将自动生成程序入口点。
传统上,词法分析器识别关键字(这使您可以使用由一组固定关键字组成的语言)。但是当然你可以在解析过程中做到这一点。您甚至可以完全摆脱您的词法分析器,使用众多的无词法分析技术之一(例如,PEG)。它可能会帮助您避免混淆。