編譯原理課程設(shè)計---pl0編輯器擴充_第1頁
已閱讀1頁,還剩16頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p><b>  編譯原理課程設(shè)計</b></p><p>  題 目 __ _PL0編輯器擴充__ __</p><p>  學(xué) 院 計算機學(xué)院 </p><p>  專 業(yè) 軟件工程 </p><p>  2013 年 1 月 4

2、日</p><p><b>  課程設(shè)計目的與要求</b></p><p><b>  1、課程設(shè)計目的:</b></p><p>  在分析理解一個教學(xué)型編譯程序(如PL/0)的基礎(chǔ)上,對其詞法分析程序、語法分析程序和語義處理程序進行部分修改擴充。達到進一步了解程序編譯過程的基本原理和基本實現(xiàn)方法的目的。</p&g

3、t;<p><b>  2、課程設(shè)計要求:</b></p><p>  基本內(nèi)容(成績范圍:“中”、“及格”或“不及格”)</p><p> ?。?)擴充賦值運算:*= 和 /=</p><p>  擴充語句(Pascal的FOR語句):</p><p>  ①FOR <變量>:=<表達式

4、> TO <表達式> DO <語句></p><p>  ②FOR <變量>:=<表達式> DOWNTO <表達式> DO <語句></p><p>  其中,語句①的循環(huán)變量的步長為2,</p><p>  語句②的循環(huán)變量的步長為-2。</p><p> ?。?

5、)增加運算:++ 和 --。</p><p>  選做內(nèi)容(成績評定范圍擴大到:“優(yōu)”和“良”)</p><p> ?。?)增加類型:① 字符類型; ② 實數(shù)類型。</p><p> ?。?)擴充函數(shù):① 有返回值和返回語句;② 有參數(shù)函數(shù)。</p><p>  (3)增加一維數(shù)組類型(可增加指令)。</p>

6、<p> ?。?)其他典型語言設(shè)施。</p><p><b>  二、結(jié)構(gòu)設(shè)計方案 </b></p><p><b>  結(jié)構(gòu)設(shè)計說明:</b></p><p>  PL/0的編譯程序以語法分析程序為核心,詞法分析程序和代碼生成程序都作為一個獨立的過程,當(dāng)語法分析需要讀單詞時就用詞法分析程序,而當(dāng)語法分析正確需生

7、成相應(yīng)的目標(biāo)代碼時,則調(diào)用代碼生成程序。此外,用表格管理程序建立變量,常量和過程標(biāo)識符的說明與引用之間的信息聯(lián)系。用出錯處理程序?qū)υ~法和語法分析遇到的錯誤給出在源程序中出錯的位置和錯誤性質(zhì)。</p><p><b>  各功能模塊圖示:</b></p><p>  3. 各功能模塊作用表:</p><p>  3. 符號名字表結(jié)構(gòu):</p

8、><p>  struct tablestruct</p><p><b>  {</b></p><p>  char name[al]; /*名字*/</p><p>  enum object kind; /*類型:const,var,array or procedure*/</p>&

9、lt;p>  int val; /*數(shù)值,僅const使用*/</p><p>  int level; /*所處層,僅const不使用*/</p><p>  int adr; /*地址,僅const不使用*/</p><p>  int size; /*需要分配的數(shù)據(jù)

10、區(qū)空間,僅procedure使用*/</p><p><b>  };</b></p><p>  4. 保留關(guān)鍵字枚舉結(jié)構(gòu):</p><p>  enum symbol{</p><p>  nul, ident, number, plus,minus,</p><p>  t

11、imes, slash, oddsym, eql, neq,</p><p>  lss, leq, gtr, geq,lparen,</p><p>  rparen, comma, semicolon, period, becomes,</p><p>  beginsym, endsym,if

12、sym, thensym, whilesym,</p><p>  writesym, readsym, dosym, callsym, constsym,</p><p>  varsym, procsym, elsesym, forsym, tosym,</p><p>  downtosym, returnsym,

13、 pluseql, minuseql, plusplus,</p><p>  minusminus, </p><p><b>  };</b></p><p>  5.名字表中標(biāo)識符枚舉類型:</p><p>

