#include<string.h>
#include<stdio.h>
#define MAX 22 /*分析表的最大容量*/
#define RES_MAX 10 /*关键字的最大长度*/
#define MAXBUF 255 /*缓冲区的大小*/
char ch =' '; /*存放读入当前的输入字符*/
int Line_NO; /*纪录行号*/
struct reserve /*关键字*/
{
char lexptr[MAXBUF];
int token;
};
struct reserve symtable[MAX];
char str[MAX][10]={"program","begin","end","var","integer","real", "for","if","then","else","do","while","array","procedure", "function","of","boolean","const","div","mod","and","or"};
void init() /*对关键字表进行初始化,div,mod,and,or也作为关键字处理*/
{ /*最小的token是program:3,最大的token是or:24*/
int j;
for(j=0; j<MAX; j++)
{
strcpy(symtable[j].lexptr,str[j]);
symtable[j].token=j+3;
}
}
/***************对关键字进行搜索**************/
int se_res(char * is_res){
int i;
for(i=0;i<MAX;i++){
if((strcmp(symtable[i].lexptr,is_res))==0) break;
}
if(i<MAX) return symtable[i].token;
else return 0;
}
/*****************判断是否为字母*****************/
int IsLetter(char c)
{
if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;
else return 0;
}
/*************判断是否为数字**************/
int IsDigit(char c){
if(c>='0'&c<='9') return 1;
else return 0;
}
/***************分析程序**************/
void analyse(FILE *fpin,FILE *fpout){
char arr[MAXBUF]; /* 输入缓冲区,存放一个单词符号 */
int j=0;
while((ch=fgetc(fpin))!=EOF){
if(ch==' '||ch=='/t'){} /*碰到空格、tab则跳过*/
else if(ch=='/n'){Line_NO++;}
/*************************字符串的处理****************************/
else if(IsLetter(ch)){
while(IsLetter(ch)|IsDigit(ch)){
if((ch<='Z')&&(ch>='A')) ch=ch+32; /*忽略大小写*/
arr[j]=ch;
j++;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR); /*输入指针回退一个字符*/
arr[j]='/0';
j=0;
if (se_res(arr)){ /*如果是关键字*/
fprintf(fpout,"%s/t/t%d/n",arr,se_res(arr));
}else fprintf(fpout,"%s/t/t%d/n",arr,1); /*普通标识符*/
/*************************数字的处理****************************/
}else if(IsDigit(ch)){
while(IsDigit(ch)){
arr[j]=ch;
j++;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
arr[j]='/0';
j=0;
fprintf(fpout,"%s/t/t%d/n",arr,2) ; /*无符号整数*/
}else switch(ch){
case'+' :fprintf(fpout,"%s/t/t%d/n","+",41);break;
case'-' :fprintf(fpout,"%s/t/t%d/n","-",42);break;
case'*' :fprintf(fpout,"%s/t/t%d/n","*",43);break;
case'(' :fprintf(fpout,"%s/t/t%d/n","(",25);break;
case')' :fprintf(fpout,"%s/t/t%d/n",")",26);break;
case'[' :fprintf(fpout,"%s/t/t%d/n","[",27);break;
case']' :fprintf(fpout,"%s/t/t%d/n","]",28);break;
case';' :fprintf(fpout,"%s/t/t%d/n",";",36);break;
case'=' :fprintf(fpout,"%s/t/t%d/n","=",38);break;
case'.' :fprintf(fpout,"%s/t/t%d/n",".",39);break;
case',' :fprintf(fpout,"%s/t/t%d/n",",",40);break;
case':' :{ch=fgetc(fpin);
if(ch=='=') fprintf(fpout,"%s/t/t%d/n",":=",29);
else {fprintf(fpout,"%s/t/t%d/n",":",30);fseek(fpin,-1L,SEEK_CUR);}
}break;
case'>' :{ch=fgetc(fpin);
if(ch=='=') fprintf(fpout,"%s/t/t%d/n",">=",30);
else {fprintf(fpout,"%s/t/t%d/n",">",31);fseek(fpin,-1L,SEEK_CUR);}
}break;
case'<' :{ch=fgetc(fpin);
if(ch=='=') fprintf(fpout,"%s/t/t%d/n","<=",34);
else if(ch=='>') fprintf(fpout,"%s/t/t%d/n","<>",35);
else{fprintf(fpout,"%s/t/t%d/n","<",33);fseek(fpin,-1L,SEEK_CUR);}
}break;
/***************出现在{ }之间的全部作为注释部分处理*******************/
case'{' :{ch=fgetc(fpin);
while(ch!='}'&&ch!=EOF) {ch=fgetc(fpin);}
if(ch==EOF) fprintf(fpout,"缺少一个'}'");
}break;
/***************非法字符*******************/
default :fprintf(fpout,"在第%d行无法识别的字符/t%c/n",Line_NO,ch);
}
}
}
/**********主程序中完成对输入输出文件的读写***********/
void main(){
char in_fn[25],out_fn[25];
FILE * fpin,* fpout;
printf("//chi fa fen xi qi/n");
printf("input the input file exmaple:fin.txt:/n");
scanf("%s",in_fn);
printf("input the output file exmaple:fout.txt:/n");
scanf("%s",out_fn);
fpin=fopen(in_fn,"r");
fpout=fopen(out_fn,"w");
init();
analyse(fpin,fpout);
fclose(fpin);
fclose(fpout);
}
#