PL0-編譯程序講解課件_第1頁
PL0-編譯程序講解課件_第2頁
PL0-編譯程序講解課件_第3頁
PL0-編譯程序講解課件_第4頁
PL0-編譯程序講解課件_第5頁
已閱讀5頁,還剩55頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第二章PL/0編譯程序的實(shí)現(xiàn)本章以PL/0編譯程序?yàn)閷?shí)例,使大家對編譯程序的實(shí)現(xiàn)建立起整體概念,對編譯程序的構(gòu)造得到一些感性認(rèn)識(shí)和初步了解?!?PL/0語言§2PL/0處理機(jī)—假想棧式機(jī)§3PL/0編譯程序§4符號表的一般形式討論§5棧式存儲(chǔ)管理的再討論第二章PL/0編譯程序的實(shí)現(xiàn)本章以PL/0編譯程序?yàn)閷?shí)例,1§1PL/0語言PL/0功能簡單、結(jié)構(gòu)清晰、可讀性強(qiáng),而又具備了一般高級語言的必備部分,因而其編譯程序能充分體現(xiàn)一個(gè)高級語言編譯程序的基本技術(shù)和步驟。PL/0語言:PASCAL語言的子集,用于教學(xué)PL/0程序示例PL/0的語法描述圖PL/0語言的EBNF表示§1PL/0語言PL/0功能簡單、結(jié)構(gòu)清晰、可讀性強(qiáng),而2

PL/0語言是PASCAL語言的子集過程可嵌套定義,內(nèi)層可引用包圍它的外層定義的標(biāo)識(shí)符,可遞歸調(diào)用數(shù)據(jù)類型,只有整型數(shù)據(jù)結(jié)構(gòu),只有簡變和常數(shù)標(biāo)識(shí)符的有效長度是10語句種類:

begin/end、if、while、賦值、read/write、call、const、var、procedure過程無參,最多可嵌套三層13個(gè)保留字:if、then、while、do、read、write、call、begin、end、const、var、procedure、odd+、-、*、/、=、<>、<、<=、>、>=、(、)PL/0語言是PASCAL語言的子集過程可嵌套定義,內(nèi)層可3

PL/0程序示例

CONSTA=10;(*常量說明部分*)

VARB,C;(*變量說明部分*)PROCEDUREP;(*過程說明部分*)VARD;(*P的局部變量說明部分*)PROCEDUREQ;(*P的局部過程說明部分*)VARX;

BEGIN

READ(X);D:=X;IFX#0DOCALLP;

END;

BEGIN

CALLQ;WRITE(D);

END;

BEGINCALLP;END.PL/0程序示例CONSTA=10;4遞歸計(jì)算sum=1!+2!+...+n!varn,m,fact,sum;{遞規(guī)計(jì)算fact=m!}procedurefactorial;beginifm>0thenbeginfact:=fact*m;m:=m-1;callfactorial;end;end;begin{讀入n}read(n);sum:=0;whilen>0dobeginm:=n;fact:=1;callfactorial;sum:=sum+fact;n:=n-1;end;{輸出n!}write(sum);end.遞歸計(jì)算sum=1!+2!+...+n!5constidentnumber=,;varident,;;procedureident;分程序語句分程序程序分程序.語法圖constidentnumber=,;varident,;;6identreadend;語句表達(dá)式:=begin語句語句)(ident,identreadend;語句表達(dá)式:=begin語句語句)7PL/0語言的EBNF表示BNF(BACKUS-NAURFORM)與EBNF的介紹

BNF是根據(jù)美國的JohnW.Backus與丹麥的PeterNaur來命名的,它是從語法上描述程序設(shè)計(jì)語言的元語言。采用BNF就可說明哪些符號序列是對于某給定語言在語法上有效的程序。構(gòu)成EBNF的元素:非終結(jié)符,終結(jié)符,開始符,規(guī)則EBNF的元符號:

<>用左右尖括號括起來的內(nèi)容為非終結(jié)符

∷=或→讀做‘定義為’,→的左部由右部定義|讀做‘或’表示右部候選內(nèi)容{}表示花括號內(nèi)的內(nèi)容可重復(fù)任意次或限定次數(shù)

