編譯原理修改后地PL0報(bào)告材料_第1頁
編譯原理修改后地PL0報(bào)告材料_第2頁
編譯原理修改后地PL0報(bào)告材料_第3頁
編譯原理修改后地PL0報(bào)告材料_第4頁
編譯原理修改后地PL0報(bào)告材料_第5頁
已閱讀5頁,還剩38頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

實(shí)用文案一、上機(jī)實(shí)踐要求“編譯原理與技術(shù)”的上機(jī)實(shí)驗(yàn)要求你對(duì) PL/0語言及其編譯器進(jìn)行擴(kuò)充和修改。 每個(gè)擴(kuò)充或修改方式可得到不同的分?jǐn)?shù),滿分為 100分。完成上機(jī)作業(yè)后,必須提交下列文檔:1)修改后的PL/0語言文本。包含詞法分析(正規(guī)式),語法分析(BNF)。2)有關(guān)修改后的PL/0編譯/解釋器的說明。詳細(xì)說明你的編譯器是如何編譯新的PL/0語言程序的。指出你的程序中最精彩的部分,以及你為什么這樣做,你是如何控制和恢復(fù)語義錯(cuò)誤的。3)給出你所改動(dòng)后的編譯器源程序清單,并標(biāo)記出你所修改的部分。比較你的編譯器和原來的編譯器之間的差別。4)說明你的編譯器中可能存在的錯(cuò)誤。5)總結(jié)經(jīng)驗(yàn)與教訓(xùn),如果重做一遍,你會(huì)有哪些新的改進(jìn)?對(duì)現(xiàn)存的PL/0編譯程序可做如下修改或擴(kuò)充,其中( 1)、(2)、(11)和(12)必須完成,剩余的均可任意選擇,但總分必須超過 70分。1)注釋(5分)注釋由(*和*)包含,不允許嵌套。2)布爾類型的數(shù)據(jù)(10分)布爾類型的BNF為:var_option →ε|varvar_decl_listvar_decl_list →var_decl|var_decl_listvar_declvar_decl →ident_list:data_typedata_type →integer |boolean標(biāo)準(zhǔn)文檔實(shí)用文案這種修改包括:(i) 區(qū)別整型與布爾型變量、常量和表達(dá)式。(ii) 增加按嚴(yán)格計(jì)算的布爾類型運(yùn)算符 and、or和not。這些算符以及己有的運(yùn)算符的優(yōu)先級(jí)與Pascal語言相同。(iii) 能夠使用布爾常量 true和false。iv)把PL/0語言中的“條件”概念一般化為Pascal語言那樣。v)布爾表達(dá)式可以比較大?。篺alse<true3)布爾表達(dá)式的短路計(jì)算(5分)增加布爾類型(見(2),除(2)的(ii)外),但對(duì)and和or采取短路計(jì)算。4)數(shù)組(10分)增加由任何數(shù)據(jù)類型構(gòu)造的一維數(shù)組。數(shù)組的下標(biāo)限于純量類型。注意:數(shù)組可以由其它的數(shù)組來構(gòu)造,因而必須考慮多維數(shù)組的情況。數(shù)組的上下界可為任意的純量常數(shù)。數(shù)組的定義如下:data_type →integer |boolean |array[const..const] ofdata_typeconst →ident |number語言中允許有數(shù)組說明,對(duì)數(shù)組元素賦值,在表達(dá)式中引用數(shù)組元素。 為了便于解釋執(zhí)行,可能要增加新的PL/0機(jī)器操作指令。5)參數(shù)(10分)語法同Pascal,采用值-結(jié)果方式傳遞(不用var聲明)。6)函數(shù)(10分)語法同Pascal。7)else子句和repeat語句(5分)8)for語句,語法參照Pascal或C語言(5分)標(biāo)準(zhǔn)文檔實(shí)用文案(9) exit語句(退出當(dāng)前執(zhí)行過程)和 break語句(跳出包含它的最內(nèi)層循環(huán)),(5分)10)記錄(結(jié)構(gòu)),語法同Pascal語言(10分)。11)更有力的語法錯(cuò)誤恢復(fù)機(jī)制(20分)12)分離解釋和編譯器(5分)注意:上面的這些要求有時(shí)會(huì)互相影響 :例如實(shí)現(xiàn)布爾類型數(shù)據(jù),則數(shù)組和參數(shù)就應(yīng)該能處理其相互組合的情況,如布爾型數(shù)組(包括多維數(shù)組)、布爾型作為下標(biāo)的數(shù)組、布爾型作為參數(shù)傳遞。甚至能夠?qū)崿F(xiàn)數(shù)組作為參數(shù)傳遞等。另外,為了實(shí)現(xiàn)以上功能,你可任意增加 PL/0處理機(jī)的指令。但要注意指令的簡(jiǎn)單與合理。選做題:此題不計(jì)入總分,僅做為學(xué)生在有余力的情況下的進(jìn)一步練習(xí)。實(shí)現(xiàn)PL/0語言的輸入、輸出語句。其語法、語義定義和 Pascal語言相同??梢詢H僅實(shí)現(xiàn)一次輸入或輸出一個(gè)值的語句——語句參數(shù)固定;也可以實(shí)現(xiàn)完全和 Pascal語言一樣,能夠接受任意個(gè)數(shù)參數(shù)的輸入或輸出語句。二、實(shí)驗(yàn)原理:就像一個(gè)翻譯要把漢語翻譯成英語,必須對(duì)漢語和英語的單詞、語法結(jié)構(gòu)都很精通,才有可能翻譯得準(zhǔn)確無誤。另外,編譯程序既然是為了完成這種功能的一個(gè)程序,就存在用什么語言來編寫這個(gè)程序的問題。這些問題在本節(jié)將逐步介紹?,F(xiàn)對(duì)PL/0語言編譯程序的功能用“ T”型圖表示,并用圖形概括描述 PL/0編譯程序的結(jié)構(gòu)框架。用語法圖描述語法規(guī)則的優(yōu)點(diǎn)是直觀、 易讀。在圖1.1的語法圖中用橢圓和圓圈中的英文字表示終結(jié)符,用長方形內(nèi)的中文字表示非終結(jié)符。所謂終結(jié)符,是構(gòu)成語言文法的單詞,是語法成分的最小單位,而每個(gè)非終結(jié)符也是一個(gè)語法成分。但非終結(jié)符可由其它文法符號(hào)定義,終結(jié)符不能由其它文法符號(hào)定義。例如,程序是由非終結(jié)符 '標(biāo)準(zhǔn)文檔實(shí)用文案分程序'和終結(jié)符"."組成的串定義的。由于對(duì)某些非終結(jié)符可以遞歸定義,如圖1.1(b)、2.1(c)、2.1(e)中:分程序、表達(dá)式和語句。第一個(gè)非終結(jié)符'程序'為文法的開始符號(hào)。程序.分程序1.1(a)語句序列語句;1.1(c)條件 odd 表達(dá)式表達(dá)式>== <> < > <=表達(dá)式標(biāo)準(zhǔn)文檔實(shí)用文案1.1(e)分程序=const ident number,;var ident,;;procedure ident; 程序體標(biāo)準(zhǔn)文檔實(shí)用文案語句1.1(b)語句identcallifbeginwhile

