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;
}