错误处理

更新时间:2022-10-25 09:39

错误是指导致系统不能按照用户意图工作的一切原因、事件。在程序设计过程中,由于某些错误的存在,致使程序无法正常运行,处理这些错误以使程序正确运行就称为错误处理。错误处理功能是衡量编译器性能的重要方面,它在帮助程序员尽快修改程序方面起到了非常重要的作用。

程序错误类型

程序错误类型主要有语法错误、语义错误和逻辑错误,其中,语法错误和语义错误能通过编译器发现,逻辑错误只能由编程人员通过比对结果和设计方案发现错误并处理。

语法错误

语法错误是因为源程序中不正确的代码产生的,即在编写程序时没有遵守语法(或词法)规则,书写了错误的语法代码,从而导致编译器无法正确解释源代码而产生的错误,通常是由于录入的错误引起的,它在词法分析或语法分析时检测出来。如“非法字符”、“括号不匹配”、“缺少;”之类的错误。图1为一些常见语法错误。

语义错误

语义错误是指源程序中不符合语义规则的错误,即一条语句试图执行一条不可能执行的操作而产生的错误。语义错误有的在语义分析时检测处来,有的在运行时才能检测出来。如变量声明错误、作用域错误、数据存储区的溢出等错误。

逻辑错误

逻辑错误是指程序的运行结果和程序员的设想有出入时产生的错误。这类错误并不直接导致程序在编译期间和运行期间出现错误,但是程序未按预期方式执行,产生了不正确的运行结果,较难发现。这种错误只能通过分析结果,将结果与设计方案进行对比来发现。

错误处理规范

按照错误类型

按照错误类型,通常的处理方式如下:

按照调用类型

按照调用类型,通常的处理方式如下:

按照展现方式

按照展现方式,通常的分类如下:

错误处理技术

编译器检查出源程序中的错误后,首先要向用户报告错误信息,以便可以进一步改正错误。另外还要对错误进行适当的处理,以便分析过程可以继续下去,对错误的处理主要有两种方法:错误改正和错误局部化处理。

语法错误处理

词法分析中的错误局部化处理比较简单,而编译过程中大部分查错和改错工作集中在语法分析阶段,下文为自上而下语法分析中的错误局部化处理策略。

处理措施

在语法分析过程的每一时刻,总可以把源程序输入符号串 划分为如下形式(式1):

其中, 是已经扫描和加工过的部分, 为现行输入符号, 是输入串的余留部分。假定编译程序发现了源程序中的一个语法错误,这对自上而下分析来说,就意味着分析器已为输入串建立了一棵部分语法树,并且此部分语法树已经覆盖了子串 ,但却无法再扩大而覆盖 。此时,就必须确定如何修改源程序来“更正”这个错误。可供采用的修改措施如下:

(1) 删去符号 再进行分析;

(2) 在 与 之间插入一终结符号串α,即把式(1)修改为(式2): ,然后再从 的首部开始分析;

(3) 在 与 之间插入终结符号串α(见式(2)),但从 开始分析;

(4) 从 的尾部删去若干个符号。

以上各种修改措施既可单独使用,也可联合使用。但(3)、(4)两种措施需对源程序已加工部分进行修改,从而可能更改相应语义信息,因此实现起来比较困难而较少采用。

处理算法

假定在语法分析过程中,当扫描到输入符号 时发现了一个语法错误(见式(1)),且已构造的部分语法树不能进行扩展,则可执行下面的算法对该语法错误进行校正:

(1) 建立一个符号表L,它由所有未完成分支的各个未完成部分中的符号组成。

(2) 对于从出错点开始的余留输入串 ,删去 并考察 ,看L中是否存在这样的一个符号U且满足 U ai+1…。如果这样的U不存在,则再删去 并继续考察 ,直到找到某个 满足 为止。

(3) 根据(2)所得到的U确定它所在的那个未完成分支。

(4) 确定一个符号串α,使得若把α插入到 之前便能使分析继续下去。为了确定这样的α,只需要考察(3)所找到的那个未完成分支以及其各子树的未完成分支,并对它们都确定一个终结符号串以补齐相应的分支,最后再把这些终结符号串依次排列在一起就得到了所需的α。

(5) 把α插到 之前并从α的首部开始继续分析过程。

语义错误处理

遏止错误株连信息

错误株连,是指当源程序出现一个错误时,此错误将导致发生其它错误,而后者可能并不是一个真正的错误。例如,当编译程序处理一个形如A[ ]的下标变量时,,假定由查符号表得知A不是一个数组名,这就出现了一个错误;而其后核对此下标变量的下标个数是否与相应数组的维数一致时,由于A不是数组名而查不到内情向量,从而只能认为两者不一致,于是又株连产生了第二个错误。

为了遏止这种株连信息,一种简单的办法是在源程序中用一个“正确”的标识符去替换出错的标识符,同时把新标识符登入符号表中并尽可能填入各种属性。在此,这种符号表登记项是为改正错误而临时插入的,故对它们加以特殊标志。这样就可按下述方法实现遏止株连信息:每当发现一个引起错误的标识符时,就以该标识符的符号表登记项指针作为参数去调用输出出错信息子程序,这个子程序将查看相应的登记项,如果它已加以标志,则不再输出出错信息。

遏止重复出错信息

在源程序中,如果某一标识符未加说明或者说明不正确,则会导致程序中对该标识符的错误使用。例如下面的程序:

由于未在函数f中对整型变量c加以说明,因而赋值句中对c的每次引用都将输出“变量的类型不相容”错误信息。当在源程序中发现使用了一个未经说明的标识符时,就将它登入符号表中,并根据上下文填写所查出的一些属性;再建立另一张表,其中各个登记项有相应标识符的各种错误用法,在遇到一个错用的标识符时就顺序检查这张表。如果以前曾按同样方式使用过该标识符,就不再输出出错信息;否则,除输出出错信息外,还要将本次错用的情况登入该表。

免责声明
隐私政策
用户协议
目录 22
0{{catalogNumber[index]}}. {{item.title}}
{{item.title}}