[]表示方括號內(nèi)的內(nèi)容為任選項(xiàng)

()表示圓括號內(nèi)的內(nèi)容優(yōu)先PL/0語言的EBNF表示BNF(BACKUS-NAURF8PL/0語言文法的EBNF表示〈程序〉->〈分程序〉.

〈分程序〉->[<常量說明部分>][<變量說明部分>][<過程說明部分>]<語句>〈常量說明部分〉->CONST〈常量定義部分〉{,〈常量定義〉};

〈無符號整數(shù)〉->〈數(shù)字〉{〈數(shù)字〉}

〈變量說明部分〉->VAR〈標(biāo)識(shí)符〉{,〈標(biāo)識(shí)符〉};

〈標(biāo)識(shí)符〉->〈字母〉{〈字母〉|〈數(shù)字〉}

……<表達(dá)式〉∷=[+|-]〈項(xiàng)〉{(+|-)〈項(xiàng)〉}

〈項(xiàng)〉∷=〈因子〉{(*|/)〈因子〉}

〈因子〉∷=〈標(biāo)識(shí)符〉|〈無符號整數(shù)〉|‘(’〈表達(dá)式〉‘)’……PL/0語言文法的EBNF表示〈程序〉->〈分程序〉.

〈分9§2PL/0處理機(jī)—假想棧式機(jī)一、PL/0處理機(jī)簡介目標(biāo)代碼類p-code:一種棧式機(jī)的匯編語言棧式機(jī)系統(tǒng)結(jié)構(gòu):沒有累加器和寄存器,只有存儲(chǔ)棧指針?biāo)羞\(yùn)算都在棧頂(零地址機(jī))兩種存儲(chǔ),一個(gè)指令寄存器和三個(gè)地址寄存器兩種存儲(chǔ)指令寄存器----I,放當(dāng)前正在解釋的指令地址寄存器§2PL/0處理機(jī)—假想棧式機(jī)一、PL/0處理機(jī)簡介兩種10若有執(zhí)行調(diào)用序列:A->B->C->B---先調(diào)用,后結(jié)束B區(qū)A區(qū)B區(qū)C區(qū)BT

二、運(yùn)行時(shí)數(shù)據(jù)的存儲(chǔ)與訪問----棧式存儲(chǔ)假設(shè)A、C同層,且A中嵌套B子程序的調(diào)用、執(zhí)行和返回過程被調(diào)用時(shí),子程序的每次調(diào)用都需在數(shù)據(jù)棧頂為其分配獨(dú)立的數(shù)據(jù)區(qū)子程序返回時(shí),需做兩件事情:一是代碼返回(需記住RA),二是數(shù)據(jù)區(qū)的同步恢復(fù)(DL)子程序運(yùn)行時(shí),要存取外層數(shù)據(jù)區(qū)中的存儲(chǔ)單元當(dāng)前B數(shù)據(jù)區(qū)須記?。悍祷氐刂稲A動(dòng)態(tài)鏈DL—記錄調(diào)用者數(shù)據(jù)區(qū)基地址靜態(tài)鏈SL—記錄定義該過程的直接外層過程數(shù)據(jù)區(qū)的基地址,以便訪問外層數(shù)據(jù)若有執(zhí)行調(diào)用序列:A->B->C->B---先調(diào)用,后結(jié)束11運(yùn)行時(shí)數(shù)據(jù)棧S的變化

varm1,m2,m3;ProcedureA;vara1;procedureB;varb1,b2;procedureC;…

C過程callB;

r1:……

B過程callC;

r2:……

A過程callB;

r3:……主程序CallA;

r4:…運(yùn)行時(shí)數(shù)據(jù)棧S的變化varm1,m2,m3;12三、PL/0機(jī)的指令系統(tǒng)f:功能碼l:層次差(標(biāo)識(shí)符引用層減去定義層)a: 根據(jù)不同的指令有所區(qū)別fla指令格式:所有運(yùn)算對棧頂?shù)膬蓚€(gè)或一個(gè)元素進(jìn)行,并用運(yùn)算結(jié)果代替原來的運(yùn)算對象。三、PL/0機(jī)的指令系統(tǒng)f:功能碼fla13指令功能表指14(0)jmp08轉(zhuǎn)向主程序入口(1)jmp02轉(zhuǎn)向過程p入口(2)

