我正在学习编译器,特别是关于两阶段编译器,并且对于检测到错误的某些阶段感到困惑。让我们说我们有类似的东西:
int x, y;
x = x + y + z;
我们试图引用尚未声明的变量。我认为这是一个错误,可以在编译器的前端检测到。但我不知道前端的哪个子区域会检测到这个错误。
前端的三个部分是:扫描仪,解析器和无上下文分析器。扫描程序读取语句中的每个字符,并将语句拆分为标记。所以,我可能是错的,但我不认为这里会发现错误。解析器检查语句是否在语法上正确。这是我开始感到困惑的地方。即使z
未声明,语句的语法在技术上也是正确的,因此这里也不会检测到错误?无上下文分析器使用符号表和语法树来检查程序,以查看它是否在语义上与语言定义一致。在这里它也进行类型检查。它会在这里检测到错误吗?因为此时编译器会查看符号表并注意z
没有类型(或者它根本不存在?)。或者这是否会被编译器的后端检测到?如果是后端,我不明白为什么会这样。任何澄清都将受到高度赞赏。感谢。
答案 0 :(得分:3)
这最终取决于编译器,但通常会出现在语义分析级别,这仍然在编译器前端。
使用传统的编译器,这不可能在扫描阶段完成,因为扫描仪使用有限自动机和表示适当变量范围的字符串的语言"不定期。这通常也不会作为解析的一部分完成,因为解析通常是关于构建AST,如果是自下而上完成的,那么在解析器时,范围信息将不可用。确定了代码的结构。
但是,语义分析器具有查找此错误所需的所有信息 - 它具有AST并可以使用它来构建符号表,遍历代码中的所有表达式,并注意到z
isn& #39; t符号表中的任何位置。