實驗一 詞法分析
【實驗目的】
(1)熟悉詞法分析器的基本功能和設計方法;
(2)掌握狀態轉換圖及其實現;
(3)掌握編寫簡單的詞法分析器方法。
【實驗內容】
對一個簡單語言的子集編制一個一遍掃描的詞法分析程序。
【實驗要求】
(1)待分析的簡單語言的詞法
1) 關鍵字 begin if then while do end
2) 運算符和界符 := + - * / < <= <> > >= = ; ( ) #
3) 其他單詞是標識符(ID)和整形常數(NUM),通過以下正規式定義:
ID=letter(letter|digit)*
NUM=digitdigit*
4) 空格由空白、制表符和換行符組成。空格一般用來分隔 ID、NUM、運算符、界符和 關鍵字,詞法分析階段通常被忽略。
(2)各種單詞符號對應的種別編碼
(3)詞法分析程序的功能
輸入:所給文法的源程序字符串
輸出:二元組(syn,token 或 sum)構成的序列。
syn 為單詞種別碼;
token 為存放的單詞自身字符串;
sum 為整形常數。
【實驗代碼】
1 #include<iostream> 2 #include<string.h> 3 #include<conio.h> 4 #include<ctype.h> 5 using namespace std; 6 int sum,syn,p,m,n; 7 char ch,chs[8],s[100]; 8 char *tab[6]={"begin","if","then","while","do","end"}; 9 10 int scanner(){ 11 for(n=0;n<8;n++) chs[n]='\0'; 12 m=0; 13 n=0; 14 ch=s[p++]; 15 while(ch==' ') ch=s[p++]; 16 if(isalpha(ch)){ 17 while(isalpha(ch)||isdigit(ch)){ 18 //isalpha(ch)函數:判斷字符ch是否為英文字母,小寫字母為2,大寫字母為1,若不是字母0 19 //isdigit(ch)函數:判斷字符ch是否為數字,是返回1,不是返回0 20 chs[m++]=ch; 21 ch=s[p++]; 22 } 23 syn=10; 24 for(n=0;n<6;n++) 25 if(strcmp(chs,tab[n])==0) syn=n+1; 26 p--; 27 }else if(isdigit(ch)){ 28 sum=0; 29 while(isdigit(ch)){ 30 sum=sum*10+(ch-'0'); 31 ch=s[p++]; 32 } 33 syn=11; 34 p--; 35 }else if(ch==':'){ 36 syn=17; 37 chs[m++]=ch; 38 ch=s[p++]; 39 if(ch=='='){ syn=18;chs[m]=ch;p++;} 40 p--; 41 }else if(ch=='<'){ 42 syn=20; 43 chs[m++]=ch; 44 ch=s[p++]; 45 if(ch=='>') { syn=21;chs[m]=ch;p++;} 46 if(ch=='=') { syn=22;chs[m]=ch;p++;} 47 p--; 48 }else if(ch=='>'){ 49 syn=23; 50 chs[m++]=ch; 51 ch=s[p++]; 52 if(ch=='=') { syn=24;chs[m]=ch;p++;} 53 p--; 54 }else switch(ch){ 55 case '+':syn=13;chs[m]=ch;break; 56 case '-':syn=14;chs[m]=ch;break; 57 case '*':syn=15;chs[m]=ch;break; 58 case '/':syn=16;chs[m]=ch;break; 59 case '=':syn=25;chs[m]=ch;break; 60 case ';':syn=26;chs[m]=ch;break; 61 case '(':syn=27;chs[m]=ch;break; 62 case ')':syn=28;chs[m]=ch;break; 63 case '#':syn=0;chs[m]=ch;break; 64 default:syn=-1; 65 } 66 return 0; 67 } 68 int main(){ 69 p=0; 70 cout<<"Please input code and end with character '#':"<<endl; 71 do{ 72 //cin>>ch;不識別空格 73 ch=getchar(); 74 s[p++]=ch; 75 }while(ch!='#'); 76 p=0; 77 do{ 78 scanner(); 79 switch(syn){ 80 case 11:cout<<'('<<syn<<','<<sum<<')'<<endl;break; 81 case -1:cout<<'('<<syn<<','<<"error"<<')'<<endl;break; 82 default:cout<<'('<<syn<<','<<chs<<')'<<endl; 83 } 84 }while(syn!=0); 85 //getch():是一個不回顯函數,當用戶按下某個字符時,函數自動讀取,無需按回車,所在頭文件是conio.h。 86 return 0; 87 }
【實驗結果】