資源描述:
《pl0編譯程序的語法錯誤處理》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫。
1、2021/6/21PL0ERR.DOC2/2PL0編譯程序的語法錯誤處理1.基本法則關(guān)鍵字法則:語法結(jié)構(gòu),尤其是每種構(gòu)造語句和說明,以關(guān)鍵字開頭。鎮(zhèn)定法則:發(fā)現(xiàn)非法結(jié)構(gòu)后,即跳過后面的輸入正文,直到下一個可以正確地后隨當(dāng)前正在分析的句子結(jié)構(gòu)的符號為止。亦即每一分析程序知道在其當(dāng)前活動點的后繼符號的集合。2.處理方法(1)給每個分析函數(shù)提供一個參數(shù)FSYS,它指明可能的后繼符號。在每個函數(shù)的末尾包括一個測試,以保證輸入正文的下一個符號真的屬于后繼符號集(如果有語法錯誤的話)。(2)為了盡量減少忽略
2、直到下一個后繼符號為止的中間所有正文,在后繼符號集添加一些關(guān)鍵字,它們專門標(biāo)記那些不容忽略的結(jié)構(gòu)的開始符。因此,作為參數(shù)傳遞給分析函數(shù)的就不僅是后繼符號了,可稱為停止符號。具體來說,先用一些明顯的關(guān)鍵字給它們賦予初值,然后隨著分析子目標(biāo)的層次的深入,逐步補充別的合法符號。TEST函數(shù)就是用來完成這些驗證工作的,它有三個參數(shù):①可允許的下一個符號的集合S1;若當(dāng)前符號不屬于此集合,則當(dāng)即得到一個錯誤。②另加的停止符號集S2,這些符號的出現(xiàn)雖然是錯的,但是它們絕對不應(yīng)被忽略而跳過。③整數(shù)N,表示有關(guān)
3、錯誤的代碼。voidTEST(SYMSETS1,SYMSETS2,intN){if(!SymIn(S1)){ERROR(N);while(!SymIn(S1+S2))GetSym();}}(3)TEST也可以用作分析函數(shù)的入口,以驗證當(dāng)前符號是否為允許的頭符號。在下述情況下,這一方法值得推薦。比如規(guī)則A::=a1S1
4、…
5、anSn
6、X的翻譯結(jié)果是if(SYM==a1)S1();else…if(SYM==an)Sn();elseX();此時,分析函數(shù)X是無條件被調(diào)用的。此時,參數(shù)S1必須為X的頭符
7、號集合,而S2則選為A的后繼符號集合FOLLOW(A)。以因子(FACTOR)的語法分析函數(shù)為例,在函數(shù)FACTOR的入口處調(diào)用了一次TEST函數(shù),它的實參S1是因子開始符號的集合(FACBEGSYS),S2是每個函數(shù)的形參FSYS調(diào)用時實參的傳遞值。當(dāng)編譯程序第一次調(diào)用BLOCK時,F(xiàn)SYS的實參為:[.]與說明開始符和語句開始符的和集。以后隨著調(diào)用語法分析函數(shù)層次的深入,F(xiàn)SYS的傳遞值逐步增加。例如,調(diào)用STATEMENT時增加了[;]和[ENDSYM];在表達(dá)式語法分析中調(diào)用TERM時又
8、增加了[+]和[-],進(jìn)而調(diào)用FACTOR時又增加了[*]和[/];這樣在進(jìn)入因子分析函數(shù)時,即使當(dāng)前符號不是因子開始符,出錯后只要跳過一定的符號,遇到在FSYS2021/6/21PL0ERR.DOC2/2中或在因子開始符號集合中的單詞符號,均可繼續(xù)正常進(jìn)行語法分析。在FACTOR函數(shù)的出口處也調(diào)用了TEST,不過這時的S1和S2的實參恰恰相反,說明當(dāng)時FSYS集合的單詞符號都是因子正常出口時允許的單詞符號,而因子的開始符號為可恢復(fù)正常語法分析的補充單詞符號。以上處理方案具有這樣的性質(zhì):試圖通過
9、略過輸入正文的一個或多個符號來恢復(fù)分析的正常步驟。在錯誤僅為漏掉一個符號所引起的所有情況下,它都不是適宜的策略。經(jīng)驗表明,這類錯誤基本上限于那種僅有語法作用而不代表行動的符號。PL0中的分號即為一例。把一些關(guān)鍵字添加到后繼符號集合中去,使得分析程序不再盲目地跳過后面的符號,好象漏掉的符號已經(jīng)補上了一樣。從以下分析復(fù)合語句的程序段,可以看出上述思想。它在效果上等于在關(guān)鍵字前面插入了漏掉的分號。STATBEGSYS是‘語句’的頭符號集合(FIRST集)。if(sym==BEGINSYM){GetSy
10、m();STATEMENT([SEMICOLON,ENDSYM]+FSYS);while(SYMIN[SEMICOLON]+STATBEGSYS){if(SYM==SEMICOLON)GetSym();elseERROR(10);STATEMENT([SEMICOLON,ENDSYM]+FSYS);}if(SYM==ENDSYM)GetSym();elseERROR(17);}