14、  enum object{</p><p>  constant, /*常量*/</p><p>  variable, /*變量*/</p><p>  procedur, /*過程*/</p><p><b>  };</b></p><p>

15、  6. 運行時存儲組織和管理</p><p>  對于源程序的每一個過程(包括主程序),在被調(diào)用時,首先在數(shù)據(jù)段中開辟三個空間,存放靜態(tài)鏈SL、動態(tài)鏈DL和返回地址RA。靜態(tài)鏈記錄了定義該過程的直接外過程(或主程序)運行時最新數(shù)據(jù)段的基地址。動態(tài)鏈記錄調(diào)用該過程前正在運行的過程的數(shù)據(jù)段基址。返回地址記錄了調(diào)用該過程時程序運行的斷點位置。對于主程序來說,SL、DL和RA的值均置為0。靜態(tài)鏈的功能是在一個子過程要引

16、用它的直接或間接父過程(這里的父過程是按定義過程時的嵌套情況來定的,而不是按執(zhí)行時的調(diào)用順序定的)的變量時,可以通過靜態(tài)鏈,跳過個數(shù)為層差的數(shù)據(jù)段,找到包含要引用的變量所在的數(shù)據(jù)段基址,然后通過偏移地址訪問它?! ≡谶^程返回時,解釋程序通過返回地址恢復(fù)指令指針的值到調(diào)用前的地址,通過當(dāng)前段基址恢復(fù)數(shù)據(jù)段分配指針,通過動態(tài)鏈恢復(fù)局部段基址指針。實現(xiàn)子過程的返回。對于主程序來說,解釋程序會遇到返回地址為0的情況,這時就認為程序運行結(jié)束。

17、  解釋程序過程中的base函數(shù)的功能,就是用于沿著靜態(tài)鏈,向前查找相差指定層數(shù)的局部數(shù)據(jù)段基址。這在使用sto、lod、stoArr、lodArr等訪問局部變量的指令中會經(jīng)常用到?! ☆怭CO</p><p>  7. 擴充賦值運算:+= 和 -= 設(shè)計:</p><p>  對于+=、-=、*=和/=賦值運算符,在程序中出現(xiàn)的情況只有如下一種,文法的EBNF 表示為:</p&g

18、t;<p>  賦值語句::= <標(biāo)識符> [ += | -= ] <表達式></p><p>  (1)擴充的語法描述見結(jié)構(gòu)設(shè)計中的 PL/0 分程序和主要語句的語法描述中的描述圖;</p><p> ?。?)分析區(qū)別賦值運算符采用:讀標(biāo)識符后再讀一個字符,后根據(jù)讀到的字符轉(zhuǎn)去不同的賦值語句執(zhí)行。</p><p>  (3

19、)中間代碼生成情況:+=運算符,其他賦值運算符架構(gòu)是一樣的,只是執(zhí)行加法改為相應(yīng)的算數(shù)運算。</p><p>  else if(sym==pluseql) //檢測到+=符號</p><p><b>  {</b></p><p>  i=position(id,*ptx);

20、 //把類x+=3的x的地址取出來</p><p>  gendo(lod,lev-table[i].level,table[i].adr); /*找到變量地址并將其值入棧*/</p><p><b>  getsymdo;</b></p><p>  if(sym==semicolon)</p>

21、;<p><b>  {</b></p><p><b>  getsymdo;</b></p><p><b>  }</b></p><p>  memcpy(nxtlev,fsys,sizeof(bool)* symnum);</p><p>  expre

22、ssiondo(nxtlev,ptx,lev);</p><p>  gendo(opr,0,2);</p><p><b>  if(i!=0)</b></p><p><b>  {</b></p><p>  gendo(sto,lev-table[i].level,table[i].adr)

23、;</p><p><b>  }</b></p><p><b>  }</b></p><p>  else if(sym==minuseql) //檢測到-=符號</p><p><b>  {</b></p&

