PL0编译程序的语法错误处理

更新时间:2024-03-22 20:18:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

3/26/2013 PL0ERR.DOC 1/2

PL0编译程序的语法错误处理

1.基本法则

关键字法则:语法结构,尤其是每种构造语句和说明,以关键字开

头。

镇定法则:发现非法结构后,即跳过后面的输入正文,直到下一个

可以正确地后随当前正在分析的句子结构的符号为止。亦即每一分析程序知道在其当前活动点的后继符号的集合。

2.处理方法

(1)给每个分析函数提供一个参数FSYS,它指明可能的后继符号。在每个函数的末尾包括一个测试,以保证输入正文的下一个符号真的属于后继符号集(如果有语法错误的话)。

(2)为了尽量减少忽略直到下一个后继符号为止的中间所有正文,在后继符号集添加一些关键字,它们专门标记那些不容忽略的结构的开始符。因此,作为参数传递给分析函数的就不仅是后继符号了,可称为停止符号。具体来说,先用一些明显的关键字给它们赋予初值,然后随着分析子目标的层次的深入,逐步补充别的合法符号。TEST函数就是用来完成这些验证工作的,它有三个参数:

①可允许的下一个符号的集合S1;若当前符号不属于此集合,则当即得到一个错误。

②另加的停止符号集S2,这些符号的出现虽然是错的,但是它们绝对不应被忽略而跳过。

③整数N,表示有关错误的代码。

void TEST(SYMSET S1, SYMSET S2, int N){ if (!SymIn(S1)) { ERROR(N);

while (!SymIn(S1+S2)) GetSym(); } }

(3)TEST也可以用作分析函数的入口,以验证当前符号是否为允许的头符号。在下述情况下,这一方法值得推荐。比如规则

A::=a1S1|…|anSn|X 的翻译结果是

if (SYM==a1)S1(); else …

if (SYM==an)Sn(); else X();

此时,分析函数X是无条件被调用的。此时,参数S1必须为X的头符号集合,而S2则选为A的后继符号集合FOLLOW(A)。

以因子(FACTOR)的语法分析函数为例,在函数FACTOR的入口处调用了一次TEST函数,它的实参S1是因子开始符号的集合(FACBEGSYS),S2是每个函数的形参FSYS调用时实参的传递值。

当编译程序第一次调用BLOCK时,FSYS的实参为:[.]与说明开始符和语句开始符的和集。以后随着调用语法分析函数层次的深入,FSYS的传递值逐步增加。例如,调用STATEMENT时增加了[;]和[ENDSYM];在表达式语法分析中调用TERM时又增加了[+]和[-],进而调用FACTOR时又增加了[*]和[/];这样在进入

3/26/2013 PL0ERR.DOC 2/2

因子分析函数时,即使当前符号不是因子开始符,出错后只要跳过一定的符号,遇到在FSYS中或在因子开始符号集合中的单词符号,均可继续正常进行语法分析。在FACTOR函数的出口处也调用了TEST,不过这时的S1和S2的实参恰恰相反,说明当时FSYS集合的单词符号都是因子正常出口时允许的单词符号,而因子的开始符号为可恢复正常语法分析的补充单词符号。

以上处理方案具有这样的性质:试图通过略过输入正文的一个或多个符号来恢复分析的正常步骤。在错误仅为漏掉一个符号所引起的所有情况下,它都不是适宜的策略。经验表明,这类错误基本上限于那种仅有语法作用而不代表行动的符号。PL0中的分号即为一例。把一些关键字添加到后继符号集合中去,使得分析程序不再盲目地跳过后面的符号,好象漏掉的符号已经补上了一样。从以下分析复合语句的程序段,可以看出上述思想。它在效果上等于在关键字前面插入了漏掉的分号。STATBEGSYS是‘语句’的头符号集合(FIRST集)。

if (sym==BEGINSYM) { GetSym();

STATEMENT([SEMICOLON,ENDSYM]+FSYS); while(SYM IN[SEMICOLON]+STATBEGSYS){ if(SYM==SEMICOLON) GetSym(); else ERROR(10);

STATEMENT([SEMICOLON,ENDSYM]+FSYS); }

if (SYM==ENDSYM) GetSym(); else ERROR(17); }

本文来源:https://www.bwwdw.com/article/x388.html

Top