編譯原理實驗報告(詞法分析+語法分析)(共37頁)_第1頁
編譯原理實驗報告(詞法分析+語法分析)(共37頁)_第2頁
編譯原理實驗報告(詞法分析+語法分析)(共37頁)_第3頁
編譯原理實驗報告(詞法分析+語法分析)(共37頁)_第4頁
編譯原理實驗報告(詞法分析+語法分析)(共37頁)_第5頁
已閱讀5頁,還剩38頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、電子科技大學(xué)計算機(jī)學(xué)院實驗中心計算機(jī)專業(yè)類課程實驗報告課程名稱:編譯原理學(xué)院:計算機(jī)科學(xué)與工程專業(yè):計算機(jī)科學(xué)與技術(shù)學(xué)生姓名:林怡學(xué)號:2012060020023指導(dǎo)教師:陳昆日期:2015年6月5日電 子 科 技 大 學(xué)實 驗 報 告實驗(shyn)一實驗(shyn)名稱:詞法分析器的設(shè)計(shj)與實現(xiàn)實驗學(xué)時:4實驗內(nèi)容和目的:實驗內(nèi)容:求n!的極小語言的源程序作為詞法分析的輸入程序,根據(jù)給定的文法對其進(jìn)行詞法分析并將單詞符號與種別組成的二元式按指定格式輸出到out.dyd文件中,同時將詞法錯誤輸出到error.err文件中。其中二元式文件out.dyd 有如下要求: (1)二元式形式:

2、 單詞符號種別 (2)每行后加上 “.EOLN24” (3)文件結(jié)尾加上 “.EOF25”出錯文件error.err中錯誤信息格式如下: *LINE:行號錯誤性質(zhì)實驗(shyn)目的: 通過設(shè)計并實現(xiàn)一個詞法(cf)分析器,了解和掌握詞法分析程序設(shè)計的原理及相應(yīng)的程序設(shè)計方法,同時提高編程能力。實驗(shyn)原理:1、編譯程序要求對高級語言編寫的源程序進(jìn)行分析和合成,生成目標(biāo)程序。詞法分析是對源程序進(jìn)行的首次分析,實現(xiàn)詞法分析的程序為詞法分析程序。像用自然語言書寫的文章一樣,源程序是由一系列的句子組成的,句子是由單詞符號按一定的規(guī)則構(gòu)成的,而單詞符號又是由字符按一定規(guī)則構(gòu)成,因此,源程序?qū)嶋H

3、上是由滿足程序語言規(guī)范的字符按照一定的規(guī)則組合起來構(gòu)成的一個字符串。2、詞法分析的功能是從左到右逐個地掃描源程序字符串,按照詞法規(guī)則識別出單詞符號作為輸出,對識別過程中發(fā)現(xiàn)的詞法錯誤,輸出相關(guān)信息。3、單詞符號是程序語言最基本的語法符號,為便于語法分析,通常將單詞符號分為五類(標(biāo)識符,基本字,常數(shù),運(yùn)算符,界符),而本次實驗中單詞符號與其對應(yīng)的種別如下圖所示:4、狀態(tài)轉(zhuǎn)換(zhunhun)圖是有限有向圖,是設(shè)計詞法分析器的有效工具。圖中的節(jié)點(diǎn)(ji din)代表狀態(tài),節(jié)點(diǎn)間的有向邊代表狀態(tài)之間的轉(zhuǎn)換關(guān)系,有向邊上標(biāo)記的字符表示狀態(tài)轉(zhuǎn)換的條件。本實驗中的狀態(tài)(zhungti)轉(zhuǎn)換圖如下圖所示:5

4、、本程序所設(shè)計主要方法及作用如下: int isletter(char c) 判別(pnbi)字符c是否為字母 int isdigital(char c) 判別(pnbi)字符c是否為數(shù)字 int match_reserve(char *p) 匹配(ppi)字符串p是否為保留字 void match_symbol(const char *p) 匹配字符串p是否為標(biāo)識符 void match_double_operator(char *p) 匹配字符串p是否為雙運(yùn)算符 void match_single_operator(char *p) 匹配字符串p是否為單運(yùn)算符 void outfile()

5、 將詞法分析所得的二元式按固定格式寫入文件out.dyd實驗器材(設(shè)備、元器件) C語言+windows7+CodeBlocks+gcc實驗步驟:1、將源程序保存到in.pas文件中;2、從in.pas文件中讀取字符串保存到buf數(shù)組,若整個輸入文件已讀取完畢,程序結(jié)束;3、每次從buf數(shù)組中讀入一個字符,若已讀到buf最后一個字符,返回第2步繼續(xù)執(zhí)行;3-a 如果該字符是字母或數(shù)字將其連接到temp字符串尾部,buf索引index加1,判斷bufindex是否為0,若為0說明temp字符串為一完整單詞,跳到第4步執(zhí)行;若不為0,繼續(xù)執(zhí)行第3步;3-b 如果讀入的不是字母/數(shù)字,首先判斷并匹配

6、temp中是否已出現(xiàn)保留字/標(biāo)識符,如果沒有,通過預(yù)讀buf中的下一個字符來進(jìn)一步判斷temp中存放的是單運(yùn)算符還是雙運(yùn)算符或換行符,最終寫入相應(yīng)二元式,返回第3步繼續(xù)執(zhí)行;4、判斷temp字符串是否為保留字,若不是(b shi)保留字,進(jìn)一步判斷它是標(biāo)識符還是常量,最終生成相應(yīng)(xingyng)二元式,返回第3步繼續(xù)執(zhí)行;【注】 這里(zhl)省略了對于非法字符的出錯處理實驗數(shù)據(jù)及結(jié)果分析:測試程序如圖,在測試程序中故意添加了一些詞法錯誤如:將保留字寫成beg in,常數(shù)1kkk,符號 !=,用于檢測本實驗程序的查錯能力;程序運(yùn)行完畢,得到out.dyd文件,內(nèi)容如圖所示:報錯文件(wnji

7、n)error.err內(nèi)容如圖:由上圖可以看出,本詞法(cf)分析程序,可以識別部分(b fen)非法的常數(shù)以及字母表以外的非法字符,但對于將begin寫成beg in這一類的詞法錯誤,并未做處理,而是將其放到語法分析的部分來處理。 實驗結(jié)論、心得體會和改進(jìn)建議:1、本詞法分析程序可以正確(zhngqu)的按照給定的文法識別出源程序中的單詞符號(fho)及其對應(yīng)的種別并生成相應(yīng)的二元式文件,并具有(jyu)一定的處理錯誤信息的能力;2、由實驗結(jié)果截圖可以看到,本實驗僅能對一部分的詞法錯誤作出響應(yīng),而一個完整的詞法分析程序還應(yīng)該能夠識別出如標(biāo)識符前綴為保留字等錯誤,并且錯誤信息文件.err中還應(yīng)

8、該包括行號,所以還可以對本實驗進(jìn)行改進(jìn);3、通過本次實驗,我設(shè)計并實現(xiàn)了一個簡單的詞法分析器,在這個過程中加深了我對于詞法分析的原理及其過程的理解,而對于詞法錯誤的處理也在一定程度上提高了我的編程能力。實驗代碼如下:#include #include #include#define BEGIN 1#define END 2#define INTEGER 3#define IF 4#define THEN 5#define ELSE 6#define FUNCTION 7#define READ 8#define WRITE 9#define SYMBOL 10 /標(biāo)識符#define CONS

9、TANT 11 /常數(shù)#define EQ 12 /=#define NE 13 /#define LE 14 /=#define LT 15 /=#define BT 17 /#define SUB 18 /-#define MUL 19 /*#define ASSIGN 20 /:=#define LBRAC 21 /(#define RBRAC 22 /)#define SEM 23 /;#define BUFLEN 50#define TEMPLEN 2*BUFLENint type=0;char valTEMPLEN;FILE *infile; /.pasFILE *outfile;

