北邮编译原理词法分析报告器实验.docx
- 文档编号:8621454
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:18
- 大小:84.31KB
北邮编译原理词法分析报告器实验.docx
《北邮编译原理词法分析报告器实验.docx》由会员分享,可在线阅读,更多相关《北邮编译原理词法分析报告器实验.docx(18页珍藏版)》请在冰豆网上搜索。
北邮编译原理词法分析报告器实验
词法分析程序设计
一.问题描述
1.可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
2.可以并识别读取源程序中的注释。
3.可以统计源程序中的语句行数、单词个数和字符数,其中标点和空格不计为单词,并输出统计结果。
4.检察源程序中存在的错误,并可以报告错误所在行列的位置。
5.发现原程序中存在的错误,进行适当修复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。
二.算法思想
编写一个词法分析程序,它从左到右逐个字符的对源程序进行扫描,产生一个个的单词形成记号流文件输出。
其中,具体子问题有:
(1)源程序文件读入缓冲区中(注意要删除空格和无用符号)
(2)确定读入的为关键字还是运算符还是变量名,对于普通标识符和常量,分别建立标识符表和常量表当遇到一个标识符或常量时,查找标识符表或常量表,若存在,则返回位置,否则进入符号表或常量表中并返回表的入口地址。
(3)对于各类运算符、标点符号、以及注释符号等,准确识别出来并打印输出结果
(4)对于源文件中出现的数字常量,不但能按要求加入常量表中,还进行了字符型到float型数值的转换,便于后续程序操作处理。
(4)尽量精简整合各种情况,使算法复杂度降低,精简易读。
三、实验程序设计说明
1.主要函数说明
voidreadChar();//读字符过程,每调用一次,从输入缓冲区读一个字符,并把它放入变量C中,且向前扫描指针pointer指向下一个字符
voidignoreSpace();//每次调用时,检查C中的字符是否为空字符,若是,则反复调用该过程,直到C进入一个非空字符为止
voidlink();//把C中的字符与token中的字符串连接起来
boolalphabet();//布尔函数,判断C中的字符是否为字母,若是则返回true,否则返回false
booldigit();//布尔函数,判断C中的字符是否为数字,若是则返回true,否则返回false
intsearchForKeywords();//查关键字表,若此函数的返回值为0,则表示token中的字符串是标识符,否则为关键字
intsearchForToken();//查符号表,若此函数的返回值为0,则表示token中的字符串是新出现的,否则为已出现过的标识符
intsearchForNum();//查常数表,若此函数的返回值为0,则表示token中的数字是新出现的,否则为已出现的常数
voidinsertTokenList();//将标识符插入符号表
voidinsertNumList();//将数字插入常数表
voidfillBuffer(inta);//填充buff的半区函数
2.程序源代码
#include
#include
#include
#include
intpointer=0;//
inti=0,j=0,c=0,appear,d=0,num_location;//
introw_num=0,letter_num=0,word_num=0;
intz=1;
charC='';//
chartoken[30];//
charbuff[4095];//
chartoken_list[200][30];//
charnumber[200][10];//
charnext_charac,charac,file_name[20];
charkeywords[32][10]={"auto","break","case","char","const","continue","default","do","double","else","enum","extern","float","for","goto","if","int","long","register","return","short","signed","sizeo","fstatic","struct","switch","typedef","union","unsigned","void","volatile","while"};
doublenum;
FILE*file_pointer;
voidfillBuffer(inta)//
{
//
i=0;
while((!
feof(file_pointer))&&i<2048){//
buff[a+i]=charac;
if(charac!
=''){//
if(charac=='\n'){
row_num++;//
}
else{
letter_num++;
}
}
charac=fgetc(file_pointer);
i++;
}
if(feof(file_pointer)){
buff[a+i]='\0';
}
};
voidreadChar()//
{
C=buff[pointer];
if(pointer==1023){//
fillBuffer(1024);//
pointer++;//
}
elseif(pointer==2047){//
fillBuffer(0);//
pointer==0;//
}
else{
pointer++;
}
};
voidignoreSpace()//
{
if(C==''||C=='\n'||C=='\t'){
C=buff[pointer];
if(pointer==1023){//
fillBuffer(1024);//
pointer++;//
}
elseif(pointer==2047){//
fillBuffer(0);//
pointer=0;//
}
else{
pointer++;
}
ignoreSpace();
}
};
voidlink()//
{
token[j++]=C;
};
boolalphabet()//
{
if((C>=97&&C<=122)||(C>=65&&C<=90)){
returntrue;
}
else{
returnfalse;
}
};
booldigit()//
{
if(C>=48&&C<=57){
returntrue;
}
else{
returnfalse;
}
};
intsearchForKeywords()//
{
for(intx=0;x<32;x++){
if(strcmp(token,keywords[x])==0){
return0;//
}
}
return1;
};
intsearchForToken()//
{
inti=0;
while(i<=c-1){
if(strcmp(token,token_list[i])==0){
appear=i;
return0;
}//
i++;
}
word_num++;
return1;
};
intsearchForNum()//
{
inti=0;
while(i<=d-1){
if(strcmp(token,number[i])==0){
num_location=i;
return0;
}//
i++;
}
word_num++;
return1;
};
voidinsertTokenList()//
{
strcpy(token_list[c++],token);
};
voidinsertNumList()//
{
strcpy(number[d++],token);
};
main()
{
printf("输入源文件的路径:
\n");
scanf("%s",file_name);
file_pointer=fopen(file_name,"r");
if(file_pointer==NULL)printf("无法查找到文件,发生错误!
\n");//
charac=fgetc(file_pointer);
fillBuffer(0);//
while(C!
='\0'){
readChar();//
ignoreSpace();//
switch(C){
//
case65:
case66:
case67:
case68:
case69:
case70:
case71:
case72:
case73:
case74:
case75:
case76:
case77:
case78:
case79:
case80:
case81:
case82:
case83:
case84:
case85:
case86:
case87:
case88:
case89:
case90:
case97:
case98:
case99:
case100:
case101:
case102:
case103:
case104:
case105:
case106:
case107:
case108:
case109:
case110:
case111:
case112:
case113:
case114:
case115:
case116:
case117:
case118:
case119:
case120:
case121:
case122:
case'_':
//ǰזΪזĸʽזϟ
while(alphabet()||digit()||C=='_'){//
link();//
readChar();//
}
//
token[j]='\0';//
j=0;//
pointer--;//
if(searchForKeywords()==1){//
if(searchForToken()==1){//
insertTokenList();//
printf("
}
else{
printf("
}//
}
else{
printf("<%s,ؼז>\n",token);//
}
break;
case48:
case49:
case50:
case51:
case52:
case53:
case54:
case55:
case56:
case57:
num=(C-48);
link();
readChar();
while(digit()){
link();
num=num*10+(C-48);//
readChar();
}
if(C=='.'){
link();
readChar();
while(digit()){
link();
num=num+(C-48)*pow(0.1,z++);//
readChar();
}
}
token[j]='\0';//
j=0;//
pointer--;
if(searchForNum()==1){//
insertNumList();//
printf("<%f,%d>\n",num,d-1);
}
else{
printf("<%f,%d>\n",num,num_location);
}//
break;
case'+':
readChar();
if(C=='='){
printf("<+=,赋值运算符>\n");
}
elseif(C=='+'){
printf("<++,自加>\n");
}
else{
pointer--;
printf("<+,加号>\n");
}
break;
case'-':
readChar();
if(C=='-'){
printf("<--,自减>");
}
elseif(C=='='){
printf("<-=,赋值运算符>\n");
}
else{
pointer--;
printf("<-,减号>\n");
}
break;
case'*':
printf("<*,乘号>\n");break;
case'/':
readChar();
if(C=='*'){
readChar();
next_charac=buff[pointer];
while(C!
='*'&&next_charac!
='/'){
readChar();
next_charac=buff[pointer];
}
readChar();
printf("*,多行注释>\n");
}
elseif(C=='/'){
readChar();
while(C!
='\n'){
readChar();
}
printf("/,单行注释>\n");
}
else{
pointer--;
printf(",除号>\n");
}
break;
case'%':
printf("<%,取模>\n");break;
case'(':
printf("<(,左小括号>\n");break;
case')':
printf("<),右小括号>\n");break;
case'[':
printf("<[,左中括号>\n");break;
case']':
printf("<],右中括号>\n");break;
case'{':
printf("<{,-左大括号>\n");break;
case'}':
printf("<},右大括号>\n");break;
case':
':
printf("<:
冒号>\n");break;
case';':
printf("<;,分号>\n");break;
case',':
printf("<,逗号>\n");break;
case'.':
printf("<.,句号>\n");break;
case'?
':
printf("
问号>\n");break;
case'"':
printf("<"",引号>\n");break;
case'#':
printf("<#,井号>\n");break;
case'>':
readChar();
if(C=='='){
printf("<>=,大于等于>\n");
}
else{
pointer--;
printf("<>,大于>\n");
}
break;
case'<':
readChar();
if(C=='='){
printf("<<=,小于等于>\n");
}
else{
pointer--;
printf("<<,小于>\n");
}
break;
case'=':
readChar();
if(C=='='){
printf("<==,判等>\n");
}
else{
pointer--;
printf("<=,赋值等>\n");
}
break;
case'&':
readChar();
if(C=='&'){
printf("<&&,且>\n");
}
else{
pointer--;
printf("<&,取地址符>\n");
}
break;
case'|':
readChar();
if(C=='|'){
printf("<||,或>\n");
}
else{
pointer--;
printf("<|,运算符>\n");
}
break;
case'!
':
readChar();
if(C=='='){
printf("
=,不等>\n");
}
else{
pointer--;
printf("
非>\n");
}
break;
}
}
printf("该源文件的行数为:
%d,单词数为%d,字符数为%d.\n",row_num,word_num,letter_num);
system("pause");
return0;
}
3.程序的执行结果
测试程序为:
运行结果为:
四、有待改进的地方
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 邮编 原理 词法 分析 报告 实验