1、里仁学院编译原理实验报告2015 一、 词法分析器: 1、 程序功能: ① 读取一个写有C语言源代码的TXT文档,能分析出源代码中的标识符、关键字、数字、界符、运算符。 ② 能跳过其中的斜杠”//”后的注释。 ③ 屏幕输出例如(int 关键字)。 ④ 在D盘生成OUT.txt文件,写入屏幕输出的内容。 2、程序流程图: 1)判断流程: 开始 读入一个字符 文件结束 T F 字母 标识符
2、关键字处理 T 数字 F 数字处理 T F 符号、未知字符处理 结束 2)标识符、关键字处理: 字母连接成单词 T 下一个是字母 F 与关键字比较 F
3、 T 输出是标识符 输出是关键字 3)数字处理: 数字连接成数字串 下一个为数字或。 T F 输出是数字串 4)符号、未知字符处理:(简略) switch ! 输出运算符!= swich // 跳过 输出未知字符 = 输出运算符! T F T F T F 3、源代码:
4、/*
Name: 词法分析器
Copyright:
Author:
Date: 25/04/15 22:54
Description:
*/
#include
5、n"},{"enum"}, {"typedef"},{"const"},{"unsigned"},{"signed"},{"extern"}, {"register"},{"static"},{"volatile"},{"void"},{"if"},{"else"}, {"switch"},{"case"},{"for"},{"do"},{"while"},{"goto"}, {"continue"},{"break"},{"default"},{"sizeof"},{"return"}}; //*********************************判断关键字,处理单
6、词
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 7、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); //指针后 8、退一位
}
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 9、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';
}
//***** 10、处理符号
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,c 11、h);
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++;b 12、reak;
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 13、'\"':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 14、\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 15、\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);
16、 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) 17、
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 > 18、 运算符\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(w 19、fp,"%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);
f 20、printf(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);
21、
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\ 22、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);
23、 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++;
24、}
}
//*************************************判断类型
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 (i 25、salpha(ch)) //判断是否为字母
{
JugKeyWord(ch,fp,wfp); //转关键字、标识符处理
}
else
if(isdigit(ch)) //判断是否为数字
{
JugNumber(ch,fp,wfp); //转数字处理
}
else
{
JugSign(ch,fp,wfp); //转符号处理
}
}
}
//***********************主函数
int main()
{
26、 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






