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

下載本文檔

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

文檔簡介

1、課程設計班級:21301學號:姓名:馬瑞澤百度一.課程設計目的在分析理解一個教學型編譯程序(如 PL/0)的基礎上,對其詞法分析程序、語法 分析程序和語義處理程序進行部分修改擴充。達到進一步了解程序編譯過程的基本原 理和基本實現(xiàn)方法的目的。二.課程設計要求1.基本內(nèi)容(1)擴充賦值運算:+=和-=(2)擴充語句(Pascal的FO硒句):FOR變量:= 表達式 TO 表達式 DO 語句FOR變量:= 表達式 DOWNTO表達式 DO 語句其中,語句的循環(huán)變量的步長為 2,語句的循環(huán)變量的步長為-2。2.選做內(nèi)容(1)增加運算:+和一。(2)增加類型: 字符類型; 實數(shù)類型。(3)擴充函數(shù): 有

2、返回值和返回語句; 有參數(shù)函數(shù)。(4)增加一維數(shù)組類型(可增加指令)。(5)其他典型語言設施。3.本人在課程設計中已實現(xiàn)的功能(1)增力口單詞:保留字 ELSE, FOR TO, DOWNTO, REPEAT, UNTIL, RETURN 咫:算符 += , -= , +,-(2)修改單詞:不等號#改為(3)增加條件語句的ELSE子句(4)擴充賦值運算:+=和-=(5)擴充語句FOR變量:=表達式 TO 表達式 DO 語句FOR變量 :=表達式 DOWNTO表達式 DO 語句增加運算:+和-(包括前后+、-運算)(7)增加一維數(shù)組類型(8) 其他典型語言設施:REPEATS句UNTIL語句三.

3、課程設計環(huán)境與工具(1)計算機及操作系統(tǒng):PC機,Win7 (2)實現(xiàn)工具:VC+ 6.0, C語言(3)教學型編譯程序:PL/0四.結構設計說明1) PL/0編譯程序的結構圖2) PL/0編譯程序的過程或函數(shù)的功能表 過程或函數(shù)名 "picerrorgetsym getch gen test block enter position(函數(shù)) constdeclaration vardeclaration listodestatement expression termfactorcondition interpretbase(函數(shù))3) PL/0編譯程序的總體流程圖簡要功能說明主程

4、序出錯處理,打印出錯位置和錯誤編碼詞法分析,讀取一個單詞漏掉空格,讀取一個字符生成目標代碼,并送入目標程序區(qū)測試當前單詞符號是否合法分程序分析處理過程登錄名字表查找標識符在名字表中的位置常量定義處理變量說明處理列出目標代碼清單語句處理表達式處理項處理因子處理條件處理對目標代碼的解釋執(zhí)行程序通過靜態(tài)鏈求出數(shù)據(jù)區(qū)的基地址啟動置初值4)詞法分析詞法分析是編譯的第一個階段,它的主要任務是從左向右逐個字符地對源程序進行 掃描,產(chǎn)生一個個單詞序列用于語法分析。PL/0詞法分析程序GETSYMJ功能是為語法 分析提供單詞用的,是語法分析的基礎,把輸入的字符串形式的源程序分割成一個個 單詞符號。經(jīng)過詞法分析程

5、序分析出來的單詞,對語言固有的單詞只給出類別存放在 全程變量SYMfr,而對用戶定義的單詞(標識符或常數(shù))既給出類別又給值,其類別 放在SYMfr,值放在全程變量ID或全程變量NUMfr,全部單詞種類由編譯程序定義的 純量類型SYMBO拾出,稱為語法詞匯表。詞法分析器的分析過程:調(diào)用 GETSYMf,它通過GETCHi程從源程序中獲得一個 字符。如果這個字符是字母,則繼續(xù)獲取字符或數(shù)字,最終可以拼成一個單詞,查保 留字表,如果查到為保留字,則把 SYM變量賦成相應的保留字類型值;如果沒有查到, 則這個單詞應是一個用戶自定義的標識符(可能是變量名、常量名或是過程的名字), 把SYMR為IDENT

