編譯原理詞法分析程序?qū)崿F(xiàn)實驗報告_第1頁
編譯原理詞法分析程序?qū)崿F(xiàn)實驗報告_第2頁
編譯原理詞法分析程序?qū)崿F(xiàn)實驗報告_第3頁
編譯原理詞法分析程序?qū)崿F(xiàn)實驗報告_第4頁
編譯原理詞法分析程序?qū)崿F(xiàn)實驗報告_第5頁
已閱讀5頁,還剩46頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、實驗一 詞法分析程序?qū)崿F(xiàn)一、實驗內(nèi)容選取無符號數(shù)的算術(shù)四則運(yùn)算中的各類單詞為識別對象,要求將其中的各個單詞識別出來。輸入:由無符號數(shù)和+,*,/, ( , ) 構(gòu)成的算術(shù)表達(dá)式,如1.5E+2100。輸出:對識別出的每一單詞均單行輸出其類別碼(無符號數(shù)的值暫不要求計算)。二、 設(shè)計部分因為需要選取無符號數(shù)的算術(shù)四則運(yùn)算中的各類單詞為識別對象,要求將其中的各個單詞識別出來,而其中的關(guān)鍵則為無符號數(shù)的識別,它不僅包括了一般情況下的整數(shù)和小數(shù),還有以E為底數(shù)的指數(shù)運(yùn)算,其中關(guān)于詞法分析的無符號數(shù)的識別過程流程圖如下:GOTO 1:GOTO 2:三、 源程序代碼部分#include #include#

2、include #define MAX 100#define UNSIGNEDNUMBER 1#define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6#define RIGHTBRACKET 7#define INEFFICACIOUSLABEL 8#define FINISH 111int count=0;int Class;void StoreType();int Type100;char Store20=0;void ShowStrFile();/已經(jīng)將要識別的字符串存在

3、文件a中void Output(int a,char *p1,char *p2);/字符的輸出過程int Sign(char *p);/+-*/整體識別過程int UnsignedNum(char *p);/是否適合合法的正整數(shù)09int LegalCharacter(char *p);/是否是合法的字符:Sign(p)|UnsignedNum(p)|E|.void DistinguishSign(char *p);/+-*/具體識別過程void TypyDistinguish();/字符的識別過程void ShowType();/將類別碼存儲在Type100中,為語法分析做準(zhǔn)備void Sh