:= 表達(dá)式ident語句序列條件 then 語句enddo條件 語句標(biāo)準(zhǔn)文檔實(shí)用文案1.1(d)表達(dá)式+項(xiàng)1.1(f)項(xiàng)

- + -項(xiàng)因子/*因子標(biāo)準(zhǔn)文檔實(shí)用文案1.1(g)因子identnumber( 表達(dá)式 )1.1(h)如:{*}表示*重復(fù)任意次,{*}38表示*重復(fù)3-8次。[]:方括號(hào)表示其內(nèi)的成分為任選項(xiàng)。():表示圓括號(hào)內(nèi)的成分優(yōu)先。例:用EBNF描述<整數(shù)>文法的定義 :<整數(shù)>∷=[+|-]< 數(shù)字>{<數(shù)字>}<數(shù)字>∷=0|1|2|3|4|5|6|7|8|9或更好的寫法整數(shù)>∷=[+|-]<非零數(shù)字>{<數(shù)字>}|0非零數(shù)字>∷=1|2|3|4|5|6|7|8|9標(biāo)準(zhǔn)文檔實(shí)用文案數(shù)字>∷=0|<非零數(shù)字>PL/0語言文法的EBNF表示為:〈程序〉∷=〈分程序〉.〈分程序〉∷=[〈常量說明部分〉][〈變量說明部分〉][〈過程說明部分〉]〈語句〉〈常量說明部分〉∷=CONST〈常量定義〉{,〈常量定義〉};〈常量定義〉∷=〈標(biāo)識(shí)符〉=〈無符號(hào)整數(shù)〉〈無符號(hào)整數(shù)〉∷=〈數(shù)字〉{〈數(shù)字〉}〈變量說明部分〉∷=VAR〈標(biāo)識(shí)符〉{,〈標(biāo)識(shí)符〉};〈標(biāo)識(shí)符〉∷=〈字母〉{〈字母〉|〈數(shù)字〉}〈過程說明部分〉∷=〈過程首部〉〈分程序〉{;〈過程說明部分〉};〈過程首部〉∷=PROCEDURE〈標(biāo)識(shí)符〉;〈語句〉∷=〈賦值語句〉|〈條件語句〉|〈當(dāng)型循環(huán)語句〉|〈過程調(diào)用語句〉|〈讀語句〉|〈寫語句〉|〈復(fù)合語句〉|〈空〉〈賦值語句〉∷=〈標(biāo)識(shí)符〉∶=〈表達(dá)式〉〈復(fù)合語句〉∷=BEGIN〈語句〉{;〈語句〉}END〈條件〉∷=〈表達(dá)式〉〈關(guān)系運(yùn)算符〉〈表達(dá)式〉|ODD〈表達(dá)式〉〈表達(dá)式〉∷=[+|-]〈項(xiàng)〉{〈加法運(yùn)算符〉〈項(xiàng)〉}〈項(xiàng)〉∷=〈因子〉{〈乘法運(yùn)算符〉〈因子〉}〈因子〉∷=〈標(biāo)識(shí)符〉|〈無符號(hào)整數(shù)〉|'('〈表達(dá)式〉')'〈加法運(yùn)算符〉∷=+|-〈乘法運(yùn)算符〉∷=*|/〈關(guān)系運(yùn)算符〉∷=#|=|<|<=|>|>=標(biāo)準(zhǔn)文檔實(shí)用文案〈條件語句〉∷=IF〈條件〉THEN〈語句〉〈過程調(diào)用語句〉∷=CALL〈標(biāo)識(shí)符〉〈當(dāng)型循環(huán)語句〉∷=WHILE〈條件〉DO〈語句〉〈讀語句〉∷=READ'('〈標(biāo)識(shí)符〉{,〈標(biāo)識(shí)符〉}')'〈寫語句〉∷=WRITE'('〈表達(dá)式〉{,〈表達(dá)式〉}')'〈字母〉∷=a|b|?|X|Y|Z〈數(shù)字〉∷=0|1|2|?|8|9EBNF表示的符號(hào)說明?!担河米笥壹饫ㄌ?hào)括起來的中文字表示語法構(gòu)造成分,或稱語法單位,為非終結(jié)符?!?:該符號(hào)的左部由右部定義,可讀作'定義為'。|:表示'或',為左部可由多個(gè)右部定義。{}:花括號(hào)表示其內(nèi)的語法成分可以重復(fù)。在不加上下界時(shí)可重復(fù) 0到任意次數(shù),有上下界時(shí)為可重復(fù)次數(shù)的限制。用語法圖描述語言的語法與 EBNF描述相比較:語法圖描述: 直觀,易讀,易寫。EBNF表示:形式化強(qiáng),易機(jī)器識(shí)別。無論用語法圖或 EBNF作為描述程序設(shè)計(jì)語言語法的工具,對(duì)描述的語法可以檢查哪些符號(hào)序列是所給語言的合法程序,一個(gè)程序設(shè)計(jì)語言如 C或JAVA,用戶可用它寫出成千上萬個(gè)不同的程序, 但C或JAVA它們各自的語法只有一個(gè),這就使得無窮的句子集可用有窮的文法(語法)描述。PL/0編譯程序的使用限制標(biāo)識(shí)符的有效長度是10數(shù)字最多為14位標(biāo)準(zhǔn)文檔實(shí)用文案

過程最多可嵌套三層,可遞歸調(diào)用

標(biāo)識(shí)符的作用域同 PASCAL,內(nèi)層可引用包圍它的外層定義的標(biāo)識(shí)符(如:變量名,過程名,常量名)目標(biāo)指令有8條:①LIT:將常量值取到運(yùn)行棧頂。 a域?yàn)槌?shù)值。LOD:將變量放到棧頂。a域?yàn)樽兞吭谒f明層中的相對(duì)位置,l為調(diào)用層與說明層的層差值。③STO:將棧頂?shù)膬?nèi)容送入某變量單元中。 a,l域的含意同LOD指令。④CAL:調(diào)用過程的指令。a為被調(diào)用過程的目標(biāo)程序入口地址, l為層差。INT:為被調(diào)用的過程(或主程序)在運(yùn)行棧中開辟數(shù)據(jù)區(qū)。a域?yàn)殚_辟的單元個(gè)數(shù)。⑥JMP:無條件轉(zhuǎn)移指令,a為轉(zhuǎn)向地址。⑦JPC:條件轉(zhuǎn)移指令,當(dāng)棧頂?shù)牟紶栔禐榉钦鏁r(shí),轉(zhuǎn)向 a域的地址,否則順序執(zhí)行。⑧OPR:關(guān)系運(yùn)算和算術(shù)運(yùn)算指令。將棧頂和次棧頂?shù)膬?nèi)容進(jìn)行運(yùn)算,結(jié)果存放在次棧頂,此外還可以是讀寫等特殊功能的指令,具體操作由 a域值給出。(詳見解釋執(zhí)行程序)。類pcode代碼指令的詳細(xì)解釋(指令功能表)認(rèn)識(shí)目標(biāo)代碼類pcode目標(biāo)代碼類pcode是一種假想棧式計(jì)算機(jī)的匯編語言。指令格式:f l a功能碼l層次差 (標(biāo)識(shí)符引用層減去定義層)標(biāo)準(zhǔn)文檔實(shí)用文案根據(jù)不同的指令有所區(qū)別指令功能表LIT0a將常數(shù)值取到棧頂,a為常數(shù)值LODla將變量值取到棧頂,a為偏移量,l為層差STOla將棧頂內(nèi)容送入某變量單元中,a為偏移量,l為層差CALla調(diào)用過程,a為過程地址,l為層差I(lǐng)NT0a在運(yùn)行棧中為被調(diào)用的過程開辟a個(gè)單元的數(shù)據(jù)區(qū)JMP0a無條件跳轉(zhuǎn)至a地址JPC0a條件跳轉(zhuǎn),當(dāng)棧頂布爾值非真則跳轉(zhuǎn)至a地址,否則順序執(zhí)行OPR00過程調(diào)用結(jié)束后,返回調(diào)用點(diǎn)并退棧OPR01棧頂元素取反OPR02次棧頂與棧頂相加,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR03次棧頂減去棧頂,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR04次棧頂乘以棧頂,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR05次棧頂除以棧頂,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR06棧頂元素的奇偶判斷,結(jié)果值在棧頂標(biāo)準(zhǔn)文檔實(shí)用文案OPR07OPR08 次棧頂與棧頂是否相等,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR09 次棧頂與棧頂是否不等,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR010 次棧頂是否小于棧頂,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR011 次棧頂是否大于等于棧頂,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR012 次棧頂是否大于棧頂,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR013 次棧頂是否小于等于棧頂,退兩個(gè)棧元素,結(jié)果值進(jìn)棧OPR014 棧頂值輸出至屏幕OPR015 屏幕輸出換行OPR016 從命令行讀入一個(gè)輸入置于棧頂PL/0語言可看成是PASCAL語言的子集,它的編譯程序是一個(gè)編譯解釋執(zhí)行系統(tǒng)。 PL/0的目標(biāo)程序?yàn)榧傧霔J接?jì)算機(jī)的匯編語言,與具體計(jì)算機(jī)無關(guān)。 PL/0的編譯程序和目標(biāo)程序的解釋執(zhí)行程序都是用PASCAL語言書寫的,因此 PL/0語言可在配備PASCAL語言的任何機(jī)器上實(shí)現(xiàn)。其編譯過程采用一趟掃描方式,以語法分析程序?yàn)楹诵模~法分析程序和代碼生成程序都作為一個(gè)獨(dú)立的過程,當(dāng)語法分析需要讀單詞時(shí)就調(diào)用詞法分析程序, 而當(dāng)語法分析正確需生成相應(yīng)的目標(biāo)代碼時(shí), 則調(diào)用代碼生成程序。此外,用表格管理程序建立變量、常量和過程標(biāo)識(shí)符的說明與引用之間的信息聯(lián)系。用出錯(cuò)處理程序?qū)?biāo)準(zhǔn)文檔實(shí)用文案詞法和語法分析遇到的錯(cuò)誤給出在源程序中出錯(cuò)的位置和錯(cuò)誤性質(zhì)。 當(dāng)源程序編譯正確時(shí),PL/0編譯程序自動(dòng)調(diào)用解釋執(zhí)行程序,對(duì)目標(biāo)代碼進(jìn)行解釋執(zhí)行,并按用戶程序要求輸入數(shù)據(jù)和輸出運(yùn)行結(jié)果。本書所提供的PL/0語言編譯器的基本工作流程如圖 1-1所示:源程序詞法分析語法分析符錯(cuò)誤號(hào)診表語義分析斷管處理理代碼生成代碼執(zhí)行執(zhí)行結(jié)果圖1-1PL/0 編譯器基本工作流程標(biāo)準(zhǔn)文檔實(shí)用文案由于PL/0編譯程序采用一趟掃描方法,所以語法分析過程 BLOCK是整個(gè)編譯過程的核心。下面我們將在圖2.4中先給出編譯程序的總體流程,以弄清 BLOCK過程在整個(gè)編譯程序中的作用。在流程圖 2.4中可以看出,主程序置初值后先調(diào)用讀單詞過程 GETSYM取一個(gè)單詞,然后再調(diào)用語法分析過程BLOCK,直到遇源程序的結(jié)束符 "."為止。語法分析過程 BLOCK是整個(gè)編譯過程的核心,是指開始由主程序調(diào)用 GETSYM取一個(gè)單詞,再調(diào)用語法分析過程BLOCK,BLOCK由當(dāng)前單詞根據(jù)語法規(guī)則再調(diào)用其它過程, 如說明處理、代碼生成或出錯(cuò)處理等過程進(jìn)行分析,當(dāng)分析完一個(gè)單詞后, BLOCK再調(diào)用GETSYM取下一個(gè)單詞,一直重復(fù)到當(dāng)前單詞為結(jié)束符"."表明源程序已分析結(jié)束。若未取到結(jié)束符 ".",而源程序已沒有輸入符號(hào),這時(shí)表明源程序有錯(cuò)誤,無法再繼續(xù)分析。PL/0的詞法分析程序 GETSYM(圖2.5)是一個(gè)獨(dú)立的過程,其功能是為語法分析提供單詞用的,是語法分析的基礎(chǔ),它把輸入的字符串形式的源程序分割成一個(gè)個(gè)單詞符號(hào)。為此 PL/0編譯程序設(shè)置了三個(gè)全程量的公用單元如下:SYM:存放每個(gè)單詞的類別,用內(nèi)部編碼形式表示。ID:存放用戶所定義的標(biāo)識(shí)符的值。即標(biāo)識(shí)符字符串的機(jī)內(nèi)表示。NUM:存放用戶定義的數(shù)。標(biāo)準(zhǔn)文檔實(shí)用文案單詞的種類有五種?;咀郑阂部煞Q為保留字或關(guān)鍵字,如 BEGIN,END,IF,THEN等。運(yùn)算符:如:+、-、*、/、∶=、#、>=、<=等。標(biāo)識(shí)符:用戶定義的變量名、常數(shù)名、過程名。常數(shù):如:10,25,100等整數(shù)。界符:如:','、'.'、';'、'('、')'等。如果我們把基本字、運(yùn)算符、界符稱為語言固有的單詞,而對(duì)標(biāo)識(shí)符、常數(shù)稱為用戶定義的單詞。那么經(jīng)詞法分析程序分出的單詞,對(duì)語言固有的單詞只給出類別存放在 SYM中,而對(duì)用戶定義的單詞(標(biāo)識(shí)符或常數(shù))既給類別又給值,其類別放在 SYM中,值放在ID或NUM中,全部單詞種類由編譯程序定義的純量類型 SYMBOL給出,也可稱為語法的詞匯表。如下面提到的 IFSYM,THENSYM,IDENT,NUMBER均屬SYMBOL中的元素。當(dāng)識(shí)別到字母開頭的字母數(shù)字串時(shí),先查關(guān)鍵字表。若查不到則為標(biāo)識(shí)符,查到則為關(guān)鍵字。 PL/0編譯程序文本中主程序開始對(duì)關(guān)鍵字表置初值如下:關(guān)鍵字表為:word[1]:='begin' ;word[2]:='call' ;...word[13]:='write' ;每個(gè)數(shù)組元素的字符長度為 10,不滿10個(gè)字符時(shí),以空格補(bǔ)滿。查到時(shí)找到關(guān)鍵字相應(yīng)的內(nèi)部表示為:Wsym[1]:=beginsym;wsym[2]:=callsym ;?wsym[13]:=writesym ;標(biāo)準(zhǔn)文檔實(shí)用文案PL/0編譯程序文本中開始對(duì)類型的定義中給出單詞定義為:typesymbol=(nul,ident,number,plus, ?,varsym,procsym) ;定義單詞是純量/枚舉類型,又定義了 3個(gè)全程量為:sym:symbol;id:alfa;num:integer;因此詞法分析程序 GETSYM將完成下列任務(wù):濾空格:空格在詞法分析時(shí)是一種不可缺少的界符,而在語法分析時(shí)則是無用的,所以必須濾掉。識(shí)別保留字:設(shè)有一張保留字表。對(duì)每個(gè)字母打頭的字母、數(shù)字字符串要查此表。若查著則為保留字,將對(duì)應(yīng)的類別放在SYM中。如IF對(duì)應(yīng)值IFSYM,THEN對(duì)應(yīng)值為THENSYM。若查不著,則認(rèn)為是用戶定義的標(biāo)識(shí)符。(3)識(shí)別標(biāo)識(shí)符:對(duì)用戶定義的標(biāo)識(shí)符將IDENT放在SYM中,標(biāo)識(shí)符本身的值放在ID中。(4)拼數(shù):當(dāng)所取單詞是數(shù)字時(shí),將數(shù)的類別NUMBER放在SYM中,數(shù)值本身的值存放在NUM中。拼復(fù)合詞:對(duì)兩個(gè)字符組成的算符如:>=、∶=、<= 等單詞,識(shí)別后將類別送 SYM中。輸出源程序:為邊讀入字符邊輸出(可輸出在文件中)。GETCH所用單元說明:CH:存放當(dāng)前讀取的字符,初值為空。LINE:為一維數(shù)組,其數(shù)組元素是字符,界對(duì)為 1∶80。用于讀入一行字符的緩沖區(qū)。LL和CC為計(jì)數(shù)器,初值為 0。標(biāo)準(zhǔn)文檔實(shí)用文案GETSYM流程圖的工作單元說明:A:一維數(shù)組,數(shù)組元素為字符,界對(duì) [1∶10]。ID:同A。WORD:保留字表,一維數(shù)組,數(shù)組元素是以字符為元素的一維數(shù)組。界對(duì)為 [1∶13]。查表方式采用二分法。單個(gè)字符對(duì)應(yīng)的單詞表的建立是,首先在主程序中定義了下標(biāo)為字符的數(shù)組 ssym,數(shù)組ssym的元素為單詞,主程序開始對(duì)下標(biāo)為字符的所有數(shù)組元素置初值為 nul,對(duì)PL/0語言用到的單個(gè)字符為單詞的,將其字符作為數(shù)組下標(biāo)的元素置初值為對(duì)應(yīng)的單詞。如:ssym['+']:=plus;ssym['-']:=minus;?ssym[';']:=semicolon;PL/0編譯程序的語法分析PL/0編譯程序語法、語義分析是整個(gè)編譯程序設(shè)計(jì)與實(shí)現(xiàn)的核心部分 ,要求學(xué)員努力學(xué)習(xí)掌握實(shí)現(xiàn)技術(shù)和方法?,F(xiàn)分別說明語法分析實(shí)現(xiàn)的主要思想方法和語義分析的實(shí)現(xiàn)。語法分析的任務(wù)是識(shí)別由詞法分析給出的單詞符號(hào)序列在結(jié)構(gòu)上是否符合給定的文法規(guī)則。 PL/0語言的文法規(guī)則已在 2.1節(jié)中給出。本節(jié)將以語法圖描述的語法形式為依據(jù),給出語法分析過程的直觀思想。PL/0編譯程序的語法分析采用了自頂向下的遞歸子程序法。什么是自頂向下的語法分析?可形象地對(duì)該程序自頂向下構(gòu)造一棵倒掛著的語法分析樹,其構(gòu)造方法是:(1)由開始符號(hào)非終結(jié)符'程序'作為分析樹的根結(jié)點(diǎn),由非終結(jié)符 '程序'規(guī)則的右部為子結(jié)點(diǎn)。(2)對(duì)分析樹中的每個(gè)非終結(jié)符結(jié)點(diǎn),選擇它規(guī)則的一個(gè)右部為子結(jié)點(diǎn)構(gòu)造分析樹的下一層。標(biāo)準(zhǔn)文檔實(shí)用文案(3)重復(fù)(2)直到分析樹中的末端結(jié)點(diǎn)只有終結(jié)符。(4)若分析樹中的末端結(jié)點(diǎn)從左到右連接的終結(jié)符號(hào)串剛好是輸入的程序終結(jié)符號(hào)串,則說明所給程序在語法上是正確的。粗略地說:自頂向下的遞歸子程序法就是對(duì)應(yīng)每個(gè)非終結(jié)符語法單元,編一個(gè)獨(dú)立的處理過程 (或子程序)。語法分析從讀入第一個(gè)單詞開始由非終結(jié)符'程序'即開始符號(hào)出發(fā),沿語法描述圖箭頭所指出的方向進(jìn)行分析。當(dāng)遇到非終結(jié)符時(shí),則調(diào)用相應(yīng)的處理過程,從語法描述圖看也就進(jìn)入了一個(gè)語法單元,再沿當(dāng)前所進(jìn)入的語法描述圖的箭頭方向進(jìn)行分析,當(dāng)遇到描述圖中是終結(jié)符時(shí),則判斷當(dāng)前讀入的單詞是否與圖中的終結(jié)符相匹配,若匹配,則執(zhí)行相應(yīng)的語義程序(就是翻譯程序)。再讀取下一個(gè)單詞繼續(xù)分析。遇到分支點(diǎn)時(shí)將當(dāng)前的單詞與分支點(diǎn)上的多個(gè)終結(jié)符逐個(gè)相比較,若都不匹配時(shí),可能是進(jìn)入下一非終結(jié)符語法單位或是出錯(cuò)。如果一個(gè)PL/0語言的單詞序列在整個(gè)語法分析中,都能逐個(gè)得到匹配,直到程序結(jié)束符'.',這時(shí)就說所輸入的程序是正確的。對(duì)于正確的語法分析做相應(yīng)的語義翻譯,最終得出目標(biāo)程序。以上所說語法分析過程非常直觀粗淺,實(shí)際上應(yīng)用遞歸子程序法構(gòu)造語法分析程序時(shí),對(duì)文法有一定的要求和限制,這個(gè)問題我們將在第5章詳細(xì)討論。此外,從PL/0的語法描述圖中可以清楚地看到,當(dāng)對(duì)PL/0語言進(jìn)行語法分析時(shí),各個(gè)非終結(jié)符語法單元所對(duì)應(yīng)的分析過程之間必須存在相互調(diào)用的關(guān)系。這種調(diào)用關(guān)系可用圖1-2表示。也可稱為PL/0語法的依賴圖,在圖中箭頭所指向的程序單元表示存在調(diào)用關(guān)系,從圖中不難看出這些子程序在語法分析時(shí)被直接或間接遞歸調(diào)用。由圖1-2PL/0語法調(diào)用關(guān)系圖可以看出對(duì)分程序和語句為直接遞歸調(diào)用, 對(duì)表達(dá)式為間接遞歸調(diào)用。程序程序體標(biāo)準(zhǔn)文檔 語句實(shí)用文案標(biāo)準(zhǔn)文檔實(shí)用文案表達(dá)式的EBNF〈表達(dá)式〉∷=[+|-]〈項(xiàng)〉{(+|-)〈項(xiàng)〉}〈項(xiàng)〉∷=〈因子〉{(*|/)〈因子〉}〈因子〉∷=〈標(biāo)識(shí)符〉|〈無符號(hào)整數(shù)〉|‘(’〈表達(dá)式〉‘)’〈表達(dá)式〉的遞歸子程序?qū)崿F(xiàn)procedureexpr;beginifsymin[plus,minus]thenbegingetsym;term;endelseterm;whilesymin[plus,minus]dobegingetsym;term;endend;〈項(xiàng)〉的遞歸子程序?qū)崿F(xiàn)procedureterm;beginfactor;whilesymin[times,slash]do標(biāo)準(zhǔn)文檔實(shí)用文案begingetsym;factor;endend;〈因子〉的遞歸子程序?qū)崿F(xiàn)procedurefactor;beginifsym<>identthenbeginifsym<>numberthenbeginifsym= ‘(‘thenbegingetsym;expr;ifsym= ‘)’thengetsymelseerrorendelseerrorend標(biāo)準(zhǔn)文檔實(shí)用文案endend;語法分析程序除總控外主要有兩大部分的功能,即對(duì)說明部分的處理和對(duì)程序體部分的處理,也就是在語法單元中的分程序功能。PL/0編譯程序語法、語義分析的的核心程序是 BLOCK過程,在BLOCK過程內(nèi)又定義了許多嵌套及并列的過程。在過程BLOCK內(nèi)對(duì)說明部分及程序體部分的分析說明如下:說明部分的分析由于PL/0語言允許過程調(diào)用語句,且允許過程嵌套定義。因此每個(gè)過程應(yīng)有過程首部以定義局部于它自己過程的常量、變量和過程標(biāo)識(shí)符,也稱局部量。每個(gè)過程所定義的局部量只能供它自己和它自己定義的內(nèi)過程引用。對(duì)于同一層并列過程的調(diào)用關(guān)系是先定義的可以被后定義的引用,反之則不行。說明部分的處理任務(wù)就是對(duì)每個(gè)過程的說明對(duì)象造名字表,填寫所在層次、標(biāo)識(shí)符的屬性和分配的相對(duì)位置等。標(biāo)識(shí)符的屬性不同時(shí),所需要填寫的信息也有所不同。登錄信息是調(diào)用 ENTER過程完成的。說明部分的處理對(duì)主程序看成是第 0層過程,主程序定義的過程為第 1層,隨著嵌套的深度增加而層次數(shù)加大。PL/0允許最大層次為 3。所造名字表放在全程量一維數(shù)組 TABLE表中。TX為索引表的指針,表中的每個(gè)元素為記錄型數(shù)據(jù)。LEV給出層次,DX給出每層局部量當(dāng)前已分配到的相對(duì)位置,可稱地址指示器,每說明完一個(gè)變量后DX指示器加1。PL/0編譯程序文本中對(duì)名字表定義有:說明類型的定義:typeobject=(constant,variable,procedur)標(biāo)準(zhǔn)文檔實(shí)用文案(定義為純量/枚舉類型)名字表的定義:table:array[0..txmax]ofrecordname:alfa;casekind:objectofconstant:(val:integer);variable:procedur:(level,adr,size:integer);end;例如:一個(gè)過程的說明部分為:CONSTA=35,B=49 ;VARC,D,E;PROCEDUREP;VARG,...對(duì)常量,變量和過程說明分析后,在 TABLE表中的信息如表2.2所示。在說明處理后TABLE表中的信息對(duì)于過程名的 ADR域,是在過程體的目標(biāo)代碼生成后再反填過程體的入口地址。例中在處理 P過程的說明時(shí)對(duì) LEV就增加1。在P過程中的變量名的層次為 LEV+1后的值。對(duì)過程還有一項(xiàng)數(shù)據(jù) SIZE,是記錄該過程體運(yùn)行時(shí)所需的數(shù)據(jù)空間。 至于在造表和查表的過程中,如何保證每個(gè)過程的局部量不被它的外層引用,請(qǐng)讀者閱讀完 PL/0編譯程序后自己總結(jié)。過程體的分析程序的主體是由語句構(gòu)成的。處理完過程的說明后就處理由語句組成的過程體,從語法上要對(duì)語句逐句分析。當(dāng)語法正確時(shí)就生成相應(yīng)語句功能的目標(biāo)代碼。 當(dāng)遇到標(biāo)識(shí)符的引用時(shí)就調(diào)用 POSITION函標(biāo)準(zhǔn)文檔實(shí)用文案數(shù)查TABLE表,看是否有過正確的定義,若已有,則從表中取相應(yīng)的有關(guān)信息,供代碼的生成用。若無定義則出錯(cuò)。PL/0編譯程序的目標(biāo)代碼結(jié)構(gòu)和代碼生成編譯程序的目標(biāo)代碼是在分析程序體時(shí)生成的,在處理說明部分時(shí)并不生成目標(biāo)代碼,而當(dāng)分析程序體中的每個(gè)語句時(shí),當(dāng)語法正確則調(diào)用目標(biāo)代碼生成過程以生成與 PL/0語句等價(jià)功能的目標(biāo)代碼,直到編譯正常結(jié)束。PL/0語言的代碼生成是由過程 GEN完成的。GEN過程有三個(gè)參數(shù),分別代表目標(biāo)代碼的功能碼、層差和位移量(對(duì)不同的指令含意不同)。生成的代碼順序放在數(shù)組 CODE中。CODE為一維數(shù)組,數(shù)組元素為記錄型數(shù)據(jù)。每一個(gè)記錄就是一條目標(biāo)指令。 CX為指令的指針,由 0開始順序增加。實(shí)際上目標(biāo)代碼的順序是內(nèi)層過程的排在前邊,主程序的目標(biāo)代碼在最后。下面我們給出一個(gè) PL/0源程序和對(duì)應(yīng)的目標(biāo)程序的清單。PL/0編譯程序的目標(biāo)代碼生成是由 GEN過程完成的 ,當(dāng)語法分析正確則調(diào)用目標(biāo)代碼生成過程以生成與PL/0語句等價(jià)功能的目標(biāo)代碼,直到編譯正常結(jié)束。除了過程說明部分外,變量和常量的說明都不產(chǎn)生目標(biāo)代碼。在block入口處生成一條(jmp,0,0)指令,作為過程體入口指令,該指令的第3區(qū)域的'0'需分析到過程體入口時(shí)才返填。目標(biāo)代碼生成時(shí)所用到的變量地址和層差等信息是由名字表 table提供的,而名字表的信息是在說明時(shí)填寫的。在代碼生成時(shí)查名字表,這就是表格管理的作用。這些信息之間的連接關(guān)系學(xué)員必須弄清。下面對(duì)一些重要程序段給予扼要的解釋。( gen過程的實(shí)現(xiàn)很簡(jiǎn)單不再解釋)對(duì)分程序體人口的處理(見程序文本 block 的過程體)begin(*block*)dx:=3;tx0:=tx; (*保留當(dāng)前table表指針值,實(shí)際為過程名在 table表中的位置*)標(biāo)準(zhǔn)文檔實(shí)用文案table[tx].adr:=cx; (*保留當(dāng)前code指針值到過程名的 adr域*)gen(jmp,0,0);(*生成轉(zhuǎn)向過程體入口的指令,該指令的地址為 cx已保留在過程名的 adr域,真正的過程體入口地址,等生成過程體入口的指令時(shí),再由 table[tx].adr 中取出 cx將過程體入口返填到 cx所指目標(biāo)代碼,即:(jmp,0,0)的第3區(qū)域,同時(shí)填到table[tx].adr 中*)程體入口時(shí)的處理code[table[tx0].adr].a:=cx; (cx為過程入口地址,填寫在 code中)withtable[tx0]dobeginadr:=cx; (過程的入口填寫在 table表的過程名中)size:=dx; (過程需要的空間填寫在 table中)end;cxo:=cx; (保留過程在code中的入口地址在輸出目標(biāo)代碼時(shí)用)gen(int,0,dx); (生成過程入口指令)請(qǐng)?zhí)貏e注意dx、tx、cx的作用和如何處理信息之間的連接關(guān)系。PL/0編譯程序的語法錯(cuò)誤處理編寫一個(gè)程序,往往難于一次成功,常常會(huì)出現(xiàn)各種類型的錯(cuò)誤。 一般有語法錯(cuò)、語義錯(cuò)及運(yùn)行錯(cuò)。出錯(cuò)的原因是多方面的,這就給錯(cuò)誤處理帶來不少困難。就語法錯(cuò)來說,任何一個(gè)編譯程序在進(jìn)行語法分析遇到錯(cuò)誤時(shí),總不會(huì)就此停止工作,而是希望能準(zhǔn)確地指出出錯(cuò)位置和錯(cuò)誤性質(zhì)并盡可能進(jìn)行校正,以便使編譯程序能繼續(xù)工作。但對(duì)所有的錯(cuò)誤都做到這樣的要求是很困難的,主要困難在校正上,因?yàn)榫幾g程序不能完全確定程序人員的意圖。例如在一個(gè)表達(dá)式中,圓括號(hào)不配對(duì)時(shí),就不能確定應(yīng)補(bǔ)在何標(biāo)準(zhǔn)文檔實(shí)用文案處。有時(shí)由于校正得不對(duì)反而會(huì)影響到后邊,導(dǎo)致出現(xiàn)誤判錯(cuò)誤的情況。因此編譯程序只能采取一些措施,對(duì)源程序中的錯(cuò)誤盡量查出,加以修改,以便提高調(diào)試速度。PL/0編譯程序?qū)φZ法錯(cuò)誤的處理采用兩種辦法:對(duì)于一些易于校正的錯(cuò)誤,如丟了逗號(hào)、分號(hào)等,則指出出錯(cuò)位置,并加以校正。校正的方式就是補(bǔ)上逗號(hào)或分號(hào)。對(duì)某些錯(cuò)誤編譯程序難于確定校正的措施,為了使當(dāng)前的錯(cuò)誤不致影響整個(gè)程序的崩潰,把錯(cuò)誤盡量局限在一個(gè)局部的語法單位中。這樣就需跳過一些后面輸入的單詞符號(hào),直到讀入一個(gè)能使編譯程序恢復(fù)正常語法分析工作的單詞為止。具體做法是:當(dāng)語法分析進(jìn)入以某些關(guān)鍵字(保留字)或終結(jié)符集合為開始符的語法單元時(shí),通常在它的入口和出口處,調(diào)用一個(gè)測(cè)試程序 TEST(見圖2.9)。例如:語句的開始符是 begin,if,while,call,read,write;說明的開始符是var,const,procedure ;因子的開始符是"(",ident,number。當(dāng)語法分析進(jìn)入這樣的語法單元前,可用測(cè)試程序檢查當(dāng)前單詞符號(hào)是否屬于它們開始符號(hào)的集合,若不是則出錯(cuò)。請(qǐng)讀者對(duì)照?qǐng)D 2.1各語法描述圖直觀地找出每個(gè)非終結(jié)符語法單元的開始符號(hào)集合,與表 2.3進(jìn)行比較,驗(yàn)證對(duì)開始符號(hào)集合理解的正確性。對(duì)于一個(gè)文法符號(hào)的開始符號(hào)集合的形式定義將在第 5章詳細(xì)介紹?,F(xiàn)給出 PL/0文法部分非終結(jié)符語法單元的開始符號(hào)和后繼符號(hào)的集合。另外由于PL/0編譯程序采用自頂向下的分析方法,一個(gè)語法單元分析程序調(diào)用別的語法單元的分析程序時(shí),以參數(shù)形式(文本中以FSYS定義為單詞符號(hào)集合作為形參 )給出被調(diào)用的語法分析程序出口時(shí)合法的后繼單詞符號(hào)集合(如表2.3所給出),在出口處也調(diào)用測(cè)試程序。若當(dāng)前單詞符號(hào)是屬于所給集合,則語法分析正常進(jìn)行,否則出錯(cuò)。單詞符號(hào)集合 FSYS參數(shù)是可傳遞的,隨著調(diào)用語法分析程序?qū)哟蔚纳钊耄現(xiàn)SYS的集合逐步補(bǔ)充合法單詞符。非終結(jié)符(S) FIRST(S) FOLLOW(S)程序體 constvarprocedureident .;標(biāo)準(zhǔn)文檔實(shí)用文案callifbeginwhile語句identcallbeginifwhile.;end條件odd+-(identnumberthendo表達(dá)式+-(identnumber.;)Rendthendo項(xiàng)identnumber(.;)R+-endthendo因子identnumber(.;)R+-*/endthendo注:表2.3中'R'表示關(guān)系運(yùn)算符集合,如=,#,<,<=,>,>=。在進(jìn)入某個(gè)語法單位時(shí),調(diào)用TEST,檢查當(dāng)前符號(hào)是否屬于該語法單位的開始符號(hào)集合。 若不屬于,則濾去開始符號(hào)和后繼符號(hào)集合外的所有符號(hào)。在語法單位分析結(jié)束時(shí),調(diào)用TEST,檢查當(dāng)前符號(hào)是否屬于調(diào)用該語法單位時(shí)應(yīng)有的后繼符號(hào)集合。若不屬于,則濾去后繼符號(hào)和開始符號(hào)集合外的所有符號(hào)。TEST測(cè)試過程有三個(gè)參數(shù),它們的含意是:S1:當(dāng)語法分析進(jìn)入或退出某一語法單元時(shí)當(dāng)前單詞符號(hào)應(yīng)屬于的集合,它可能是一個(gè)語法單元開始符號(hào)的集合或后繼符號(hào)的集合。②S2:在某一出錯(cuò)狀態(tài)時(shí),可恢復(fù)語法分析繼續(xù)正常工作的補(bǔ)充單詞符號(hào)集合。因?yàn)楫?dāng)語法分析出錯(cuò)時(shí),即當(dāng)前單詞符號(hào)不在S1集合中,為了繼續(xù)編譯,需跳過后邊輸入的一些單詞符號(hào),直到當(dāng)前輸入的單詞符號(hào)是屬于S1或S2集合的元素。③n:整型數(shù),出錯(cuò)信息編號(hào)。為了進(jìn)一步明確S1,S2集合的含意,現(xiàn)以因子(FACTOR)的語法分析程序?yàn)槔?,在過程FACTOR的入口處調(diào)用了一次TEST過程,它的實(shí)參S1是因子開始符號(hào)的集合(文本中的FACBEGSYS)。S2是每個(gè)過程的形參FSYS調(diào)用時(shí)實(shí)參的傳遞值。當(dāng)編譯程序第一次調(diào)用BLOCK時(shí),F(xiàn)SYS實(shí)參為[·]與說明開始符和語句開始符集合的和。 以后隨著調(diào)用語法分析程序?qū)哟蔚纳钊胫鸩皆鰳?biāo)準(zhǔn)文檔實(shí)用文案加。如調(diào)用語句時(shí)增加了 [;]和[endsym],在表達(dá)式語法分析中調(diào)用項(xiàng)時(shí)又增加了 [+]和[-],而在項(xiàng)中調(diào)用因子時(shí)又增加了[*]和[/],這樣在進(jìn)入因子分析程序時(shí)即使當(dāng)前符號(hào)不是因子開始符,出錯(cuò)后只要跳過一定的符號(hào),遇到當(dāng)時(shí)輸入的單詞符號(hào)在 FSYS中或在因子開始符號(hào)集合中,均可繼續(xù)正常進(jìn)行語法分析。而在因子過程的出口處也調(diào)用了測(cè)試程序,不過這時(shí) S1和S2實(shí)參恰恰相反。說明當(dāng)時(shí)的 FSYS集合的單詞符號(hào)都是因子正常出口時(shí)允許的單詞符號(hào),而因子的開始符號(hào)為可恢復(fù)正常語法分析的補(bǔ)充單詞符號(hào)。從PL/0編譯程序文本中因子過程的處理片段說明上述問題。(1)PL/0編譯程序文本中給出關(guān)于某些語法單位開始符號(hào)集合的定義為:symset=setofsymbol; (見PL/0文本類型說明部分)declbegsys,statbegsys,facbegsys:symset;declbegsys:=[constsym,varsym,procsym]; (見PL/0文本主程序置初值部分)statbegsys:=[beginsym,callsym,ifsym,whilesym,readsym,writesym];facbegsys:=[ident,number,lparen];(2)后繼符號(hào)集合 fsys作為參數(shù)傳遞(見 PL/0文本相應(yīng)過程的說明部分)proceduretest(s1,s2:symset;n:integer);procedureblock(lev,tx:integer;fsys:symset);procedurestatement(fsys:symset);procedureexpression(fsys:symset);procedureterm(fsys:symset);procedurefactor(fsys:symset);(3)因子過程的處理片段test過程有三個(gè)參數(shù):標(biāo)準(zhǔn)文檔實(shí)用文案可允許的下一個(gè)符號(hào)集合 S1,如果當(dāng)前符號(hào)不在此集合中,當(dāng)即得到一個(gè)錯(cuò)誤號(hào);另加的停止符號(hào)集合 S2,有些符號(hào)的出現(xiàn),雖然無疑是錯(cuò)的,但它們絕對(duì)不應(yīng)被忽略而跳過;整數(shù)n,表示有關(guān)錯(cuò)誤的診斷號(hào):voidtest(symsets1,symsets2,intn){symsets;if(!inset(sym,s1)){error(n);s=uniteset(s1,s2);while(!inset(sym,s))getsym();destroyset(s);}}(4)由于后繼符號(hào)集合 fsys作為參數(shù)傳遞,隨著調(diào)用語法分析程序?qū)哟蔚纳钊牒罄^符號(hào)集合逐步增加,但對(duì)調(diào)用同一個(gè)過程所需增加的后跟符與調(diào)用位置有關(guān)。例如: 在write語句和factor 中調(diào)用expression(fsys); 所增加的后繼符號(hào)不完全相同?!rite語句的語法:<寫語句>∷=write(<exp>{,<exp>});處理在( )內(nèi)調(diào)用expression 時(shí)在fsys中應(yīng)增加 rparen,comma 。標(biāo)準(zhǔn)文檔實(shí)用文案expression([rparen,comma]+fsys);·factor 的語法:<因子>∷=...|'('exp')在處理( )內(nèi)調(diào)用expression 時(shí)在fsys中應(yīng)增加rparen。expression([rparen]+fsys);然而PL/0編譯程序?qū)y(cè)試程序 TEST的調(diào)用有一定的靈活性。對(duì)語義錯(cuò)誤,如標(biāo)識(shí)符未加說明就引用,或雖經(jīng)說明,但引用與說明的屬性不一致。這時(shí)只給出錯(cuò)誤信息和出錯(cuò)位置,編譯工作可繼續(xù)進(jìn)行。而對(duì)運(yùn)行錯(cuò),如溢出,越界等,只能在運(yùn)行時(shí)發(fā)現(xiàn),由于 PL/0編譯程序的功能限制無法指出運(yùn)行錯(cuò)在源程序中的錯(cuò)誤位置。出錯(cuò)編號(hào)出錯(cuò)原因1:常數(shù)說明中的"="寫成"∶="。2:常數(shù)說明中的"="后應(yīng)是數(shù)字。3:常數(shù)說明中的標(biāo)識(shí)符后應(yīng)是"="。4:const,var,procedure后應(yīng)為標(biāo)識(shí)符。5:漏掉了','或';'。6:過程說明后的符號(hào)不正確(應(yīng)是語句開始符,或過程定義符)。7:應(yīng)是語句開始符。8:程序體內(nèi)語句部分的后跟符不正確。9:程序結(jié)尾丟了句號(hào)'.'。10:語句之間漏了';'。11:標(biāo)識(shí)符未說明。12:賦值語句中,賦值號(hào)左部標(biāo)識(shí)符屬性應(yīng)是變量。13:賦值語句左部標(biāo)識(shí)符后應(yīng)是賦值號(hào)'∶='。標(biāo)準(zhǔn)文檔實(shí)用文案14:call后應(yīng)為標(biāo)識(shí)符。15:call后標(biāo)識(shí)符屬性應(yīng)為過程。16:條件語句中丟了'then'。17:丟了'end"或';'。18:while型循環(huán)語句中丟了'do'。19:語句后的符號(hào)不正確。20:應(yīng)為關(guān)系運(yùn)算符。21:表達(dá)式內(nèi)標(biāo)識(shí)符屬性不能是過程。22:表達(dá)式中漏掉右括號(hào)')'。23:因子后的非法符號(hào)。24:表達(dá)式的開始符不能是此符號(hào)。31:數(shù)越界。32:read語句括號(hào)中的標(biāo)識(shí)符不是變量。PL/0編譯程序的目標(biāo)代碼解釋執(zhí)行時(shí)的存儲(chǔ)分配當(dāng)源程序經(jīng)過語法分析,如果未發(fā)現(xiàn)錯(cuò)誤時(shí),由編譯程序調(diào)用解釋程序,對(duì)存放在 CODE中的目標(biāo)代碼CODE[0]開始進(jìn)行解釋執(zhí)行。當(dāng)編譯結(jié)束后,記錄源程序中標(biāo)識(shí)符的 TABLE表已沒有作用。因?yàn)橛?jì)算每個(gè)變量在運(yùn)行棧中相對(duì)本過程基地址的偏移量 dx的值,放在table表中的adr域,生成目標(biāo)代碼時(shí)再從 adr域中取出基地址的偏移量 ,放在code中的a域。因此數(shù)據(jù)空間只需以數(shù)組 CODE存放的只讀目標(biāo)程序和運(yùn)行時(shí)的數(shù)據(jù)棧 S。S是由解釋程序定義的一維整型數(shù)組。由于 PL/0語言的目標(biāo)程序是一種假想的棧式計(jì)算機(jī)的匯編語言,仍用 PASCAL語言解釋執(zhí)行。解釋執(zhí)行時(shí)的數(shù)據(jù)空間 S為棧式計(jì)算機(jī)的存儲(chǔ)空間。遵循后進(jìn)先出規(guī)則,對(duì)每個(gè)過程(包括主程序)當(dāng)被調(diào)用時(shí),才分配數(shù)據(jù)空間,退出過程時(shí),則所分配的數(shù)據(jù)空間被釋放。標(biāo)準(zhǔn)文檔實(shí)用文案解釋程序還定義了 4個(gè)寄存器。I:指令寄存器。存放著當(dāng)前正在解釋的一條目標(biāo)指令。(2)P:程序地址寄存器。指向下一條要執(zhí)行的目標(biāo)程序的地址(相當(dāng)目標(biāo)程序CODE數(shù)組的下標(biāo))。(3)T:棧頂寄存器。由于每個(gè)過程當(dāng)它被運(yùn)行時(shí),給它分配的數(shù)據(jù)空間(下邊稱數(shù)據(jù)段)可分成兩部分。靜態(tài)部分:包括變量存放區(qū)和三個(gè)聯(lián)系單元 (聯(lián)系單元的作用見后)。動(dòng)態(tài)部分:作為臨時(shí)工作單元和累加器用。需要時(shí)隨時(shí)分配,用完后立即釋放。棧頂寄存器 T指出了當(dāng)前棧中最新分配的單元 (T也是數(shù)組S的下標(biāo))。(4)B:基址寄存器。指向每個(gè)過程被調(diào)用時(shí),在數(shù)據(jù)區(qū) S中給它分配的數(shù)據(jù)段起始地址,也稱基地址。為了實(shí)現(xiàn)對(duì)每個(gè)過程調(diào)用時(shí)給它分配數(shù)據(jù)段,也就是對(duì)即將運(yùn)行的過程所需數(shù)據(jù)段進(jìn)棧;過程運(yùn)行結(jié)束后釋放數(shù)據(jù)段,即該數(shù)據(jù)段退棧;以及嵌套過程之間對(duì)標(biāo)識(shí)符引用的尋址問題。 每個(gè)過程被調(diào)用時(shí),在棧頂分配三個(gè)聯(lián)系單元,這三個(gè)單元存放的內(nèi)容分別為:SL:靜態(tài)鏈:它是指向定義該過程的直接外過程(或主程序)運(yùn)行時(shí)最新數(shù)據(jù)段的基地址。DL:動(dòng)態(tài)鏈:它是指向調(diào)用該過程時(shí)正在運(yùn)行過程的數(shù)據(jù)段基地址。(3)RA:返回地址:記錄調(diào)用該過程時(shí)目標(biāo)程序的斷點(diǎn),即當(dāng)時(shí)的程序地址寄存器 P的值。也就是調(diào)用過程指令的下一條指令的地址。具體的過程調(diào)用和結(jié)束,對(duì)上述寄存器及三個(gè)聯(lián)系單元的填寫和恢復(fù)由下列目標(biāo)指令完成。(1)INT0A每個(gè)過程目標(biāo)程序的入口都有這樣一條指令,用以完成開辟數(shù)據(jù)段的工作。 A域的值指出數(shù)據(jù)段的大小,即為局部變量個(gè)數(shù) +3(聯(lián)系單元個(gè)數(shù)為3)。由編譯程序的代碼生成給出。開辟數(shù)據(jù)段的結(jié)果是改變棧頂寄存器 T的值,即T∶=T+A;。標(biāo)準(zhǔn)文檔實(shí)用文案(2)OPR00是每個(gè)過程出口處的一條目標(biāo)指令。用以完成該過程運(yùn)行結(jié)束后釋放數(shù)據(jù)段的工作,即退棧工作。恢復(fù)調(diào)用該過程前正在運(yùn)行的過程 (或主程序)的數(shù)據(jù)段基地址寄存器的值,和棧頂寄存器 T的值,并將返回地址送到指令地址寄存器 P中,以使調(diào)用前的程序從斷點(diǎn)開始繼續(xù)執(zhí)行。CALLA;為調(diào)用過程的目標(biāo)指令,其中L:為層次差,它是尋找靜態(tài)鏈的依據(jù)。在解釋程序中由 BASE(L)函數(shù)來計(jì)算,L為參數(shù),實(shí)參為所給層差。A:為被調(diào)用過程的目標(biāo)程序入口。CAL指令還完成填寫靜態(tài)鏈、動(dòng)態(tài)鏈、返回地址,給出被調(diào)用過程的基地址值,送入基址寄存器 B中,目標(biāo)程序的入口地址 A的值送指令地址寄存器 P中,使指令從A開始執(zhí)行。由于PL/0編譯程序是用PASCAL語言編寫的(若文件名為PL0.PAS),所以要對(duì)PL/0語言的源程序進(jìn)行編譯,如在PC機(jī)上,首先必須對(duì) PL0.PAS進(jìn)行編譯、匯編、連接得到 PL0.EXE文件。運(yùn)行PL0.EXE文件才是啟動(dòng) PL/0的編譯程序。因此執(zhí)行命令。RUNPL0<回車>啟動(dòng)PL/0編譯程序,輸出一些詢問信息,需用戶回答。輸出信息 回答信息INPUTFILE? PL/0源程序文件名<回車>LISTOBJECTCODE? Y或N<回車>目標(biāo)程序輸出的次序是,最內(nèi)層的過程體在最前邊,主程序體在最后。源程序清單中的序號(hào),是該語句在目標(biāo)程序中對(duì)應(yīng)的起始位置。但需指出例題中序號(hào)為0,1指令的內(nèi)容為:0jmp088為主程序入口1jmp022為過程P的入口標(biāo)準(zhǔn)文檔實(shí)用文案三、實(shí)驗(yàn)結(jié)果:測(cè)試

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論