int03為過程p開辟空間(3)lod13(4)lit010(5)opr02(6)sto14(7)opr00退棧并返回調(diào)用點(diǎn)(8)

int05(9)opr016(10)sto03(11)lod03(12)lit00(13)opr09(14)jpc024

條件不滿足轉(zhuǎn)24(15)cal02

(16)lit02(17)lod04(18)opr04(19)opr014(20)opr015換行(21)opr016(22)sto03(23)jmp011(24)opr00SL0DL0RA0變量b變量cRA16SL0DL0運(yùn)行棧consta=10;

varb,c;

procedurep;

begin

c:=b+a;

end;

begin

read(b);

whileb#0do

begin

callp;

write(2*c);

read(b);

end

end.SL:靜態(tài)鏈DL:動(dòng)態(tài)鏈RA:返回地址0演示執(zhí)行過程(0)jmp08轉(zhuǎn)向主程序入口SL0DL15§3PL/0編譯程序的實(shí)現(xiàn)PL/0編譯程序的總體設(shè)計(jì)PL/0編譯程序詞法分析的設(shè)計(jì)與實(shí)現(xiàn)PL/0編譯程序語法分析的設(shè)計(jì)與實(shí)現(xiàn)PL/0編譯程序語義分析的設(shè)計(jì)與實(shí)現(xiàn)PL/0編譯程序語法錯(cuò)誤處理的實(shí)現(xiàn)PL/0編譯程序代碼生成的實(shí)現(xiàn)pcode代碼解釋器的設(shè)計(jì)與實(shí)現(xiàn)§3PL/0編譯程序的實(shí)現(xiàn)PL/0編譯程序的總體設(shè)計(jì)163.1PL/0編譯程序的總體設(shè)計(jì)單趟方式以語法、語義分析程序?yàn)楹诵?,詞法分析程序和代碼生成程序都作為一個(gè)過程,當(dāng)語法分析需要讀單詞時(shí)就調(diào)用詞法分析程序,而當(dāng)語法、語義分析正確,需要生成相應(yīng)的目標(biāo)代碼時(shí),則調(diào)用代碼生成程序。表格管理程序?qū)崿F(xiàn)變量,常量和過程標(biāo)識(shí)符的信息的登錄與查找。出錯(cuò)處理程序,對詞法和語法、語義分析遇到的錯(cuò)誤給出在源程序中出錯(cuò)的位置和與錯(cuò)誤性質(zhì)有關(guān)的編號,并進(jìn)行錯(cuò)誤恢復(fù)。3.1PL/0編譯程序的總體設(shè)計(jì)單趟方式17PL/0編譯程序PL/0編譯程序類p-code解釋程序類p-code代碼PL/0源程序輸入數(shù)據(jù)輸出數(shù)據(jù)PL/0編譯程序的結(jié)構(gòu)框架PL/0編譯程序PL/0編譯程序類p-code解釋程序類18

PL/0編譯程序的結(jié)構(gòu)詞法分析程序語法語義分析程序代碼生成程序表格管理程序出錯(cuò)處理程序PL/0源程序目標(biāo)程序PL/0編譯程序的結(jié)構(gòu)詞法分析程序語法語義分析程序代碼生成19編譯系統(tǒng)總體流程圖PL/0編譯程序語法、語義分析的核心編譯系統(tǒng)總體流程圖PL/0編譯程序語法、語義分析的核心203.2PL/0編譯程序詞法分析的實(shí)現(xiàn)詞法分析函數(shù)getsym()所識(shí)別的單詞:保留字或關(guān)鍵字:如:BEGIN、END、IF、THEN等運(yùn)算符:如:+、-、*、/、:=、#、>=、<=等標(biāo)識(shí)符:用戶定義的變量名、常數(shù)名、過程名常數(shù):如:10、25、100等整數(shù)界符:如:‘,’、‘.’、‘;’、‘(’、‘)’等詞法分析過程:getsym()框圖(P19圖2.5)在編譯程序中,單詞的表示方式:(sym,id/num)3.2PL/0編譯程序詞法分析的實(shí)現(xiàn)詞法分析函數(shù)getsy21enumsymbol{nul,ident,number,plus,…,varsym,procsym};當(dāng)識(shí)別出標(biāo)識(shí)符時(shí)先查保留字表保留字及內(nèi)部表示對應(yīng)表:charword[norw][al];enumsymblewsym[norw];字符對應(yīng)的單詞表:enumsymblessym[256];ssym[‘+’]=plus;ssym[‘-’]=minus;…詞法分析通過三個(gè)全程量

