资源描述
里仁学院编译原理实验报告2015
一、 词法分析器:
1、 程序功能:
① 读取一个写有C语言源代码的TXT文档,能分析出源代码中的标识符、关键字、数字、界符、运算符。
② 能跳过其中的斜杠”//”后的注释。
③ 屏幕输出例如(int 关键字)。
④ 在D盘生成OUT.txt文件,写入屏幕输出的内容。
2、程序流程图:
1)判断流程:
开始
读入一个字符
文件结束
T
F
字母
标识符、关键字处理
T
数字
F
数字处理
T
F
符号、未知字符处理
结束
2)标识符、关键字处理:
字母连接成单词
T
下一个是字母
F
与关键字比较
F
T
输出是标识符
输出是关键字
3)数字处理:
数字连接成数字串
下一个为数字或。
T
F
输出是数字串
4)符号、未知字符处理:(简略)
switch !
输出运算符!=
swich //
跳过
输出未知字符
=
输出运算符!
T
F
T
F
T
F
3、源代码:
/*
Name: 词法分析器
Copyright:
Author:
Date: 25/04/15 22:54
Description:
*/
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<conio.h>
#define N 32
int w=0;
char key[N][10]={{"auto"},{"short"},{"int"},{"long"},{"float"}, {"double"},{"char"},{"struct"},{"union"},{"enum"},
{"typedef"},{"const"},{"unsigned"},{"signed"},{"extern"},
{"register"},{"static"},{"volatile"},{"void"},{"if"},{"else"},
{"switch"},{"case"},{"for"},{"do"},{"while"},{"goto"},
{"continue"},{"break"},{"default"},{"sizeof"},{"return"}};
//*********************************判断关键字,处理单词
void JugKeyWord (char ch,*wfp)
{
int m=1,i=0,j=0,k=0;
char keyStr[10]={"\0"};
char wordStr[20]={"\0"};
while((isalnum(ch))||(ch=='_')) //判断下一字符是否为字母、数字下划线
{
wordStr[i]=ch; //字母连接成单词
ch=fgetc(fp);
i++;
}
i=0;
for(i=0;i<N;i++)
{
for(j=0;j<10;j++) //提取关键字
keyStr [j]=key[i][j];
if(strcmp(wordStr, keyStr)==0)
m=0; //匹配关键字成功
for(k=0;k<10;k++)
keyStr [k]='\0';
}
if(m==0)
{
printf("%s\t\t关键字\n\n", wordStr);
fprintf(wfp,"%d %s 关键字\n",w,wordStr); //写入OUT.txt输出
w++;
fseek(fp,-1L,SEEK_CUR); //指针后退一位
}
else
{
printf("%s\t\t标识符\n\n", wordStr);
fprintf(wfp,"%d %s 标识符\n",w,wordStr);
w++;
fseek(fp,-1L,SEEK_CUR);
}
for(k=0;k<20;k++) wordStr[k]='\0'; //清空存放单词的数组
}
//**************************************处理数字
void JugNumber(char ch,*wfp)
{
int i=0,k=0;
char numberStr[20]={"\0"};
while(isdigit(ch)||(ch=='.'))//小数点
{
numberStr[i]=ch;
ch=fgetc(fp);
i++;
}
i=0;
printf("%s\t\t数字\n\n",numberStr);
fprintf(wfp,"%d %s 数字\n",w,numberStr);
w++;
fseek(fp,-1L,SEEK_CUR);
for(k=0;k<20;k++) numberStr[k]='\0';
}
//*************************************处理符号
void JugSign(char ch,*wfp)
{
void JugNote(char ch,*wfp);
char nch;
switch(ch)
{
case'#':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'(':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case')':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'[':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case']':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'{':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'}':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'\'':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'\"':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'.':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case':':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'$':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case',':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case';':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;break;
case'+':printf("%c\t\t运算符\n\n",ch);
fprintf(wfp,"%d %c 运算符\n",w,ch);
w++;break;
case'-':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 运算符\n",w,ch);
w++;break;
case'*':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 运算符\n",w,ch);
w++;break;
case'%':printf("%c\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 运算符\n",w,ch);
w++;break;
case'=':if(nch=fgetc(fp)=='=')
{
printf("==\t\t运算符\n\n");
fprintf(wfp,"%d == 运算符\n",w);
w++;
break;
}
else
{
printf("%c\t\t运算符\n\n",ch);
fprintf(wfp,"%d = 运算符\n",w);
w++;
fseek(fp,-1L,SEEK_CUR);
break;
}
case'>':if(nch=fgetc(fp)=='=')
{
printf(">=\t\t运算符\n\n");
fprintf(wfp,"%d >= 运算符\n",w);
w++;
break;
}
else
{
printf("%c\t\t运算符\n\n",ch);
fprintf(wfp,"%d > 运算符\n",w);
w++;
fseek(fp,-1L,SEEK_CUR);
break;
}
case'<':if(nch=fgetc(fp)=='=')
{
printf("<=\t\t运算符\n\n");
fprintf(wfp,"%d <= 运算符\n",w);
w++;
break;
}
else
{
printf("%c\t\t运算符\n\n",ch);
fprintf(wfp,"%d < 运算符\n",w);
w++;
fseek(fp,-1L,SEEK_CUR);
break;
}
case'!':if(nch=fgetc(fp)=='=')
{
printf("!=\t\t运算符\n\n");
fprintf(wfp,"%d != 运算符\n",w);
w++;
break;
}
else
{
printf("%c\t\t运算符\n\n",ch);
fprintf(wfp,"%d ! 运算符\n",w);
w++;
fseek(fp,-1L,SEEK_CUR);
break;
}
case'&':if(nch=fgetc(fp)=='&')
{
printf("&&\t\t运算符\n\n");
fprintf(wfp,"%d && 运算符\n",w);
w++;
break;
}
else
{
printf("%c\t\t运算符\n\n",ch);
fprintf(wfp,"%d & 运算符\n",w);
w++;
fseek(fp,-1L,SEEK_CUR);
break;
}
case'|':if(nch=fgetc(fp)=='|')
{
printf("||\t\t运算符\n\n");
fprintf(wfp,"%d || 运算符\n",w);
w++;
break;
}
else
{
printf("%c\t\t运算符\n\n",ch);
fprintf(wfp,"%d | 运算符\n",w);
w++;
fseek(fp,-1L,SEEK_CUR);
break;
}
case'/':JugNote(ch,fp,wfp);break; //如果是"//"转注释处理
case' ':break;
default:printf("%c\t\t无法识别的字符\n\n",ch);
fprintf(wfp,"%d %c 无法识别的字符\n",w,ch);
break;
}
}
//********************************跳过注释
void JugNote(char ch,*wfp)
{
char nch='\0';
char noteStr[60]={"\0"};
nch=fgetc(fp);
if(nch=='/')
{
fgets(noteStr,60,fp); //读取一行跳过
}
else
{
printf("/\t\t界符\n\n",ch);
fprintf(wfp,"%d %c 界符\n",w,ch);
w++;
}
}
//*************************************判断类型
void Judge(*wfp)
{
void JugKeyLetter(char c,*wfp);
void JugNumber(char c,*wfp);
void JugSign(char c,*wfp);
char ch;
while((ch=fgetc(fp))!=EOF)
{
if((ch=='\n')||(ch=='\t')||(ch==' ')) //跳过开头空格
{
}
else
if (isalpha(ch)) //判断是否为字母
{
JugKeyWord(ch,fp,wfp); //转关键字、标识符处理
}
else
if(isdigit(ch)) //判断是否为数字
{
JugNumber(ch,fp,wfp); //转数字处理
}
else
{
JugSign(ch,fp,wfp); //转符号处理
}
}
}
//***********************主函数
int main()
{
FILE *fp;
FILE *wfp;
void Judge(*wfp);
char wayStr[50];
printf("输入文件完整路径名:");
gets(wayStr);
if((fp=fopen(wayStr,"r"))==NULL)
{
printf("Error can't open file!\n");
}
if((wfp=fopen("D:\\OUT.txt","w"))==NULL)
{
printf("Error can't open OUT.txt!\n");
}
printf("\n");
printf("***************************************\n\n");
Judge(fp,wfp); //判断
fclose(fp);
fclose(wfp);
getch();
return 0;
}
4、运行结果截图:
输出文件OUT.txt截图:
读入文件截图:
5、心得体会:
28 / 28
展开阅读全文