版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p><b> 課 程 設 計</b></p><p> 課程名稱_____編譯原理_____ </p><p> 題目名稱 PL/0功能擴充 </p><p> 學生學院 計算機學院 </p><p> 專業(yè)班級 計科一班 </p&
2、gt;<p> 學 號_____ ______</p><p> 2012年 1 月 1 日</p><p><b> 課程設計目的</b></p><p> 在分析理解一個教學型編譯程序(如PL/0)的基礎上,對其詞法分析程序、語法分析程序和語義處理程序進行部分修改擴充。達到進一步了解程序編譯過程的基本
3、原理和基本實現(xiàn)方法的目的。</p><p><b> 課程設計要求</b></p><p><b> 基本內容</b></p><p> ?。?)擴充賦值運算:+= 和 -= </p><p> ?。?)擴充語句(Pascal的FOR語句):</p><p> ①FOR
4、 <變量>:=<表達式> TO <表達式> DO <語句></p><p> ?、贔OR <變量>:=<表達式> DOWNTO <表達式> DO <語句></p><p> 其中,語句①的循環(huán)變量的步長為1,</p><p> 語句②的循環(huán)變量的步長為-1。</
5、p><p> ?。?)增加運算:++ 和 --。</p><p><b> 課程設計環(huán)境與工具</b></p><p> (1)計算機及操作系統(tǒng):PC機,Windows7</p><p> ?。?)實現(xiàn)工具:C++Builder6</p><p> ?。?)教學型編譯程序:PL/0 </p&
6、gt;<p><b> 說明</b></p><p> 1、PL/0編譯程序的結構圖</p><p> 2、PL/0編譯程序的總體流程圖:</p><p> 3、PL/0編譯程序的過程或函數(shù)的功能表</p><p><b> 4、詞法分析</b></p><
7、;p> 詞法分析是編譯的第一個階段,它的主要任務是從左向右逐個字符地對源程序進行掃描,產(chǎn)生一個個單詞序列用于語法分析。PL/0詞法分析程序GETSYM的功能是為語法分析提供單詞用的,是語法分析的基礎,把輸入的字符串形式的源程序分割成一個個單詞符號。經(jīng)過詞法分析程序分析出來的單詞,對語言固有的單詞只給出類別存放在全程變量SYM中,而對用戶定義的單詞(標識符或常數(shù))既給出類別又給值,其類別放在SYM中,值放在全程變量ID或全程變量N
8、UM中,全部單詞種類由編譯程序定義的純量類型SYMBOL給出,稱為語法詞匯表。</p><p><b> 5、語法分析</b></p><p> PL/0編譯程序的語法分析采用了自頂向下的遞歸的子程序法。語法分析同時也根據(jù)程序的語義生成相應三元代碼,并提供了出錯處理的機制。語法分析主要由分程序分析過程(BLOCK)、常量定義分析過程(ConstDeclaratio
9、n)、變量定義分析過程(Vardeclaration)、語句分析過程(Statement)、表達式處理過程(Expression)、項處理過程(Term)、因子處理過程(Factor)和條件處理過程(Condition)構成。這些過程在結構上構成一個嵌套的層次結構。詳細見作圖</p><p><b> 6、語義分析</b></p><p> PL/0 的語義分析主
10、要進行以下檢查:</p><p> ?。?) 是否存在標識符先引用未聲明的情況;</p><p> ?。?) 是否存在己聲明的標識符的錯誤引用;</p><p> ?。?) 是否存在一般標識符的多重聲明。</p><p><b> 7、中間代碼生成</b></p><p> 目標代碼類pcod
11、e是一種假想棧式計算機的匯編語言。</p><p><b> 添加覆蓋:</b></p><p> OPR L 14棧頂值輸出至屏幕(L=1:字符型;L=0:整型)</p><p> OPR 0 15輸出回車</p><p> OPR L 16從命令行讀入一個字符輸入置于棧頂(L=1:字符型;L
12、=0:整型)</p><p> STP L A將棧頂置入暫存數(shù)組TMP[A]里,L=1退一棧,否則不退</p><p> GTP 0 A 將暫存數(shù)組TMP[A]的值放到棧頂</p><p> 以下3個為數(shù)組新增:</p><p> ACP L AL=1則將當前離棧頂偏移A的值復制到新棧頂;L=0不操作<
13、/p><p> AST L A 將棧頂?shù)闹祵懭肱cA偏移量等于次棧頂?shù)牡刂?,棧?</p><p> ALD L A 從與A偏移量等于棧頂?shù)玫刂返闹捣旁谠摋m斏?lt;/p><p><b> 8、語法錯誤處理</b></p><p> PL/0編譯程序對語法錯誤的處理采用兩種辦法:</p>
14、<p> ?。?)對于一些易于校正的錯誤,如丟了逗號、分號等,指出出錯的位置,加以校正,繼續(xù)進行分析。 </p><p> (2)對于難于校正的錯誤,給出錯誤的位置與性質,跳過后面一些單詞,直到下一個可以進行正常語法分析的語法單位。</p><p><b> 錯誤類型如下</b>
15、</p><p> 0 過程開始部分說明不正確</p><p> 1 常數(shù)說明中"="寫成":="</p><p> 2 常數(shù)說明中"="后應為整數(shù)或實數(shù)或字符</p><p> 3 常數(shù)說明中的標識符后應是"="</p><p
16、> 4 const, var, procedure后應為標識符</p><p> 5 漏掉了","或";"</p><p> 6 過程說明后的符號不正確(應該是語句開始符,或過程定義符)</p><p> 7 應是語句開始符</p><p> 8 程序體內語句部分的后跟符不正確
17、</p><p> 9 程序結尾丟了句號"."</p><p> 10 語句間漏了";"</p><p><b> 11 標識符未說明</b></p><p> 12 賦值語句中,賦值號左部標識符屬性應是變量</p><p> 13 變量后不能是
18、此符號</p><p> 14 call后應為標識符</p><p> 15 call后標識符屬性應為過程</p><p> 16 條件語句中丟了"then"</p><p> 17 丟了"end"或";"</p><p> 18 while型循環(huán)語
19、句丟了"do"</p><p> 19 語句后的符號不正確</p><p> 20 應為關系運算符</p><p> 21 表達式內標識符屬性不能是過程</p><p> 22 表達式中漏掉右括號"("</p><p> 23 因子后的非法符號</p>&
20、lt;p> 24 表達式的開始符不能是此符號</p><p><b> 31 數(shù)越界</b></p><p> 32 read語句中的標識符不是變量</p><p> 33 后接符號應該是“'”</p><p><b> 34 未知的類型</b></p><
21、;p><b> 35 缺少“]”</b></p><p> 36 運行??臻g不足,無法申請該數(shù)組</p><p> 37數(shù)組的下標不合法</p><p> 38 后接符號應該是“DO”</p><p> 39 應為TO或者DOWNTO</p><p><b> 五、設計
22、過程:</b></p><p> A、增加運算+=,-=,++,--</p><p><b> 1、代碼:</b></p><p><b> 詞法分析:</b></p><p> case '+': GetCh();</p><p> i
23、f(CH=='+'){SYM=INC;GetCh();}</p><p> else if(CH=='='){SYM=APPEND;GetCh();}</p><p> else SYM= PLUS;</p><p><b> break;</b></p><p> case
24、39;-': GetCh();</p><p> if(CH=='-'){SYM=DEC;GetCh();}</p><p> else if(CH=='='){SYM=REDUCE;GetCh();}</p><p> else SYM= MINUS;</p><p><b> 語法
25、分析:</b></p><p> 1、在因子處理程序里:</p><p> case CONSTANT:</p><p> if(SYM==INC||SYM==DEC){Error(23);break;}</p><p> GEN(LIT,0,TABLE[i].VAL); break;</p><p&g
26、t; case VARIABLE:</p><p> if(SYM==LMPAREN)</p><p><b> {</b></p><p><b> GetSym();</b></p><p> set=AST;lod=ALD;</p><p> EXPRESS
27、ION(SymSetAdd(RMPAREN,FSYS),LEV,TX);</p><p> if(RMPAREN==SYM) GetSym();</p><p> else Error(35);</p><p><b> }</b></p><p> if(SYM==INC||SYM==DEC){</p&g
28、t;<p> GEN(ACP,AST==set,0);</p><p> GEN(lod,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> if(SYM==INC)</p><p> GEN(LIT,0,1);</p><p> else GEN(LIT,0,-1)
29、;</p><p> GEN(OPR,0,2);</p><p> GEN(set,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> GEN(ACP,AST==set,-1);</p><p> GEN(lod,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR)
30、;</p><p> if(SYM==INC)</p><p> GEN(LIT,0,-1);</p><p> else GEN(LIT,0,1);</p><p> GEN(OPR,0,2);</p><p><b> GetSym();</b></p><
31、p><b> }</b></p><p> else GEN(lod,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p><b> break;</b></p><p><b> case INC:</b></p><p&g
32、t;<b> case DEC:</b></p><p><b> GetSym();</b></p><p> if(SYM==IDENT){</p><p> i=POSITION(ID,TX);</p><p><b> if(i!=0)</b></p&g
33、t;<p> { VSTYLE=TABLE[i].STYLE;</p><p><b> GetSym();</b></p><p> if(SYM==LMPAREN)</p><p><b> {</b></p><p><b> GetSym();</
34、b></p><p> set=AST;lod=ALD;</p><p> EXPRESSION(SymSetAdd(RMPAREN,FSYS),LEV,TX);</p><p> if(RMPAREN==SYM) GetSym();</p><p> else Error(35);</p><p>&l
35、t;b> }</b></p><p> if(CurSym==INC)</p><p> GEN(LIT,0,1);</p><p><b> else</b></p><p> GEN(LIT,0,-1);</p><p> GEN(ACP,set==AST,1);
36、</p><p> GEN(lod,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> GEN(OPR,0,2);</p><p> GEN(set,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> GEN(ACP,set==AST,-1);
37、</p><p> GEN(lod,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p><b> }</b></p><p> else Error(11);</p><p> } //if(SYM==IDENT)</p><p> else
38、Error(23);</p><p> 2、在語句處理分程序:</p><p> case IDENT:</p><p> i=POSITION(ID,TX);</p><p><b> GetSym();</b></p><p> if (i==0) Error(11);</p&
39、gt;<p><b> else</b></p><p> if (TABLE[i].KIND!=VARIABLE) { /*ASSIGNMENT TO NON-VARIABLE*/</p><p> Error(12); i=0;</p><p><b> }</b></p><
40、p> else {VSTYLE=TABLE[i].STYLE;</p><p> if(SYM==LMPAREN)</p><p><b> {</b></p><p><b> GetSym();</b></p><p> set=AST;lod=ALD;</p>&
41、lt;p> EXPRESSION(SymSetAdd(RMPAREN,FSYS),LEV,TX);</p><p> if(RMPAREN==SYM) GetSym();</p><p> else Error(35);</p><p><b> }</b></p><p><b> }<
42、/b></p><p> switch(SYM)</p><p><b> {</b></p><p> case BECOMES:</p><p><b> GetSym();</b></p><p> EXPRESSION(FSYS,LEV,TX);<
43、;/p><p> if (i==0) Error(11);//GEN(set,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p><b> break;</b></p><p> case APPEND:</p><p><b> GetSym();</b&
44、gt;</p><p> EXPRESSION(FSYS,LEV,TX);</p><p> if (i!=0){</p><p> GEN(ACP,set==AST,1);</p><p> GEN(lod,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> G
45、EN(OPR,0,2);</p><p> //GEN(set,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p><b> }</b></p><p><b> break;</b></p><p> case REDUCE:</p>
46、<p><b> GetSym();</b></p><p> EXPRESSION(FSYS,LEV,TX);</p><p> if (i!=0){</p><p> GEN(ACP,set==AST,1);</p><p> GEN(lod,LEV-TABLE[i].vp.LEVEL,TAB
47、LE[i].vp.ADR);</p><p> GEN(OPR,0,3);</p><p> GEN(OPR,0,1);</p><p> //GEN(set,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p><b> }</b></p><p&g
48、t;<b> break;</b></p><p><b> case INC:</b></p><p><b> GetSym();</b></p><p> if (i!=0){</p><p> GEN(LIT,0,1);</p><p>
49、; GEN(ACP,set==AST,1);</p><p> GEN(lod,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> GEN(OPR,0,2);</p><p> //GEN(set,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p&g
50、t;<b> }</b></p><p><b> break;</b></p><p><b> case DEC:</b></p><p><b> GetSym();</b></p><p> if (i!=0){</p>&
51、lt;p> GEN(LIT,0,-1);</p><p> GEN(ACP,set==AST,1);</p><p> GEN(lod,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> GEN(OPR,0,2);</p><p> //GEN(set,LEV-TABLE[i].v
52、p.LEVEL,TABLE[i].vp.ADR);</p><p><b> }</b></p><p><b> break;</b></p><p> default: Error(13);break;</p><p><b> }</b></p>&
53、lt;p> GEN(set,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p><b> break;</b></p><p><b> 測試程序:</b></p><p><b> INCDEC程序:</b></p><p
54、> PROGRAM TESTELSE;</p><p> VAR A,B,C,D,E,F,G;</p><p><b> BEGIN</b></p><p><b> A:=5;</b></p><p><b> F:=0;</b></p><
55、;p><b> G:=0;</b></p><p><b> B:=A++;</b></p><p><b> C:=++A;</b></p><p><b> D:=A--;</b></p><p><b> E:=--A;&l
56、t;/b></p><p><b> F+=A;</b></p><p><b> G-=A;</b></p><p> PRINTLN(A,B,C,D,E,F,G);</p><p><b> END.</b></p><p><b
57、> 測試結果:</b></p><p> === COMPILE PL0 ===</p><p> 0 PROGRAM TESTELSE; </p><p> 0 VAR A,B,C,D,E,F,G; </p><p><b> 1 BEGIN </b></p><p>
58、;<b> 2 A:=5; </b></p><p><b> 4 F:=0; </b></p><p><b> 6 G:=0; </b></p><p> 8 B:=A++; </p><p> 18 C:=++A; </p><p>
59、26 D:=A--; </p><p> 36 E:=--A; </p><p><b> 44 F+=A; </b></p><p><b> 49 G-=A; </b></p><p> 55 PRINTLN(A,B,C,D,E,F,G); </p><p>&l
60、t;b> 70 END. </b></p><p> 0 JMP 0 1</p><p> 1 INI 0 10</p><p> 2 LIT 0 5</p><p> 3 STO 0 3</p><p> 4 LIT 0 0</p&g
61、t;<p> 5 STO 0 8</p><p> 6 LIT 0 0</p><p> 7 STO 0 9</p><p> 8 ACP 0 0</p><p> 9 LOD 0 3</p><p> 10 LIT 0 1</
62、p><p> 11 OPR 0 2</p><p> 12 STO 0 3</p><p> 13 ACP 0 -1</p><p> 14 LOD 0 3</p><p> 15 LIT 0 -1</p><p> 16 OPR 0
63、 2</p><p> 17 STO 0 4</p><p> 18 LIT 0 1</p><p> 19 ACP 0 1</p><p> 20 LOD 0 3</p><p> 21 OPR 0 2</p><p> 22
64、STO 0 3</p><p> 23 ACP 0 -1</p><p> 24 LOD 0 3</p><p> 25 STO 0 5</p><p> 26 ACP 0 0</p><p> 27 LOD 0 3</p><p&g
65、t; 28 LIT 0 -1</p><p> 29 OPR 0 2</p><p> 30 STO 0 3</p><p> 31 ACP 0 -1</p><p> 32 LOD 0 3</p><p> 33 LIT 0 1</p>
66、<p> 34 OPR 0 2</p><p> 35 STO 0 6</p><p> 36 LIT 0 -1</p><p> 37 ACP 0 1</p><p> 38 LOD 0 3</p><p> 39 OPR 0 2<
67、;/p><p> 40 STO 0 3</p><p> 41 ACP 0 -1</p><p> 42 LOD 0 3</p><p> 43 STO 0 7</p><p> 44 LOD 0 3</p><p> 45 ACP
68、0 1</p><p> 46 LOD 0 8</p><p> 47 OPR 0 2</p><p> 48 STO 0 8</p><p> 49 LOD 0 3</p><p> 50 ACP 0 1</p><p> 51
69、 LOD 0 9</p><p> 52 OPR 0 3</p><p> 53 OPR 0 1</p><p> 54 STO 0 9</p><p> 55 LOD 0 3</p><p> 56 OPR 0 14</p><p
70、> 57 LOD 0 4</p><p> 58 OPR 0 14</p><p> 59 LOD 0 5</p><p> 60 OPR 0 14</p><p> 61 LOD 0 6</p><p> 62 OPR 0 14</p>
71、;<p> 63 LOD 0 7</p><p> 64 OPR 0 14</p><p> 65 LOD 0 8</p><p> 66 OPR 0 14</p><p> 67 LOD 0 9</p><p> 68 OPR 0 14&
72、lt;/p><p> 69 OPR 0 15</p><p> 70 OPR 0 0</p><p> ~~~ RUN PL0 ~~~</p><p> 5 5 7 7 5 5 -5 </p><p> ~~~ END PL0 ~~~</p><p
73、><b> B、FOR語句:</b></p><p> 修改STATEMENT就能實現(xiàn)FOR語句的擴充,代碼如下:</p><p> case FORSYM:</p><p> // FOR <變量>:=<表達式> TO <表達式> DO <語句></p>
74、<p> // FOR <變量>:=<表達式> DOWNTO <表達式> DO <語句></p><p><b> GetSym();</b></p><p> FSYS=SymSetUnion(SymSetNew(DOSYM,TOSYM,DOWNTOSYM),FSYS);<
75、;/p><p> if(SYM==IDENT)</p><p><b> {</b></p><p> i=POSITION(ID,TX);</p><p><b> if( i!=0)</b></p><p><b> {</b></p&g
76、t;<p><b> GetSym();</b></p><p> if(BECOMES==SYM)</p><p><b> {</b></p><p><b> GetSym();</b></p><p> EXPRESSION(FSYS,LEV,T
77、X);</p><p> GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> if(TOSYM==SYM||DOWNTOSYM==SYM)</p><p><b> {</b></p><p> TmpSYM=SYM;</p><p
78、><b> GetSym();</b></p><p> EXPRESSION(FSYS,LEV,TX);</p><p> if(DOSYM==SYM)</p><p> { GetSym();</p><p> TMPADDR=1;</p><p> GEN(STP,1
79、,TMPADDR);</p><p> //循環(huán)體無條件回跳到這里重新判斷循環(huán)條件</p><p><b> CX1=CX;</b></p><p> //循環(huán)體條件判斷碼的生成</p><p> switch(TmpSYM)</p><p><b> {</b>&
80、lt;/p><p> case TOSYM:</p><p> GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> GEN(GTP,0,TMPADDR);</p><p><b> Step=1;</b></p><p><b
81、> break;</b></p><p> case DOWNTOSYM:</p><p> GEN(GTP,0,TMPADDR);</p><p> GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p><b> Step=-1;</b&g
82、t;</p><p><b> break;</b></p><p> default: Error(8);</p><p><b> }</b></p><p> GEN(OPR,0,10); // 棧頂:原(次棧頂<棧頂?shù)慕Y果)</p><p><b&
83、gt; //條件碼結束</b></p><p> CX2=CX; //CX2用于記錄產(chǎn)生跳轉位置的 GEN(JPC,0,0)的位置</p><p> //便于回填時找到該跳轉命令 GEN(JPC,0,0)</p><p> GEN(JPC,0,0);</p><p><b> //循環(huán)語句 ></b
84、></p><p> STATEMENT(FSYS,LEV,TX);</p><p><b> //<循環(huán)語句完</b></p><p> //步長+1或者-1操作 ></p><p> GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p
85、><p> GEN(LIT,0,Step);</p><p> GEN(OPR,0,2);</p><p> GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);</p><p> //<步長+1或者-1操作 結束</p><p> GEN(JMP,0,CX1);/
86、/無條件跳回CX1,至此循環(huán)體結束</p><p> CODE[CX2].A=CX; //將跳出循環(huán)體的位置回填</p><p><b> }</b></p><p> else Error(38);</p><p><b> }</b></p><p> else
87、 Error(39);</p><p><b> }</b></p><p> else Error(11);</p><p><b> }</b></p><p> else Error(8);</p><p><b> }</b></
88、p><p><b> 測試程序:</b></p><p> FORSYM.PL0;</p><p> PROGRAM EX01;</p><p> VAR A,B,C;</p><p><b> BEGIN</b></p><p><b&g
89、t; C:=0;</b></p><p><b> B:=5;</b></p><p><b> A:=11;</b></p><p> FOR A:=0 DOWNTO -5 DO</p><p><b> BEGIN</b></p><
90、;p> PRINTLN(A);</p><p><b> END;</b></p><p> FOR A:=0 TO 5 DO</p><p><b> BEGIN</b></p><p> PRINTLN(A);</p><p><b> END
91、</b></p><p><b> END.</b></p><p><b> 測試結果:</b></p><p> ***** PL/0 Compiler Demo *****</p><p> === COMPILE PL0 ===</p><p>
92、 0 PROGRAM EX01; </p><p> 0 VAR A,B,C; </p><p><b> 1 BEGIN </b></p><p><b> 2 C:=0; </b></p><p><b> 4 B:=5; </b></p><
93、;p> 6 A:=11; </p><p> 8 FOR A:=0 DOWNTO -5 DO </p><p> 12 BEGIN </p><p> 17 PRINTLN(A); </p><p><b> 20 END; </b></p><p><b>
94、; 25 </b></p><p> 25 FOR A:=0 TO 5 DO </p><p> 28 BEGIN </p><p> 33 PRINTLN(A); </p><p><b> 36 END </b></p><p><b> 36
95、 </b></p><p><b> 36 END. </b></p><p> 0 JMP 0 1</p><p> 1 INI 0 6</p><p> 2 LIT 0 0</p><p> 3 STO 0 5</p>
96、;<p> 4 LIT 0 5</p><p> 5 STO 0 4</p><p> 6 LIT 0 11</p><p> 7 STO 0 3</p><p> 8 LIT 0 0</p><p> 9 STO 0 3</p&
97、gt;<p> 10 LIT 0 5</p><p> 11 OPR 0 1</p><p> 12 STP 1 1</p><p> 13 GTP 0 1</p><p> 14 LOD 0 3</p><p> 15 OPR 0 1
98、0</p><p> 16 JPC 0 25</p><p> 17 LOD 0 3</p><p> 18 OPR 0 14</p><p> 19 OPR 0 15</p><p> 20 LOD 0 3</p><p> 21 LI
99、T 0 -1</p><p> 22 OPR 0 2</p><p> 23 STO 0 3</p><p> 24 JMP 0 13</p><p> 25 LIT 0 0</p><p> 26 STO 0 3</p><p>
100、 27 LIT 0 5</p><p> 28 STP 1 1</p><p> 29 LOD 0 3</p><p> 30 GTP 0 1</p><p> 31 OPR 0 10</p><p> 32 JPC 0 41</p>&
101、lt;p> 33 LOD 0 3</p><p> 34 OPR 0 14</p><p> 35 OPR 0 15</p><p> 36 LOD 0 3</p><p> 37 LIT 0 1</p><p> 38 OPR 0 2</
102、p><p> 39 STO 0 3</p><p> 40 JMP 0 29</p><p> 41 OPR 0 0</p><p> ~~~ RUN PL0 ~~~</p><p><b> 0 </b></p><p><b&
103、gt; -1 </b></p><p><b> -2 </b></p><p><b> -3 </b></p><p><b> -4 </b></p><p><b> 0 </b></p>&
104、lt;p><b> 1 </b></p><p><b> 2 </b></p><p><b> 3 </b></p><p><b> 4 </b></p><p> ~~~ END PL0 ~~~</p>
105、<p><b> C、字符類型:</b></p><p> 聲明、因子、語句(變量、輸入、輸出)、解釋等分程序都有涉及,這里不貼代碼,主要處理字符變量的賦值,增加'x'為ACHAR,參加運算以及類型轉換:表達式中如果有char型,則輸出為char型,其它運算int型和char型其實是相通的,只需要處理表達形式和變量的類型,我用了一個全局變量VSTYLE來跟蹤當
106、前棧頂?shù)闹祽摓楹畏N類型。</p><p><b> 測試程序:</b></p><p> PROGRAM EX01;</p><p> VAR CHAR B;</p><p><b> VAR A;</b></p><p><b> BEGIN</
107、b></p><p><b> A:=5;</b></p><p><b> READ(B);</b></p><p> PRINTLN(A,A+B,'A'+1,'H');</p><p><b> END.</b></p&g
108、t;<p><b> 測試結果:</b></p><p> === COMPILE PL0 ===</p><p> 0 PROGRAM EX01; </p><p> 0 VAR CHAR B; </p><p><b> 1 VAR A; </b></p>
109、<p><b> 1 BEGIN </b></p><p><b> 2 A:=5; </b></p><p> 4 READ(B); </p><p> 6 PRINTLN(A,A+B,'A'+1,'H'); </p><p><b&g
110、t; 19 END. </b></p><p> 0 JMP 0 1</p><p> 1 INI 0 5</p><p> 2 LIT 0 5</p><p> 3 STO 0 4</p><p> 4 OPR 1 16</p>&
111、lt;p> 5 STO 0 3</p><p> 6 LOD 0 4</p><p> 7 OPR 0 14</p><p> 8 LOD 0 4</p><p> 9 LOD 0 3</p><p> 10 OPR 0 2</p>
112、<p> 11 OPR 1 14</p><p> 12 LIT 0 65</p><p> 13 LIT 0 1</p><p> 14 OPR 0 2</p><p> 15 OPR 1 14</p><p> 16 LIT 0 72&l
113、t;/p><p> 17 OPR 1 14</p><p> 18 OPR 0 15</p><p> 19 OPR 0 0</p><p> ~~~ RUN PL0 ~~~</p><p><b> Input: 8</b></p><p>
114、; 5 = B H </p><p> ~~~ END PL0 ~~~</p><p><b> D、一維數(shù)組:</b></p><p><b> 初始化:</b></p><p> void ENTER(OBJECTS K, int LEV, int &TX, i
115、nt &DX) { /*ENTER OBJECT INTO TABLE*/</p><p><b> TX++;</b></p><p> strcpy(TABLE[TX].NAME,ID); TABLE[TX].KIND=K;</p><p> TABLE[TX].STYLE=VSTYLE;</p><p&g
116、t; switch (K) {</p><p> case CONSTANT:</p><p><b> GetSym();</b></p><p> if(CHCH==VSTYLE)</p><p><b> {</b></p><p> TABLE[TX].c
117、CHAR=VALUE;</p><p><b> }</b></p><p> else if(INTINT==VSTYLE)</p><p><b> {</b></p><p> if (NUM>IMAX) { Error(31); NUM=0; }</p><
118、;p> TABLE[TX].VAL=NUM;</p><p> } else Error(34);</p><p><b> break;</b></p><p> case VARIABLE:</p><p><b> GetSym();</b></p><p&
119、gt; if(LMPAREN==SYM)</p><p><b> {</b></p><p><b> GetSym();</b></p><p> if(SYM==NUMBER&&NUM+DX<AMAX)</p><p><b> {</b>
120、</p><p> TABLE[TX].vp.SIZE=NUM;</p><p> TABLE[TX].vp.ADR=DX;</p><p><b> DX+=NUM;</b></p><p> // NEWARRAY(NUM,DX);</p><p><b> GetSym(
121、);</b></p><p> if(RMPAREN!=SYM)Error(35);</p><p> else GetSym();</p><p><b> }</b></p><p><b> //數(shù)組的處理</b></p><p> else Er
122、ror(36);</p><p><b> }</b></p><p><b> else {</b></p><p> TABLE[TX].vp.LEVEL=LEV; TABLE[TX].vp.ADR=DX;</p><p> TABLE[TX].vp.SIZE=0; //0在這里只是用來
123、標識變量A和數(shù)組A[1]的差別</p><p><b> DX++;</b></p><p><b> }</b></p><p><b> break;</b></p><p> case PROCEDUR:</p><p> TABLE[T
124、X].vp.LEVEL=LEV;</p><p><b> break;</b></p><p><b> }</b></p><p> } /*ENTER*/</p><p> 其它代碼大部分也有涉及,為了能夠使數(shù)組和一般變量一樣參加運算,需要對其偏移地址進行計算,一般偏移地址計算后都會放
125、在棧頂,處理這個偏移量成了一個問題,主要有:如何讓賦值左邊的數(shù)組的偏移量不被先計算的賦值式右邊的數(shù)組偏移量所替代,因此在存儲上我的思路是:將偏移量放在棧頂先不處理,等到要賦值到數(shù)組元素的地址時,有兩種操作:ALD和AST,ALD根據(jù)棧頂這個便宜量+數(shù)組基址取得值放在這個頂上,此時偏移量被沖走;AST是棧頂為表達式算出的值,次棧頂為偏移量,將棧頂?shù)闹蹈鶕?jù)次棧頂?shù)钠屏抠x到正確的位置(有一個操作用于協(xié)助這兩個操作:ACP)。下面是這三個操作
126、的具體代碼:</p><p> case ACP: if(I.L!=0){</p><p> S[T+1]=S[T-I.A]; T++;</p><p><b> }</b></p><p><b> break;</b></p><p> case ALD: S[
127、T]=S[BASE(I.L,B,S)+I.A+S[T]];</p><p><b> break;</b></p><p> case AST: S[BASE(I.L,B,S)+I.A+S[T-1]]=S[T];</p><p><b> T-=2;</b></p><p><b>
128、 break;</b></p><p> 對這三個操作的應用在因子,語句中的輸入,變量中;因為時間不足,沒有實現(xiàn)數(shù)組的總體賦值A[2]={1,2}這種形式,只能單個賦值。沒有邊界判斷。</p><p><b> 測試程序:</b></p><p> PROGRAM EX01;</p><p> VA
129、R A,B[2],C;</p><p> VAR D[10];</p><p><b> BEGIN </b></p><p><b> B[0]:=1;</b></p><p><b> B[1]:=2;</b></p><p> FOR A
130、:=0 TO 10 DO</p><p><b> BEGIN</b></p><p> D[A]:=B[A/2]++;</p><p> PRINTLN(D[A]);</p><p><b> END;</b></p><p> PRINTLN(B[0],B[1]
131、);</p><p><b> END.</b></p><p><b> 測試結果:</b></p><p> === COMPILE PL0 ===</p><p> 0 PROGRAM EX01; </p><p> 0 VAR A,B[2],C; </
132、p><p> 1 VAR D[10]; </p><p><b> 1 BEGIN </b></p><p> 2 B[0]:=1; </p><p> 5 B[1]:=2; </p><p> 8 FOR A:=0 TO 10 DO </p><p> 1
133、1 BEGIN </p><p> 16 D[A]:=B[A/2]++; </p><p> 30 PRINTLN(D[A]); </p><p><b> 34 END; </b></p><p> 39 PRINTLN(B[0],B[1]); </p><p>&
134、lt;b> 46 END. </b></p><p> 0 JMP 0 1</p><p> 1 INI 0 17</p><p> 2 LIT 0 0</p><p> 3 LIT 0 1</p><p> 4 AST 0 4</p&
135、gt;<p> 5 LIT 0 1</p><p> 6 LIT 0 2</p><p> 7 AST 0 4</p><p> 8 LIT 0 0</p><p> 9 STO 0 3</p><p> 10 LIT 0 10<
136、/p><p> 11 STP 1 1</p><p> 12 LOD 0 3</p><p> 13 GTP 0 1</p><p> 14 OPR 0 10</p><p> 15 JPC 0 39</p><p> 16 LOD 0
137、 3</p><p> 17 LOD 0 3</p><p> 18 LIT 0 2</p><p> 19 OPR 0 5</p><p> 20 ACP 1 0</p><p> 21 ALD 0 4</p><p> 22
138、 LIT 0 1</p><p> 23 OPR 0 2</p><p> 24 AST 0 4</p><p> 25 ACP 1 -1</p><p> 26 ALD 0 4</p><p> 27 LIT 0 -1</p><p&
139、gt; 28 OPR 0 2</p><p> 29 AST 0 7</p><p> 30 LOD 0 3</p><p> 31 ALD 0 7</p><p> 32 OPR 0 14</p><p> 33 OPR 0 15</p>
140、<p> 34 LOD 0 3</p><p> 35 LIT 0 1</p><p> 36 OPR 0 2</p><p> 37 STO 0 3</p><p> 38 JMP 0 12</p><p> 39 LIT 0 0&l
141、t;/p><p> 40 ALD 0 4</p><p> 41 OPR 0 14</p><p> 42 LIT 0 1</p><p> 43 ALD 0 4</p><p> 44 OPR 0 14</p><p> 45 OPR
142、 0 15</p><p> 46 OPR 0 0</p><p> ~~~ RUN PL0 ~~~</p><p><b> 1 </b></p><p><b> 2 </b></p><p><b> 2 </b>
143、</p><p><b> 3 </b></p><p><b> 3 </b></p><p><b> 4 </b></p><p><b> 4 </b></p><p><b> 5
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 課程設計---pl0功能擴充
- pl0功能擴充課程設計
- 課程設計---PL0功能擴充.doc
- PL0功能擴充課程設計.doc
- 編譯原理課程設計-- pl0語言的擴充
- 編譯原理課程設計---pl0編輯器擴充
- 編譯原理課程設計--對pl0進行擴充和修改
- 編譯原理課程設計--對pl0進行擴充和修改
- 編譯原理課程設計報告--pl0編譯器的擴充
- 編譯原理課程設計--對PL0進行擴充和修改.doc
- 編譯原理pl0課程設計報告
- 編譯原理課程設計-pl_0編譯器及其擴充
- 編譯原理課程設計報告---pl0編譯程序改進及完善
- pl0擴展編譯器_設計文檔
- 編譯原理實驗報告pl0
- 第二章pl0編譯程序-
- 微機原理課程設計課程設計----微機內存擴充卡
- 微機原理課程設計課程設計----微機內存擴充卡
- 計算機組成原理課程設計---內存擴充與cpu連接
- 課程設計---多功能秒表
評論
0/150
提交評論