最簡單的詞法分析器
阿新 • • 發佈:2019-02-10
1、 實驗目的:
設計、編制、除錯一個詞法分析程式,對單詞進行識別和編碼,加深對詞法分析原理的理解。
2、 實驗要求
(1) 允許使用者自己輸入源程式並儲存為檔案
(2) 系統能夠輸出經過預處理後的源程式(去掉註釋、換行、空格等)
(3) 能夠將該源程式中所有的單詞根據其所屬型別(整數、保留字、運算子、識別符號等。定義的類C語言中的識別符號只能以字母或下劃線開頭)進行歸類顯示,例如:識別保留字:if、int、for、while、do、return、break、continue等,其他的都識別為識別符號;常數為無符號整形數;運算子包括:+、-、*、/、=、>、<、>=、<=
實現檔案的讀取操作,而不是將文字以字串形式預存於程式中。文字內容為待分析的類C語言程式。
設計並實現一個詞法分析器,實現對指定位置的類C語言源程式文字檔案的讀取,並能夠對該源程式中的所有單詞進行分類,指出其所屬型別,實現簡單的詞法分析操作。
例如下面為一段C語言源程式:
main()
{
int a,b;
a = 10;
b = a + 20;
}
要求輸出如下
(1,’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,’}’)
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct Word { int num;//詞所屬型別 char w[20];//詞 }Word; int main() { char ch,word_temp[20]=""; int i=0,j=0,k=0,key=0,chioce; char ktt[28][20]={"int","do","else","main","if","while","break","continue","for","return", ",",";",":","(",")","[","]","{","}","+","-","*","/","=","<",">","<=",">="}; FILE *fp; Word word[100]; printf("1:輸入源程式儲存成檔案\n"); printf("2:開啟檔案進行詞法分析\n"); printf("請輸入你的選擇:"); scanf("%d",&chioce); switch(chioce) { case 1: fp=fopen("F:\\程式設計小試\\C語言\\詞法分析\\C_program.txt","w"); if(!fp) { printf("can't open file C_program.txt\n"); exit(1); } printf("請輸入一段程式(以#結束):\n"); ch=getchar(); while(ch!='#') { fputc(ch,fp); ch=getchar(); } fclose(fp);break; case 2: fp=fopen("F:\\程式設計小試\\C語言\\詞法分析\\C_program.txt","r"); if(!fp) { printf("can't open file C_program.txt\n"); exit(1); } printf("源程式如下:"); while((ch=fgetc(fp))!=EOF) { putchar(ch); } fclose(fp); printf("\n詞法分析結果如下:\n"); fp=fopen("F:\\程式設計小試\\C語言\\詞法分析\\C_program.txt","r"); if(!fp) { printf("can't open file C_program.txt\n"); exit(1); } while((ch=fgetc(fp))!=EOF) { if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')) { word_temp[key++]=ch;//連續幾個字母的連成單詞 word_temp[key]='\0'; continue; } else { if(strcmp(word_temp,"")!=0) { strcpy(word[i].w,word_temp);//將單詞拷貝到結構陣列中 strcpy(word_temp,""); key=0;//回到臨時陣列的開始位置 i++;//結構陣列的下標加1 } if(ch==' '||ch==10||ch==' ')//去掉空格、回車和tab鍵 { continue; } else { word_temp[0]=ch; word_temp[1]='\0';//字串結束符 strcpy(word[i].w,word_temp);//將非字母數字符號拷貝到結構陣列中 strcpy(word_temp,""); key=0;//回到臨時陣列的開始位置 i++; } } }break; default: printf(" 輸入錯誤!"); } for(j=0;j<i;j++) { for(k=0;k<28;k++) { if((strcmp(word[j].w,ktt[k]))==0) { if(k>=0&&k<10) word[j].num=1;//保留字 else if(k>=10&&k<19) word[j].num=5;//分隔符 else if(k>=19&&k<28) word[j].num=4;//運算子 else if(word[j].w[0]>='0'&&word[j].w[0]<='9') word[j].num=3;//數字 break; } else word[j].num=2;//變數 } } for(j=0;j<i;j++)//按格式要求列印輸出 { printf("(%d,'%s')\n",word[j].num,word[j].w); } fclose(fp); return 0; }