




已閱讀5頁(yè),還剩43頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
此文檔收集于網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系網(wǎng)站刪除二、課程設(shè)計(jì)正文1 編寫(xiě)一個(gè)L-語(yǔ)言的詞法分析器,從左到右逐個(gè)字符地對(duì)L-語(yǔ)言的源程序進(jìn)行掃描,產(chǎn)生一個(gè)個(gè)單詞符號(hào)的機(jī)內(nèi)表示。程序結(jié)構(gòu)如圖L-1所示: scanner IsAlpha IsNumberIsCharIsother OutPutError 圖 L-111 Sanner()1 功能:完成初始化,并循環(huán)調(diào)用子模塊,完成單詞的識(shí)別。2 算法描述如下Void Scanner() 調(diào)用ScannerInit()進(jìn)行初始化; 讀入源程序的第一個(gè)字符; while (字符!=EOF) if (字符= =字母)IsAlPha();else if ( 字符= = 數(shù)字) IsNumber(); else if (字符= =)IsChar(); else IsOther();打印結(jié)束信息;結(jié)束操作;12 IsAlPha() 1功能:識(shí)別保留字和標(biāo)識(shí)符。 2算法描述如下: Void IsAlPha() while(字符為字母或數(shù)字或_) 記錄當(dāng)前字符; 讀取下一字符;判斷當(dāng)前字符串是否為保留字,并設(shè)置標(biāo)志位h;調(diào)用OutPut()函數(shù)輸出保留字或標(biāo)識(shí)符; 13 IsNumber() 1功能:識(shí)別整數(shù)和實(shí)數(shù)。 2算法描述如下: void IsNumber() int flag=0; while (字符為數(shù)字) 記錄當(dāng)前字符; 讀取下一字符; If(字符為.號(hào)) 記錄當(dāng)前字符; flag=1; 讀下一字符; 跳出循環(huán);記單詞編碼為整數(shù)的編碼(當(dāng)前Token為整數(shù));If(flag=1) if (當(dāng)前字符為數(shù)字) 記錄當(dāng)前數(shù)字; while(當(dāng)前字符為數(shù)字) 記錄字符; 讀取下一字符;記單詞編碼為實(shí)數(shù)的編碼(當(dāng)前Token為實(shí)數(shù));else Error(2);if (當(dāng)前字符為.)刪除余下數(shù)字;if (當(dāng)前字符為字母) 舍去后面的部分;OutPut();14 IsChar() 1功能:識(shí)別字符串。 2算法描述: void IsChar() for (;) 讀取下一字符; 現(xiàn)行Token為字符串; If(當(dāng)前字符不是.號(hào)) 記錄字符; Else break;OutPut();讀下一字符;15 IsOther() 1功能:識(shí)別其他單詞。 2算法描述如下: void IsOther() switch(當(dāng)前字符) 對(duì)于不同字符做出不同處理,主要有: 1、符號(hào)內(nèi)容的記取; 2、查出機(jī)內(nèi)碼; 3、調(diào)用OutPut()輸出至Token()文件; 4、讀取下一字符; 5、對(duì)于錯(cuò)誤符號(hào)將其刪除,并報(bào)錯(cuò);16 ScannerInit() 1功能:進(jìn)行初始化,主要包括: 1、建立單詞編碼表、token表、符號(hào)表,并將它們清空。 2、打開(kāi)單詞編碼文件,并將單詞編碼讀到編碼表中。17 OutPut() 1功能:輸出識(shí)別出的單詞,包括: 2若單詞為標(biāo)識(shí)符或常數(shù)再查,填符號(hào)表。18 Error() 1.功能:判斷錯(cuò)誤原因。2在由詞法分析程序?qū)語(yǔ)言源程序分析產(chǎn)生的token,符號(hào)表文件的基礎(chǔ)上,從完成語(yǔ)法語(yǔ)義分析,并產(chǎn)生相應(yīng)的中間代碼-四元式序列。21 paser() 1功能:主模塊,完成初始化,并調(diào)用復(fù)合語(yǔ)句分析模塊和說(shuō)明語(yǔ)句分析模塊,完成分析任務(wù)。 2算法描述如下: void paser() 初始化; 從Token文件讀取第一個(gè)單詞; if (單詞= =program) 讀取下一單詞; if (單詞= =標(biāo)識(shí)符) 讀取下一單詞; if(單詞為;) 行數(shù)加一; 讀取下一單詞; if (單詞為var) declear( ); if (單詞為begin) S_Begin(); if (code 不是等于號(hào)) Error(49);else 出錯(cuò)處理;else 出錯(cuò)處理;else出錯(cuò)處理;else 出錯(cuò)處理;22 S_Begin() 1功能:完成復(fù)合語(yǔ)句的分析。 2算法描述 S_Begin() if (當(dāng)前字符為begin) 讀取下一字符; 調(diào)用L_Analize(); if(當(dāng)前字符為end) 結(jié)束; else 非正常結(jié)束,返回0;讀取下一字符;返回; 23 L_Analize() 1功能:完成語(yǔ)句序列分析。 2算法描述 L_Analize() int rtn; switch(當(dāng)前字符) case IF:調(diào)用S_IF()函數(shù);break; case BEGIN :調(diào)用S_Begin()函數(shù);braek; case 標(biāo)識(shí)符:調(diào)用 S_Let()函數(shù);break; case WHILE:調(diào)用 S_While();break;if (當(dāng)前字符為:) 行數(shù)加一; 讀取下一字符; 遞歸調(diào)用L_Analize()else return rtn;24 S_Let() 1功能:完成賦值語(yǔ)句的分析。 2算法分析 S_Let(int a) if (當(dāng)前字符為標(biāo)識(shí)符) if (需要記錄變量的地址) 記錄賦值變量的地址;讀取下一個(gè)單詞; if(當(dāng)前單詞為賦值號(hào)) 調(diào)用表達(dá)式分析函數(shù)L_Analize(); if(表達(dá)式正確) 生成賦值句四元式;else 賦值句出錯(cuò);return四元式序號(hào);25 S_IF() 1功能:完成條件語(yǔ)句的分析。 2算法描述: Int S_IF() int a; int rtn=0; 定義一個(gè)真出口True_address和一個(gè)假出口Flase_address; if(當(dāng)前單詞為if) 布爾表達(dá)式初始化; 調(diào)用布爾表達(dá)式分析函數(shù)B_Analize(); rtn=布爾表達(dá)式的四元式首址; 產(chǎn)生無(wú)條件跳轉(zhuǎn)四元式; if (當(dāng)前單詞為then) 讀取下一單詞; switch(當(dāng)前單詞) case IF:調(diào)用S_IF()函數(shù);break; case BEGIN :調(diào)用S_Begin()函數(shù);braek; case 標(biāo)識(shí)符:調(diào)用 S_Let()函數(shù);break; case WHILE:調(diào)用 S_While();break; BackPatch(); if(當(dāng)前單詞為else) 讀取下一單詞; switch(當(dāng)前單詞) case IF:調(diào)用S_IF()函數(shù);break; case BEGIN :調(diào)用S_Begin()函數(shù);braek; case 標(biāo)識(shí)符:調(diào)用 S_Let()函數(shù);break; case WHILE:調(diào)用 S_While();break; BackPatch(); else rtn;else 報(bào)錯(cuò);(缺少then)rtn;26 S_While() 1功能:完成while循環(huán)語(yǔ)句的分析。 2算法描述; int S_While() int rtn=0;boor_value,True_address,False_address; if (當(dāng)前單詞為while) rtn=布爾表達(dá)式分析函數(shù)B_Analize(); boor_value=布爾表達(dá)式值地址; 產(chǎn)生跳轉(zhuǎn)四元式; if(當(dāng)前單詞為do) 讀取下一單詞; switch(當(dāng)前單詞) case IF:調(diào)用S_IF()函數(shù);break; case BEGIN :調(diào)用S_Begin()函數(shù);braek; case 標(biāo)識(shí)符:調(diào)用 S_Let()函數(shù);break; case WHILE:調(diào)用 S_While();break; BackPatch();BackPatch();else 出錯(cuò),缺少do;return rtn;27 gen() 該函數(shù)形成一個(gè)四元式,并將其輸出至四元式文件。28 E_Analize() 1該函數(shù)是算術(shù)分析表達(dá)式的主模塊,它調(diào)用算術(shù)表達(dá)式的子模塊,采用遞歸下降分析法完成算術(shù)表達(dá)式的分析。 2算術(shù)表達(dá)式的各個(gè)子模塊: aE_Init()將算術(shù)表達(dá)式讀入分析棧; bint E_AddSub()完成E-TE1|T的分析; cint E1_AddSub(int a) 完成E1-+TE1|-TE1| dT_MulDiv() 完成T-FT1|F的分析; eT1_MulDiv(int a) 完成T1-*FT1|/FT1|; fF_Number() 完成F-i|(E)的分析;29 B_Analize() 1布爾表達(dá)式分析的主模塊,調(diào)用其他布爾表達(dá)式的子模塊,采用遞歸下降分析法完成布爾表達(dá)式的分析。并返回該布爾表達(dá)式的首個(gè)四元式地址。 aB_OR()完成B-LB|L的分析; bB1_OR(int a) 完成B1-orLB1|的分析; cL_AND() 完成L-ML1|M的分析; dL1_AND()完成L1-andM1|的分析; eM_NOT()完成M-notM|K的分析; fK_END()完成K-i|false|true|(B)的分析; gK_CMP()完成K-iSi,S-|=|=|的分析。三、課程設(shè)計(jì)總結(jié) 1、 實(shí)驗(yàn)中遇到的問(wèn)題 詞法分析器程序中要讀入一個(gè)單詞編碼文件,但是文件的格式在編寫(xiě)的時(shí)候和程序有點(diǎn)差異,因而導(dǎo)致輸出結(jié)果再三的錯(cuò)誤。語(yǔ)法/語(yǔ)義分析器中,在修改符號(hào)表時(shí),出現(xiàn)錯(cuò)誤,最終沒(méi)有的到正確結(jié)果。2、 對(duì)實(shí)驗(yàn)原理有更深的理解 通過(guò)該課程設(shè)計(jì),掌握了什么是編譯程序,編譯程序工作的基本過(guò)程及其各階段的基本任務(wù),熟悉了編譯程序總流程框圖,了解了編譯程序的生成過(guò)程,構(gòu)造工具及其相關(guān)的技術(shù)對(duì)課本上的知識(shí)有了更深的理解,課本上的知識(shí)師機(jī)械的,表面的.通過(guò)把該算法的內(nèi)容,算法的執(zhí)行順序在計(jì)算機(jī)上實(shí)現(xiàn),把原來(lái)以為很深?yuàn)W的書(shū)本知識(shí)變的更為簡(jiǎn)單,對(duì)實(shí)驗(yàn)原理有更深的理解。3、 對(duì)該理論在實(shí)踐中的應(yīng)用有深刻的理解 通過(guò)把該算法的內(nèi)容,算法的執(zhí)行順序在計(jì)算機(jī)上實(shí)現(xiàn),知道和理解了該理論在計(jì)算機(jī)中是怎樣執(zhí)行的,對(duì)該理論在實(shí)踐中的應(yīng)用有深刻的理解。四、參考文獻(xiàn)1 賀訊. 編譯方法學(xué)習(xí)指導(dǎo)與實(shí)踐.北京:機(jī)械工業(yè)出版社, 第一版. 2004年8月。 五、附錄1單詞編碼文件ni.txt and1or11begin2program12bool3real13+23=33do4then14-2434else5true15*2535end6var16/2636false7while17.27=37if8標(biāo)識(shí)符18,28integer9整數(shù)19:29not10實(shí)數(shù)20;30(21:=31)22=32char 382測(cè)試代碼文件11.txt program abc; var a:real; begin if a22.2 then x:=c+d; end3詞法分析完整源代碼 #include#include#include#define LENGTH 61#define N 100/*/typedef struct tokenint label;char name30;int code;int addr;token;typedef struct KeyWordchar name30;int code;KeyWord;typedef struct symbleint number;int type;char name30;symble;/*/char ch;int var_count;int error_count;int label_count;int code_count;int addr_count;int LineOfPro;char filename30;FILE*KeyFin;FILE*SourceFin;FILE*TokenFout;FILE*SymbleFout;KeyWord keyLENGTH;token CurrentToken;symble CurrentSimble;symble SymbleListN;/*/void Scanner();void ScannerInit();void IsAlpha();void IsNumber();void IsAnotation();void IsChar();void IsOther();void OutPut();void Error(int a);int WordHave();int strcmp(char*s,char*t)for(;*s=*t;s+,t+)if(*s=0)return 0;return 1;/*/int main()int i=0,j=0;code_count=0;LineOfPro=0;var_count=0;addr_count=1;label_count=1;for(i=0;iN;i+)SymbleListi.number=0;SymbleListi.type=0;for(j=0;j30;j+)SymbleLj=0;Scanner();system(pause);return 0;/*主程序*/void Scanner()int i=0;error_count=0;ScannerInit();printf( * );printf( *L語(yǔ)言詞法分析器);printf( * ); printf(輸入原文件名:);for(;)scanf(%c,&filenamei);if(filenamei=10)break;i+;filenamei=0;if(SourceFin=fopen(filename,rt)=NULL)printf(無(wú)法打開(kāi)文件 %s.n,filename);exit(1);if(TokenFout=fopen(token.txt,wt+)=NULL)printf(無(wú)法打開(kāi)文件 symble.txtn);exit(1);if(SymbleFout=fopen(symble.txt,wt+)=NULL)printf(無(wú)法打開(kāi)文件 symble.txtn);exit(1);ch=fgetc(SourceFin);while(ch!=EOF)for(i=0;i47)&(ch64)&(ch96)&(ch123)|(ch=_)IsAlpha(); elseif(ch=)IsChar(); else IsOther();fclose(SourceFin);fclose(TokenFout);fclose(SymbleFout);printf(分析完畢/n);/*初始化*/void ScannerInit()int i=1;int k=0;if(KeyFin=fopen(ni.txt,rt)=NULL)printf(cannot open ni.txtn);exit(1);for(i=0;i60;i+)for(k=0;k30;k+)k=0;for(i=0;i47)&(ch47)&(ch47)&(ch47)&(ch64)&(ch96)&(ch64)&(ch96)&(ch47)&(ch64)&(ch96)&(ch123)|(ch=_)CurrentTi+=ch; ch=fgetc(SourceFin);for(i=1;iLENGTH;i+)h=strcmp(CurrentT,);if(!h)break;if(!h)CurrentToken.code=keyi.code;CurrentToken.addr=-1;else CurrentToken.code=18;CurrentToken.addr=addr_count+;CurrentToken.label=label_count+;OutPut();/*字符串處理*/void IsChar()int i=0;for(;)ch=fgetc(SourceFin);CurrentToken.code=20;if(ch!=) CurrentTi+=ch;else break;CurrentToken.addr=addr_count+;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);/*其他情況*/void IsOther()char ch1;int i;for(i=0;i30;i+)CurrentTi=0;switch(ch)case(:CurrentT0=(;CurrentToken.code=21;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case):CurrentT0=);CurrentToken.code=22;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case*:CurrentT0=*;CurrentToken.code=25;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break; case+:CurrentT0=+;CurrentToken.code=23;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case,:CurrentT0=1;CurrentToken.code=28;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case-:CurrentT0=-;CurrentToken.code=24;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case.:CurrentT0=.;CurrentToken.code=27;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case:ch1=ch;ch=fgetc(SourceFin);if(ch!=)CurrentT0=:; CurrentToken.code=29; CurrentToken.addr=-1; CurrentToken.label=label_count+; OutPut();elseCurrentT0=:;CurrentT1=; CurrentToken.code=31; CurrentToken.addr=-1; CurrentToken.label=label_count+; OutPut(); ch=fgetc(SourceFin); break;case;:CurrentT0=;CurrentToken.code=30;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case:ch1=fgetc(SourceFin);if(ch1=) CurrentT0=)CurrentT0=; CurrentToken.code=35; CurrentToken.addr=-1; CurrentToken.label=label_count+; OutPut(); ch1=fgetc(SourceFin); elseCurrentT0=:ch1=fgetc(SourceFin);if(ch1=) CurrentT0=; CurrentT1=;CurrentToken.code=37; CurrentToken.addr=-1; CurrentToken.label=label_count+; OutPut(); ch1=fgetc(SourceFin);elseCurrentT0=; CurrentToken.code=36; CurrentToken.addr=-1; CurrentToken.label=label_count+; OutPut();ch=ch1;break;case 10: LineOfPro+; ch=fgetc(SourceFin); break;case 13: LineOfPro+; ch=fgetc(SourceFin); break;case : ch=fgetc(SourceFin); break;case EOF: Error(1);ch=fgetc(SourceFin);break;/*輸出模塊*/void OutPut()int flag,i=0;int k;/*查填符號(hào)模塊*/if(CurrentToken.code=18)|(CurrentToken.code=19)|(CurrentToken.code=20)CurrentSimble.number=CurrentToken.addr;CurrentSimble.type=CurrentToken.code;strcpy(CurrentS,CurrentT);flag=WordHave();if(CurrentToken.code=18)&(flag=1)|(CurrentToken.code=20)|(CurrentToken.code=19)fprintf(SymbleFout,%3d %3d %sn,CurrentSimble.number,CurrentSimble.type,CurrentS);/*輸出到token表*/for(;)if(CurrentTi+=0)break;fprintf(TokenFout,%3d %s,CurrentToken.label,CurrentT);printf(%3d %s,CurrentToken.label,CurrentT);for(k=20-i;k0;k-)fprintf(TokenFout, );printf( );fprintf(TokenFout,%3d %3dn,CurrentToken.code,CurrentToken.addr);printf(%3d %3dn,CurrentToken.code,CurrentToken.addr);void Error(int a)error_count+;switch(a)case 1: printf(error %2d 非法字符于 %3d 行.n, error_count,LineOfPro+1);break;case 2: printf(error %2d 實(shí)常數(shù)出過(guò)于 %3d 行.n, error_count,LineOfPro+1);break;case 3: printf(error %2d 沒(méi)有匹配的注釋符 */ n,error_count);break;case 4: printf(error %2d 非正常結(jié)束!n,error_count);break; default: break;return;int WordHave()int flag,i=0;for(i=0;ivar_count;i+)flag=strcmp(CurrentS,SymbleL);if(flag=0)CurrentToken.addr=SymbleListi.number;return 0;SymbleListvar_count.number=CurrentToken.addr;SymbleListvar_count.type=CurrentToken.code;strcpy(SymbleListvar_,CurrentT);var_count+;return 1;4詞法分析的結(jié)果 5詞法分析產(chǎn)生的Token文件 6詞法分析產(chǎn)生的符號(hào)表文件 7語(yǔ)法/語(yǔ)義分析器的完整代碼 #include#include#includetypedef struct stackchar name20;int cod;int addr;stack;typedef struct equint op;int op1;int op2;int result;equ;typedef struct varchar name20;int addr;int type;int value;var;#define EXP_LEN 100#define EQU_LEN 1024#define ONE 50001#define ZERO 50000#define E_EXPR 7#define IF 8#define WHILE 9#define FOR 10#define B_EXP 12FILE *TokenFin;FILE *SymbleFin;FILE *EquFout;int code ;int address;int LineOfPro;int LineOfEqu;stack var_listEXP_LEN;stack exprEXP_LEN;equ EquEQU_LEN;var TempListEQU_LEN;char ID20;int var_count;int len_count;int pos;int now_addr;int temp_count;int error_count;int let_count;int E_Contrl;int E_rtn;int True_address;int False_address;int gen_pos;int EquPush(int op,int a,int b,int r);void GetNext();void Error(int num);int Num(char cc);int gen(int op,int a,int b,int r);void Declear();void InitStack();void Push(int cod,int addr);int NewTemp();void BackPatch(int addr,int addr2);/布爾表達(dá)式分析函數(shù)int B_Analize();void B_Init();int B_OR();int B1_OR(int a);int L_AND();int L1_AND(int a);int M_NOT();int K_END();int K_CMP();/算術(shù)表達(dá)式分析函數(shù)int E_Analize();void E_Init();int E_AddSub();
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 安全生產(chǎn)許可證辦理審核
- 特種設(shè)備法律法規(guī)培訓(xùn)
- 安全生產(chǎn)事故匯報(bào)時(shí)間
- 化工企業(yè)安全生產(chǎn)臺(tái)賬
- 企業(yè)安全生產(chǎn)管理機(jī)構(gòu)職責(zé)
- 保安隊(duì)崗位職責(zé)
- 賓館安全生產(chǎn)規(guī)章制度
- 2025屆江蘇省蘇州市星海中學(xué)物理高二下期末考試模擬試題含解析
- 2025屆北京市豐臺(tái)區(qū)第十二中學(xué)物理高二第二學(xué)期期末聯(lián)考模擬試題含解析
- 關(guān)于安全生產(chǎn)心得體會(huì)200字
- 公司法期末考試卷及答案
- GB/T 45604-2025船舶與海洋技術(shù)大抓力平衡錨
- 國(guó)家中小學(xué)智慧教育平臺(tái)與人工智能融合應(yīng)用指南(試行)
- 港口夏季四防安全培訓(xùn)
- 混凝土攪拌站企業(yè)管理規(guī)范與要求
- 棘阿米巴角膜炎診斷與治療專家共識(shí)(2025) 解讀
- 物業(yè)公司接管寫(xiě)字樓項(xiàng)目工作時(shí)間倒推計(jì)劃表(T日為入駐日)
- 重點(diǎn)人口管理工作規(guī)定
- T-CALC 005-2024 急診患者人文關(guān)懷規(guī)范
- T-AHLPA 0003-2024 古樹(shù)名木雷電災(zāi)害風(fēng)險(xiǎn)評(píng)估技術(shù)規(guī)范
- 病理學(xué)小鼠取材
評(píng)論
0/150
提交評(píng)論