📜  编译器中的错误检测和恢复

📅  最后修改于: 2021-09-28 10:26:23             🧑  作者: Mango

在这个编译阶段,用户可能犯的所有错误都会被检测出来并以错误信息的形式报告给用户。这个定位错误并报告给用户的过程称为错误处理过程
错误处理程序的功能

  • 检测
  • 报告
  • 恢复

错误分类

编译时错误分为三种类型:-

词汇相位错误

这些错误是在词法分析阶段检测到的。典型的词汇错误是

  • 超过标识符或数字常量的长度。
  • 出现非法字符
  • 不匹配的字符串
Example 1 : printf("Geeksforgeeks");$
This is a lexical error since an illegal character $ appears at the end of statement.

Example 2 : This is a comment */
This is an lexical error since end of comment is present but beginning is not present. 

错误恢复:
恐慌模式恢复

  • 在此方法中,一次删除输入中的连续字符,直到找到一组指定的同步标记。同步令牌是分隔符,例如;要么 }
  • 优点是容易实现,保证不死循环
  • 缺点是大量的输入被跳过而不检查它是否有额外的错误

句法相位错误

这些错误是在语法分析阶段检测到的。典型的语法错误是

  • 结构错误
  • 缺少运算符
  • 拼写错误的关键字
  • 不平衡括号
Example : swicth(ch)
              {
                 .......
                 .......
              }

关键字switch错误地写为 swicth。因此,会出现“Unidentified keyword/identifier”错误。

错误恢复:

  1. 恐慌模式恢复
    • 在这种方法中,一次删除输入中的连续字符,直到找到一组指定的同步标记。同步令牌是 deli-meter,例如 ;要么 }
    • 优点是容易实现,保证不会死循环
    • 缺点是大量的输入被跳过而不检查它是否有额外的错误
  2. 语句模式恢复
    • 在这种方法中,当解析器遇到错误时,它会对剩余的输入进行必要的纠正,以便输入语句的其余部分允许解析器提前解析。
    • 更正可以是删除多余的分号、用分号替换逗号或插入缺少的分号。
    • 在进行校正时,最多应该注意不要进入无限循环。
    • 缺点是很难处理在检测点之前发生实际错误的情况。
  3. 错误产生
    • 如果用户了解可能会遇到的常见错误,则可以通过使用生成错误结构的错误产生式扩充语法来合并这些错误。
    • 如果使用它,则在解析期间可以生成适当的错误消息并可以继续解析。
    • 缺点是难以维护。
  4. 全局校正
    • 解析器检查整个程序并尝试找出最接近的匹配,并且没有错误。
    • 最接近的匹配程序具有较少数量的令牌插入、删除和更改以从错误输入中恢复。
    • 由于时间和空间复杂度高,该方法没有实际实现。

语义错误

这些错误是在语义分析阶段检测到的。典型的语义错误是

  • 不兼容的操作数类型
  • 未声明的变量
  • 实际参数与形式参数不匹配
Example : int a[10], b;
                 .......
                 .......
                 a = b;

由于 a 和 b 的类型不兼容,它会产生语义错误。

错误恢复

  • 如果遇到错误“Undeclared Identifier”,则为从中恢复相应标识符的符号表条目。
  • 如果两个操作数的数据类型不兼容,则编译器会自动进行类型转换。