资源描述
#include<stdio.h>
#include<cstring>
#include<stdlib.h>
#define MaxSize1 17//关键字的个数
#define MaxSize2 20//运算符的个数
#define MaxSize3 4//结束符的个数
//数据结构
struct TNode
{
char value[20]; //存放标识符的值
int number; //存放标识符的种别码
char description[20];//描述
}KeyWords[MaxSize1],Operation[MaxSize2],EndOperation[MaxSize3];
//存放关键字的数组
char *WordsBuff[MaxSize1]={"const","long","float","double","void","main","if","else","then","break","int","char","include","for","while","printf","scanf"};
//存放运算符的数组
char *OperationBuff[MaxSize2]={"+","-","*","/","+=","-=","*=","++","--","<","<=",">",">=","<>","=","(",")","#","{","}"};
char EndOperationBuff[MaxSize3]={' ',';','\n','\t'};
//存放词法分析程序输出的结果
TNode Table1[500];
TNode Variable[100];//标识符表
TNode Const[100];
//关键字数组初始化
void inputKeyWords(char * buff[],int size)
{
//关键字编码从1-size
for(int i=0;i<size;i++)
{
strcpy(KeyWords[i].value,buff[i]);
KeyWords[i].number=i+1;
strcpy(KeyWords[i].description,"关键字");
}
}
//运算符数组初始化
void inputOperation(char * buff[],int size)
{
//运算符编码从50-(50+size)
for(int i=0;i<size;i++)
{
strcpy(Operation[i].value,buff[i]);
Operation[i].number=i+50;
strcpy(Operation[i].description,"运算符");
}
}
//结束符数组初始化
void inputEndOperation(char buff[],int size)
{
//结束符编码从100-(100+size);
for(int i=0;i<size;i++)
{
EndOperation[i].value[0]=buff[i];
EndOperation[i].value[1]='\0';
EndOperation[i].number=i+100;
strcpy(EndOperation[i].description,"结束符");
}
}
//输出数据结构数组中的信息
void outputInfo(TNode a[],int size)
{
for(int i=0;i<size;i++)
{
printf("(%d",a[i].number);
printf("\t");
printf("%s)",a[i].value);
printf("\t");
printf(a[i].description);
printf("\n");
}
}
void outInfoToFile(TNode a[],int size,FILE *out)
{
//将词法分析程序的结果输出到文件中去
for(int i=0;i<size;i++)
{
fprintf(out,"(%d",a[i].number);
fprintf(out,"\t");
fprintf(out,"%s)",a[i].value);
fprintf(out,"\t");
fprintf(out,a[i].description);
fprintf(out,"\n");
}
}
//从文件中读取一个字符
//返回文件中读取的字符
char getChar(FILE *fp)
{
char ch=fgetc(fp);
return ch;
}
//判读是否是运算符
int isOperation(char a[])
{
//返回i表示是运算符在运算符数组中的位置
//返回-1表示不是运算符
int result;
for(int i=0;i<MaxSize2;i++)
{
result=strcmp(a,Operation[i].value);
if(result==0)
{
return i;
break;
}
}
return -1;
}
//判读是否是关键字
int isKeyWords(char a[])
{
//返回i表示在关键字表中的位置
//返回-1表示不是关键字
int result;
for(int i=0;i<MaxSize1;i++)
{
result=strcmp(a,KeyWords[i].value);
if(result==0)
{
return i;
break;
}
}
return -1;
}
//判读是否是结束符
int isEndOperation(char a)
{
//返回i表示是结束符在结束符表中的位置
//返回-1表示不是结束符
for(int i=0;i<MaxSize3;i++)
{
if(a==EndOperation[i].value[0])
{
return i;
break;
}
}
return -1;
}
//判读是否是字符
int isChar(char a)
{
//返回1表示是字符
//返回0表示不是字符
if(a>='a'&&a<='z')
return 1;
else if(a>'A'&&a<='Z')
return 1;
else
return 0;
}
//判读是否是数字
int isDigit(char a)
{
//返回1表示是数字
//返回0表示不是数字
if(a>='0'&&a<='9')
return 1;
else
return 0;
}
int count=0;//记录结果表中的关键字及运算符等表项个数,用于返回
int count1=0;//记录标识符的表项个数
int count2=0;//记录常量的表项的个数
//从屏幕上面获得字符并解析,返回在结果表中的表项
int start1(FILE *in)
{
char buff[20];//用于保存单词的缓冲区
char nextchar[2];
char temp[20];//用于保存变量或常量的类型数组
int i=0;//缓冲区指针
int a;//比较的结果指针
char op[3];//用于保存第一个运算符
op[2]='\0';
nextchar[0]=fgetc(in);
nextchar[1]='\0';
while(nextchar[0]!=EOF)
{
if(isChar(nextchar[0]))
{
buff[i]=nextchar[0];i++;
nextchar[0]=fgetc(in);
}
else if(isDigit(nextchar[0]))
{
buff[i]=nextchar[0];i++;
nextchar[0]=fgetc(in);
}
else if(nextchar[0]=='\r'||nextchar[0]=='\n')
{
buff[i]='\0';
a=isKeyWords(buff);
if(a!=-1&&i>0)
{
strcpy(Table1[count].value,KeyWords[a].value);
Table1[count].number=KeyWords[a].number;
strcpy(Table1[count].description,KeyWords[a].description);
count++;//计数器加一
i=0;//清空缓冲区
}
else if(i>0)
{
if(isChar(buff[0]))
{
//是标识符
strcpy(Variable[count1].value,buff);
Variable[count1].number=count1;
strcpy(Variable[count1].description,"标识符");
count1++;//计数器加一
i=0;//清空缓冲区
}
else if(isDigit(buff[0]))
{
//是常量
strcpy(Const[count2].value,buff);
Const[count2].number=count2;
strcpy(Const[count2].description,"常量");
count2++;//计数器加一
i=0;//清空缓冲区
}
}
else
{
//缓冲区为空!
}
//处理回车符与换行符
nextchar[0]=fgetc(in);
}
else if(isEndOperation(nextchar[0])!=-1)
{
buff[i]='\0';
a=isKeyWords(buff);
if(a!=-1&&i>0)
{
strcpy(Table1[count].value,KeyWords[a].value);
Table1[count].number=KeyWords[a].number;
strcpy(Table1[count].description,KeyWords[a].description);
strcpy(temp,KeyWords[a].value);
count++;//计数器加一
i=0;//清空缓冲区
}
else if(i>0)
{
if(isChar(buff[0]))
{
//是标识符
strcpy(Variable[count1].value,buff);
Variable[count1].number=count1;
strcpy(Variable[count1].description,"标识符");
count1++;//计数器加一
i=0;//清空缓冲区
}
else if(isDigit(buff[0]))
{
//是常量
strcpy(Const[count2].value,buff);
Const[count2].number=count2;
strcpy(Const[count2].description,"常量");
count2++;//计数器加一
i=0;//清空缓冲区
}
}
else
{
//缓冲区为空!
}
nextchar[0]=fgetc(in);
}
else if((a=isOperation(nextchar))!=-1)
{
//首先输出缓冲区中的数据
buff[i]='\0';
a=isKeyWords(buff);
if(a!=-1&&i>0)
{
strcpy(Table1[count].value,KeyWords[a].value);
Table1[count].number=KeyWords[a].number;
strcpy(Table1[count].description,KeyWords[a].description);
count++;//计数器加一
i=0;//清空缓冲区
}
else if(i>0)
{
if(isChar(buff[0]))
{
//是标识符
strcpy(Variable[count1].value,buff);
Variable[count1].number=count1;
strcpy(Variable[count1].description,"标识符");
count1++;//计数器加一
i=0;//清空缓冲区
}
else if(isDigit(buff[0]))
{
//是常量
strcpy(Const[count2].value,buff);
Const[count2].number=count2;
strcpy(Const[count2].description,"常量");
count2++;//计数器加一
i=0;//清空缓冲区
}
}
else
{
//缓冲区为空!
}
//处理运算符
op[0]=nextchar[0];
nextchar[0]=fgetc(in);
if(nextchar[0]!='@')
{
if(isOperation(nextchar)!=-1)
{
op[1]=nextchar[0];
if((a=isOperation(op))!=-1)
{
//输出双目运算符
strcpy(Table1[count].value,Operation[a].value);
Table1[count].number=Operation[a].number;
strcpy(Table1[count].description,Operation[a].description);
count++;//计数器加一
//读取下一个字符
nextchar[0]=fgetc(in);
}
else
{
//错误的双目运算符
strcpy(Table1[count].value,op);
Table1[count].number=-1;
strcpy(Table1[count].description,"未定义的运算符");
count++;//计数器加一
//读取下一个字符
nextchar[0]=fgetc(in);
}
}
else
{
//输出一元运算符
op[1]='\0';
a=isOperation(op);
strcpy(Table1[count].value,Operation[a].value);
Table1[count].number=Operation[a].number;
strcpy(Table1[count].description,Operation[a].description);
count++;//计数器加一
}
}
}
}
return count;
}
void main()
{
inputKeyWords(WordsBuff,MaxSize1);
inputOperation(OperationBuff,MaxSize2);
inputEndOperation(EndOperationBuff,MaxSize3);
FILE *in,*out;
bool Flag=true;
while(Flag)
{
printf("源文件的位置:C:\\input.txt\n");
if((in=fopen("C:\\input.txt","r"))==NULL)
{
printf("读取源文件失败!\n");
exit(0);
}
if((out=fopen("C:\\out.txt","w"))==NULL)
{
printf("打开文件失败!\n");
exit(0);
}
int MaxSize=start1(in);
printf("关键字及运算符\n");
fprintf(out,"关键字及运算符\n");
outputInfo(Table1,MaxSize);
outInfoToFile(Table1,MaxSize,out);
printf("标识符表:\n");
fprintf(out,"标识符表:\n");
outputInfo(Variable,count1);
outInfoToFile(Variable,count1,out);
printf("常量表:\n");
fprintf(out,"常量表:\n");
outputInfo(Const,count2);
outInfoToFile(Const,count2,out);
Flag=false;
fclose(in);
fclose(out);
}
getchar();
}
展开阅读全文