6、,把這個單詞存入ID變量。查保留字表時使用了二分法查找以提高 效率。如果Getch獲得的字符是數(shù)字,則繼續(xù)用 Getch獲取數(shù)字,并把它們拼成一個 整數(shù)或?qū)崝?shù),然后把SYMR為INTEGER并把拼成白數(shù)值放入NU械量。如果識別出其它合法的符號(比如:賦值號、大于號、小于等于號等),則把SYMM成相應的類型。如果遇到不合法的字符,把 SYMS成NUL詞法分析程序GETSYM完成下列任務:(1)濾空格(2)識別保留字(3)識別標識符(4)拼數(shù)(5)拼復合詞(6)輸出源程序5)語法分析PL/0編譯程序的語法分析采用了自頂向下的遞歸的子程 序法。語法分析同時也根據(jù)程序的語義生成相應三元代碼, 并提供了

7、出錯處理的機制。語法分析主要由分程序分析過程 (BLOCK、常量定義分析過程(ConstDeclaration )、變量 定義分析過程(Vardeclaration )、語句分析過程(Statement)、表達式處理過程(Expression )、項處理過 程(Term)、因子處理過程(Factor)和條件處理過程(Condition )構成。這些過程在結構上構成一個嵌套的層次 結構。除此之外,還有出錯報告過程(Error )、代碼生成過 程(Ge。、測試單詞合法性及出錯恢復過程(Test)、登錄 名字表過程(Enter)、查詢名字表函數(shù)(Position )以及列 出類PCODE弋碼過程(L

8、istcode )作過語法分析的輔助過程。由PL/0的語法圖可知:一個完整的 PL/0程序是由分程 序和句號構成的。因此,本編譯程序在運行的時候,通過主 程序中調(diào)用分程序處理過程block來分析分程序部分(分程 序分析過程中還可能會遞歸調(diào)用 block過程),然后,判斷 最后讀入的符號是否為句號。如果是句號且分程序分析中未 出錯,則是一個合法的PL/0程序,可以運行生成的代碼,否 則就說明源PL/0程序是不合法的,輸出出錯提示即可。6)語義分析PL/0的語義分析主要進行以下檢查:(1)是否存在標識符先引用未聲明的情況;(2)是否存在己聲明的標識符的錯誤引用;PL/0語法調(diào)用關系圖(3)是否存在

9、一般標識符的多重聲明。7) 中間代碼生成目標代碼類pcode 是一種假想棧式計算機的匯編語言。自己添加覆蓋了OPR 0 14棧頂值輸出至屏幕(字符型)OPR 0 15棧頂值輸出至屏幕(整數(shù)型)OPR 0 16棧頂值輸出至屏幕(實數(shù)型)OPR 0 17屏幕輸出換行OPR 0 18從命令行讀入一個字符輸入置于棧頂OPR 0 19從命令行讀入一個整數(shù)輸入置于棧頂OPR 0 20從命令行讀入一個實數(shù)輸入置于棧頂8) 語法錯誤處理PL/0 編譯程序?qū)φZ法錯誤的處理采用兩種辦法:( 1)對于一些易于校正的錯誤,如丟了逗號、分號等,指出出錯的位置,加以校正,繼續(xù)進行分析。( 2)對于難于校正的錯誤,給出錯誤

10、的位置與性質(zhì),跳過后面一些單詞,直到下一個可以進行正常語法分析的語法單位。錯誤類型如下0 過程開始部分說明不正確1 常數(shù)說明中"=" 寫成":="2 常數(shù)說明中"=" 后應為整數(shù)或?qū)崝?shù)或字符3 常數(shù)說明中的標識符后應是"="4 const, var, procedure 后應為標識符5 漏掉了 "," 或 ""6 過程說明后的符號不正確( 應該是語句開始符, 或過程定義符)7 應是語句開始符8 程序體內(nèi)語句部分的后跟符不正確9 程序結尾丟了句號"."10

11、語句間漏了""11 標識符未說明12 賦值語句中, 賦值號左部標識符屬性應是變量13 變量后不能是此符號14 call 后應為標識符15 call 后標識符屬性應為過程16 條件語句中丟了"then"17 丟了 "end" 或 ""18 while 型循環(huán)語句丟了"do"19 語句后的符號不正確20 應為關系運算符21 表達式內(nèi)標識符屬性不能是過程22 表達式中漏掉右括號"("23 因子后的非法符號24 表達式的開始符不能是此符號31 數(shù)越界補充說明了:32 read 或 w

