編譯原理PL專業(yè)課程設計方案報告_第1頁
編譯原理PL專業(yè)課程設計方案報告_第2頁
編譯原理PL專業(yè)課程設計方案報告_第3頁
編譯原理PL專業(yè)課程設計方案報告_第4頁
編譯原理PL專業(yè)課程設計方案報告_第5頁
已閱讀5頁,還剩38頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

課程設計班級:21301學號:姓名:馬瑞澤baidu一.課程設計目標 在分析了解一個教學型編譯程序(如PL/0)基礎上,對其詞法分析程序、語法分析程序和語義處理程序進行部分修改擴充。達成深入了解程序編譯過程基礎原理和基礎實現(xiàn)方法目標。二.課程設計要求1.基礎內(nèi)容(1)擴充賦值運算:+=和-=(2)擴充語句(PascalFOR語句):①FOR<變量>:=<表示式>TO<表示式>DO<語句>②FOR<變量>:=<表示式>DOWNTO<表示式>DO<語句>其中,語句①循環(huán)變量步長為2,語句②循環(huán)變量步長為-2。2.選做內(nèi)容(1)增加運算:++和--。(2)增加類型:①字符類型;②實數(shù)類型。(3)擴充函數(shù):①有返回值和返回語句;②有參數(shù)函數(shù)。(4)增加一維數(shù)組類型(可增加指令)。(5)其它經(jīng)典語言設施。3.本人在課程設計中已實現(xiàn)功效(1)增加單詞:保留字ELSE,F(xiàn)OR,TO,DOWNTO,REPEAT,UNTIL,RETURN運算符+=,-=,++,--(2)修改單詞:不等號#改為<>(3)增加條件語句ELSE子句(4)擴充賦值運算:+=和-=(5)擴充語句 ①FOR<變量>:=<表示式>TO<表示式>DO<語句>②FOR<變量>:=<表示式>DOWNTO<表示式>DO<語句>(6)增加運算:++和--(包含前后++、--運算)(7)增加一維數(shù)組類型其它經(jīng)典語言設施:REPEAT語句UNTIL語句三.課程設計環(huán)境和工具(1)計算機及操作系統(tǒng):PC機,Win7(2)實現(xiàn)工具:VC++6.0,C語言教學型編譯程序:PL/0四.結構設計說明PL/0編譯程序結構圖PL/0編譯程序過程或函數(shù)功效表過程或函數(shù)名簡明功效說明pl0主程序error犯錯處理,打印犯錯位置和錯誤編碼getsym詞法分析,讀取一個單詞getch遺漏空格,讀取一個字符gen生成目標代碼,并送入目標程序區(qū)test測試目前單詞符號是否正當block分程序分析處理過程enter登錄名字表position(函數(shù))查找標識符在名字表中位置constdeclaration常量定義處理vardeclaration變量說明處理listode列出目標代碼清單statement語句處理expression表示式處理term項處理factor因子處理condition條件處理interpret對目標代碼解釋實施程序base(函數(shù))經(jīng)過靜態(tài)鏈求出數(shù)據(jù)區(qū)基地址PL/0編譯程序總體步驟圖調(diào)用解釋過程interpret解釋實施目標實施目標程序開啟置初值調(diào)用解釋過程interpret解釋實施目標實施目標程序開啟置初值詞法分析詞法分析是編譯第一個階段,它關鍵任務是從左向右逐一字符地對源程序進行掃描,產(chǎn)生一個個單詞序列用于語法分析。PL/0詞法分析程序GETSYM功效是為語法分析提供單詞用,是語法分析基礎,把輸入字符串形式源程序分割成一個個單詞符號。經(jīng)過詞法分析程序分析出來單詞,對語言固有單詞只給出類別存放在全程變量SYM中,而對用戶定義單詞(標識符或常數(shù))既給出類別又給值,其類別放在SYM中,值放在全程變量ID或全程變量NUM中,全部單詞種類由編譯程序定義純量類型SYMBOL給出,稱為語法詞匯表。詞法分析器分析過程:調(diào)用GETSYM時,它經(jīng)過GETCH過程從源程序中取得一個字符。假如這個字符是字母,則繼續(xù)獲取字符或數(shù)字,最終能夠拼成一個單詞,查保留字表,假如查到為保留字,則把SYM變量賦成對應保留字類型值;假如沒有查到,則這個單詞應是一個用戶自定義標識符(可能是變量名、常量名或是過程名字),把SYM置為IDENT,把這個單詞存入ID變量。查保留字表時使用了二分法查找以提升效率。假如Getch取得字符是數(shù)字,則繼續(xù)用Getch獲取數(shù)字,并把它們拼成一個整數(shù)或?qū)崝?shù),然后把SYM置為INTEGER,并把拼成數(shù)值放入NUM變量。假如識別出其它正當符號(比如:賦值號、大于號、小于等于號等),則把SYM則成對應類型。假如碰到不正當字符,把SYM置成NUL。詞法分析程序GETSYM將完成下列任務:(1)濾空格(2)識別保留字(3)識別標識符(4)拼數(shù)(5)拼復合詞(6)輸出源程序程序分程序語句條件程序分程序語句條件表示式項因子PL/0語法調(diào)用關系圖PL/0編譯程序語法分析采取了自頂向下遞歸子程序法。語法分析同時也依據(jù)程序語義生成對應三元代碼,并提供了犯錯處理機制。語法分析關鍵由分程序分析過程(BLOCK)、常量定義分析過程(ConstDeclaration)、變量定義分析過程(Vardeclaration)、語句分析過程(Statement)、表示式處理過程(Expression)、項處理過程(Term)、因子處理過程(Factor)和條件處理過程(Condition)組成。這些過程在結構上組成一個嵌套層次結構。除此之外,還有犯錯匯報過程(Error)、代碼生成過程(Gen)、測試單詞正當性及犯錯恢復過程(Test)、登錄名字表過程(Enter)、查詢名字表函數(shù)(Position)和列出類PCODE代碼過程(Listcode)作過語法分析輔助過程。由PL/0語法圖可知:一個完整PL/0程序是由分程序和句號組成。所以,本編譯程序在運行時候,經(jīng)過主程序中調(diào)用分程序處理過程block來分析分程序部分(分程序分析過程中還可能會遞歸調(diào)用block過程),然后,判定最終讀入符號是否為句號。假如是句號且分程序分析中未犯錯,則是一個正當PL/0程序,能夠運行生成代碼,不然就說明源PL/0程序是不正當,輸出犯錯提醒即可。語義分析PL/0語義分析關鍵進行以下檢驗:(1)是否存在標識符先引用未申明情況;(2)是否存在己申明標識符錯誤引用;(3)是否存在通常標識符多重申明。中間代碼生成目標代碼類pcode是一個假想棧式計算機匯編語言。自己添加覆蓋了OPR014 棧頂值輸出至屏幕(字符型)OPR015 棧頂值輸出至屏幕(整數(shù)型)OPR016 棧頂值輸出至屏幕(實數(shù)型)OPR017 屏幕輸出換行OPR018 從命令行讀入一個字符輸入置于棧頂OPR019 從命令行讀入一個整數(shù)輸入置于棧頂OPR020 從命令行讀入一個實數(shù)輸入置于棧頂語法錯誤處理PL/0編譯程序?qū)φZ法錯誤處理采取兩種措施:(1)對于部分易于校正錯誤,如丟了逗號、分號等,指出犯錯位置,加以校正,繼續(xù)進行分析。(2)對于難于校正錯誤,給犯錯誤位置和性質(zhì),跳過后面部分單詞,直到下一個能夠進行正常語法分析語法單位。錯誤類型以下0過程開始部分說明不正確1常數(shù)說明中"="寫成":="2常數(shù)說明中"="后應為整數(shù)或?qū)崝?shù)或字符3常數(shù)說明中標識符后應是"="4const,var,procedure后應為標識符5遺漏了","或";"6過程說明后符號不正確(應該是語句開始符,或過程定義符)7應是語句開始符8程序體內(nèi)語句部分后跟符不正確9程序結尾丟了句號"."10語句間漏了";"11標識符未說明12賦值語句中,賦值號左部標識符屬性應是變量13變量后不能是此符號14call后應為標識符15call后標識符屬性應為過程16條件語句中丟了"then"17丟了"end"或";"18while型循環(huán)語句丟了"do"19語句后符號不正確20應為關系運算符21表示式內(nèi)標識符屬性不能是過程22表示式中遺漏右括號"("23因子后非法符號24表示式開始符不能是此符號31數(shù)越界補充說明了:32read或write語句括號中標識符不是變量33read或write語句缺乏右括號")"34read或write語句缺乏左括號"("35read或write括號里應為變量自己增加了:45++或--后面應為變量46repeat缺乏until47for語句錯誤48for語句缺乏do49類型值不匹配50類型無法轉(zhuǎn)換51只有整數(shù)能++或--52類型不正確TESTTESTSYM在S1中?打印犯錯編號nS1:=S1+S2SYM在S1中?GETSYM返回YYNNTEST測試過程步驟圖設計過程試驗內(nèi)容1.增加單詞:保留字ELSE,F(xiàn)OR,TO,DOWNTO,REPEAT,UNTIL,RETURN運算符+=(PLUSBK),-=(MINUSBK),++(INC),--(DEC)首先要擴展SYMBOL,在此基礎上再進行其它細節(jié)修改。要添加SYMBOL為:typedefenum{NUL,IDENT,NUMBER,PLUS,MINUS,TIMES, SLASH,ODDSYM,EQL,NEQ,LSS,LEQ,GTR,GEQ, LPAREN,RPAREN,COMMA,SEMICOLON,PERIOD, BECOMES,BEGINSYM,ENDSYM,IFSYM,THENSYM, WHILESYM,WRITESYM,READSYM,DOSYM,CALLSYM, CONSTSYM,VARSYM,PROCSYM,PROGSYM,ELSESYM,FORSYM,TOSYM,DOWNTOSYM,REPEATSYM,UNTILSYM,RETURNSYM,PLUSBK,MINUSBK,INC,DEC}SYMBOL;char*SYMOUT[]={"NUL","IDENT","NUMBER","PLUS","MINUS","TIMES", "SLASH","ODDSYM","EQL","NEQ","LSS","LEQ","GTR","GEQ", "LPAREN","RPAREN","COMMA","SEMICOLON","PERIOD", "BECOMES","BEGINSYM","ENDSYM","IFSYM","THENSYM", "WHILESYM","WRITESYM","READSYM","DOSYM","CALLSYM", "CONSTSYM","VARSYM","PROCSYM","PROGSYM","ELSE","FOR","TO","DOWNTO","REPEAT","UNTIL","RETURN","PLUSBK","MINUSBK","INC”"DEC"};其中黑斜體為新加入SYMBOL。再將"ELSE","FOR","TO","DOWNTO",,"REPEAT","UNTIL","RETURN","PLUSBK","MINUSBK","INC","DEC"關鍵字加到KWORD和將對應SYM加到WSYM,按字母次序排列。和修改NEQ后以下void__fastcallTForm1::ButtonRunClick(TObject*Sender){for(CH='';CH<='^';CH++)SSYM[CH]=NUL;strcpy(KWORD[1],"BEGIN");strcpy(KWORD[2],"CALL");strcpy(KWORD[3],"CONST");strcpy(KWORD[4],"DEC");strcpy(KWORD[5],"DO");strcpy(KWORD[6],"DOWHILE");strcpy(KWORD[7],"DOWNTO");strcpy(KWORD[8],"ELSE");strcpy(KWORD[9],"END");strcpy(KWORD[10],"FOR");strcpy(KWORD[11],"IF");strcpy(KWORD[12],"INC");strcpy(KWORD[13],"MINUSBK");strcpy(KWORD[14],"ODD");strcpy(KWORD[15],"PLUSBK");strcpy(KWORD[16],"PROCEDURE");strcpy(KWORD[17],"PROGRAM");strcpy(KWORD[18],"READ");strcpy(KWORD[19],"REPEAT");strcpy(KWORD[20],"RETURN");strcpy(KWORD[21],"THEN");strcpy(KWORD[22],"TO");strcpy(KWORD[23],"VAR");strcpy(KWORD[24],"UNTIL");strcpy(KWORD[25],"WHILE");strcpy(KWORD[26],"WRITE");WSYM[1]=BEGINSYM;WSYM[2]=CALLSYM;WSYM[3]=CONSTSYM;WSYM[4]=DEC;WSYM[5]=DOSYM;WSYM[6]=DOWHILESYM;WSYM[7]=DOWNTOSYMs;WSYM[8]=ELSESYM;WSYM[9]=ENDSYM;WSYM[10]=FORSYM;WSYM[11]=IFSYM;WSYM[12]=INCSYM;WSYM[13]=MINUSBK;WSYM[14]=ODDSYM;WSYM[15]=PLUSBK;WSYM[16]=PROCSYM;WSYM[17]=PROGSYM;WSYM[18]=READSYM;WSYM[19]=REPEATSYM;WSYM[20]=RETURNSYM;WSYM[21]=THENSYM;WSYM[22]=TOSYM;WSYM[23]=VARSYM;WSYM[24]=UNTILSYM;WSYM[25]=WHILESYM;WSYM[26]=WRITESYM;SSYM['+']=PLUS;SSYM['-']=MINUS;SSYM['*']=TIMES;SSYM['/']=SLASH;SSYM['(']=LPAREN;SSYM[')']=RPAREN;SSYM['=']=EQL;SSYM[',']=COMMA;SSYM['.']=PERIOD;SSYM[';']=SEMICOLON;因為關鍵字增加到了26個,所以令constNORW=26;SYMBOL由原來33個值擴展為現(xiàn)在44個值,SYMOUT也由原來33個元素擴展為現(xiàn)在44個元素.我用個SYMMAX來統(tǒng)計SYMBOL值個數(shù),所以,除了Error函數(shù)中可能出現(xiàn)作為參數(shù)“33”不被替換為“44”外,其它“33”均用“SYMMAX2.修改單詞:不等號#改為<>只要修改GetSym()函數(shù)。當編譯器檢測到目前字符為“〈”時,接著檢測下一個字符,假如是“〉”,則使SYM=NEQ。代碼修改以下:if(CH=='<'){GetCh();if(CH=='='){SYM=LEQ;GetCh();}elseif(CH=='>'){SYM=NEQ;GetCh();}//增加<>為不等于號;elseSYM=LSS;}3.增加條件語句ELSE子句該條件語法描述圖以下:語句語句只要在STATEMENT修改以下代碼: caseIFSYM: GetSym(); CONDITION(SymSetUnion(SymSetNew(THENSYM,DOSYM),FSYS),LEV,TX); if(SYM==THENSYM)GetSym(); elseError(16); CX1=CX;GEN(JPC,0,0); STATEMENT(SymSetUnion(SymSetNew(ELSESYM),FSYS),LEV,TX);if(SYM!=ELSESYM)CODE[CX1].A=CX;//假如程序中沒有else語句,實施JPC時跳到此地址else{//添加ELSE語句GetSym();CX2=CX;GEN(JMP,0,0);//跳過else語句CODE[CX1].A=CX;//假如程序中有else語句,實施JPC時跳到此地址STATEMENT(FSYS,LEV,TX);CODE[CX2].A=CX;//實施完then語句后跳出} break;ELSE子句擴充完成。課程設計內(nèi)容1.增加運算符+=,-=,++,--詞法分析在GetSym()中完成INC(++)、PLUSBK(+=)詞法分析,代碼修改以下:elseif(CH=='+'){GetCh();if(CH=='='){//增加+=SYM=PLUSBK;GetCh();}elseif(CH=='+'){//增加++SYM=INC;GetCh();}elseSYM=PLUS;}在GetSym()中完成DEC(--)、MINUSBK(-=)詞法分析,代碼修改以下:elseif(CH=='-'){GetCh();if(CH=='='){//增加-=SYM=MINUSBK;GetCh();}elseif(CH=='-'){//增加--SYM=DEC;GetCh();}elseSYM=MINUS;}b)擴充后++和后--操作存在INC和DEC操作語法圖有以下兩個:依據(jù)以上語法圖,我們只要對語句處理程序和因子處理程序進行修改添加,即可實現(xiàn)增加后INC和后DEC操作,首先對語句處理程序STATEMENT進行以下修改:CaseIDENT: i=POSITION(ID,TX); if(i==0)Error(11); else if(TABLE[i].KIND!=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/ Error(12);i=0; }GetSym(); if(SYM==BECOMES){GetSym();EXPRESSION(FSYS,LEV,TX); if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);}elseif(SYM==INC)//語句中++運算{if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GetSym();}elseif(SYM==DEC)//語句中--運算{if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GEN(LIT,0,1);GEN(OPR,0,3);if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GetSym();}在接收到SYM=IDENT后,假如SYM為INC,則關鍵實施這四條指令:GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR)將IDENT值放到棧頂,GEN(LIT,0,1);將常數(shù)1放到棧頂,GEN(OPR,0,2)次棧頂加棧頂,GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);將棧頂內(nèi)容保留到IDENT中。這么就完成了語句中++運算。假如SYM為DEC,則關鍵實施這四條指令:GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR)將IDENT值放到棧頂,GEN(LIT,0,1);將常數(shù)1放到棧頂,GEN(OPR,0,3)次棧頂減棧頂,GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);將棧頂內(nèi)容保留到IDENT中。這么就完成了語句中--運算。其次,再對因子處理程序FACTOR修改以下:if(SYM==IDENT){ i=POSITION(ID,TX); if(i==0)Error(11); else switch(TABLE[i].KIND){ caseCONSTANT:GEN(LIT,0,TABLE[i].VAL);GetSym();break; caseVARIABLE:GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GetSym();if(SYM==INC||SYM==DEC)//因子中++和--運算{GEN(LIT,0,1);if(SYM==INC)GEN(OPR,0,2);//假如為INC,則加1elseGEN(OPR,0,3);//不然減一GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//將棧頂送入變量單元GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//將變量送入棧頂GetSym();}break; casePROCEDUR:Error(21);break; } }這么,對后INC和后DEC操作就擴充完成c)擴充前++和前--操作存在前INC和前DEC操作語法圖有以下兩個: 語句語句++―-...........indentindent首先將STATBEGSYS[INC]=1; STATBEGSYS[DEC]=1; FACBEGSYS[INC]=1; FACBEGSYS[DEC]=1;其次依據(jù)以上語法圖,我們只要對語句處理程序和因子處理程序進行修改添加,即可實現(xiàn)增加前INC和前DEC操作,首先對語句處理程序STATEMENT進行以下修改:caseINC://前++GetSym();if(SYM==IDENT){i=POSITION(ID,TX); if(i==0)Error(11); elseif(TABLE[i].KIND!=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;}if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GetSym();}elseError(45);break;caseDEC://前--GetSym();if(SYM==IDENT){i=POSITION(ID,TX); if(i==0)Error(11); elseif(TABLE[i].KIND!=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;}if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GEN(LIT,0,1);GEN(OPR,0,3);if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GetSym();}elseError(45);break;再次,再對因子處理程序FACTOR修改以下:因子因子++―-...........indentindentelseif(SYM==INC){//前++GetSym();if(SYM==IDENT){i=POSITION(ID,TX); if(i==0)Error(11); elseif(TABLE[i].KIND!=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;}if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);if(i!=0){GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//將棧頂送入變量單元GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//將變量送入棧頂}GetSym();}elseError(45);}elseif(SYM==DEC){//前--GetSym();if(SYM==IDENT){i=POSITION(ID,TX); if(i==0)Error(11); elseif(TABLE[i].KIND!=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/Error(12);i=0;}if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GEN(LIT,0,1);GEN(OPR,0,3);if(i!=0){GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//將棧頂送入變量單元GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//將變量送入棧頂}GetSym();}elseError(45);}d)擴充+=和-=操作這兩個操作全部是一個對變量進行賦值形式,其正當語句形式語法圖以下所表示:依據(jù)圖3,在語句處理STATEMENT中,在已經(jīng)處理INC和DEC基礎上,添加對PLUSBK(+=)運算和MINUSBK(-=)運算擴充,相關代碼添加以下:elseif(SYM==PLUSBK)//增加運算符+={if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GetSym();EXPRESSION(FSYS,LEV,TX);GEN(OPR,0,2);if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);}elseif(SYM==MINUSBK)//增加運算符-={if(i!=0)GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GetSym();EXPRESSION(FSYS,LEV,TX);GEN(OPR,0,3);if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);}這么就完成了對+=運算和-=運算添加。2.增加PascalFOR語句:a)格式以下: FOR<變量>:=<常數(shù)> TO(或DOWNTO)<常數(shù)> DO <語句>b)添加語句for語句語句語法圖以下:首先,詞法分析部分增加關鍵字在SYMBOL里增加FORSYM,TOSYM,DOWNTOSYM,對應SYMMAX=44;NORW=25;初始化中strcpy(KWORD[10],"FOR"); WSYM[10]=IFSYM;strcpy(KWORD[22],"TO"); WSYM[22]=TOSYM;strcpy(KWORD[7],"DOWNTO"); WSYM[7]=DOWNTOSYM;其次,修改STATEMENT,代碼以下:caseFORSYM://添加FOR語句。GetSym();if(SYM!=IDENT)Error(47);elsei=POSITION(ID,TX); if(i==0)Error(11); elseif(TABLE[i].KIND!=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/ Error(12);i=0;}GetSym();if(SYM==BECOMES)GetSym(); elseError(13); EXPRESSION(SymSetUnion(SymSetNew(TOSYM,DOWNTOSYM),FSYS),LEV,TX); if(i!=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);if(SYM==TOSYM){//假如是to語句CX1=CX;//統(tǒng)計目前地址入口GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);//取ident變量值到棧頂GetSym();EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX);//取表示式值到棧頂GEN(OPR,0,13);//判定變量是否小于或等于棧頂CX2=CX;GEN(JPC,0,0);GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //變量加一if(SYM==DOSYM){//實施DO后語句GetSym();STATEMENT(FSYS,LEV,TX);}elseError(48);GEN(JMP,0,CX1);CODE[CX2].A=CX;}elseif(SYM==DOWNTOSYM){//假如為down語句CX1=CX;GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GetSym();EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX);GEN(OPR,0,11);//變量大于或等于棧頂CX2=CX;GEN(JPC,0,0);GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);GEN(LIT,0,1);GEN(OPR,0,3);GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR); //變量減一if(SYM==DOSYM){//實施DO后語句GetSym();STATEMENT(FSYS,LEV,TX);}elseError(48);GEN(JMP,0,CX1);CODE[CX2].A=CX;}elseError(47);break;//添加FOR語句。FOR語句擴充完成。3.增加一維數(shù)組類型首先設置一維數(shù)組左右括號:ssym['[']=lepa;//一維數(shù)組左括號[ssym[']']=ripa;//一維數(shù)組右括號]增加指令:strcpy(&(mnemonic[gar][0]),"gar");//依據(jù)棧頂偏移地址從數(shù)組中取值到新棧頂strcpy(&(mnemonic[sar][0]),"sar");//依據(jù)次棧頂偏移地址把棧頂值存入數(shù)組strcpy(&(mnemonic[shd][0]),"shd");//將棧頂值下移到次棧頂,棧頂出棧,即次棧頂成為棧頂strcpy(&(mnemonic[del][0]),"del");//出棧頂strcpy(&(mnemonic[jud][0]),"jud");//判定數(shù)組下標正當性strcpy(&(mnemonic[tra][0]),"tra");//將數(shù)組下標范圍入棧,gendo(tra,0,數(shù)組下標最大值);增加標識符類型屬性:/*--標識符類型屬性--*/enumobject{constant,variable,procedur,array,//數(shù)組};在block()函數(shù)中添加以下代碼:for(i=tx0+1;i<=tx;i++){switch(table[i].kind){caseconstant: printf("%dconst%s",i,table[i].name); printf("val=%d\n",table[i].val); fprintf(fas,"%dconst%s",i,table[i].name); fprintf(fas,"val=%d\n",table[i].val);break;casevariable:printf("%dvar%s",i,table[i].name);printf("lev=%daddr=%d\n",table[i].level,table[i].adr);fprintf(fas,"%dvar%s",i,table[i].name);fprintf(fas,"lev=%daddr=%d\n",table[i].level,table[i].adr);break;caseprocedur:printf("%dproc%s",i,table[i].name);printf("lev=%daddr=%dsize=%d\n",table[i].level,table[i].adr,table[i].size); fprintf(fas,"%dproc%s",i,table[i].name); fprintf(fas,"lev=%dadr=%dsize=%d\n",table[i].level,table[i].adr,table[i].size); break; casearray://數(shù)組變量 printf("%dvar-array%s",i,table[i].name); printf("lev=%daddr=%dsize=%d\n",table[i].level,table[i].adr,table[i].size); fprintf(fas,"%dvar-array%s",i,table[i].name);fprintf(fas,"lev=%daddr=%dsize=%d\n",table[i].level,table[i].adr,table[i].size); } }在enter()函數(shù)添加以下代碼: switch(k) { caseconstant:/*常量名字*/ if(num>amax) { error(31); num=0; } table[(*ptx)].val=num; break; casevariable:/*變量名字*/ table[(*ptx)].level=lev; table[(*ptx)].adr=(*pdx); table[(*ptx)].size=0; (*pdx)++; break;/*過程名字*/ caseprocedur: table[(*ptx)].level=lev; break; casearray:/*數(shù)組名字*/ table[(*ptx)].level=lev; table[(*ptx)].adr=(*pdx)-arraysize; table[(*ptx)].size=arraysize; break; }在Vardeclaration()函數(shù)中添加數(shù)組變量申明,代碼以下:intvardeclaration(int*ptx,intlev,int*pdx){ inti; charidtemp[al+1];//臨時保留數(shù)組名字 if(sym==ident) { strcpy(idtemp,id); getsymdo; //假如是數(shù)組 if(sym==lepa)//數(shù)組左中括號 { getsymdo; if(sym==number)//a[]中中括號里是數(shù)字話 { *pdx=*pdx+num;//為數(shù)組分配空間 arraysize=num;//保留數(shù)組長度 } else { if(sym==ident)//a[]中中括號里是變量話 { //要檢驗是不是以申明常量 i=position(id,*ptx);//查找名字表 if(i==0) { error(11);//標識符未說明 } else { if(table[i].kind==constant)//標識符屬性是常量 { *pdx=*pdx+table[i

溫馨提示

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

評論

0/150

提交評論