10、 /.dydFILE *errfile; /.errchar bufBUFLEN; /讀入緩沖區(qū)char tempTEMPLEN;char reserve2;/*判別是否(sh fu)字母*/int isletter(char c) if(c=a)&(c=A)&(c=0&c=9) return 1; return 0;/*匹配(ppi)保留字*/int match_reserve(char *p) memset(val,0,TEMPLEN);if(!(strcmp(p,begin) type=BEGIN; strcpy(val,begin);to_outfile();return 1; els

11、e if(!(strcmp(p,end) type=END;strcpy(val,end);to_outfile();return 1; else if(!(strcmp(p,integer) type=INTEGER;strcpy(val,integer);to_outfile();return 1; else if(!(strcmp(p,if) type=IF;strcpy(val,if);to_outfile();return 1; else if(!(strcmp(p,then) type=THEN;strcpy(val,then);to_outfile();return 1; els

12、e if(!(strcmp(p,else) type=ELSE;strcpy(val,else);to_outfile();return 1; else if(!(strcmp(p,function) type=FUNCTION;strcpy(val,function);to_outfile();return 1; else if(!(strcmp(p,read) type=READ;strcpy(val,read);to_outfile();return 1; else if(!(strcmp(p,write) type=WRITE;strcpy(val,write);to_outfile(

13、);return 1; elsereturn 0;/*匹配(ppi)標(biāo)識符*/void match_symbol(const char *p,int len) /以字母(zm)開頭,是標(biāo)識符 if(isletter(p0) type=SYMBOL; strcpy(val,p);to_outfile(); / 不是(b shi)以字母開頭的是常數(shù)else if(isdigital(p0) type=CONSTANT; strcpy(val,p); to_outfile(); int i; for (i=1;istrlen(val);i+) if(isletter(vali) fprintf(er

14、rfile,標(biāo)識符%s不正確n,val); break; / 不是以字母開頭(ki tu)也不是以數(shù)字開頭的報錯 elsestrcpy(val,p);to_outfile(); fprintf(errfile,標(biāo)識符%s不正確(zhngqu)n,val);/*匹配(ppi)雙運(yùn)算符*/void match_double_operator(char *p)if(!(strcmp(p,:=) type=ASSIGN;strcpy(val,:=);to_outfile(); else if(!(strcmp(p,) type=NE;strcpy(val,);to_outfile(); else if

15、(!(strcmp(p,=) type=LE;strcpy(val,=) type=BE;strcpy(val,=);to_outfile(); elsestrcpy(val,p);to_outfile(); fprintf(errfile,運(yùn)算符%s不正確n,val);/*匹配(ppi)單個運(yùn)算符*/void match_single_operator(char *p)if(!(strcmp(p,) type=LT;strcpy(val,) type=BT;strcpy(val,);to_outfile(); else if(!(strcmp(p,-) type=SUB;strcpy(val

16、,-);to_outfile(); else if(!(strcmp(p,*) type=MUL;strcpy(val,*);to_outfile(); else if(!(strcmp(p,=) type=EQ;strcpy(val,=);to_outfile(); else if(!(strcmp(p,() type=LBRAC;strcpy(val,();to_outfile(); else if(!(strcmp(p,) type=RBRAC;strcpy(val,);to_outfile(); else if(!(strcmp(p,;) type=SEM;strcpy(val,;);

17、to_outfile(); else if (!(strcmp(p, ) /如果是空格(kn )空操作 elsestrcpy(val,p);to_outfile(); fprintf(errfile,運(yùn)算符%s不正確(zhngqu)n,val);void to_outfile() fprintf(outfile,%16s %02dn,val,type);int main(int argc,char *argv) int index=0; /指針(zhzhn)指向緩存數(shù)組 int length=0; /非運(yùn)算符(標(biāo)識符)數(shù)組長度 memset(temp,0,TEMPLEN); if(infile

18、=fopen(in.pas,r+)=NULL) /*打開in.pas*/ printf(Source file cannot be openedn); exit(1); if(!(outfile=fopen(out.dyd,w+) /*打開out.dyd*/ printf(Destination file cannot be openedn); exit(1); if(!(errfile=fopen(error.err,w+) /*打開error.err*/ printf(Destination file cannot be openedn); exit(1); /*讀字符串并判斷(pndun

19、)*/ while (!feof(infile) memset(buf,0,BUFLEN); index = 0; fgets(buf,BUFLEN,infile); printf(%s,buf); if(buf0=0)break; /*遍歷(bin l)buf數(shù)組對讀入的字符逐個判斷*/while(indexBUFLEN)&(bufindex!=0) memset(reserve,0,2); /*若讀入的是字母(zm)或數(shù)字*/if(isletter(bufindex) = 1)|(isdigital(bufindex) = 1)length+;reserve0=bufindex;strca

20、t(temp,reserve); /注意這里tail1=0 保證temp是完整字符串index+;if(bufindex=0) /*匹配保留字*/if(temp0!=0)int fm=match_reserve(temp); /*若不是保留字(fm=0),判斷是標(biāo)識符還是常量*/if(fm=0) match_symbol(temp,length); memset(temp,0,TEMPLEN); memset(reserve,0,2); length=0; /*讀入的是運(yùn)算符or界符*/else /*首先判斷temp中是否已出現(xiàn)一個單詞*/if(temp0!=0)int fm=match_re

21、serve(temp); /先判斷是否為保留字 if(fm=0) match_symbol(temp,length); memset(temp,0,TEMPLEN); /將temp,length和tail清零(qn ln) length=0; /*是否(sh fu)為雙操作符 := | = | */if(bufindex=:)&(bufindex+1=)|(bufindex=)&(bufindex+1=)|(bufindex=)reserve0=bufindex;reserve1=bufindex+1;match_double_operator(reserve);index += 2;/*如果

22、(rgu)是換行符寫入EOLN 24*/else if (bufindex=n) fprintf(outfile, EOLN 24n); index += 1; /*不是雙操作符,判斷是否為單操作符*/ elsereserve0=bufindex;match_single_operator(reserve);index+; memset(reserve,0,2); memset(buf,0,BUFLEN); /buffer清零 fprintf(outfile, EOF 25);return 0;電 子 科 技 大 學(xué)實 驗 報 告實驗(shyn)二實驗(shyn)名稱:遞歸下降詞法(cf)分析

23、器的設(shè)計與實現(xiàn)實驗學(xué)時:4實驗內(nèi)容和目的:實驗內(nèi)容:根據(jù)給定的方法,編寫相應(yīng)的遞歸下降的語法分析程序,實現(xiàn)對詞法分析后的單詞序列的語法檢查和程序結(jié)構(gòu)的分析,生成相應(yīng)的變量名表和過程名表,并將編譯中語法檢查出來的錯誤寫入相應(yīng)的文件。語法錯分類: (1) 缺少符號錯; (2) 符號匹配錯 (3) 符號無定義或重復(fù)定義。 變量名表內(nèi)容:變量名vname: char(16)所屬過程vproc:char(16)分類vkind: 0.1(0變量、1形參)變量類型vtype: types變量層次vlev: int 變量在變量表中的位置vadr: int(相對第一個變量而言)過程名表內(nèi)容:過程(guchng)

24、名pname: char(16)過程(guchng)類型ptype: types過程(guchng)層次plev: int 第一個變量在變量表中的位置fadr: int 最后一個變量在變量表中的位置ladr: int 實驗?zāi)康模?通過設(shè)計并實現(xiàn)一個遞歸下降語法分析器,了解和掌握語法分析程序設(shè)計的原理及相應(yīng)的程序設(shè)計方法,同時提高編程能力。實驗原理:1、語法分析是對源程序經(jīng)過詞法分析后轉(zhuǎn)換成的單詞流按方法規(guī)則進(jìn)行判斷,對能構(gòu)成正確句子的單詞流,給出相應(yīng)的語法樹;對不能構(gòu)成正確句子的單詞流判斷其語法錯誤并做出相應(yīng)處理。2、語法分析方法有自上而下和自下而上的分析方法。在不含左遞歸的文法G中,如果對每

25、一個非終結(jié)符的所有候選式的第一個終結(jié)符都是兩兩不相交的(即無公共左因子),則可能構(gòu)造出一個不帶回溯的自上而下的分析程序,這個分析程序由一組遞歸過程組成,每個過程對應(yīng)文法的一個非終結(jié)符。這樣的分析程序稱為遞歸下降分析程序。要使用遞歸下降分析法,我們必須先消除文法的左遞歸和提取公共左因子,消除左遞歸的方法如圖:本實驗中程序語言的文法如下: begin ; end ;integer abcdefghijklmnopqrstuvwxyz 0123456789integer function ();begin ; end;read()write():=-*ifthenelse =本程序所設(shè)計的主要數(shù)據(jù)結(jié)

26、構(gòu)及方法如下:方法:void addVar(char var_name) 添加變量到變量名表,若變量重復(fù)定義則報錯;void addProc(char proc_name) 添加過程到過程名表;int findVar(char var_name) 查找變量名表中變量是否已存在,主要用于查重;int findProc(char proc_name) 查找過程名表中過程是否已存在;void advance() 從out.dyd中讀取一行獲取一個單詞符號及其種別;void error(int type) 向error.err文件(wnjin)中寫入對應(yīng)的報錯信息;void S() 代表(dibio)

27、 begin ; end 中的;void A() void A_STAR() ;消除左遞歸后出現(xiàn)的A*,即;int C() ;void H() void E() void B() void Z() void J() void X() void Y() void K() void P() int main() 主函數(shù)還有X_STAR()、B_STAR()與J_STAR()都是對應(yīng)的文法消除左遞歸以后新出現(xiàn)的非終極符數(shù)據(jù)結(jié)構(gòu):struct variable var_table10; /變量名表struct procedure proc_table10; /過程名表struct variable /

28、變量結(jié)構(gòu)體 char vname16; char vtype10; int vadr; char vproc16; int vlev; ;struct procedure /過程結(jié)構(gòu)體 char pname16; char ptype10; int plev,fadr,ladr; ;實驗(shyn)器材(設(shè)備、元器件)C語言+windows7+CodeBlocks+gcc實驗(shyn)步驟:化簡、提取公共左因子和消除左遞歸后的文法(wnf)如下:begin ; end /消除左遞歸;|integer /提取公共左因子function ();begin ; end /消除左遞歸;|read()

29、write():=ifthenelse - /消除左遞歸*| =【注】 由于標(biāo)識符可由詞法分析階段得到的二元式判斷,所以在文法中將其推導(dǎo)省略用簡單的英文字符替換中文后得文法如下:begin ; end ;|integer integer function (); |begin ; end ;|read()write():=ifthenelse -| |*=程序(chngx)主要流程:從out.dyd中讀取待匹配(ppi)的單詞符號保存到sym中,用構(gòu)造的遞歸下降分析器匹配該單詞符號,若匹配成功(chnggng),繼續(xù)讀取下一單詞符號;若匹配失敗,向錯誤文件error.err中寫入相應(yīng)的出錯信息

30、,繼續(xù)讀取下一單詞符號,直到所有未匹配符號皆處理完畢。實驗數(shù)據(jù)及結(jié)果分析:測試程序如圖所示,所包含的語法錯誤有:錯誤的保留字integr和beginnnnn,重復(fù)定義的標(biāo)識符k,不匹配的括號read(m;,以及最后一行缺少了end關(guān)鍵字;錯誤(cuw)信息(xnx)文件(wnjin)error.err的內(nèi)容如圖:由上圖可以看到測試程序中的5處錯誤都正確的識別出來,并且雖然源測試程序的第3行和第6行的都是integer k;但語法分析程序并沒有報重復(fù)定義的錯,說明本實驗程序還可以識別不同層次的重復(fù)定義。本實驗程序把F和m也當(dāng)做未定義(dngy)的變量,這里我個人認(rèn)為按照慣例F和m還是應(yīng)該定義一下

31、,直接拿來使用不符合我們一般的編程習(xí)慣,但是error.err的8、9、11、12行對于已經(jīng)報過錯的變量F 和m又報了一次未定義錯誤,感覺有一些啰嗦,可以改進(jìn)一下本程序讓它不要重復(fù)報錯。實驗結(jié)論(jiln)、心得體會和改進(jìn)建議:一開始(kish)本實驗程序?qū)τ谌鄙俜痔柕腻e誤不能正確處理,這個問題一直困擾著我,后來我發(fā)現(xiàn)這是由于文法begin ; end 中當(dāng)說明語句表只有一條說明語句時,遞歸下降分析器并不能判定這條說明語句的接下來的一條語句到底是一條執(zhí)行語句還是仍然是一條說明語句,所以在函數(shù)體A_STAR中需要增加一段程序判斷一下下一條語句是不是執(zhí)行語句,若是執(zhí)行語句,由于當(dāng)只有一個說明語句時

32、,執(zhí)行語句之前的那個分號已經(jīng)被說明語句表匹配,所以這是需要回退一步(back),sym重新取一次分號,讓執(zhí)行語句表之前的分號得以匹配; 2、本實驗中的過程表不是很完整,我只處理了過程名以及其對應(yīng)的層次和類型,對于實驗中要求的fadr,ladr并未做相應(yīng)處理,這點(diǎn)值得改進(jìn);3、如果把第2行或第7行的integer改為integr,將會使得程序由于無法判斷這條語句到底是說明語句還是執(zhí)行語句而無法正確執(zhí)行,其實這個問題還是出在說明語句表和執(zhí)行語句表之間的界限不清楚,我現(xiàn)在還沒有想出一個很好的方法來解決這個問題;4、 實驗一開始的時候我根本不知道語法分析應(yīng)該報哪些錯,對于詞法分析應(yīng)不應(yīng)該報錯也不了解,

33、但是通過第13周的實驗程序的檢查和自己慢慢的調(diào)試,我逐漸加深了對于詞法分析、語法分析的過程的理解,雖然這個程序的功能也不是很完善,但是自己動手編寫遞歸下降分析器的這個過程確實使我對于編譯的原理有了更深入的掌握;實驗代碼如下:#include #include #include #define MISSINGSEM 1 /缺少分號錯誤#define MISSINGEND 2 /缺少(qusho)end#define MISSINGBEGIN 3 /缺少(qusho)begin#define MISSINGTYPE 4 /缺少(qusho)類型定義#define MISSINGRBRAC 5 /缺

34、少右括號#define MISSINGLBRAC 6 /缺少左括號#define MISSINGPARA 7 /缺少參數(shù)#define MISSINGFUCNAME 8/缺少函數(shù)名稱#define MISSINGFUC 9 /缺少function關(guān)鍵字#define MISSINGOP 10 /缺少操作符#define MISSINGELSE 11 /缺少else#define MISSINGTHEN 12 /缺少then#define MISSINGVAR 13 /缺少變量名#define UndefinedVar 14 /變量未定義#define RepeatDefine 15 /變量重復(fù)

35、定義FILE *infile;FILE *errfile;char *t;char sym16;int id;int lineNum = 1;int var_len= 0;int proc_len = 0;int level = 0;/*變量名表*/struct variable char vname16; char vtype10; /ints int vadr; /char vproc16; int vlev; ;/*過程名表*/struct procedure char pname16; char ptype10; / int plev,fadr,ladr; ;struct variab

36、le var_table10;struct procedure proc_table10;/*添加(tin ji)變量到變量名表*/void addVar(char var_name16) if (findVar(var_name) error(RepeatDefine); else printf( 添加(tin ji)到變量名表%sn,var_name); strcpy(var_tablevar_len.vname,var_name); strcpy(var_tablevar_len.vtype,integer); var_tablevar_len.vlev = level; var_tab

37、levar_len.vadr = 4*var_len; var_len+; /*添加(tin ji)過程到過程名表*/void addProc(char proc_name16) printf( 添加到過程名表%sn,proc_name); strcpy(proc_tableproc_len.pname,proc_name); strcpy(proc_tableproc_len.ptype,integer); proc_len+;/*在變量名表中查找變量是否存在*/int findVar(char var_name16) printf(查找變量%s n,var_name); int finde

38、d = 0,i = 0; for (i = 0;i var_len+1;i+) if (!strcmp(var_tablei.vname,var_name)&(var_tablei.vlev=level) finded = 1; printf(var_tablei.vname %sn,var_tablei.vname); break; if (!finded) printf(沒找到!n); return finded;/*在過程名表中查找過程是否(sh fu)存在*/int findProc(char proc_name16) int finded = 0,i = 0; for (i = 0;

39、i proc_len+1;i+) if (!strcmp(proc_tablei.pname,proc_name) finded = 1; break; return finded;/*if id = 25 文件(wnjin)讀取完畢!*/void advance() char line21; if(!feof(infile) fgets(line,21,infile); line 19 = 0; /去掉(q dio)換行符n char *buf = line; t = strtok(buf, ); /使用strtok進(jìn)行字符串分割 buf = NULL; id = atoi(strtok(b

40、uf, ); strcpy(sym,t); printf(line%d: sym=%s,id=%dn,lineNum,sym,id); if (id = 24) /如遇到EOLN,行號+1繼續(xù)讀取下一個字符串 lineNum+; advance(); void back() printf(back!n); fseek(infile,-60,1); lineNum -; advance();void error(int type) switch(type) case 1: fprintf(errfile,LINE %02d: missing ; here. n,lineNum);break; c

41、ase 2: fprintf(errfile,LINE %02d: missing end here. n,lineNum);break; case 3: fprintf(errfile,LINE %02d: missing begin here. n,lineNum);break; case 4: fprintf(errfile,LINE %02d: 缺少(qusho)類型定義關(guān)鍵字,%s不是(b shi)保留字n,lineNum,sym);break; case 5: fprintf(errfile,LINE %02d: missing ) here. n,lineNum);break;

42、case 6: fprintf(errfile,LINE %02d: missing ( here. n,lineNum);break; case 7: fprintf(errfile,LINE %02d: 缺少(qusho)參數(shù). n,lineNum);break; case 8: fprintf(errfile,LINE %02d: 缺少函數(shù)名 n,lineNum);break; case 9: fprintf(errfile,LINE %02d: 缺少function關(guān)鍵字. n,lineNum);break; case 10: fprintf(errfile,LINE %02d: 缺少

43、操作數(shù). n,lineNum);break; case 11: fprintf(errfile,LINE %02d: missing else here. n,lineNum);break; case 12: fprintf(errfile,LINE %02d: missing then here. n,lineNum);break; case 13: fprintf(errfile,LINE %02d: 缺少變量名. n,lineNum);break; case 14: fprintf(errfile,LINE %02d: 變量%s未定義. n,lineNum,sym);break; cas

44、e 15:fprintf(errfile,LINE %02d: 變量%s重復(fù)定義. n,lineNum,sym);break; default: fprintf(errfile,LINE %02d: unknown error n,lineNum); /*begin ; end*/void S() if (!strcmp(sym,begin) advance(); A(); printf(函數(shù)體定義完end,進(jìn)入執(zhí)行語句表n); if (!strcmp(sym,;) advance(); B(); if (!strcmp(sym,end) advance(); else error(MISSI

45、NGEND); /缺少(qusho)end else error(MISSINGSEM); /缺少(qusho)分號報錯 else error(MISSINGBEGIN); /缺少(qusho)begin advance(); A(); printf(函數(shù)體定義完end,進(jìn)入執(zhí)行語句表n); if (!strcmp(sym,;) advance(); B(); if (!strcmp(sym,end) advance(); else error(MISSINGEND); /缺少end else error(MISSINGSEM); /缺少分號報錯 printf(*Done!*n);/* ;*/

46、*需要注意當(dāng)只有一個說明語句時,由于執(zhí)行語句之前也有一個分號,所以分號已經(jīng)被匹配!*/void A() printf( sym = %sn,sym); printf(call A!n); C(); /說明語句 A_STAR(); /;說明語句void A_STAR() int isC = 0; printf( sym = %sn,sym); printf(call A_STAR!n); if (!strcmp(sym,;) advance(); /*注意(zh y)這里需判斷一下下一條是不是執(zhí)行語句*/ if (!strcmp(sym,if)|!strcmp(sym,read)|!strcmp

47、(sym,write)|(id = 10) printf(下一條是執(zhí)行語句(yj)!說明語句完n); back(); /如果(rgu)下一條是執(zhí)行語句,需回退一步,繼續(xù)取分號 return; C(); A_STAR(); else error(MISSINGSEM);/*integer integer function ();*/int C() printf( sym = %sn,sym); printf(call C!n); if (!strcmp(sym,integer) advance(); H(); return 1; else error(MISSINGTYPE); advance(

48、); H(); return 0; void H() printf( sym = %sn,sym); printf(call H!n); if (id = 10) /如果是標(biāo)識符 addVar(sym); /加入(jir)變量表 advance(); else if (!strcmp(sym,function) advance(); if (id = 10) addProc(sym); /加入(jir)過程表 advance(); if (!strcmp(sym,() advance(); if (id = 10) advance(); if (!strcmp(sym,) advance();

49、 if (!strcmp(sym,;) advance(); E(); else error(MISSINGSEM); /缺少(qusho)分號 else error(MISSINGRBRAC); /缺少右括號 else error(MISSINGPARA); /缺少參數(shù) else error(MISSINGLBRAC); /缺少左括號 else error(MISSINGFUCNAME); /缺少函數(shù)名稱 else error(MISSINGVAR); /缺少變量名/*begin ;end*/void E() printf( sym = %sn,sym); printf(call E!n);

50、 if (!strcmp(sym,begin) level+; advance(); A(); if (!strcmp(sym,;) advance(); B(); if (!strcmp(sym,end) /注意這里(zhl)在執(zhí)行語句表后面增加了一個分號 advance(); else error(MISSINGEND); else error(MISSINGSEM); else level+; error(MISSINGBEGIN); advance(); A(); if (!strcmp(sym,;) advance(); B(); if (!strcmp(sym,end) /注意這里

51、在執(zhí)行語句表后面(hu mian)增加了一個分號 advance(); else error(MISSINGEND); else error(MISSINGSEM); /*;*/void B() printf( sym = %sn,sym); printf(call B!n); Z(); B_STAR();void B_STAR() printf( sym = %sn,sym); printf(call B_STAR!n); if (!strcmp(sym,;) advance(); Z(); B_STAR(); else if (!strcmp(sym,end)|!strcmp(sym,EO

52、F); /最后(zuhu)一個執(zhí)行語句無分號 else error(MISSINGSEM);/*read()write():=ifthenelse */void Z() printf( sym = %sn,sym); printf(call Z!n); if (!strcmp(sym,read) advance(); if (!strcmp(sym,() advance(); if (id = 10) /*查變量(binling)表,如果不存在,則該變量未定義*/ if (!findVar(sym) error(UndefinedVar); advance(); if (!strcmp(sym,) advance(); else error(MISSINGRBRAC); else error(MISSINGPARA); else error(MISSINGLBRAC); else if (!strcmp(sym,write) advance()

溫馨提示

  • 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

提交評論