12、rite 語句括號中的標識符不是變量33 read或write語句缺少右括號")”34 read或write語句缺少左括號"("35 read或write括號里應為變量 自己增加了:45 +或-后面應為變量46 repeat 缺少 until47 for語句錯誤48 for語句缺少do49類型值不匹配50類型無法轉(zhuǎn)換51只有整數(shù)能+或-52類型不正確五.設計過程(一)實驗內(nèi)容1 .增力口單詞:保留字ELSE, FOR, TO, DOWNTO, REPEAT , UNTIL , RETURN運算符 +=(PLUSBK), -=(MINUSBK), +(INC),-

13、(DEC)首先要擴展SYMBOL ,在此基礎上再進行其它細節(jié)的修改。要添加的SYMBOL為:typedef enum 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, P

14、ROGSYM, ELSESYM,FORSYM, TOSYM, DOWNTOSYM, REPEATSYM, UNTILSYM, RETURNSYM, PLUSBK,MINUSBK, INC, DEC SYMBOL;char *SYMOUT = "NUL", "IDENT", "NUMBER", "PLUS", "MINUS", "TIMES", "SLASH", "ODDSYM", "EQL", "NEQ&q

15、uot;, "LSS", "LEQ", "GTR", "GEQ", "LPAREN", "RPAREN", "COMMA", "SEMICOLON", "PERIOD", "BECOMES", "BEGINSYM", "ENDSYM", "IFSYM", "THENSYM", "WHILESYM",

16、 "WRITESYM", "READSYM", "DOSYM", "CALLSYM","CONSTSYM", "VARSYM", "PROCSYM", "PROGSYM", "ELSE","FOR","TO", "DOWNTO", "REPEAT", "UNTIL", "RETU RN", &quo

17、t;PLUSBK", "MINUSBK", "INC "DEC" ;其中黑斜體為新加入的SYMBOL 。再將 "ELSE","FOR" , "TO" , "DOWNTO" , "REPEAT", "UNTIL", "RETURN", "PLUSBK", "MINUSBK", "INC","DEC" 關鍵字加到KWORD

18、 和將相應的SYM 加到 WSYM ,按字母順序排列。以及修改NEQ 后如下void _fastcall TForm1:ButtonRunClick(TObject *Sender) for (CH=' ' CH<='N; CH+) SSYMCH=NUL;strcpy(KWORD 1,"BEGIN");strcpy(KWORD 3,"CONST");strcpy(KWORD 5,"DO");strcpy(KWORD 2,"CALL");strcpy(KWORD 4,"DEC&

19、quot;);strcpy(KWORD 6," DOWHILE");strcpy(KWORD 7," DOWNTO "); strcpy(KWORD 8,"ELSE");strcpy(KWORD 9,"END");strcpy(KWORD 11,"IF");strcpy(KWORD13,"MINUSBK");strcpy(KWORD15,"PLUSBK");strcpy(KWORD17,"PROGRAM");strcpy(KWORD 1

20、0,"FOR");strcpy(KWORD12,"INC");strcpy(KWORD14,"ODD");strcpy(KWORD16,"PROCEDURE");strcpy(KWORD18,"READ");strcpy(KWORD19,"REPEAT");strcpy(KWORD21,"THEN");strcpy(KWORD23,"VAR");strcpy(KWORD25,"WHILE");strcpy(KWORD

21、20,"RETURN");strcpy(KWORD22,"TO");strcpy(KWORD24,"UNTIL");strcpy(KWORD26,"WRITE");WSYM 1=BEGINSYM;WSYM 3=CONSTSYM;WSYM 5=DOSYM;WSYM 7=DOWNTOSYMs;WSYM 9=ENDSYM;WSYM 11=IFSYM;WSYM13=MINUSBK;WSYM15=PLUSBK;WSYM17=PROGSYM;WSYM19=REPEATSYM;WSYM21=THENSYM;WSYM23=VARS

22、YM;WSYM25=WHILESYM;SSYM'+'=PLUS;SSYM'*'=TIMES;SSYM'('=LPAREN;WSYM 2=CALLSYM;WSYM 4=DEC;WSYM 6=DOWHILESYM;WSYM 8=ELSESYMWSYM 10=FORSYM;WSYM12=INCSYM;WSYM14=ODDSYM;WSYM16=PROCSYM;WSYM18=READSYM;WSYM20=RETURNSYM;WSYM 22=TOSYM;WSYM24=UNTILSYM;WSYM26=WRITESYM;SSYM'-'=MINUS

23、;SSYM'/'=SLASH;SSYM')'=RPAREN;SSYM'='=EQL;SSYM'.'=PERIOD;因為關鍵字增加到了SSYM','=COMMA;SSYM''=SEMICOLON;26;26個,所以令const NORWSYMBO由原來的33個值擴展為目前的 44個值,SYMOUT1由原來的33個元素擴展為目前的 44個元素. 我用個SYMMAXB記錄SYMBO遁的個數(shù), 所以,除了 Error函數(shù)中可能出現(xiàn)的作為參數(shù)的“3 3”不被 替換為“4 4”外,其余的“3 3”均用“ SYM

24、MAX來替換。SYMBOL擴展完畢。2 .修改單詞:不等號#改為<>只要修改GetSym()函數(shù)。當編譯器檢測到當前字符為“”時,接著檢測下一個字符,如果是“ 則使SYM=NEQ代碼修改如下:if (CH='<')GetCh();if (CH='=') SYM=LEQ; GetCh();elseif (CH='>') SYM=NEQ; GetCh (); /增加 <>為不等于號;else SYM=LSS;3 .增加條件語句的 ELSE子句語句該條件語法描述圖如下:只要在STATEMENT修改如下代碼:case

25、IFSYM:GetSym();CONDITION(SymSetUnion(SymSetNew(THENSYM,DOSYM),FSYS),LEV,TX);if (SYM=THENSYM) GetSym();else Error(16);CX1=CX; GEN(JPC,0,0);STATEMENT(SymSetUnion(SymSetNew(ELSESYM), FSYS), LEV, TX);if(SYM != ELSESYM) CODECX1.A=CX;如果程序中沒有else語句,執(zhí)行JPC時跳到此地址else/添加ELSE語句GetSym();CX2=CX;GEN(JMP,0,0); 跳過 e

26、lse 語句CODECX1.A = CX;如果程序中有else語句,執(zhí)行JPC時跳到此地址STATEMENT(FSYS,LEV,TX);CODECX2.A = CX; /執(zhí)行完 then 語句后跳出break;ELSE 子句擴充完畢。(二 )課 程設計內(nèi)容1 . 增加運算符+= , -= , + , -a) 詞法分析1) 在 GetSym ()中完成INC ()、else if(CH = '+')GetCh();if(CH = '=')SYM = PLUSBK;GetCh();else if(CH = '+')SYM = INC;GetCh();

