資源簡(jiǎn)介
一、實(shí)驗(yàn)?zāi)康模?
通過(guò)設(shè)計(jì)編制調(diào)試一個(gè)具體的詞法分析程序,加深對(duì)詞法分析原理的理解。并掌握在對(duì)程序設(shè)計(jì)語(yǔ)言源程序進(jìn)行掃描過(guò)程中將其分解為各類(lèi)單詞的詞法分析方法。
編制一個(gè)讀單詞過(guò)程,從輸入的源程序中,識(shí)別出各個(gè)具有獨(dú)立意義的單詞,即基本保留字、標(biāo)識(shí)符、常數(shù)、運(yùn)算符、分隔符五大類(lèi)。并依次輸出各個(gè)單詞的內(nèi)部編碼及單詞符號(hào)自身值。(遇到錯(cuò)誤時(shí)可顯示“Error”,然后跳過(guò)錯(cuò)誤部分繼續(xù)顯示)
二、實(shí)驗(yàn)預(yù)習(xí)提示
1、詞法分析器的功能和輸出格式
詞法分析器的功能是輸入源程序,輸出單詞符號(hào)。詞法分析器的單詞符號(hào)常常表示成以下的二元式(單詞種別碼,單詞符號(hào)的屬性值)。本實(shí)驗(yàn)中,采用的是按類(lèi)來(lái)安排種別碼的方式。
2、部分單詞的BNF表示(可參考教材43頁(yè)的狀態(tài)轉(zhuǎn)換圖)
->
->||
|ε
->
-> |ε
-> +
-> -
-> >
-> >=
3、 做詞法分析器需要把對(duì)象語(yǔ)言的詞法全部描述出來(lái),在這我們?nèi)語(yǔ)言子集,它的詞法如下:
(1)關(guān)鍵字
main if else int return void while…….. 所有的關(guān)鍵字都是小寫(xiě)。
(2)專(zhuān)用符號(hào)
= + - * / <= > >= == != ; : , { } [ ] ( )
(3)空格和空白、制表符和換行符。
空格一般用來(lái)分隔ID、NUM、專(zhuān)用符號(hào)和關(guān)鍵字,在詞法分析階段通常被忽略。
各種單詞符號(hào)的種別碼,這是一種符號(hào)一個(gè)編碼的設(shè)計(jì)。只供參考!
單詞符號(hào) 種別碼 單詞符號(hào) 種別碼
main 2 [ 28
int 1 ] 29
char 3 { 30
If 4 } 31
else 5 , 32
for 6 : 33
while 7 ; 34
ID 10 > 35
NUM 20 = 37
+ 22 +”,當(dāng)前字符為’>’,此時(shí),分析器倒底是將其分析為大于關(guān)系運(yùn)算符還是大于等于關(guān)系運(yùn)算符呢?顯然,只有知道下一個(gè)字符是什么才能下結(jié)論。于是分析器讀入下一個(gè)字符’+’,這時(shí)可知應(yīng)將’>’解釋為大于運(yùn)算符。但此時(shí),超前讀了一個(gè)字符’+’,所以要回退一個(gè)字符,詞法分析器才能正常運(yùn)行。在分析標(biāo)識(shí)符,無(wú)符號(hào)整數(shù)等時(shí)也有類(lèi)似情況。
5、模塊結(jié)構(gòu)
見(jiàn)附圖
三、實(shí)驗(yàn)過(guò)程和指導(dǎo):
(一)準(zhǔn)備:
1.閱讀課本有關(guān)章節(jié),明確語(yǔ)言的語(yǔ)法,寫(xiě)出基本保留字、標(biāo)識(shí)符、常數(shù)、運(yùn)算符、分隔符和程序例。
2.編制好程序。
3.準(zhǔn)備好多組測(cè)試數(shù)據(jù)。
(二)上機(jī)調(diào)試:
(三)程序要求:
程序輸入/輸出示例:
如源程序?yàn)镃語(yǔ)言。輸入如下一段:
main()
{
int a,b;
a = 10;
b = a + 20;
}
要求輸出如右圖。
(2,“main”)
(5,“(” )
(5,“ )” )
(5,“{ ” )
(1,“int” )
(2,“a” )
(5,“,” )
(2,“b” )
(5,“;” )
(2,“a” )
(4,“=” )
(3,“10” )
(5,“;” )
(2,“b” )
(4,“=” )
(2,“a” )
(4,“+” )
(3,“20” )
(5,“;” )
(5,“}” )
說(shuō)明:
識(shí)別保留字:if、int、for、while、do、return、break、continue;
單詞種別碼為1。
其他的都識(shí)別為標(biāo)識(shí)符;單詞種別碼為2。
常數(shù)為無(wú)符號(hào)整形數(shù);單詞種別碼為3。
運(yùn)算符包括:+、-、*、/、=、>、=、<=、!= ;單詞種別碼為4。
分隔符包括:,、;、{、}、(、); 單詞種別碼為5。
以上為參考,具體可自行增刪。
程序思路(參考):
這里以開(kāi)始定義的C語(yǔ)言子集的源程序作為詞法分析程序的輸入數(shù)據(jù)。在詞法分析中,自文件頭開(kāi)始掃描源程序字符,一旦發(fā)現(xiàn)符合“單詞”定義的源程序字符串時(shí),將它翻譯成固定長(zhǎng)度的單詞內(nèi)部表示,并查填適當(dāng)?shù)男畔⒈怼?經(jīng)過(guò)詞法分析后,源程序字符串(源程序的外部表示)被翻譯
代碼片段和文件信息
#include
#include
#include
char?ch;
bool?isletter(char?ch);
bool?isnumber(char?ch);
void?scanner(FILE?*f);
void?main()
{
char?fname[20];
FILE?*fp;
do{
printf(“Input?the?filename:“);
scanf(“%s“fname);
fp?=?fopen(fname“r“);
}while(!fp);
scanner(fp);
fclose(fp);
}
bool?isletter(char?ch)//是否為字母
{
if(ch>=‘A‘&&ch<=‘Z‘||ch>=‘a(chǎn)‘&&ch<=‘z‘)
return?true;
else
return?false;
}
bool?isnumber(char?ch)//是否為數(shù)字
{
if(ch>=‘0‘&&ch<=‘9‘)
return?true;
else
return?false;
}
void?scanner(FILE?*f)
{
char?arr[20];
int?i=0j=0;
while(1)
{
ch?=?fgetc(f);
if(?ch==‘?‘||?ch?==‘\t‘)
;//過(guò)濾掉空格和tab
else?if(?ch==‘\n‘)
;//回車(chē)換行符,為下面進(jìn)行錯(cuò)誤判斷
else?if(?isnumber(ch))//讀入的是數(shù)字
{
while(isnumber(ch))
{ ?
arr[j]?=?ch;
j++;
ch?=?fgetc(f);
}
????fseek(f-1LSEEK_CUR);//文件指針后退一個(gè)字節(jié)
char*?temp1?=(char*)malloc(j+1);
memcpy(temp1arrj);
temp1[j]?=‘\0‘;
j=0;//恢復(fù)初始狀態(tài),以備下次使用
printf(“(%d\t\“%s\“)\n“20temp1);//常數(shù)
free(temp1);//釋放內(nèi)存
}
else?if(isletter(ch))//是字母開(kāi)頭的
{
while(isletter(ch)?||?isnumber(ch))
{
arr[i]?=ch;
i++;
ch?=?fgetc(f);
}
fseek(f-1LSEEK_CUR);
char*?temp1?=(char*)malloc(i+1);
memcpy(temp1arri);
temp1[i]?=‘\0‘;
i=0;
/*基本思想同處理數(shù)字的*/
??????????if(strcmp(temp1“main“)==0)//關(guān)鍵字和temp字符串相同的,找到并輸出
?printf(“(%d\t\“%s\“)\n“2temp1);
??else?if(strcmp(temp1“int“)==0)
??printf(“(%d\t\“%s\“)\n“1temp1);
??else?if(strcmp(temp1“if“)==0)
??printf(“(%d\t\“%s\“)\n“4temp1);
??else?if(strcmp(temp1“else“)==0)
??printf(“(%d\t\“%s\“)\n“5temp1);
??else?if(strcmp(temp1“for“)==0)
??printf(“(%d\t\“%s\“)\n“6temp1);
??else?if(strcmp(temp1“while“)==0)
??printf(“(%d\t\“%s\“)\n“7temp1);
??else?if(strcmp(temp1“char“)==0)
??printf(“(%d\t\“%s\“)\n“3temp1);
??else?if(st
評(píng)論
共有 條評(píng)論