#include
#include
#include
#include/*VC++使用该文件*/
#define lenth1 9/*保留字表长度*/
#define lenth2 21/*运算符、界限符表长度*/
struct
{
char name[21];
int type;
int addr;
}indent[1000];/*为标识符表*/
struct st
{
char name[21];
int code;
}sym,all_word[2000];
int count;/*统计所有单词的个数*/
int lenth=0;/*为标识符表长*/
int curr_p=0;
FILE *f1,*f2;/*f1为输入文件指针,f2为输出文件指针*/
int line=1,row=1,val;//line,row/*当前输入文件的位置*/
void getsym();
char getchr();
void error(int);
void get_w();
int main(int argc,char *argv[])
/*argc表示参数的个数,argv[0]、argv[1]、argv[2]。。。。表示运行程序是输入的字符串,包括执行文件名,调试时其参数设置,
VC++6。0在菜单Project下的子菜单Setting中的选项卡Debug下的Programm argument输入对话框中,设置Turbo c 2.0在菜单Project
下的子菜单Options中,输入对话框中*/
{
char ft[12],*fc;
if((f1=fopen(argv[1],"r"))==NULL)//使用文件方式为"r"读入;argv[1]为要打开的文件名,f1指向该文件
{
printf("can not open the file\n");
exit(0);
}/*如不能打开输入文件,显示出错信息退出*/
if(argc {/*当参数个数小于等于2时,用户没有指出输出文件。此时,生成一个与输入文件名相同而后缀名不同的输出文件名;否则
用户已经输入输出文件名,可直接使用*/
strcpy(ft,argv[1]);
if((fc=strchr(ft,'.'))!=NULL)/*char *strchr(char *str,int ch);找到str指向的字符串中第一次出现字符ch的位置*/
strcpy(fc,".mid");
else
strcat(ft,".mid");
}/*后缀名为.mid*/
else
strcpy(ft,argv[2]);/*ft为输出文件名*/
if((f2=fopen(ft,"w"))==NULL)
{
printf("can not open the file");
exit(0);
}
while(!feof(f1))/*输入原文件不为空,取单词输出*/
{
getsym();/*取单词sym的方法*/
// printf("%d %s\n",sym.code,sym.name);
// fprintf(f2,"%d %s\n",sym.code,sym.name);
}
fclose(f1);
fclose(f2);
for(int i=0;i printf("%d %s\n",all_word[i].code,all_word[i].name);
/* get_w();
printf("%d %s\n",sym.code,sym.name);
get_w();
printf("%d %s\n",sym.code,sym.name);*/
return 0;
}
void get_w()
{
sym.code=all_word[curr_p].code;
strcpy(sym.name,all_word[curr_p].name);
curr_p++;
}
void getsym()
{
static char a[lenth1][10]={"main","const","void","int","for","while","if","scanf","printf"};
/*保留字表*/
static char d[lenth2][3]={"%d","{","}","&","+","-","*","/","=",">"," /*界限符、运算符表*/
static char str[21],ch;
int i,n;
fseek(f1,ftell(f1)-1,0);
ch=' ';
while(isspace(ch))/*滤去空格类字符*/
{
ch=getchr();
}
if(isalpha(ch))/*如为字母,即为保留字或标识符*/
{
n=0;
while(isalpha(ch)||isalnum(ch))/*为字母或数字接字符串str上*/
{
if(isalpha(ch))
ch=tolower(ch);
if(n str[n++]=ch;
ch=getchr();
}
str[n]='\0';/*赋字符串结束符*/
for(i=0;i if(!strcmp(str,a[i])) break;/*查保留字表*/
if(i {
strcpy(sym.name,a[i]);
sym.code=i+1;
}
else/*否则为标识符并检查标识符表中是否已经登记该标识符,若没有则登记该标识符*/
{
for(i=0;i if(!strcmp(str,indent[i].name))break;/*strcmp比较俩个字符串,相等是返回0。!strcmp(str,indent[i].name)
表示在标识符表查找到该标识符时跳出循环*/
if(i==lenth)
{ strcpy(indent[i].name,str);lenth++;}//标识符计数
strcpy(sym.name,indent[i].name);
sym.code=32;
}
}
else if(isalnum(ch))/*若为数字,则为无符号整数*/
{
val=0;n=0;
while(isalnum(ch))
{
val=val*10+ch-'0';/*拼成数字的字符串*/
sym.name[n++]=ch;
ch=getchr();
}
sym.name[n]='\0';
sym.code=31;
}
else/*既非数字也非字母的其他类界限符或运算符*/
{
if(ch=='-'||ch=='*'||ch=='/'||ch==','||ch=='{'||ch=='}'||ch==';'||ch=='('||ch==')'||ch=='\"'||ch=='')
{/*若为单字符类直接查表*/
str[0]=ch;
str[1]='\0';
ch=getchr();
for(i=0;i {
if(!strcmp(str,d[i]))
{
strcpy(sym.name,str);
sym.code=i+10;
}
}
}
else
{ /*若为有可能组成的复合单词的判断后面的字符是否组成复合单词,并查表*/
n=0;
if(ch=='>')
{
str[n++]=ch;
if((ch=getchr())=='=')
{
str[n++]=ch;
ch=getchr();
}
}
else if(ch=='=')
{
str[n++]=ch;
if((ch=getchr())=='=')
{
str[n++]=ch;
ch=getchr();
}
}
else if(ch=='+')
{
str[n++]=ch;
if((ch=getchr())=='+')
{
str[n++]=ch;
ch=getchr();
}
}
else if(ch=='%')
{
str[n++]=ch;
if((ch=getchr())=='d')
{
str[n++]=ch;
ch=getchr();
}
}
else if(ch==' {
str[n++]=ch;
ch=getchr();
if(ch=='=')
{
str[n++]=ch;
ch=getchr();
}
}
else if(ch=='!')
{
str[n++]=ch;
ch=getchr();
if(ch=='=')
{
str[n++]=ch;
ch=getchr();
}
}
else if(ch==-1)
{
strcpy(sym.name,"");
sym.code=33;
}
else
error(1);
str[n]='\0';
for( i=0;i if(!strcmp(str,d[i]))
{
strcpy(sym.name,str);
sym.code=i+10;
}
}
}
all_word[count].code=sym.code;
strcpy(all_word[count].name,sym.name);
count++;
}
char getchr()
{
char ch=fgetc(f1);
if(ch=='\n')
{
row=1;
line++;
}
else if(ch!=' '&&ch!='\t')
row++;
return (ch);
}
void error(int n)
{
printf("There are %d-error\n",n);
exit(0);
}