24、gt;<p>  i=position(id,*ptx); //把類x-=3的x的地址取出來</p><p>  gendo(lod,lev-table[i].level,table[i].adr); /*找到變量地址并將其值入棧*/</p><p><b>  getsymdo;</b>&l

25、t;/p><p>  if(sym==semicolon)</p><p><b>  {</b></p><p><b>  getsymdo;</b></p><p><b>  }</b></p><p>  memcpy(nxtlev,fsys,si

26、zeof(bool)* symnum);</p><p>  expressiondo(nxtlev,ptx,lev);</p><p>  gendo(opr,0,3);</p><p><b>  if(i!=0)</b></p><p><b>  {</b></p><p

27、>  gendo(sto,lev-table[i].level,table[i].adr);</p><p><b>  }</b></p><p><b>  }</b></p><p>  8.擴充語句(Pascal的FOR語句):</p><p> ?、貴OR <變量&g

28、t;:=<表達式> TO <表達式> DO <語句></p><p> ?、贔OR <變量>:=<表達式> DOWNTO <表達式> DO <語句></p><p>  其中,語句①的循環(huán)變量的步長為2,</p><p>  語句②的循環(huán)變量的步長為-2</p><

29、;p>  For i:= E1 to E2 do S1 循環(huán)語句ALGOL等價于:</p><p><b>  i:= E1;</b></p><p>  goto OVER;</p><p>  AGAIN :i:= i+2</p><p>  OVER : if i<E2 then </p>

30、;<p><b>  Begin S1;</b></p><p>  goto again end;</p><p>  注意程序中基礎(chǔ)用到循環(huán)控制變量i,因此 entry(i)必須被保存下來,而Pascal這樣的語言中,循環(huán)變量在循環(huán)外也是可見的,本次擴充約定循環(huán)步長為 2或者-2。具體需要在程序staement()添加for的句法判斷:</p&

31、gt;<p>  else if(sym==forsym) //檢測到for語句</p><p><b>  {</b></p><p><b>  getsymdo;</b></p><p>  if(sym==ident)</p><p><b>  {<

32、/b></p><p>  i=position(id,*ptx);</p><p>  if(i==0) error(11);</p><p><b>  else</b></p><p><b>  {</b></p><p>  if(table[i].kind!

33、=variable) //賦值語句中,賦值號左部標(biāo)識符屬性應(yīng)是變量</p><p><b>  {</b></p><p>  error(12);i=0;</p><p><b>  }</b></p><p><b>  else</b></p><p&

34、gt;<b>  {</b></p><p><b>  getsymdo;</b></p><p>  if(sym!=becomes) error(13); //賦值語句左部標(biāo)識符后應(yīng)是賦值號:=</p><p>  else getsymdo;</p><p>  me

35、mcpy(nxtlev,fsys,sizeof(bool)*symnum); </p><p>  nxtlev[tosym]=true; //后跟符to和downto</p><p>  nxtlev[downtosym]=true;</p><p>  expressiondo(nxtlev,ptx,lev);

36、 //處理賦值語句右部的表達式E1</p><p>  gendo(sto,lev-table[i].level,table[i].adr); //保存初值</p><p>  switch(sym)</p><p><b>  {</b></p><p>  case tosym: //步長

37、為的向上增加</p><p><b>  getsymdo;</b></p><p>  cx1=cx; //保存循環(huán)開始點</p><p>  //將循環(huán)判斷變量取出放到棧頂</p><p>  gendo(lod,lev-table[i].level,table[i].adr);

38、 memcpy(nxtlev,fsys,sizeof(bool)*symnum); //處理表達式E2</p><p>  nxtlev[dosym]=true; //后跟符do</p><p>  expressiondo(nxtlev,ptx,lev);</p><p>  gendo

39、(opr,0,13); //生成比較指令,i是否小于等于E2的值</p><p>  cx2=cx; //保存循環(huán)結(jié)束點</p><p>  //生成條件跳轉(zhuǎn)指令,跳出循環(huán),跳出的地址未知</p><p>  gendo(jpc,0,0);</p><p>  if

40、(sym==dosym) //處理循環(huán)體S</p><p><b>  {</b></p><p><b>  getsymdo;</b></p><p>  statement(fsys,ptx,lev); //循環(huán)體處理</p><p>  //增加循環(huán)變量步長為&

41、lt;/p><p>  //將循環(huán)變量取出放在棧頂</p><p>  gendo(lod,lev-table[i].level,table[i].adr); gendo(lit,0,1); //將步長取到棧頂</p><p>  gendo(opr,0,2);

42、 //循環(huán)變量加步長</p><p>  //將棧頂?shù)闹荡嫒胙h(huán)變量</p><p>  gendo(sto,lev-table[i].level,table[i].adr); </p><p>  gendo(jmp,0,cx1); //無條件跳轉(zhuǎn)到循環(huán)開始點</p><p&

43、gt;  code[cx2].a=cx;</p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  error(29); //for語句中少了do</p>&

44、lt;p><b>  }</b></p><p><b>  break;</b></p><p>  case downtosym: //步長為的向下減少</p><p><b>  getsymdo;</b></p><p>  cx1=cx;

45、 //保存循環(huán)開始點</p><p>  //將循環(huán)判斷變量取出放到棧頂</p><p>  gendo(lod,lev-table[i].level,table[i].adr); memcpy(nxtlev,fsys,sizeof(bool)*symnum); //處理表達式E2</p>

46、;<p>  nxtlev[dosym]=true; //后跟符do</p><p>  expressiondo(nxtlev,ptx,lev);</p><p>  gendo(opr,0,11); //生成比較指令,i是否大于等于E2的值</p><p>  cx2=cx;

47、 //保存循環(huán)結(jié)束點</p><p>  //生成條件跳轉(zhuǎn)指令,跳出循環(huán),跳出的地址未知</p><p>  gendo(jpc,0,0); </p><p>  if(sym==dosym) //處理循環(huán)體S</p><p><b>  {</b></p><p&g

48、t;<b>  getsymdo;</b></p><p>  statement(fsys,ptx,lev); //循環(huán)體處理</p><p>  //增加循環(huán)變量步長為</p><p>  //將循環(huán)變量取出放在棧頂</p><p>  gendo(lod,lev-table[i].level,table[i].

49、adr); gendo(lit,0,1); //將步長取到棧頂</p><p>  gendo(opr,0,3); //循環(huán)變量加步長</p><p>  //將棧頂?shù)闹荡嫒胙h(huán)變量</p><p>  gendo(sto,lev

50、-table[i].level,table[i].adr); gendo(jmp,0,cx1); //無條件跳轉(zhuǎn)到循環(huán)開始點</p><p>  code[cx2].a=cx;</p><p><b>  }</b></p><p><b>  else </b>