27、else SYM = PLUS;2) 在 GetSym ()中完成DEC ()、else if(CH = '-')GetCh();if(CH = '=')SYM = MINUSBK;GetCh();else if(CH = '-')SYM = DEC;GetCh();else SYM = MINUS;b)擴充后+和后-操作存在 INC 和 DEC 操作的語法圖有如下兩個:PLUSBK ( + = )的詞法分析,代碼修改如下:/增加 +=/增加 +MINUSBK (- = )的詞法分析,代碼修改如下:/增加-=/增加-后 INC 和 后根據(jù)以上語法

28、圖,我們只要對語句處理程序和因子處理程序進行修改添加,即可實現(xiàn)增加DEC 操作,首先對語句處理程序STATEMENT 進行如下修改:Case IDENT:i=POSITION (ID,TX);if (i=0) Error(11);elseif (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/Error(12); i=0;GetSym();if (SYM=BECOMES)GetSym ();EXPRESSION (FSYS, LEV, TX);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp

29、.ADR);else if (SYM=INC) / 語句中的+運算 if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym();else if (SYM=DEC) / 語句中的-運算 if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GEN (LIT,0,1);GEN (OPR,0,3);if (i!=0) GEN(ST

30、O,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym ();在接受到SYM=IDENT 后,如果SYM 為 INC ,則主要執(zhí)行這四條指令:GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR)GEN(LIT,0,1); 將常數(shù) 1 放到棧頂,GEN(OPR,0,2) 次棧頂加棧頂,GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); 句中的 +運算。 如果SYM為DEC,則主要執(zhí)行這四條指令:GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR)GEN(LIT,0,

31、1); 將常數(shù) 1 放到棧頂,GEN(OPR,0,3) 次棧頂減棧頂,GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); 句中的 -運算。 其次,再對因子處理程序FACTOR 修改如下:將 IDENT 的值放到棧頂,將棧頂內(nèi)容保存到IDENT將 IDENT 的值放到棧頂,將棧頂內(nèi)容保存到IDENT這樣就完成了語這樣就完成了語if (SYM=IDENT) i=POSITION(ID,TX); if (i=0) Error(11); elseswitch (TABLEi.KIND) case CONSTANT: GEN(LIT,0,TABLEi.VAL);Get