symbolsym;charid[];intnum;將識(shí)別出的單詞信息傳遞給語法分析程序。sym:存放單詞的類別如:initial:=60;中各單詞對應(yīng)的類別為:initialident,‘:=‘becomes,60number,‘;’semicolonid:存放用戶標(biāo)識(shí)符,對initial(sym<-ident,id<-initial)num:存放用戶定義的數(shù)對60(sym<-number,num<-60)enumsymbol{nul,ident,number,22用狀態(tài)轉(zhuǎn)換圖實(shí)現(xiàn)詞法分析程序的設(shè)計(jì)方法狀態(tài),對應(yīng)每個(gè)狀態(tài)編一段程序,每個(gè)狀態(tài)調(diào)用取字符程序,根據(jù)當(dāng)前字符轉(zhuǎn)到不同的狀態(tài),并做相應(yīng)操作。表示終態(tài),已識(shí)別出一個(gè)單詞用狀態(tài)轉(zhuǎn)換圖實(shí)現(xiàn)詞法分析程序的設(shè)計(jì)方法狀態(tài),對應(yīng)每個(gè)狀態(tài)編一233.3PL/0編譯程序語法分析語法分析的設(shè)計(jì)與實(shí)現(xiàn)自頂向下的語法分析遞歸子程序法(遞歸下降分析器recursive-descentparser):對應(yīng)每個(gè)非終結(jié)符(語法成分),編一個(gè)獨(dú)立的處理子程序。由<程序>開始,按規(guī)則右部(語法描述圖箭頭方向)進(jìn)行分析遇到非終結(jié)符,則調(diào)用相應(yīng)的處理過程遇到終結(jié)符,則判斷當(dāng)前讀入的單詞是否與該終結(jié)符相匹配,若匹配,再讀取下一個(gè)單詞繼續(xù)分析。3.3PL/0編譯程序語法分析語法分析的設(shè)計(jì)與實(shí)現(xiàn)24

程序pl/0分程序block語句statement條件condition表達(dá)式expression項(xiàng)term因子factor語法調(diào)用關(guān)系圖程序pl/0分程序block語句statement條25VARA;BEGINREAD(A)END.

<程序><分程序>.<變量說明部分><語句>VAR<標(biāo)識(shí)符>;<復(fù)合語句>

A

BEGIN<語句>END<讀語句>

READ

(<標(biāo)識(shí)符>)

A<程序>為文法的開始符號,以開始符號作為根結(jié)點(diǎn)存在一棵倒掛著的語法樹。遞歸下降語法分析過程隱含著對對語法樹的前序遍歷VARA;<程序><程序>26〈表達(dá)式〉∷=[+|-]〈項(xiàng)〉{(+|-)〈項(xiàng)〉}intexpression(bool*fsys,int*ptx,intlev){if(sym==plus||sym==minus) {getsymdo; termdo(nxtlev,ptx,lev);//處理項(xiàng) }else {termdo(nxtlev,ptx,lev);}//處理項(xiàng)while(sym==plus||sym==minus) {getsymdo; termdo(nxtlev,ptx,lev);//處理項(xiàng) }return0;}注意一致性:進(jìn)入每一語法單位處理程序之前,其第一個(gè)單詞已讀出,退出時(shí),應(yīng)讀出下一個(gè)語法單位的第一個(gè)單詞〈表達(dá)式〉∷=[+|-]〈項(xiàng)〉{(+|-)〈項(xiàng)〉}inte27〈項(xiàng)〉∷=〈因子〉{(*|/)〈因子〉}intterm(bool*fsys,int*ptx,intlev){factordo(nxtlev,ptx,lev); /*處理因子*/while(sym==times||sym==slash) {getsymdo; factordo(nxtlev,ptx,lev); } return0;}〈項(xiàng)〉∷=〈因子〉{(*|/)〈因子〉}intterm(b28〈因子〉∷=〈標(biāo)識(shí)符〉|〈無符號整數(shù)〉|‘(’〈表達(dá)式〉‘)’intfactor(bool*fsys,int*ptx,intlev){if(sym==ident) /*因子為常量或變量*/getsymdo;else{if(sym==number)getsymdo; elseif(sym==lparen) /*因子為表達(dá)式*/ {getsymdo;expressiondo(nxtlev,ptx,lev); if(sym==rparen)getsymdo; elseerror(22); /*缺少右括號*/ }}return0;}〈因子〉∷=〈標(biāo)識(shí)符〉|〈無符號整數(shù)〉|‘(’〈表達(dá)式〉‘)293.4PL/0語義分析的設(shè)計(jì)與實(shí)現(xiàn)說明部分的分析與處理表格管理過程體(語句)的分析與處理3.4PL/0語義分析的設(shè)計(jì)與實(shí)現(xiàn)說明部分的分析與處理30

說明部分的分析與處理--登錄符號表對每個(gè)過程(含主程序)說明的對象(變量,常量和過程)造符號表登錄標(biāo)識(shí)符的屬性。標(biāo)識(shí)符的屬性:種類,所在層次,值和分配的相對位置。登錄信息由ENTER過程完成。符號表結(jié)構(gòu)enumobject{constant,variable,procedur};structtablestruct{charname[al];enumobjectkind;intval,level,adr,size;}table[txmax];

說明部分的分析與處理--登錄符號表對每個(gè)過程(含主程序)說31consta=35;//常量無層次vara1,a2,a3;ProcedureP;varb1,b2;procedureP1;varc;……procedureP2;vard;………………注意:在單趟編譯中,對于并列的函數(shù)(或分程序),其相應(yīng)的符號表不會(huì)同時(shí)存在。過程P2在code的入口

(0)jmp00

CX(1)jmp00(2)jmp00……(k)jmp00

名字類值層次地址大小consta=35;//常量無層次注意:在單趟編譯中,對于32<變量說明部分>::=var<標(biāo)識(shí)符>{,<標(biāo)識(shí)符>};if(sym==varsym)/*收到變量聲明符號,開始處理變量聲明*/{getsymdo;do{vardeclarationdo(&tx,lev,&dx);while(sym==comma)

{getsymdo;vardeclarationdo(&tx,lev,&dx);}if(sym==semicolon)

{getsymdo;}

elseerror(5);}while(sym==ident);

}注意:&tx<變量說明部分>::=var<標(biāo)識(shí)符>{,<標(biāo)識(shí)符>};33變量說明處理intvardeclaration(int*ptx,intlev,int*pdx){if(sym==ident)

{enter(variable,ptx,lev,pdx);//填寫名字表getsymdo;

}

else{error(4);} /*var后應(yīng)是標(biāo)識(shí)符*/return0;}變量說明處理intvardeclaration(int*34過程ENTER的實(shí)現(xiàn)/*在名字表中加入一項(xiàng)**k:名字種類const,varorprocedure*ptx:名字表尾指針*lev:名字所在的層次,以后所有的lev都是這樣*pdx:當(dāng)前應(yīng)分配變量的相對地址,分配后增加1*/voidenter(enumobjectk,int*ptx,intlev,int*pdx){(*ptx)++;strcpy(table[(*ptx)].name,id);/*全局變量id中已存有當(dāng)前名字的名字*/table[(*ptx)].kind=k;過程ENTER的實(shí)現(xiàn)/*在名字表中加入一項(xiàng)35

switch(k)

{caseconstant: /*常量名字*/if(num>amax){error(31); /*數(shù)越界*/num=0;

}table[(*ptx)].val=num;break;

casevariable: /*變量名字*/table[(*ptx)].level=lev;table[(*ptx)].adr=(*pdx);(*pdx)++;break;caseprocedur: /*過程名字*/table[(*ptx)].level=lev;break;}}switch(k)36過程體的處理-變量引用的處理對語句進(jìn)行語法分析語義分析當(dāng)遇到標(biāo)識(shí)符的引用時(shí)就調(diào)用POSITION函數(shù)查TABLE表,看是否有過正確定義,若已有,則從表中取相應(yīng)的有關(guān)信息,供代碼的生成使用。若無定義則錯(cuò)。語義分析TABLE表若已有過正確定義,檢查引用與說明的屬性是否一致,若不一致則錯(cuò)。當(dāng)語法語義正確時(shí),就生成相應(yīng)語句功能的目標(biāo)代碼intposition(char*id){inti;

strcpy(table[0].name,id);

i=tx+1;

while(strcmp(table[--i].name,id)!=0);

returni;}//position思考:在造表和查表過程中,如何保證每個(gè)過程的局部量不被它的外層引用?過程體的處理-變量引用的處理對語句進(jìn)行語法分析intpos37賦值語句的處理if(sym==ident) /*準(zhǔn)備按照賦值語句處理*/{i=position(id,*ptx);if(i==0)error(11); /*變量未找到*/else{if(table[i].kind!=variable)

{error(12); /*賦值語句格式錯(cuò)誤*/

i=0;

}

else{......gendo(sto,lev-table[i].level,table[i].adr);......

}}}賦值語句的處理if(sym==ident) /*準(zhǔn)38〈因子〉∷=〈標(biāo)識(shí)符〉|〈無符號整數(shù)〉|‘(’〈表達(dá)式〉‘)’intfactor(bool*fsys,int*ptx,intlev)//因子的語義分析{if(sym==ident) /*因子為常量或變量*/ {i=position(id,*ptx); /*查找名字*/ if(i==0){error(11); }/*標(biāo)識(shí)符未聲明*/ else{switch(table[i].kind) {caseconstant: /*名字為常量*/ break;casevariable: /*名字為變量*/ break;caseprocedur: /*名字為過程*/ error(21);/*不能為過程名*/ …… 〈因子〉∷=〈標(biāo)識(shí)符〉|〈無符號整數(shù)〉|‘(’〈表達(dá)式〉‘)393.5編譯程序的錯(cuò)誤處理錯(cuò)誤處理的原則:盡可能準(zhǔn)確指出出錯(cuò)位置,錯(cuò)誤性質(zhì),盡可能進(jìn)行校正。PL/0編譯程序?qū)φZ法錯(cuò)誤的處理:

(1)對于易于校正的錯(cuò)誤,如丟了逗號,分號等,指出出錯(cuò)位置,加以校正,繼續(xù)進(jìn)行分析。

(2)對于難于校正的錯(cuò)誤,給出錯(cuò)誤的位置與性質(zhì),跳過后面的一些單詞,直到下一個(gè)可以進(jìn)行正常語法分析的語法單位3.5編譯程序的錯(cuò)誤處理錯(cuò)誤處理的原則:盡可能準(zhǔn)確指出出錯(cuò)40

在進(jìn)入某個(gè)語法單位時(shí),調(diào)用TEST,檢查當(dāng)前符號是否屬于該語法單位的開始符號集合。若不屬于,則濾去開始符號和后跟符號集合外的所有符號。在語法單位分析結(jié)束時(shí),調(diào)用TEST,檢查當(dāng)前符號是否屬于調(diào)用該語法單位時(shí)應(yīng)有的后跟符號集合。若不屬于,則濾去后跟符號和開始符號集合外的所有符號。╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳TESTTEST在進(jìn)入某個(gè)語法單位時(shí),調(diào)用TEST,檢查當(dāng)前符號是否屬于該41開始符號集合

booldeclbegsys[symnum],statbegsys[symnum],facbegsys[symnum];declbegsys:[constsym,varsym,procsym];

statbegsys:[beginsym,callsym,ifsym,whilesym,readsym,writesym];

facbegsys:[ident,number,lparen];后跟符號集合fsys作為參數(shù):inttest(bool*s1,bool*s2,intn);intblock(intlev,inttx,bool*fsys);intstatement(bool*fsys,int*ptx,intlev);intexpression(bool*fsys,int*ptx,intlev);intterm(bool*fsys,int*ptx,intlev);intfactor(bool*fsys,int*ptx,intlev);為symble的元素?cái)?shù)32后跟符號集開始符號集合為symble的元素?cái)?shù)32后跟符號集42TESTSYM在S1中?打印出錯(cuò)編號nS1:=S1+S2SYM在S1中?GETSYM返回YYNNTEST測試過程流程圖TESTSYM在S1中?打印出錯(cuò)編號nS1:=S1+S2SY43因子的處理過程procedurefactor(fsys:symset);vari:integer;begin入口:test(facbegsys,fsys,24);whilesyminfacbegsysdo

