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