32、Sym(); break;case VARIABLE: GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym();if(SYM=INC|SYM=DEC) / 因子中的+和 -運算GEN(LIT,0,1);if(SYM=INC) GEN(OPR,0,2);/ 如果為 INC ,貝功口 1 else GEN(OPR,0,3);/否則減一 GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);將棧頂送入變量單元GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); 將變量送入棧頂GetSym

33、(); break;case PROCEDUR: Error(21); break; 這樣,對 后INC和后DEC操作就擴充完成 c)擴充前+和前-操作 存在前INC和前DEC操作的語法圖有如下兩個:else Error(45);首先將STATBEGSYSINC=1;STATBEGSYSDEC=1;FACBEGSYSINC =1;FACBEGSYSDEC =1;前INC其次根據(jù)以上語法圖,我們只要對語句處理程序和因子處理程序進行修改添加,即可實現(xiàn)增加和前DEC操作,首先對語句處理程序STATEMENT進行如下修改:case INC: / 前+GetSym();if (SYM = IDENT)

34、i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND!=VARIABLE) "ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0;if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym();break;case DEC: /前-GetSym();if (SYM = ID

35、ENT) i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND!=VARIABLE) "ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0;if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GEN (LIT,0,1);GEN (OPR,0,3);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym ();else Error(45);break;再次,再對因子處理程序

36、FACTOR修改如下:因子else if(SYM = INC) /前+GetSym();if (SYM = IDENT) i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND!=VARIABLE) "ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0; if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TA

37、BLEi.vp.ADR); 將棧頂送入變量單元GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); 將變量送入棧頂 GetSym();前 -else if(SYM = DEC) /GetSym();if (SYM = IDENT) i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NON-VARIABLE*/ Error(12); i=0;if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR)

38、;GEN (LIT,0,1);GEN (OPR,0,3); if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /將棧頂送入變量單元GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); /將變量送入棧頂 GetSym (); else Error(45); d)擴充+=和-=操作 這兩個操作都是一種對變量進行賦值的形式,其合法的語句形式的語法圖如下所示: 根據(jù)圖3,在語句處理 STATEMEN甘,在已經(jīng)處理INC和DEC的基礎上,添加對PLUSBK( + =)運算和MINUSBK( =)運算的擴充,相關代

39、碼添加如下: else if (SYM=PLUSBK) / 增加運算符+= if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym();EXPRESSION(FSYS,LEV,TX);GEN(OPR,0,2);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); else if (SYM=MINUSBK) /增加運算符-=if (i!=0) GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym();EXPRESSION(FSYS,L

40、EV,TX);GEN(OPR,0,3);if (i!=0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); 這樣就完成了對+ =運算和=運算的添加。2 .增加Pascal的FOR語句:a)格式如下:FOR <變量> := < 常數(shù) >TO(或 DOWNTO)常數(shù) >DO < 語句 >b )添加語句for 語句的語句語法圖如下:首先 ,詞法分析部分增加關鍵字在 SYMBOK增力口 FORSYM, TOSYM, DOWNTOSYM應 SYMMAX=44 ; NORW = 25;初始化中strcpy(KWORD10,&

41、quot;FOR");WSYM 10=IFSYM;strcpy(KWORD22,"TO");WSYM22=TOSYM;strcpy(KWORD 7,"DOWNTO");WSYM 7=DOWNTOSYM;其次 ,修改 STATEMENT ,代碼如下:case FORSYM:/添加FOR 語句。GetSym();if(SYM != IDENT) Error(47);else i=POSITION(ID,TX);if(i = 0) Error(11);else if (TABLEi.KIND!=VARIABLE) /*ASSIGNMENT TO NO

42、N-VARIABLE*/ Error(12); i=0;GetSym();if(SYM = BECOMES) GetSym();else Error(13);EXPRESSION(SymSetUnion(SymSetNew(TOSYM,DOWNTOSYM),FSYS),LEV,TX);if(i != 0) GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);if(SYM = TOSYM)/如果是to 語句CX1=CX;/ 記錄當前地址入口GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/取 ident 變量值到棧頂GetS

