




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、精選優(yōu)質(zhì)文檔-傾情為你奉上 一 、 實驗?zāi)康?通過在實驗二的基礎(chǔ)上,增加中間代碼生成部分,使程序能夠?qū)嶒灦械淖R別出的賦值語句,if語句和while語句進行語義分析,生成四元式中間代碼。二 、 實驗方法 實驗程序由c語言完成,在Turboc 2.0環(huán)境中調(diào)試通過。 語義分析程序的基本做法是對文法中的每個產(chǎn)生式分別編寫一個語義分析子程序,當程序語法部分進行推倒或規(guī)約時,就分別調(diào)用各自的語義分析程序。當語法分析結(jié)束時,語義分析也就結(jié)束了。 在本實驗程序中,當語法分析部分識別出語法正確的句子時,就進入content函數(shù)(當語法分析識別出不正確的句子時,不進入content函數(shù),也就是不進行語義分析
2、),然后根據(jù)句子的類型進行分類,進入不同的語義處理部分。 對于賦值語句,關(guān)鍵是產(chǎn)生正確的處理算術(shù)表達式E的四元式。程序中的ec函數(shù)的功能就是產(chǎn)生算術(shù)表達式的四元式,在ec函數(shù)中使用了兩個棧idshed,opshed,分別是算術(shù)表達式的數(shù)據(jù)棧和符號棧。每次提取一個數(shù)字和一個算符,然后將算符與與棧頂算符進行優(yōu)先級比較,優(yōu)先級高則將單前數(shù)字和算符進棧,低或者相等的話則將當前棧頂元素進行合并,產(chǎn)生四元式。直至整個算術(shù)表達式結(jié)束。其中還有一些細節(jié)問題,具體的做法可以參看程序。 對于實驗給定的if語句的文法格式,條件判斷式C只中可能是>或者<=兩種關(guān)系,不可能是布爾表達式,這樣程序就簡單的多了
3、。通過ec函數(shù)可以產(chǎn)生條件判斷式C中的E的四元式,然后只要加上轉(zhuǎn)向四元式就可以了。本實驗程序中只給出真出口的轉(zhuǎn)向四元式,沒有給出假出口的轉(zhuǎn)向四元式,這在實際中是不可以的,但在本實驗中,實際上是對每條獨立的語句進行語法分析,給出假出口轉(zhuǎn)向四元式實際上意義不大,而且假出口轉(zhuǎn)向語句的轉(zhuǎn)移目標必須要到整個語句分析結(jié)束以后才可以知道,這樣就要建立棧,然后回填,這樣會使程序復雜很多,所以沒有加上假出口轉(zhuǎn)向四元式。 對于while語句,具體的做法和if語句差不多,所不同的是當while語句結(jié)束時,要多出一條無條件轉(zhuǎn)向四元式,重新轉(zhuǎn)到條件判斷式C的第一條四元式。當要產(chǎn)生無條件轉(zhuǎn)向四元式時,它的轉(zhuǎn)向目標C的第一
4、條四元式已經(jīng)產(chǎn)生了,所以具體的做起來是不太困難的。只要記下當前while中的C的第一條四元式的位置,填上就可以了。 整個程序的結(jié)束是當讀入“ . ”時,程序就中止。 程序中還有很多細節(jié)問題,具體的可以后面的附錄:程序的完整代碼。三 、 測試程序 ff:=6+6*6-; if sl>89+56*67 then f:=7*7+4; ff:=6+6*6-6%4+8; if sl+78*76>89*56+67 then while a-7>98+45*45 do f:=7*7+4; . 四 、 運行結(jié)果 首先對測試程序進行語法分析,識別出正確的句子,當識別出正確的句子時,就對當前句子
5、進行語義分析,而語法不正確的句子不進行語義分析。ff:=6+6*6- Error(4):Except ID or NUM ; Error(2):Syntax error if sl>89+56*67 then f:=7*7+4; success!(1) *, 56, 67, T1 (2) +, 89, T1, T2 (3) j>, sl, T2, (4) (4) *, 7, 7, T3 (5) +, T3, 4, T4 (6) :=, T4, -, f ff:=6+6*6-6%4+8; success!(7) *, 6, 6, T5 (8) +, 6, T5, T6 (9) %,
6、6, 4, T7 (10) -, T6, T7, T8 (11) +, T8, 8, T9 (12) :=, T9, -, ff if sl+78*76>89*56+67 then while a-7>98+45*45 do f:=7*7+4; success!(13) *, 78, 76, T10 (14) +, sl,T10, T11 (15) *, 89, 56, T12 (16) +,T12, 67, T13 (17) j>, T11, T13, (18) (18) -, a, 7, T14 (19) *, 45, 45, T15 (20) +, 98,T15, T1
7、6 (21) j>, T14, T16, (22) (22) *, 7, 7, T17 (23) +,T17, 4, T18 (24) :=, T18, -, f (25) j, _, _, (18). Error(2):Syntax error 五 、 實驗小結(jié) 終于完成了編譯原理的三次實驗,這幾次實驗使我們更徹底地鞏固了編譯原理。從詷法分析到語法分析直到這次的中間代碼都是看似簡單的基礎(chǔ)知識,卻花了不少時間對課本多次反復研究、請教學習,進行深層次地探討才找出編程時出現(xiàn)的種種問題。還有很多程序方面很細節(jié)的問題,很容易被突略,卻往往又是關(guān)鍵。 總地來說,雖然實驗做得很辛苦,但真的可以從實驗
8、當中學習到很多,認識到很多。并對編譯理解也透徹了許多,比較清晰地掌握了編譯程序的原理和方法。 附錄: #include<string.h>#include<stdio.h>#include<stdlib.h> #define reser 20 char *charstring="abcdefghijklmnopqrstuvwxyz" char *numstring="" char *strstring="abcdefghijklmnopqrstuvwxyz" char reservereser10;
9、 char idshed4010,opshed4010; char token15,id15,sym15; char line80,tempp240; char ch,ch1,temp,tem; char tx10; char tn4,signt120,signt220,ju20; int cc,ii,k,num,kind,t,e4=0,e3=0,judge=1,row1=0; int startc,idsh=0,opsh=0,tt=1,nn=1,signwh,over=0,adds=0,whs=0,pp=0; int li=0; char filename15; FILE *fp;void
10、getch() if(li=0) if (cc=ii) cc=1; ii=0; if (row1=1) fseek(fp,-1,1); /*讀行首字符將指針退回一格,若是整個文本的開頭,則不需要*/ line0=fgetc(fp); row1=1; while(temp=fgetc(fp)!='n') && (temp!=EOF) linecc=temp;cc+; tempppp=temp;pp+; linecc=' ' /*將緩沖帶后加上一個空字符,以便行和行之間號區(qū)分 */ cc+; tempppp=' ' pp+; whil
11、e(temp=fgetc(fp)='n') && (temp!=EOF); /* 跳過空行*/ linecc='0' tem=lineii; ii+; ch=tem; else ch=tempppp; pp+; void getnbc()getch();while (ch=' ') getch(); if (ch='') do getch(); while( ch=''); getnbc(); void retract() ii-; void ret() pp-;int jchar(char ch)
12、 /* 判斷ch是不是字母 */if(strchr(charstring,ch)=0) return 0; else return 1;int jnum(char ch) /* 判斷ch是不是數(shù)字 */if(strchr(numstring,ch)=0) return 0; else return 1;int jstr(char ch) /* 判斷ch是不是字母或數(shù)字 */if(strchr(strstring,ch)=0) return 0; else return 1;void advance() getnbc(); kind=0; if (jchar(ch)=1) k=0; do if(
13、k<15) tokenk=ch; k+;getch(); while(jstr(ch)=1); if (li=0) retract(); else ret(); tokenk='0' /*截去token中的無用字符*/ strcpy(id,token); for(t =0;t<=20;t+) if(strcmp(reservet,id)=0) break; if ( t<=20 ) kind=t ; else kind=21; strcpy(sym,id); else if (jnum(ch)=1) k=0;do if ( k<15 ) tokenk=c
14、h; k+; getch(); while( jstr(ch)=1); if (li=0) retract(); else ret();kind=22;tokenk='0'strcpy(sym,token); else if(ch='.') kind=26; k=0; do symk=' ' k+; while(k!=15); sym0=ch; sym1='0' void error(int n) judge=0; /*出錯退出,將judge0*/ switch(n) case 0:printf(" Error(0):E
15、xpect ':' n"); break; case 1:printf(" Error(1):Expect '=' n"); break; case 2:printf(" Error(2):Syntax error n");break; case 3:printf(" Error(3):Except Operater n");break; case 4:printf(" Error(4):Except ID or NUM n");break; case 5:printf(&
16、quot; Error(5):Except '' n");break; case 6:printf(" Error(6):Except '<' or '>'n");break; case 7:printf(" Error(7):Except '=' n" );break; case 8:printf(" Error(8):Except 'then' n");break; case 9:printf(" Error(9):Ex
17、cept Condition Expressionn ");break; case 10:printf(" Error(10):Except 'do' ");break; default: ; void e() advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) printf("%s",sym); advance();
18、 if(kind=21) | (kind=22) /* kind為21,22分別表示的是標志符和數(shù)字 */ printf("%s",sym); e(); else e4=1 ;error(4); /*出錯退出,e4=1*/ void c() advance(); if(kind=21) | (kind=22) printf("%s",sym); e(); if(e4=1); /*e4的作用是判斷程序從e()中是不是出錯退出*/else if(strcmp(sym,">")=0) printf("%s",sym
19、); advance(); if(kind=21) | (kind=22) printf("%s",sym); e(); elseerror(4); else if(strcmp(sym,"<")=0) printf("%s",sym); advance();if(strcmp(sym,"=")=0) printf("%s",sym); advance(); if(kind=21) | (kind=22) printf("%s",sym); e();elseerror(
20、4); elseerror(7); elseerror(6); elsee3=1; error(9); /*出錯退出,e3=1*/ void statement() if(judge=1) /*judge的作用為判斷程序是不是出錯退出,若是,則無需advance()*/ advance(); switch (kind) case 21: /* id */ printf("%s",sym); advance(); if(strcmp(sym,":")=0) printf("%s",sym);advance(); if(strcmp(sy
21、m,"=")=0) printf("%s",sym); advance(); if(kind=21) | (kind=22) printf("%s",sym); e(); if(e4=1) ; else if(strcmp(sym,"")=0) printf("%s",sym); judge=1; printf(" success!n"); startc=1; else error(5); e4=0; /*將e4重新置為0,以免對下面程序有影響*/ else error(4)
22、; else error(1); else error(0); break; case 8: printf("%s ",sym); /* if */ c(); if(e4=1); else if(e3=1); /*e3的作用是判斷程序從c()中是不是出錯退出*/ else if(strcmp(sym,"then")=0)printf(" %s ",sym); statement(); elseerror(8); e3=0; /*將e3重新置為0,以免對下面程序有影響*/ e4=0; break; case 19: /* while *
23、/ printf("%s ",sym); c(); if(e4=1); else if(e3=1); else if(strcmp(sym,"do")=0)printf(" %s ",sym); statement(); elseerror(10); e3=0; e4=0; break; default: printf("%s ",sym);error(2); judge=1; break; void pushid()strcpy(idshedidsh,sym);idsh+; void pushop() strcp
24、y(opshedopsh,sym); opsh+; void gen(char op10,char a10,char b10) printf("(%d) %2s,%3s,%3s, T%d n",nn,op,a,b,tt);tt+;nn+; itoa(tt-1,tn,10); strcpy(tx,"T"); strcat(tx,tn); void ec() advance(); pushop(); advance(); pushid(); if(strcmp(opshedopsh-1,"*")=0)|(strcmp(opshedopsh
25、-1,"%")=0) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1);opsh-;idsh=idsh-1;strcpy(idshedidsh-1,tx); else if(strcmp(opshedopsh-1,"+")=0)|(strcmp(opshedopsh-1,"-")=0) adds=1;if(strcmp(opshedopsh-2,"+")=0)|(strcmp(opshedopsh-2,"-")=0) gen(opshedopsh-2,ids
26、hedidsh-3,idshedidsh-2);strcpy(idshedidsh-2,tx); advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strc mp(sym,"%")=0) if (li=0) retract(); else ret(); ec(); void content() int reu; reu=nn; switch(kind) case 21:advance();advance();advan
27、ce();pushid(); advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) if (li=0) retract(); else ret();ec(); if (adds=1) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1); adds=0; printf("(%d) :=, %s, -, %s n",nn,tx,ids
28、hed0); nn+; idsh=0; opsh=0; else printf("(%d) :=, %s, -, %s n",nn,idshed1,idshed0); nn+;break; case 8: idsh=0; opsh=0;advance();pushid(); advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) if (li=0) retract()
29、; else ret(); ec(); if(adds=1) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1);adds=0; strcpy(signt1,tx); idsh=0; opsh=0; else strcpy(signt1,idshed0); if(strcmp(sym,">")=0) strcpy(ju,"j>"); else strcpy(ju,"j<="); advance(); idsh=0; opsh=0; advance(); pushid(); adva
30、nce(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) if (li=0) retract(); else ret(); ec(); if (adds=1) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1); adds=0; strcpy(signt2,tx); idsh=0; opsh=0; else strcpy(signt2,idshed0); pri
31、ntf("(%d) %s, %s, %s, (%d) n",nn,ju,signt1,signt2,nn+1); nn+; advance(); idsh=0; opsh=0; if(kind=21) pushid(); content();break; case 19: idsh=0; opsh=0;advance();pushid(); advance(); if(strcmp(sym,"+")=0)|(strcmp(sym,"-")=0)|(strcmp(sym,"*")=0)|(strcmp(sym,"%")=0) if (li=0) retract(); else ret();ec(); if(adds=1) gen(opshedopsh-1,idshedidsh-2,idshedidsh-1);adds=0; strcpy(signt1,tx); idsh=0; opsh=0; else strcpy(signt1,idshed0); if(strcmp(sym,">")=0) strcpy(ju,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 時尚雜志插畫師聘用合同
- 內(nèi)科品管圈護理實踐應(yīng)用
- 大學生如何報考部隊文職
- 2024貿(mào)易公司簡介范文大全(35篇)
- 直腸癌患者術(shù)后健康宣教
- 廣發(fā)銀行工作總結(jié)專用
- 心外護理工作流程優(yōu)化
- 護理實踐指南:手術(shù)室人員管理
- 教育家學術(shù)體系解析
- 創(chuàng)造力與想象力培養(yǎng)課件
- 人教版七年級下冊數(shù)學全冊課件
- 全自動橡膠注射硫化成型機操作規(guī)程
- 申報正高工程師職稱技術(shù)總結(jié)范文
- 比亞迪秦PLUS EV說明書
- 幼兒園中班紅色經(jīng)典故事《抗日英雄王二小》紅色革命教育繪本故事PPT課件【幼兒教案】
- 貝雷法簡介及貝雷三參數(shù)在瀝青混合料配合級配設(shè)計中應(yīng)用
- 信用管理師(三級)理論考試題庫(300題)
- 電大《中國現(xiàn)代文學專題》期末復習題及答案
- 投標密封條格式大全
- (2023)國庫知識競賽題庫(含答案)
- 2023年北京理工附中小升初英語分班考試復習題
評論
0/150
提交評論