51、</p><p><b>  {</b></p><p>  error(29);//for語句中少了do</p><p><b>  }</b></p><p><b>  break;</b></p><p><b>  }</b&g

52、t;</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  else </b></p><p><b>  {</b>

53、;</p><p>  error(19); //for語句后跟賦值語句,賦值語句左部是變量,缺少變量</p><p><b>  }</b></p><p><b>  }</b></p><p>  11. 增加運算:++ 和 -- :</p><p> 

54、 對于++和--運算符,擴充時要注意存在++,--有兩個情況:1、作為語句的時候;2、作為表達式中的因子的時候.</p><p>  (1) 作為語句的時候,有四種情況:</p><p>  A++ ++A A-- --A</p><p>  文法的 EBNF 表示形式為:</p><p>  <自增自減語句>::=&l

55、t;標(biāo)識符>[ ++ | -- ] | [ ++ | -- ]<標(biāo)識符></p><p>  (2) 作為因子的時候,有兩種情況</p><p>  a++和 a--作為因子,比如:b:=a++*a--;語句</p><p>  ++a 和--a 作為因子,比如:b:= --a+2*++a;語句</p><p>  文法的

56、EBNF 表示形式為:</p><p>  <表達式>::=...[ ++ | -- ]<標(biāo)識符>|<標(biāo)識符>[ ++ | -- ]...</p><p>  其中的...表示前后都可以有其他的項或因子</p><p>  (1)作為語句 ++ -- 符號分為以下兩種情況考慮:</p><p>  情況1對

57、于自增自減符號置后的只需要在判斷+= -=后面添加句法分析即可:</p><p>  /*************后置自增符號 a++ a--類型添加代碼****************************/</p><p>  else if(sym==plusplus) //檢測到后置++符號</p><p>&

58、lt;b>  {</b></p><p>  gendo(lit,0,1);</p><p>  gendo(lod,lev-table[i].level,table[i].adr); /*找到變量地址并將其值入棧*/</p><p>  gendo(opr,0,2); //執(zhí)行加操作,</p>

59、<p><b>  if(i!=0)</b></p><p><b>  {</b></p><p>  gendo(sto,lev-table[i].level,table[i].adr);</p><p><b>  }</b></p><p><b&g

60、t;  getsymdo;</b></p><p><b>  }</b></p><p>  else if(sym==minusminus) //檢測到后置--符號</p><p><b>  {</b></p><p>  gendo

61、(lod,lev-table[i].level,table[i].adr); /*找到變量地址并將其值入棧*/</p><p>  gendo(lit,0,1);</p><p>  gendo(opr,0,3); //執(zhí)行減操作,</p><p><b>  if(i!=0)</b>&

62、lt;/p><p><b>  {</b></p><p>  gendo(sto,lev-table[i].level,table[i].adr);</p><p><b>  }</b></p><p>  getsymdo;</p><p><b>  

63、}</b></p><p>  情況2對于++ --前置的需要添加因子開始符號:</p><p>  facbegsys[plusplus]=true; /***增加符號++開始因子plusplus***/</p><p>  facbegsys[minusminus]=true; /***增加符號--開始因子minusminu

64、s***/</p><p>  /***************前置自增符號 ++a - -a類型添加代碼****************************/</p><p>  if(sym==plusplus)</p><p><b>  {</b></p><p><b>  getsymdo;&l

65、t;/b></p><p>  if(sym==ident) //后面跟的是變量</p><p><b>  {</b></p><p>  i=position(id,*ptx);</p><p><b>  if

66、(i==0)</b></p><p><b>  {</b></p><p>  error(11);</p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b

67、></p><p>  if(table[i].kind!=variable) //++后沒跟變量,出錯</p><p><b>  {</b></p><p>  error(12);</p><p><b>  i=0;</b></p&

68、gt;<p><b>  }</b></p><p>  else //++后跟變量,處理生成中間代碼</p><p><b>  {</b></p><p>  if(table[i].kind==variable)&l

69、t;/p><p><b>  {</b></p><p>  gendo(lod,lev-table[i].level,table[i].adr);//先取值到棧頂</p><p>  gendo(lit,0,1); //將值為入棧</p><p>  gendo(opr

70、,0,2); //加法,即+1,棧頂加次棧頂</p><p>  gendo(sto,lev-table[i].level,table[i].adr);//出棧取值到內(nèi)存</p><p><b>  getsymdo;</b></p><p><b>  }</b>&l

71、t;/p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  else if(sym==minusminus)<

72、;/p><p><b>  {</b></p><p><b>  getsymdo;</b></p><p>  if(sym==ident) //后面跟的是變量</p><p><b>  {</

73、b></p><p>  i=position(id,*ptx);</p><p><b>  if(i==0)</b></p><p><b>  {</b></p><p>  error(11);</p><p><b>  }</b><

74、;/p><p><b>  else</b></p><p><b>  {</b></p><p>  if(table[i].kind!=variable) //--后沒跟變量,出錯</p><p><b>  {</b></

75、p><p>  error(12);</p><p><b>  i=0;</b></p><p><b>  }</b></p><p>  else //--后跟變量,處理生成中間代碼</p>&l

76、t;p><b>  {</b></p><p>  if(table[i].kind==variable) //后跟變量</p><p><b>  {</b></p><p>  gendo(lod,lev-table[i].level,table[i].adr);//先取值到

77、棧頂</p><p>  gendo(lit,0,1); //將值為入棧</p><p>  gendo(opr,0,3); //加法,即-1,棧頂減次棧頂</p><p>  gendo(sto,lev-table[i].level,table[i].adr

78、);//出棧取值到內(nèi)存</p><p><b>  getsymdo;</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>

79、;  }</b></p><p><b>  }</b></p><p> ?。?)作為因子的時候也有兩種情形考慮:</p><p>  添加int factor(bool*fsys,int *ptx,int lev)函數(shù)如下:</p><p>  /********************如果因子可能出現(xiàn)b

80、:=a++或b:=a--類型的處理******************/if(sym==plusplus)</p><p><b>  {</b></p><p>  gendo(lit,lev-table[i].level,1); //將值為入棧</p><p>  gendo(opr,lev-table[i].le

81、vel,2); //加法,即+1,棧頂加次棧頂</p><p>  gendo(sto,lev-table[i].level,table[i].adr); //出棧取值到內(nèi)存</p><p>  gendo(lod,lev-table[i].level,table[i].adr); //取值到棧頂</p><p>  gendo(lit,0,1