43、ym();EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX);/取表達式值到棧頂GEN(OPR,0,13);/ 判斷變量是否小于或等于棧頂CX2=CX;GEN(JPC,0,0);GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GEN(LIT,0,1);GEN(OPR,0,2);GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/變量加一if(SYM = DOSYM)/ 執(zhí)行 DO 后的語句GetSym();STATEMENT(FSYS,LEV,TX);else Er

44、ror(48);GEN(JMP,0,CX1);CODECX2.A=CX;/如果為down 語句else if (SYM=DOWNTOSYM)CX1=CX;GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GetSym();EXPRESSION(SymSetUnion(SymSetNew(DOSYM),FSYS),LEV,TX);GEN(OPR,0,11);/ 變量大于或等于棧頂CX2=CX;GEN(JPC,0,0);GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);GEN(LIT,0,1);GEN(OPR,0,3);GEN

45、(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR);/變量減一if (SYM=DOSYM)/ 執(zhí)行 DO 后的語句GetSym();STATEMENT(FSYS,LEV,TX);else Error(48);GEN(JMP,0,CX1);CODECX2.A=CX;else Error(47);break;/添加FOR 語句。FOR 語句擴充完畢。3 .增加一維數(shù)組類型首先設置一維數(shù)組的左右括號:strcpy(&(mnemonicgar0),"gar"); / strcpy(&(mnemonicsar0),"sar&quo

46、t;);/ strcpy(&(mnemonicshd0),"shd");/ strcpy(&(mnemonicdel0),"del");/ strcpy(&(mnemonicjud0),"jud");/ strcpy(&(mnemonictra0),"tra");/ 增加標識符類型屬性:ssym''=lepa;/ 一維數(shù)組的左括號 ssym''=ripa;/ 一維數(shù)組的右括號 增加指令:根據(jù)棧頂?shù)钠频刂窂臄?shù)組中取值到新的棧頂根據(jù)次棧頂?shù)钠频刂钒褩m?/p>

47、的值存入數(shù)組將棧頂?shù)闹迪乱频酱螚m?,棧頂出棧,即次棧頂成為棧頂出棧頂判斷?shù)組下標合法性將數(shù)組的下標范圍入棧,gendo(tra,0, 數(shù)組下標最大值);/*- 標識符的類型屬性-*/enum object constant,variable,procedur,array,/數(shù)組;在block ()函數(shù)中添加如下代碼: for(i=tx0+1;i<=tx;i+)switch(tablei.kind) case constant:printf("%d const %s ",i,);printf("val=%dn",tablei.v

48、al);fprintf(fas,"%d const %s",i,); fprintf(fas,"val=%dn",tablei.val);break;case variable:printf("%d var %s ",i,);printf("lev=%d addr=%dn",tablei.level,tablei.adr);fprintf(fas,"%d var %s",i,);fprintf(fas,"lev=%d a

49、ddr=%dn",tablei.level,tablei.adr);break;case procedur:printf("%d proc %s ",i,);printf("lev=%d addr=%d size=%dn",tablei.level,tablei.adr,tablei.size);fprintf(fas,"%d proc%s",i,);fprintf(fas,"lev=%d adr=%d size=%d n",tablei.level,table

50、i.adr,tablei.size); break;printf("%d var-array %s ",i,);printf("lev=%d addr=%d size=%dn",tablei.level,tablei.adr,tablei.size);fprintf(fas,"%d var-array %s",i,);fprintf(fas,"lev=%d addr=%d size=%dn",tablei.level,tablei.adr,tablei.size);在en

51、ter ()函數(shù)添加如下代碼:switch(k)case constant:if (num>amax)error(31);num=0;table(*ptx).val=num;break;case variable:table(*ptx).level=lev;table(*ptx).adr=(*pdx);table(*ptx).size=0;(*pdx)+;break;case procedur:table(*ptx).level=lev;/*常量名字*/* 變量名字*/* 過程名字*/break;/* 數(shù)組名字*/case array:table(*ptx).level=lev;table(*ptx).adr=(*pdx)-arraysize;table(*ptx).size=arraysize;break;在 Vardeclaration ()函數(shù)中添加數(shù)組的變量聲明,代碼如下:int vardeclaration(int * ptx,int lev,int * pdx)int i;char idtempal+1;/ 臨時保存數(shù)組名字if(sym=ident)strcpy(idtemp,id);getsymdo;/如果是數(shù)組if(sym=lepa)/ 數(shù)組的左中括號getsymdo;if(sym

溫馨提示

  • 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

提交評論