beginif...出口:test(fsys,facbegsys,23);endend;Facbegsysy

處理identnumberlparentestntest因子的處理過程procedurefactor(fsys:s44后跟符集是逐步補(bǔ)充的,需補(bǔ)充的內(nèi)容與當(dāng)前所處小環(huán)境有關(guān)。對調(diào)用expression(fsys);由于write語句的語法write(<exp>{,<exp>});所以在write語句中調(diào)用expression時(shí)后跟符為:expression([rparen,comma]+fsys);factor的語法:factor∷=...|‘(’exp’)在factor中調(diào)用expression時(shí)后跟符expression([rparen]+fsys);后跟符集是逐步補(bǔ)充的,需補(bǔ)充的內(nèi)容與當(dāng)前所處小環(huán)境有關(guān)。453.6代碼生成代碼生成是由過程GEN完成。GEN有3個(gè)參數(shù),分別代表目標(biāo)代碼的功能碼,層差和位移量。例如gen(opr,0,16);gen(sto,lev-level,adr)

lev:當(dāng)前處理的過程層次

level:被引用變量或過程所在層次CX:為目標(biāo)代碼code數(shù)組的下標(biāo)指針3.6代碼生成代碼生成是由過程GEN完成。46代碼結(jié)構(gòu)變換,地址回填getsym;condition;ifsym=thensymthengetsymelseerror(16);cx1:=cx;gen(jpc,0,0)statement();code[cx1].a:=cxIfcthens代碼結(jié)構(gòu)變換,地址回填getsym;Ifcthen47intmain(){......

if(-1==block(0,0,nxtlev)){...}......interpret();//調(diào)用解釋執(zhí)行程序......}intblock(intlev,inttx,bool*fsys){……dx=3;tx0=tx;table[tx].adr=cx;gen(jmp,0,0);//生成轉(zhuǎn)向過程體入口的指令……

while(sym==procsym)

{getsymdo();

if(sym==ident)

{enter(procedur,&tx,

lev,

&dx);…}

......

if(-1==block(lev+1,tx,nxtlev))

......

}

......}3.7PL/0分程序的處理子程序--block初值為fsys[period]+declbegsys+statbegsysintmain()3.7PL/0分程序的處理子程序--48下標(biāo)指針cx,tx和變量dx的作用CX:為目標(biāo)代碼code數(shù)組的下標(biāo)指針。實(shí)際上目標(biāo)代碼的順序是內(nèi)層過程的在前邊,主程序的目標(biāo)代碼在最后。tx:table表的下標(biāo)指針,是以值參數(shù)形式使用的。dx:計(jì)算每個(gè)變量在運(yùn)行棧中相對本過程基地址的偏移量,放在table表中的adr域,生成目標(biāo)代碼時(shí)再放在code中的a域。過程體入口時(shí)的處理code[table[tx0].adr].a=cx;//過程入口地址填寫在code中table[tx0].adr=cx;//過程的入口填寫在table中table[tx0].size=dx;//過程占的空間填寫在table中

cx0=cx;//保留過程在code中的入口地址gen(int,0,dx);//生成過程入口指令下標(biāo)指針cx,tx和變量dx的作用過程體入口時(shí)的處理493.8類p-code解釋器目標(biāo)代碼存放在數(shù)組CODE中(程序地址寄存器p)解釋程序定義一個(gè)一維整型數(shù)組S作為運(yùn)行棧棧頂寄存器(指針)t,基址寄存器(指針)b,指令寄存器i(當(dāng)前正在解釋的目標(biāo)指令)3.8類p-code解釋器目標(biāo)代碼存放在數(shù)組CODE中(程50目標(biāo)代碼的解釋執(zhí)行幾條特殊指令在code中的位置和功能INT0A

在過程目標(biāo)程序的入口處,開辟A個(gè)單元的數(shù)據(jù)段。A為局部變量的個(gè)數(shù)+3。OPR00

在過程目標(biāo)程序的出口處,釋放數(shù)據(jù)段(退棧),恢復(fù)調(diào)用該過程前正在運(yùn)行的過程的數(shù)據(jù)段基址寄存器B和棧頂寄存器T的值,并將返回地址送到指令地址寄存器P中。CALLA

調(diào)用過程,填寫靜態(tài)鏈、動(dòng)態(tài)鏈、返回地址,給出被調(diào)用過程的基地址值,送入基址寄存器B中,目標(biāo)程序的入口地址A的值送指令地址寄存器P中,使指令從A開始執(zhí)行目標(biāo)代碼的解釋執(zhí)行幾條特殊指令在code中的位置和功能51interpret三個(gè)寄存器賦初值t:=0;b:=1;p:=0;主程序的SL,DL,RA賦初值s[1]:=0;s[2]=0;s[3]=0;i:=code[p];p:=p+1;P=0?返回解釋執(zhí)行的流程圖執(zhí)行指令iNYinterpret三個(gè)寄存器賦初值主程序的SL,DL,RA賦52幾條特殊指令的解釋執(zhí)行過程出口—opr00RADLSLb..tMtbt=b-1;p=s[t+3];b=s[t+2]Q幾條特殊指令的解釋執(zhí)行過程出口—opr00RAb.t53調(diào)用過程---calla{s[t+1]=base(l,s,b);

填寫靜態(tài)鏈s[t+2]=b;填寫動(dòng)態(tài)鏈s[t+3]=p;填寫返回地址

b=t+1;被調(diào)用過程的基地址

p=a

過程入口地址a送p}//t在int中設(shè)置intbase(intl,int*s,intb){intb1;

b1:=b;//findbaselleveldownwhile(l>0){b1=s[b1];l=l-1;}returnb1;}調(diào)用過程---callaintbase(intl,54§4符號表的一般形式討論1、符號表的作用和內(nèi)容語義檢查的依據(jù);目標(biāo)代碼生成階段地址分配的依據(jù);在編譯中,符號表被頻繁使用,表的組織方式對編譯的效率起著十分重要的作用。符號表中,包括名字、種類、類型、層次、相對地址、存儲(chǔ)類別等名字的屬性信息,以及動(dòng)態(tài)數(shù)組的內(nèi)情向量、記錄結(jié)構(gòu)型的成員信息、函數(shù)及過程的形參等結(jié)構(gòu)信息。2、符號表的組織方式:線性表、散列表、樹結(jié)構(gòu),…符號表的組織方式必須維持源程序中的作用域信息?!?符號表的一般形式討論1、符號表的作用和內(nèi)容55棧符號表:函數(shù)或分程序的嵌套結(jié)構(gòu),使得程序中出現(xiàn)的符號的處理(內(nèi)層可引用外層符號、同名變量內(nèi)層優(yōu)先)與棧的操作相一致。一個(gè)過程結(jié)束時(shí)將釋放相應(yīng)的子符號表---解決作用域檢查問題。3、符號表的操作:創(chuàng)建符號表:在編譯開始時(shí)或進(jìn)入一個(gè)分程序插入表項(xiàng):定義時(shí)(包括變量和形參定義)查詢表項(xiàng):可執(zhí)行語句使用時(shí)修改表項(xiàng):在獲得新的語義值信息時(shí)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論