北邮大三上编译原理词法分析实验报告.docx
《北邮大三上编译原理词法分析实验报告.docx》由会员分享,可在线阅读,更多相关《北邮大三上编译原理词法分析实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
![北邮大三上编译原理词法分析实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/2/55639c2c-e98f-46d6-b6d5-ffee7d26b424/55639c2c-e98f-46d6-b6d5-ffee7d26b4241.gif)
北邮大三上编译原理词法分析实验报告
编译原理
第三章词法分析
班级:
2009211311
学号:
姓名:
schnee
3.源代码……………………………………………………………………..4
1.实验题目和要求
题目:
词法分析程序的设计与实现。
实验内容:
设计并实现C语言的词法分析程序,要求如下。
(1)、可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
(2)、可以识别并读取源程序中的注释。
(3)、可以统计源程序汇总的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果
(4)、检查源程序中存在的错误,并可以报告错误所在的行列位置。
(5)、发现源程序中存在的错误后,进行适当的恢复,使词法分析可以继续进行,通过一次词法分析处理,可以检查并报告源程序中存在的所有错误。
实验要求:
方法1:
采用C/C++作为实现语言,手工编写词法分析程序。
方法2:
通过编写LEX源程序,利用LEX软件工具自动生成词法分析程序。
2.检测代码分析
1、HelloWorld简单程序输入:
2、较复杂程序输入:
3.异常程序输入检测
三,源代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
usingnamespacestd;
constintFILENAME=105;
constintMAXBUF=82;
constintL_END=40;
constintR_END=81;
constintSTART=0;//开始指针
vectorKey;//C保留的关键字表
classfuntion//词法分析结构
{
public:
//变量声明
charfilename[FILENAME];//需要词法分析的代码文件名
ifstreamf_in;
charbuffer[MAXBUF];//输入缓冲区
intl_end,r_end,forward;//左半区终点,右半区终点,前进指针,
booll_has,r_has;//辅助标记位,表示是否已经填充过缓冲区
vectorId;//标识符表
charC;//当前读入的字符
intlinenum,wordnum,charnum;//行数,单词数,字符数
stringcurword;//存放当前的字符串
//函数声明
voidget_char();//从输入缓冲区读一个字符,放入C中,forward指向下一个
voidget_nbc();//检查当前字符是否为空字符,反复调用直到非空
voidretract();//向前指针后退一位
voidinitial();//初始化要词法分析的文件
voidfillBuffer(intpos);//填充缓冲区,0表示左,1表示右
voidanalyzer();//词法分析
voidtoken_table();//以记号的形式输出每个单词符号
voidnote_print();//识别并读取源程序中的注释
voidcount_number();//统计源程序汇总的语句行数、单词个数和字符个数
voiderror_report();//检查并报告源程序中存在的所有错误
voidsolve(char*file);//主调用函数
};
voidwelcome()
{
printf("\n*********************************************************\n");
printf("**WelcometouseLexicalAnalyzer**\n");
printf("**Byschnee@BUPTDate:
2011/20/10**\n");
printf("*********************************************************\n\n\n");
}
voidinitKey()
{
Key.clear();
Key.push_back("auto");Key.push_back("break");Key.push_back("case");Key.push_back("char");
Key.push_back("const");Key.push_back("continue");Key.push_back("default");Key.push_back("do");
Key.push_back("double");Key.push_back("else");Key.push_back("enum");Key.push_back("extern");
Key.push_back("float");Key.push_back("for");Key.push_back("goto");Key.push_back("if");
Key.push_back("int");Key.push_back("long");Key.push_back("register");Key.push_back("return");
Key.push_back("short");Key.push_back("signed");Key.push_back("static");Key.push_back("sizeof");
Key.push_back("struct");Key.push_back("switch");Key.push_back("typedef");Key.push_back("union");
Key.push_back("unsigned");Key.push_back("void");Key.push_back("volatile");Key.push_back("while");
}
voidfuntion:
:
get_char()
{
C=buffer[forward];
if(C==EOF)return;//结束
if(C=='\n')linenum++;//统计行数和字符数
elseif(isalnum(C))charnum++;
forward++;
if(buffer[forward]==EOF)
{
if(forward==l_end)
{
fillBuffer
(1);
forward++;
}
elseif(forward==r_end)
{
fillBuffer(0);
forward=START;
}
}
}
voidfuntion:
:
get_nbc()
{
while(C==''||C=='\n'||C=='\t'||C=='\0')
get_char();
}
voidfuntion:
:
initial(char*file)
{
Id.clear();//清空标识符表
l_end=L_END;r_end=R_END;//初始化缓冲区
forward=0;
l_has=r_has=false;
buffer[l_end]=buffer[r_end]=EOF;
fillBuffer(0);
linenum=wordnum=charnum=0;//初始化行数,单词数,字符数
}
voidfuntion:
:
fillBuffer(intpos)
{
if(pos==0)//填充缓冲区的左半边
{
if(l_has==false)
{
fin.read(buffer,l_end);
if(fin.gcount()!
=l_end)
buffer[fin.gcount()]=EOF;
}
elsel_has=false;
}
else//填充缓冲区的右半边
{
if(r_has==false)
{
fin.read(buffer+l_end+1,l_end);
if(fin.gcount()!
=l_end)
buffer[fin.gcount()+l_end+1]=EOF;
}
elser_has=false;
}
}
voidfuntion:
:
retract()
{
if(forward==0)
{
l_has=true;//表示已经读取过文件,避免下次再次读取
forward=l_end-1;
}
else
{
forward--;
if(forward==l_end)
{
r_add=true;
forward--;
}
}
}
voidfuntion:
:
analyzer()
{
FILE*token_file,*note_file,*count_file,*error_file;
token_file=fopen("token_file.txt","w");
note_file=fopen("note_file.txt","w");
count_file=fopen("count_file.txt","w");
error_file=fopen("error_file.txt","w");
inti;
curword.clear();
get_char();
get_nbc();
if(C==EOF)returnfalse;
if(isalpha(C)||C=='_')//关键字和标识符的处理,以字母或下划线开头
{
curword.clear();
while(isalnum(C)||C=='_')
{
curword.push_back(C);
get_char();
}
retract();
wordnum++;
Id.push_back(curword);
for(i=0;iif(Key[i]==curword)
break;
//输出每一个单词的标识符
if(ifprintf(token_file,"%8d----%20s%s\n",wordnum,"KEYWORD",curword);
else
fprintf(token_file,"%8d----%20s%s\n",wordnum,"Identifier",curword);
}
elseif(isdigit(C))//无符号数的处理
{
curword.clear();
while(isdigit(C))
{
curword.push_back(C);
get_char();
}
if(C=='.'||C=='E'||C=='e')//处理小数和指数形式
{
curword.push_back(C);
get_char();
while(isdigit())
{
curword.push_back(C);
get_char();
}
}
retract();
wordnum++;
Id.push_back(curword);
fprintf(token_file,"%8d----%20s%s\n",wordnum,"UnsignedNumber",curword);
}
elseif(C=='#')//过滤掉以#开头的预处理
{
fprintf(note_file,"preproccessLine%d:
",linenum);
get_char();
fprintf(note_file,"%c",C);
while(C!
='\n')
{
get_char();
fprintf(note_file,"%c",C);
}
fprintf(note_file,"%c",C);
}
elseif(C=='"')//""内的句子当成整个串保存起来
{
curword.clear();
get_char();
while(C!
='"')
{
curword.push_back(C);
get_char();
}
fprintf(token_file,"*****stringin""----%s\n",curword);
}
elseif(C=='/')
{
get_char();
if(C=='/')//过滤掉//开头的行注释
{
fprintf(note_file,"single-linenoteLine%d:
",linenum);
get_char();
curword.clear();
while(C!
='\n')
{
curword.push_back(C);
get_char();
}
fprintf(note_file,"%s\n",curword);
}
elseif(C=='*')//过滤掉/**/之间的段注释
{
fprintf(note_file,"paragraphnoteLine%d:
",linenum);
get_char();
while(true)
{
while(C!
='/')
{
fprintf(note_file,"%c",C);
get_char();
}
get_char();
if(C=='*')
{
fprintf(note_file,"\ntoLine%d\n",linenum);
break;
}
fprintf(note_file,"%c",C);
}
}
elseif(C=='=')fprintf(token_file,"*****ASSIGN-OP,DIV\n");
else
{
fprintf(token_file,"*****CAL-OP,DIV\n");
retract();
}
}//处理各种比较,赋值,运算符号
elseif(C=='<')
{
get_char();
if(C=='=')fprintf(token_file,"*****RELOP,LE\n");
else
{
fprintf(token_file,"*****RELOP,LT\n");
retract();
}
}
elseif(C=='>')
{
get_char();
if(C=='=')fprintf(token_file,"*****RELOP,GE\n");
else
{
fprintf(token_file,"*****RELOP,GT\n");
retract();
}
}
elseif(C=='=')
{
get_char();
if(C=='=')fprintf(token_file,"*****RELOP,EQ\n");
else
{
fprintf(token_file,"*****ASSIGN-OP,EASY\n");
retract();
}
}
elseif(C=='+')
{
get_char();
if(C=='=')fprintf(token_file,"*****ASSIGN-OP,ADD\n");
else
{
fprintf(token_file,"*****CAL-OP,ADD\n");
retract();
}
}
elseif(C=='-')
{
get_char();
if(C=='=')fprintf(token_file,"*****ASSIGN-OP,SUB\n");
else
{
fprintf(token_file,"*****CAL-OP,SUB\n");
retract();
}
}
elseif(C=='*')
{
get_char();
if(C=='=')fprintf(token_file,"*****ASSIGN-OP,MUL\n");
else
{
fprintf(token_file,"*****CAL-OP,MUL\n");
retract();
}
}
elseif(C=='!
')
{
get_char();
if(C=='=')fprintf(token_file,"*****RELOP,UE\n");
elseif(!
isalpha(C)&&C!
='_')
{
fprintf(error_file,"Line%d:
error:
'!
'wasillegalchar\n",linenum);
}
}
elseif(C==':
'||C=='('||C==')'||C==';'||C=='{'||C=='}'||C==',')
fprintf(token_file,"*****Otherchar----%c\n",C);
else
fprintf(error_file,"Line%d:
error:
'%c'wasillegalchar\n",linenum,C);
fprintf(count_file,"TheLinenumberis%d\n",linenum);
fprintf(count_file,"Thewordnumberis%d\n",wordnum);
fprintf(count_file,"Thecharnumberis%d\n",charnum);
fclose(token_file);
fclose(note_file);
fclose(count_file);
fclose(error_file);
}
voidfuntion:
:
token_table()
{
fin.open("token_file.txt");
printf("Thetoken_tableisasfollowing:
\n");
charstr[1];
while
(1)
{
fin.read(str,1);
if(str[0]!
=EOF)printf("%c",str[0]);
}
}
voidfuntion:
:
note_print()
{
fin.open("note_file.txt");
printf("Thenoteisasfollowing:
\n");
charstr[1];
while
(1)
{
fin.read(str,1);
if(str[0]!
=EOF)printf("%c",str[0]);
}
}
voidfuntion:
:
count_number()
{
fin.open("count_file.txt");
printf("Thecountresultisasfollowing:
\n");
charstr[1];
while
(1)
{
fin.read(str,1);
if(str[0]!
=EOF)printf("%c",str[0]);
}
}
voidfuntion:
:
error_report()
{
fin.open("error_file.txt");
printf("Theerrorreportisasfollowing:
\n");
charstr[1];
while
(1)
{
fin.read(str,1);
if(str[0]!
=EOF)printf("%c",str[0]);
}
}
voidfuntion:
:
solve(char*file)
{
filename=file;
fin.open(filename);
intitial();
analyzer();
intchoice;
printf("****Wehaveanalyzed%s\n");
printf("**0:
Toend\n");
printf("**1:
Togetthetokentable\n");
printf("**2:
Togetthenotepartoffile\n");
printf("**4:
Toreportalltheerrorofthefile\n");
printf("**3:
Togetthelinenum,wordnumandcharternum\n\n");
while
(1)
{
printf("****pleaseinputyourchoice:
");
scanf("%d",&choice);
if(choice==0)break;
if(choice==1)token_table();
elseif(choice==2)note_print();
elseif(choice==3)count_number();
elseerror_report();
printf("\n");
}
}
voidLexicalAnaylzer(char*file)
{
funtiontest;
test.solve(file);
}
intmain()
{
welcome();
initKey();
char