北邮编译原理词法分析报告器实验.docx

上传人:b****6 文档编号:8621454 上传时间:2023-02-01 格式:DOCX 页数:18 大小:84.31KB
下载 相关 举报
北邮编译原理词法分析报告器实验.docx_第1页
第1页 / 共18页
北邮编译原理词法分析报告器实验.docx_第2页
第2页 / 共18页
北邮编译原理词法分析报告器实验.docx_第3页
第3页 / 共18页
北邮编译原理词法分析报告器实验.docx_第4页
第4页 / 共18页
北邮编译原理词法分析报告器实验.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

北邮编译原理词法分析报告器实验.docx

《北邮编译原理词法分析报告器实验.docx》由会员分享,可在线阅读,更多相关《北邮编译原理词法分析报告器实验.docx(18页珍藏版)》请在冰豆网上搜索。

北邮编译原理词法分析报告器实验.docx

北邮编译原理词法分析报告器实验

词法分析程序设计

一.问题描述

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("\n",c-1);

}

else{

printf("\n",appear);

}//

}

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.程序的执行结果

测试程序为:

运行结果为:

四、有待改进的地方

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1