4、owStrFile()/已經(jīng)將要識別的字符串存在文件a中FILE *fp_s;char ch;if(fp_s=fopen(a.txt,r)=NULL)printf(The FILE cannot open!); exit(0);elsech=fgetc(fp_s);while(ch!=EOF)putchar(ch);ch=fgetc(fp_s);printf(n);void StoreStr()/將文件中的字符串存儲到數(shù)組Storei FILE *fp=fopen(a.txt,r);char str;int i=0;while(!feof(fp)fscanf(fp,%c,&str);if(st

5、r=?)Storei=0;break;Storei=str;i+;Storei=0;void ShowStore()int i;for (i=0;Storei!=0;i+) printf(%c,Storei);printf(n);void Output(int a,char *p1,char *p2) printf(%3st%dt%st,CLASS,a,VALUE);while(p1=p2)printf(%c,*p1);p1+;printf(n);int Sign(char *p)char ch=*p;if(ch=+|ch=-|ch=*|ch=/|ch=(|ch=)return 1;elser

6、eturn 0;int UnsignedNum(char *p)char ch=*p;if(0=ch&ch=9)return 1;elsereturn 0;int LegalCharacter(char *p)char ch=*p;if(Sign(p)|UnsignedNum(p)|ch=E|ch=.)return 1;else return 0;void DistinguishSign(char *p) int Class;char ch=*p;switch(ch) case +: Output(PLUS,p,p);Typecount+=PLUS;break; case -: Output(

7、SUBTRACT,p,p);Typecount+=SUBTRACT;break; case *: Output(MULTIPLY,p,p);Typecount+=MULTIPLY;break; case /: Output(DIVIDE,p,p);Typecount+=DIVIDE;break; case (: Output(LEFTBRACKET,p,p);Typecount+=LEFTBRACKET;break; case ): Output(RIGHTBRACKET,p,p);Typecount+=RIGHTBRACKET;break; default: break; void Typy

8、Distinguish() printf(詞法開始,分析結(jié)果如下:n); char *p; p=&Store0; while(*p!=0) if(Sign(p) DistinguishSign(p+); continue; else if(UnsignedNum(p)|*p=.) char *p1=p;if(UnsignedNum(p)while(UnsignedNum(p)p+;if(*p=0) Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=E)p+;if(UnsignedNum(p

9、)while(UnsignedNum(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=+|*p=-)p+;while(UnsignedNum(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else Output(INEFFICACIOUSLABEL,p1,-p);printf(輸入的這個符號是不合法的!);break;Typecount+=INEFFICACIOUSLABEL;p+

10、;continue;else if(*p=.)p+;while(UnsignedNum(p)p+;if(*p=0) Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=E)p+;if(UnsignedNum(p)while(UnsignedNum(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=+|*p=-)p+;if(UnsignedNum(p)while(Unsigned

11、Num(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else Output(INEFFICACIOUSLABEL,p1,-p);printf(輸入的這個符號是不合法的! /n);break;Typecount+=INEFFICACIOUSLABEL;p+;continue;elseOutput(INEFFICACIOUSLABEL,p1,-p);printf(輸入的這個符號是不合法的!因為他的后面既不是09也不是“+”或者“-);break;/1.5E*2這樣的字符串不是無符號數(shù) Typecou

12、nt+=INEFFICACIOUSLABEL;p+;continue;else Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;if(*p=.)p+;if(UnsignedNum(p)p+;while(UnsignedNum(p)p+;if(*p=0) Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;

13、continue;else if(*p=E)p+;if(UnsignedNum(p)while(UnsignedNum(p)p+; Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=+|*p=-)p+;while(UnsignedNum(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUM

14、BER;p+;continue;else Output(INEFFICACIOUSLABEL,p1,-p); printf(輸入的這個符號是不合法的!);break;Typecount+=INEFFICACIOUSLABEL;p+;continue; else if(*p=E) Output(INEFFICACIOUSLABEL,p,p);break; Typecount+=INEFFICACIOUSLABEL; printf(輸入的這個符號是不合法的!); p+; continue; printf(nn詞法分析完畢!);void ShowType()/將類別碼存儲在Type100中,為語法分

15、析做準(zhǔn)備 printf(n用類別碼表示輸入的字符如下:n);int i;printf(n);for(i=0;Typei!=FINISH;i+)printf(%d,Typei);printf(nn); void main() /詞法分析部分 StoreStr(); ShowStore(); TypyDistinguish(); Typecount=FINISH; ShowType(); 四、 實驗結(jié)果正確的結(jié)果:錯誤的結(jié)果:輸入的字符串中有1.5E*2因為實驗是以文件的形式進(jìn)行讀取的所以,在讀取不合法的過程中只是將存在project 中的a.txt 中的內(nèi)容改變改為1.5E*2+100*555實

16、驗結(jié)果如下:結(jié)果分析:對于正確的結(jié)果,我以二元式的形式輸出,包括他的值和他的類別碼,其中將類別碼存放在另外的一個數(shù)組中,為了在實驗二中的語法識別打下基礎(chǔ)。對于錯誤的結(jié)果,我選擇的是跳出這個程序,并且能過分析出錯的原因。改進(jìn)設(shè)計:(1)字符串是以文件的形式輸出的,連續(xù)重復(fù)輸入存在局限性(2)能夠跳過錯誤的字符繼續(xù)識別剩下的字符實驗一擴(kuò)展李曉萌 一、實驗內(nèi)容:試對基礎(chǔ)實驗識別的單詞種類進(jìn)行擴(kuò)充,構(gòu)造識別以下單詞的詞法分析程序。語言中具有的單詞包括五個有代表性的關(guān)鍵字begin、end、if、then、else;標(biāo)識符;整型常數(shù);六種關(guān)系運(yùn)算符;一個賦值符和四個算術(shù)運(yùn)算符。二、 設(shè)計部分基礎(chǔ)實驗和擴(kuò)

17、展實驗的差別在基礎(chǔ)實驗的關(guān)鍵在于無符號數(shù)的判斷,但是,擴(kuò)展實驗的關(guān)鍵在于關(guān)鍵字和標(biāo)識符的識別。關(guān)于關(guān)鍵字的識別,通過和題目中給出的幾個關(guān)鍵字的對比,若相同則可以確定是關(guān)鍵字,否則,就可自動確定為標(biāo)識符具體實現(xiàn)的流程圖如下:三、 源程序代碼部分#include #include #define BEGIN 1#define END 2#define IF 3#define THEN 4#define ELSE 5# define ID 6# define INT 7# define LT 8# define LE 9# define EQ 10# define NE 11# define GT

18、12# define GE 13#define IS 14#define PL 15#define MI 16#define MU 17#define DI 18char *KeyWord5=begin,end,if,then,else; int i=0,j=0,k=0,t=0;/搜索指示器 char ch;/存放最新讀入的原程序字符 char strToken20;/存放構(gòu)成單詞符號的字符串 char * chr_form100;/字符表 char * int_form100;/常數(shù)表 char form1000; int q=0; int temp; void GetChar()/將下一個

19、字符讀入ch中,搜索指示器前移一字符位 ch=formk; k+; void GetBC()/檢查ch中的字符是否為空白,若是則調(diào)用Getchar直至ch中進(jìn)入 /一個非空白字符 while(ch= ) /k-; GetChar(); void Concat()/將ch中的字符連接到strToken之后, strTokeni=ch; i+; bool IsLetter()/判斷ch中的字符是否為字符 if(ch=a)|(ch=A) return (1); else return(0); bool IsDigit()/判斷ch中的字符是否為數(shù)字 /k-; if(ch)=0) return (1)

20、; else return (0); int Reserve()/對strToken中的字符串查找保留字表,若它是一個保留字 /則返回它的編碼,否則返回-1值 for(int q=0;q5;q+) if(strcmp(KeyWordq,strToken)=0) return q; if(q=4) return -1; void Retract()/將搜索指示器回調(diào)一個字符位置,將ch置為空白字符 k-; ch=NULL; char*InsertId()/將strToken中的標(biāo)識符插入符號表,返回符號表的指針 chr_formj=strToken; j+; return chr_form0;

21、char * InsertConst()/將strToken中的常數(shù)插入常數(shù)表,返回常數(shù)表指針 int_formt=strToken; t+; return int_form0; int code; / void Output(int a,char *p1,char *p2)coutt類別碼(CLASS):at 單詞值(VALUE):;while(p1=p2)cout*p1;p1+;coutendl; void analyze() GetChar(); GetBC(); /cout此處沒有錯endl; if(IsLetter() while(IsLetter()|IsDigit() Conca

22、t(); GetChar(); /cout此處沒有錯endl; Retract(); code=Reserve(); switch(code) case 0:cout需檢測的的單詞:strToken 類別碼為: BEGIN endl;break; case 1:cout需檢測的的單詞:strToken 類別碼為: ENDendl;break; case 2:cout需檢測的的單詞:strToken 類別碼為: IFendl;break; case 3:cout需檢測的的單詞:strToken 類別碼為: THENendl;break; case 4:cout需檢測的的單詞:strToken 類

23、別碼為: ELSEendl;break; default: cout需檢測的的單詞:strToken 類別碼為: IDendl;break; else if(IsDigit() while(IsDigit()|ch=.) Concat(); GetChar(); Retract(); cout需檢測的的單詞:strToken 類別碼為: INTendl; else switch (ch) case +: cout需檢測的的單詞:+ 類別碼為: PLendl;break; case-: cout需檢測的的單詞:- 類別碼為: MIendl;break; case*: cout需檢測的的單詞:*

24、類別碼為: MUendl;break; case/: cout需檢測的的單詞:/ 類別碼為: DIendl;break; case:GetChar(); if(ch=) cout需檢測的的單詞:= 類別碼為: ISendl;break; else Retract(); cout需檢測的的單詞為非法輸入!endl;break; case=:cout需檢測的的單詞:= 類別碼為: EQ:GetChar();switch(ch) case=: cout= 類別碼為: GEendl;break; default:Retract(); cout 類別碼為: GTendl;break; case:GetC

25、har(); switch(ch) case=:cout需檢測的的單詞:= 類別碼為: LE:cout需檢測的的單詞: 類別碼為: NEendl;break; default:Retract(); cout需檢測的的單詞: 類別碼為: LTendl;break; while(kq) for(int p=0;p50;p+) strTokenp=0; i=0; analyze(); void main() cout請輸入一段程序,以#號結(jié)束:endl; form0=cin.get(); for( q=1;formq-1!=#;q+) formq=cin.get(); if(formq=#) cou

26、t你輸入的程序段為n; cout.write(form,q); break; coutE(自己添加的)E-E+T| E-T|TT-T*F| T/F|FF-(E)|i該表1是根據(jù)下一頁的圖畫出來的:+-*/()i#E T F0S4S51231S6S7acc2R3S8S9R3R33R6R6R6R6R6R64S4S510235R8R8R8R8R8R86S4S51137S4S51238S4S5139S4S51410S6S7S1511R1R1S8S9R1R112R2R2S8S9R2R213R4R4R4R4R4R414R5R5R5R5R5R515R7R7R7R7R7R7表1(2)對實驗一得字符串1.5E+

27、2+100*555進(jìn)行驗證:經(jīng)過自己的推理所得的表2步驟狀態(tài)棧符號棧輸入串ACTIONGOTO10#i+i*iS5205#i+i*i#R8GOTO0,F=3303#F+i*i#R6GOTO0,T=2402#T+i*i#R3GOTO0,E=1501#E+i*i#S66016#E+i*i#S570165#E+i*i#R8GOTO0,F=380163#E+F*i#R6GOTO0,T=290162#E+T*i#S81001628#E+T*i#S511#E+T*i#R8GOTO0,F=312#E+T*F#R6GOTO0,T=21301611#E+T#R1GOTO0,E=11401#E#acc成功!表2程

28、序設(shè)計:(1)設(shè)置輸入緩沖區(qū)用結(jié)構(gòu)buf實現(xiàn)輸入字符的存儲,包括值和類型的存儲(為實驗三做準(zhǔn)備),為后續(xù)的語法分析和詞法分析做準(zhǔn)備(2)狀態(tài)棧state 作為狀態(tài)棧,存儲歸約和移進(jìn)過程狀態(tài)的變化(3)符號棧Symbol作為符號棧,棧頂?shù)姆柌粩嗟剡M(jìn)行著歸約和移進(jìn)的動作(4)運(yùn)用c語言編寫了相應(yīng)的程序進(jìn)行移近和歸約以及接受的動作,需要注意的是,在規(guī)約的過程中不僅需要彈出數(shù)目確定的字符,還要有相應(yīng)的字符入棧注意:在實驗設(shè)計過程中,從讀取存有算數(shù)字符的文件開始,就獲得了每一個算術(shù)表達(dá)式的字符個數(shù)(除去”-”的剩余部分)并存儲在數(shù)組VNum中三、 源程序代碼實驗代碼部分將會在實驗三給出四、 實驗結(jié)果見

29、實驗三實驗三 語義分析程序?qū)崿F(xiàn)李曉萌 一、實驗內(nèi)容:通過設(shè)計、編制、調(diào)試一個簡單的語義處理分析程序,實現(xiàn)對實驗一和實驗二所得單詞和語句的語義信息簡單處里,進(jìn)一步掌握語義處理的內(nèi)容和簡單方法。二、設(shè)計部分(1)需要將實驗一的1.5E+2+100*555中的每一個無符號數(shù)相應(yīng)的算出最終的結(jié)果:如:1500.+2.+100.*555.(2)在進(jìn)行歸約的過程中,不僅僅是彈出需要進(jìn)行歸約的字符,還要進(jìn)行值的傳遞和計算計算(3)設(shè)計思路:1 Calculate_UnsignedFigure(char *p1,char *p2) 函數(shù)能過準(zhǔn)確的計算出無符號的值2 Quarternary_Out(int a1

30、,double a2,double a3,double a4)語義分析四元式輸出3 Store_ResuctionMAX在語法分析的過程中,把歸約過程都標(biāo)記在這個數(shù)組中& UnsignedFigure在計算的過程中也已經(jīng)把相應(yīng)的算數(shù)字符的值存儲在這個數(shù)組4調(diào)用相應(yīng)的歸約過程,利用UnsignedFigure存儲的值進(jìn)行計算,最后獲得運(yùn)算結(jié)果結(jié)果可以對實驗二得標(biāo)進(jìn)一步完善步驟狀態(tài)棧符號棧輸入串ACTIONGOTO語義處理生成中間代碼10#i+i*iS5205#i+i*i#R8GOTO0,F=3i1.value=1500.303#F+i*i#R6GOTO0,T=2F1.value=1500.402

31、#T+i*i#R3GOTO0,E=1T1.value=1500.501#E+i*i#S6E1.value=1500.6016#E+i*i#S570165#E+i*i#R8GOTO0,F=3i2.value=100.80163#E+F*i#R6GOTO0,T=2F2.value=100.90162#E+T*i#S8T2.value=100.1001628#E+T*i#S511#E+T*i#R8GOTO0,F=3I3.value=555.12#E+T*F#R6GOTO0,T=2F3.value=100.(*,T2,F(xiàn)3,Q1)1301611#E+T#R1GOTO0,E=1Q1.value=5550

32、0.(+,Q1,E1,Q2)1401#E#acc成功!Q2.value=55650.由此表可以看出,最終的結(jié)果因該是55650.三、 源程序代碼#include #include#include #define MAX 100#define UNSIGNEDNUMBER 1#define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6#define RIGHTBRACKET 7#define INEFFICACIOUSLABEL 8#define FINISH 111/詞法分析定義的

33、部分int count=0;/記錄類型的13145int count1=0;/詞法分析結(jié)果緩沖表int Class;int Type100;char Store20=0;double result=0.0;/詞法分析的緩沖區(qū)struct aaint type;double value;buf1000;struct aa oth;/*_語法分析定義的部分_*/char Input20;/存放類別碼轉(zhuǎn)化的字符char Store_Grammar2010=0;/用來存放語法分析產(chǎn)生式char V_T10,V_N10;char AVT8=+,-,*,/,(,),i,#;char GVN3=E,T,F;

34、int vnNum,vtNum,stateNum=16;int VNum10;int grammarNum;typedef structchar *base;char *top;SymbolStack;typedef structint *base;int *top;StateStack;StateStack state;SymbolStack symbol;/*_詞法分析子函數(shù)部分_*/bool Tag=false;void StoreType();void ShowStrFile();void Output(int a,char *p1,char *p2);int Sign(char *p

35、);int UnsignedNum(char *p);int LegalCharacter(char *p);void DistinguishSign(char *p);void TypyDistinguish();void ShowType();/語法分析子函數(shù)void ChangStyle();/*_語義分析的相關(guān)函數(shù)_*/double CalculateStackMAX,*p_trcal;/定義計算數(shù)值用的計算棧和指向它的首地址的指針double UnsignedFigureMAX;/存放每個無符號數(shù)的值int Num2=0;int Num3=0;int Num4=0;int Num5=

36、0;boolMark=true;int Store_ResuctionMAX;/語義分析時的歸約動作所用產(chǎn)生式代號棧/語法分析SLR1表int ACTION168=0,0,0,0,104,0,105,0,106,107,0,0,0,0,-1,-1,53,53,108,109,0,53,0,53,56,56,56,56,0,56,0,56,0,0,0,0,104,0,105,0,58,58,58,58,0,58,58,58,0,0,0,0,104,0,105,0,0,0,0,0,104,0,105,0,0,0,0,0,104,0,105,0,0,0,0,0,104,0,105,0,106,107

37、,0,0,0,115,0,0,51,51,108,109,0,51,51,51,52,52,108,109,0,52,0,52,54,54,54,54,0,54,54,54,55,55,55,55,0,55,0,55,57,57,57,57,0,57,0,57;int GOtO163=1,2,3,0,0,0,0,0,0,0,0,0,10,2,3,0,0,0,0,11,3,0,12,3,0,0,13,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,;void ShowStrFile()FILE *fp_s;char ch;if(fp_s=fopen(a.tx

38、t,r)=NULL)printf(The FILE cannot open!); exit(0);elsech=fgetc(fp_s);while(ch!=EOF)putchar(ch);ch=fgetc(fp_s);printf(n);void StoreStr() FILE *fp=fopen(a.txt,r);char str;int i=0;while(!feof(fp)fscanf(fp,%c,&str);if(str=?)Storei=0;break;Storei=str;i+;Storei=0;void ShowStore()int i;for (i=0;Storei!=0;i+) printf(%c,Storei);printf(n);void Output(int a,char *p1,char *p2) printf(%3st%dt%st,CLASS,a,VALUE);while(p1=p2)printf(%c,*p1);p1+;/printf(n);double Calculate_DecimalPart(char *p1,char *p2)char *p_1=p1,*p_2=p2;int i,j,m;double sum=0.0;m=p_2-p_1;i=0;while(p_1=p_2&i=m)double k=1;double temp=double(*p

溫馨提示

  • 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. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論