?? 詞法分析.c
字號:
/*******************************************
詞法分析程序
作者:龔勛
學號:200131500342
計科系 13班
********************************************/
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
/*******************************************
初始化函數
********************************************/
void init()
{
char *key[]={" ","auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"}; /*C語言所有關鍵字,共32個*/
char *limit[]={" ","(",")","[","]","->",".","!","++","--","&","~",
"*","/","%","+","-","<<",">>","<","<=",">",">=","==","!=","&&","||",
"=","+=","-=","*=","/=",",",";","{","}","#","_","'"};/*運算、限界符*/
FILE *fp;
int i;
char c;
fp=fopen("k.txt","w");
for(i=1;i<=32;i++)
fprintf(fp,"%s\n",key[i]);
fclose(fp); /*初始化關鍵字表*/
fp=fopen("l.txt","w");
for(i=1;i<=38;i++)
fprintf(fp,"%s\n",limit[i]);
c='"';
fprintf(fp,"%c\n",c);
fclose(fp); /*初始化運算、限界符表*/
fp=fopen("i.txt","w");
fclose(fp); /*初始化標識符表*/
fp=fopen("c.txt","w");
fclose(fp); /*初始化常數表*/
fp=fopen("output.txt","w");
fclose(fp); /*初始化輸出文件*/
}
/*******************************************
十進制轉二進制函數
********************************************/
char * dtb(char *buf)
{
int temp[20];
char *binary;
int value=0,i=0,j;
for(i=0;buf[i]!='\0';i++)
value=value*10+(buf[i]-48); /*先將字符轉化為十進制數*/
if(value==0)
{
binary=malloc(2*sizeof(char));
binary[0]='0';
binary[1]='\0';
return(binary);
}
i=0;
while(value!=0)
{
temp[i++]=value%2;
value/=2;
}
temp[i]='\0';
binary=malloc((i+1)*sizeof(char));
for(j=0;j<=i-1;j++)
binary[j]=(char)(temp[i-j-1]+48);
binary[i]='\0';
return(binary);
}
/*******************************************
根據不同命令查表或造表函數
********************************************/
int find(char *buf,int type,int command)
{
int number=0;
FILE *fp;
char c;
char temp[30];
int i=0;
switch(type)
{
case 1: fp=fopen("k.txt","r");break;
case 2: fp=fopen("i.txt","r");break;
case 3: fp=fopen("c.txt","r");break;
case 4: fp=fopen("l.txt","r");
}
c=fgetc(fp);
while(c!=EOF)
{
while(c!='\n')
{
temp[i++]=c;
c=fgetc(fp);
}
temp[i]='\0';
i=0;
number++;
if(strcmp(temp,buf)==0)
{
fclose(fp);
return(number); /*若找到,返回在相應表中的序號*/
}
else
c=fgetc(fp);
}
if(command==1)
{
fclose(fp);
return(0); /*找不到,當只需查表,返回0,否則還需造表*/
}
switch(type)
{
case 1: fp=fopen("k.txt","a");break;
case 2: fp=fopen("i.txt","a");break;
case 3: fp=fopen("c.txt","a");break;
case 4: fp=fopen("l.txt","a");
}
fprintf(fp,"%s\n",buf);
fclose(fp);
return(number+1); /*造表時,將字符串添加到表尾并返回序號值*/
}
/*******************************************
數字串處理函數
********************************************/
void cs_manage(char *buffer)
{
FILE *fp;
char *pointer;
int result;
pointer=dtb(buffer);
result=find(pointer,3,2); /*先查常數表,若找不到則造入常數表并返回序號值*/
fp=fopen("output.txt","a");
fprintf(fp,"%s\t\t\t3\t\t\t%d\n",buffer,result);
fclose(fp); /*寫入輸出文件*/
}
/*******************************************
字符串處理函數
********************************************/
void ch_manage(char *buffer)
{
FILE *fp;
int result;
result=find(buffer,1,1); /*先查關鍵字表*/
fp=fopen("output.txt","a");
if(result!=0)
fprintf(fp,"%s\t\t\t1\t\t\t%d\n",buffer,result); /*若找到,寫入輸出文件*/
else
{
result=find(buffer,2,2); /*若找不到,則非關鍵字,查標識符表,還找不到則造入標識符表*/
fprintf(fp,"%s\t\t\t2\t\t\t%d\n",buffer,result);
} /*寫入輸出文件*/
fclose(fp);
}
/*******************************************
出錯處理函數
********************************************/
void er_manage(char error,int lineno)
{
printf("\nerror: %c ,line %d",error,lineno); /*報告出錯符號和所在行數*/
}
/*******************************************
掃描程序
********************************************/
void scanner()
{
FILE *fpin,*fpout;
char filename[20];
char ch;
int i=0,line=1;
int count,result,errorno=0;
char array[30];
char *word;
printf("\nthe file name:");
scanf("%s",filename);
if((fpin=fopen(filename,"r"))==NULL)
{
printf("cannot open file");
return;
}
ch=fgetc(fpin);
while(ch!=EOF)
{ /*按字符依次掃描源程序,直至結束*/
i=0;
if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_'))
{ /*以字母開頭*/
while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')||((ch>='0')&&(ch<='9')))
{
array[i++]=ch;
ch=fgetc(fpin);
}
word=(char *)malloc((i+1)*sizeof(char));
memcpy(word,array,i);
word[i]='\0';
ch_manage(word);
if(ch!=EOF)
fseek(fpin,-1L,SEEK_CUR);
}
else if(ch>='0'&&ch<='9')
{ /*以數字開頭*/
while(ch>='0'&&ch<='9')
{
array[i++]=ch;
ch=fgetc(fpin);
}
word=(char *)malloc((i+1)*sizeof(char));
memcpy(word,array,i);
word[i]='\0';
cs_manage(word);
if(ch!=EOF)
fseek(fpin,-1L,SEEK_CUR);
}
else if((ch==' ')||(ch=='\t'))
; /*消除空格符和水平制表符*/
else if(ch=='\n')
line++; /*消除回車并記錄行數*/
else if(ch=='/')
{ /*消除注釋*/
ch=fgetc(fpin);
if(ch=='=')
{ /*判斷是否為‘/=’符號*/
fpout=fopen("output.txt","a");
fprintf(fpout,"/=\t\t\t4\t\t\t32\n");
fclose(fpout);
}
else if(ch!='*')
{ /*若為除號,寫入輸出文件*/
fpout=fopen("output.txt","a");
fprintf(fpout,"/\t\t\t4\t\t\t13\n");
fclose(fpout);
fseek(fpin,-1L,SEEK_CUR);
}
else if(ch=='*')
{ /*若為注釋的開始,消除包含在里面的所有字符*/
count=0;
ch=fgetc(fpin);
while(count!=2)
{ /*當掃描到‘*’且緊接著下一個字符為‘/’才是注釋的結束*/
count=0;
while(ch!='*')
ch=fgetc(fpin);
count++;
ch=fgetc(fpin);
if(ch=='/')
count++;
else
ch=fgetc(fpin);
}
}
}
else if(ch=='"')
{ /*消除包含在雙引號中的字符串常量*/
fpout=fopen("output.txt","a");
fprintf(fpout,"%c\t\t\t4\t\t\t37\n",ch);
ch=fgetc(fpin);
while(ch!='"')
ch=fgetc(fpin);
fprintf(fpout,"%c\t\t\t4\t\t\t37\n",ch);
fclose(fpout);
}
else
{ /*首字符為其它字符,即運算限界符或非法字符*/
array[0]=ch;
ch=fgetc(fpin); /*再讀入下一個字符,判斷是否為雙字符運算、限界符*/
if(ch!=EOF)
{ /*若該字符非文件結束符*/
array[1]=ch;
word=(char *)malloc(3*sizeof(char));
memcpy(word,array,2);
word[2]='\0';
result=find(word,4,1); /*先檢索是否為雙字符運算、限界符*/
if(result==0)
{ /*若不是*/
word=(char *)malloc(2*sizeof(char));
memcpy(word,array,1);
word[1]='\0';
result=find(word,4,1); /*檢索是否為單字符運算、限界符*/
if(result==0)
{ /*若還不是,則為非法字符*/
er_manage(array[0],line);
errorno++;
fseek(fpin,-1L,SEEK_CUR);
}
else
{ /*若為單字符運算、限界符,寫入輸出文件并將掃描文件指針回退一個字符*/
fpout=fopen("output.txt","a");
fprintf(fpout,"%s\t\t\t4\t\t\t%d\t\n",word,result);
fclose(fpout);
fseek(fpin,-1L,SEEK_CUR);
}
}
else
{ /*若為雙字符運算、限界符,寫輸出文件*/
fpout=fopen("output.txt","a");
fprintf(fpout,"%s\t\t\t4\t\t\t%d\n",word,result);
fclose(fpout);
}
}
else
{ /*若讀入的下一個字符為文件結束符*/
word=(char *)malloc(2*sizeof(char));
memcpy(word,array,1);
word[1]='\0';
result=find(word,4,1); /*只考慮是否為單字符運算、限界符*/
if(result==0) /*若不是,轉出錯處理*/
er_manage(array[0],line);
else
{ /*若是,寫輸出文件*/
fpout=fopen("output.txt","a");
fprintf(fpout,"%s\t\t\t4\t\t\t%d\n",word,result);
fclose(fpout);
}
}
}
ch=fgetc(fpin);
}
fclose(fpin);
printf("\nThere are %d error(s).\n",errorno); /*報告錯誤字符個數*/
}
/*******************************************
主函數
********************************************/
main()
{
init(); /*初始化*/
scanner(); /*掃描源程序*/
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -