《語法分析實驗報告.docx》由會員分享,可在線閱讀,更多相關(guān)《語法分析實驗報告.docx(10頁珍藏版)》請在裝配圖網(wǎng)上搜索。
語法分析實驗報告
一、 語法分析功能與目的
語法分析是編譯過程的核心部分,它的主要任務(wù)是按照程序語言的語法規(guī)則,從由詞法分析輸出的源程序符號串中識別出各類語法成分,同時進行語法檢查,為語義分析和代碼生成作準(zhǔn)備。執(zhí)行語法分析任務(wù)的程序叫語法分析程序或語法分析器。
語法分析程序以詞法分析輸出的符號串作為輸入,在分析過程中檢查這個符號串是否為該程序語言的句子。如是,則輸出該句子的分析數(shù),否則就表示源程序存在語法錯誤,需要報告錯誤的性質(zhì)和位置。
二、TEST語法規(guī)則
①<程序>∶∶={<聲明序列><語句序列>}
②<聲明序列>∶∶=<聲明序列><聲明語句>|ε
③<聲明語句>∶∶=int <標(biāo)識符>;
④<語句序列>::=<語句序列><語句>|ε
⑤<語句>::=
|||
|||<復(fù)合語句>|<表達式語句>
⑥::=if(<表達式>)<語句>[else<語句>]
⑦::=while(<表達式>)<表達式>
⑧:=for(<表達式>;<表達式>;<表達式>)<語句>
⑨::=write<表達式>;
⑩::=read<標(biāo)識符>;
⑴<復(fù)合語句>::={<語句序列>}
⑵<表達式語句>:=<表達式>;|;
⑶<表達式>::=<標(biāo)識符>=<布爾表達式>|<布爾表達式>
⑷<布爾表達式>:=<算術(shù)表達式>
|<算術(shù)表達式>(>|<|>=|<=|==|!=)<算術(shù)表達式>
⑸<算術(shù)表達式>::=<項>{(+|-)<項>}
⑹<項>::=<因子>{(*|/)<因子>}
⑺<因子>::=(<表達式>)|<標(biāo)識符>|<無符號整數(shù)>
⑻::=do<語句>while(<表達式>);
三、 實驗四要求及改進思路
實驗要求:
修改詞法分析程序TESTscan.c和語法分析程序TESTparse.c這二個文件,使該程序能分析:
(1) do語句(有關(guān)文法規(guī)則參見P77的習(xí)題8。)
(2) 同一行中聲明多個變量(文法規(guī)則參見P77的習(xí)題7)。
例如:原先可以分析的變量聲明是:
int a;
int b;
現(xiàn)在能分析的變量聲明是: int a, b;
改進思路:
對于問題(1),由于do語句的語法規(guī)則為
::=do<語句>while(<表達式>);
do語句的正確輸入形式為:
do {表達式}
while (表達式);
所以do語句的前半部分為一個復(fù)合語句,所以在語法分析程序中要能分析出do語句,必須在定義do語句時先要求該句子屬于復(fù)合語句,然后使指針為while,再到(,然后是表達式,接著就是),最后為;,這就是完整的do語句。
①定義do語句的代碼如下:
int do_stat()
{
int es = 0;
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
es=compound_stat(); //調(diào)用復(fù)合語句
if(es>0) return (es);
if (strcmp(token, "while")) return(es=8);
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
if (strcmp(token, "(")) return(es=5); //少左括號
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
es = expression(); //調(diào)用表達式
if(es>0) return (es);
if (strcmp(token, ")")) return(es=6); //少右括號
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
if (strcmp(token, ";")) return(es=4); //少分號
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
return es;
}
②然后在語法分析程序的開始定義的函數(shù)中必須加上int do_stat();;
③然后在函數(shù)出錯的情況switch (es)的函數(shù)中加上case 8: printf("do后面缺少while! \n"); break;,這是說明do語句不完整的出錯情況。
對于問題(2):同一行中定義多個變量,對比前后變化的兩個變量聲明形式,我們可以看出同一行中定義多個變量時,在分析第一個變量時原來的變量聲明能分析得出來,但是在接下來的變量中就有變化了,在同一行定義多個變量的第二個變量是接第一個變量后的,第二個變量的為第一個變量后接著一個逗號,然后就是第二個變量,如果同一行有n多個變量,那么從第三個變量開始,就先能分析出其必須先要分析出第二個變量,以此類推,分析出第n個變量就必須分析出前n-1個變量,而且要能分析出第n(n>2)個變量,其要求就如同分析出第二個變量,它就是一個反復(fù)調(diào)用的過程。我們可以定義一個函數(shù)d(),要求它的結(jié)構(gòu)為逗號后接著標(biāo)識符,然后就由原來的分析出單個變量的變量聲明在分析到標(biāo)識符的時候調(diào)用我們定義的函數(shù)d(),就能實現(xiàn)一行識別出多個變量了。
函數(shù)d()的定義如下:
int d()
{if(strcmp(token,",")==0)
{ int es=0;
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
if (strcmp (token, "ID")) return (es=3); //不是標(biāo)識符
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
d();
}
}
在聲明語句定義時調(diào)用d()函數(shù)實現(xiàn)一行識別出多個變量的情況如下:
// : : = int ID;
int declaration_stat()
{
int es=0;
fscanf(fp, "%s %s\n", &token, &token1);
printf ("%s %s\n",token, token1);
if (strcmp (token, "ID")) return (es=3); //不是標(biāo)識符
fscanf(fp,"%s %s\n",&token,&token1);
printf("%s %s\n",token,token1);
d();
if (strcmp(token,";")) return(es=4);
fscanf (fp, "%s %s\n", &token, &token1);
printf ("%s %s\n",token, token1);
return(es);
}
四、 該語法分析程序是遞歸下降分析的語法分析方法
遞歸下降分析的方法思路是將文法中的每一個非終結(jié)符U的文法規(guī)則看作是識別U的一個過程定義,為每個非終結(jié)符另構(gòu)造一個子程序,以完成該非終結(jié)符號所對應(yīng)的語法成分的分析和識別任務(wù)。
如果U的文法規(guī)則的右部只有一個候選式,按從左向右的順序依次構(gòu)造規(guī)則U的識別過程代碼:
①如果有終結(jié)符號,判斷能否與輸入的符號相等,如果想等,表示識別成功,讀入指針指向下一個輸入符號;如果不想等,則意味著輸入串此時有語法錯誤;
②如果是非終結(jié)符號,則簡單調(diào)用這個非終結(jié)符號的子程序,由這個子程序完成該非終結(jié)符號所對應(yīng)的語法成分分析和識別任務(wù);
③當(dāng)一條規(guī)則右部有多個候選式時,則根據(jù)每個候選式的第一個符號確定該候選式分支;
只有被調(diào)用的分析識別某語法成分的子程序匹配輸入串成功,且正確返回時,該語法成分才算真正獲得識別。
五、輸入文件內(nèi)容及屏幕輸出內(nèi)容
⑴①輸入正確的源文件如下:
詞法分析結(jié)果內(nèi)容如下:
②語法分析屏幕輸出的內(nèi)容如下:
下面接著余下的輸出部分:
⑵①輸入文件為錯誤的源文件如下:
語法分析屏幕輸出的內(nèi)容如下:
從語法分析結(jié)果中我們看到語法分析都for語句的后半句i++的時候就停止了,然后錯誤的緣由是缺少操作數(shù),因為for語句后接著的是<語句>,而i++:形式?jīng)]有符合TEST的語法規(guī)則里的任何一種語句規(guī)則,所以出現(xiàn)錯誤。
②當(dāng)輸入源程序改為如下:
語法分析屏幕輸出的內(nèi)容如下:
從語法分析輸出結(jié)果我們看出當(dāng)分析到do語句的最后時出錯,錯誤為缺少分號,說明我們的源文件輸入do語句有錯,查看do語句的標(biāo)準(zhǔn)形式,最后面應(yīng)該以分號結(jié)束,而我們輸入的源文件缺少了分號,所以出現(xiàn)了錯誤。
③當(dāng)輸入源文件為如下所示時:
語法分析屏幕輸出如下所示:
我們從語法分析結(jié)果看出,這次語法分析根本就無法開始,錯誤為缺少{,說明我們的輸入的程序開始就有錯誤,查看TEST語法規(guī)則,第一個規(guī)則為<程序>∶∶={<聲明序列><語句序列>},說明輸入程序以{開始并以}結(jié)束,而反觀我們的輸入程序,并沒有以{開始,所以語法分析根本無法進行,所以出現(xiàn)了缺少{ 的錯誤提醒。
六、實驗體會
通過本次實驗,我們更加了解了語法分析的原理以及其與詞法分析的關(guān)系,語法分析和詞法相比其又更加復(fù)雜了一點點,雖然每次修改代碼的時候我都感覺很艱難,因為C++學(xué)得不好,但是在其他兩位組員的努力下就能順利的解決了,最后我也能在他們的幫助下懂得了實驗的原理與解答過程,真心感謝呀。
鏈接地址:http://www.820124.com/p-9084552.html