82、);</p><p>  gendo(opr,0,3); //棧頂值減</p><p><b>  getsymdo;</b></p><p><b>  }</b></p><p>  else if(sym==minusminus)<

83、/p><p><b>  {</b></p><p>  gendo(lit,lev-table[i].level,1); //將值為入棧</p><p>  gendo(opr,lev-table[i].level,3); //減法,即-1,棧頂減次棧頂</p><p>  ge

84、ndo(sto,lev-table[i].level,table[i].adr); //出棧取值到內(nèi)存</p><p>  gendo(lod,lev-table[i].level,table[i].adr);</p><p>  gendo(lit,0,1);</p><p>  gendo(opr,0,2);

85、 //棧頂值加</p><p><b>  getsymdo;</b></p><p>  } /********************************************************************************/</p><p>  /************如果因子是表達式的時候,則有可能是包

86、含++a或者--a,如b:=++a或b:=--a ********/</p><p>  else if(sym==plusplus)</p><p><b>  {</b></p><p><b>  getsymdo;</b></p><p>  if(sym==ident)</p>

87、<p><b>  {</b></p><p><b>  getsymdo;</b></p><p>  i=position(id,*ptx);</p><p><b>  if(i==0)</b></p><p><b>  {</b>

88、</p><p>  error(11);</p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  if(table[i].kind==variable) //變

89、量</p><p><b>  {</b></p><p><b>  //先加后再用a</b></p><p>  gendo(lod,lev-table[i].level,table[i].adr);//先取值到棧頂</p><p>  gendo(lit,0,1);//將值為入棧</p&

90、gt;<p>  gendo(opr,0,2);//加法,即+1,棧頂加次棧頂</p><p>  gendo(sto,lev-table[i].level,table[i].adr);//出棧取值到內(nèi)存</p><p>  gendo(lod,lev-table[i].level,table[i].adr); //取值到棧頂}</p><p&g

91、t;<b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  else if(sym==minusminus)</p><p><b>  {</b></p><p>

92、;<b>  getsymdo;</b></p><p>  if(sym==ident)</p><p><b>  {</b></p><p><b>  getsymdo;</b></p><p>  i=position(id,*ptx);</p><

93、;p><b>  if(i==0)</b></p><p><b>  {</b></p><p>  error(11);</p><p><b>  }</b></p><p><b>  else</b></p><p>

94、;<b>  {</b></p><p>  if(table[i].kind==variable) //變量</p><p><b>  {</b></p><p><b>  //先減后再用a</b></p><p>  gendo(lod,lev-table[i].le

95、vel,table[i].adr);//先取值到棧頂</p><p>  gendo(lit,0,1); //將值為入棧</p><p>  gendo(opr,0,3); //減法,即-1,棧頂減次棧頂</p><p>  gendo(sto,lev-table[i

96、].level,table[i].adr);//出棧取值到內(nèi)存</p><p>  gendo(lod,lev-table[i].level,table[i].adr); //取值到棧頂}</p><p><b>  }</b></p><p><b>  }</b></p><p>  

97、testdo(fsys,facbegsys,23); /*因子后有非法符號*/</p><p><b>  }</b></p><p><b>  程序測試</b></p><p>  擴充賦值運算:*= 和 /=</p><p>  測試文件 “test1”:<

98、/p><p><b>  運行結(jié)果:</b></p><p><b>  結(jié)果分析:</b></p><p>  a = 5 ,b = 48 , a*=3 結(jié)果為15正確,b/=6結(jié)果為8正確,擴充成功!</p><p>  擴充語句(Pascal的FOR語句):</p><p>

99、;  測試文件“test2”:</p><p><b>  運行結(jié)果:</b></p><p><b>  結(jié)果分析:</b></p><p>  For i=1 to 4 do “write(i)” 結(jié)果i= 1,3,</p><p>  For i=5 downto 1 do write(i)

100、 結(jié)果i= 5,3,1</p><p><b>  結(jié)果正確,</b></p><p>  For循環(huán)功能擴充成功!</p><p>  增加運算:++ 和 --。</p><p>  測試文件“test3”:</p><p><b>  運行結(jié)果:</b></p>

101、;<p><b>  結(jié)果分析:</b></p><p>  a=5 ,b:=6, a--結(jié)果為4,b++結(jié)果為7,結(jié)果正確 </p><p>  ++ ,--功能符號測試通過!</p><p><b>  實驗總結(jié)</b></p><p>  本次課程設(shè)計主要是在讀懂課

102、本附帶的PL/0 編譯器程序C語言版本后進行擴展和修改相關(guān)程序功能。</p><p>  通過課程設(shè)計,我對編譯器的工作原理和實現(xiàn)機制有了實際的了解和認識,進一步培養(yǎng)的編譯技術(shù)的設(shè)計思想,仔細閱讀 PL/0 的編譯程序C語言版本代碼,對詞法分析,句法分析在編程技巧和實際意義有了深刻的理解,從枯燥的理論學(xué)習(xí)到現(xiàn)在實際應(yīng)用過程對于我自身知識面的提升是巨大的。語法分析、句法分析在編譯原理中處于核心的地位,如何正確有效的

103、對它們分析提取決定了編譯后期工作方向,當(dāng)然中間代碼的如何有效的生成在編譯中也是個不小的難題,特別是其中堆棧的運用,當(dāng)然在理論上對于它們的理解程度大小也是決定設(shè)計調(diào)試</p><p><b>  難度的高低。</b></p><p>  擴展 += -= 符號相對比較簡單,只需要在語句分析模塊接著賦值符號的判斷添加就可以,對于for循環(huán)也是類似,只需要在語句分析模塊添加

104、對于for關(guān)鍵字的判斷,當(dāng)然要注意后繼符號to 還是 downto的判斷以決定步長遞增還是遞減。完成了基本功能擴展,我嘗試了++ --符號的添加,這兩個符號添加比較復(fù)雜,大體講有兩個用途情況,一個就是用在用戶標(biāo)識符,另一個就是在因子上也可能用到該功能,需要添加因子的功能判斷,具體來講這兩個符號又有兩種實現(xiàn)形式,分別是后置符號和前置符號,后置符號類似前面的+= -= 直接添加判斷即可,前置符號則除了要添加++ --的開始因子符號集外,還得

105、在語句分析模塊添加功能處理!</p><p>  總的來說,經(jīng)歷了數(shù)次的調(diào)試,功能擴展算是完成了,這次課程設(shè)計使我受益匪淺,除了更深了解了編譯技術(shù),還培養(yǎng)了發(fā)現(xiàn)問題、分析問題、解決問題的能力!</p><p><b>  附錄:</b></p><p>  源語言:PL/0語言 </p><p>  目標(biāo)語言:類PCOD

溫馨提示

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

評論

0/150

提交評論