北邮编译原理词法分析文档和程序.docx
《北邮编译原理词法分析文档和程序.docx》由会员分享,可在线阅读,更多相关《北邮编译原理词法分析文档和程序.docx(14页珍藏版)》请在冰豆网上搜索。
北邮编译原理词法分析文档和程序
实验报告
班级:
2011211314
姓名:
oneseven
学号:
一.题目:
词法分析程序设计与实现
二.实验内容:
设计并实现C语言的词法分析程序,要求如下。
(1)可以识别出用C语言编写的源程序中的每个单词符号,并以记号的形式输出每个单词符号。
(2)可以识别并读取源程序中的注释。
(3)可以统计源程序中的语句行数、单词个数和字符个数,其中标点和空格不计算为单词,并输出统计结果。
(4)检查源程序中存在的非法字符错误,并可以报告错误所在的行列位置。
三.实现要求:
采用C/C++作为实现语言,手工编写词法分析程序。
四.实现功能:
基本完成了实验内容中要求的所有功能。
(1)识别出源程序中的每个单词符号,并以记号的形式输出每个单词符号
(2)识别并读取源程序中的注释(3)统计源程序中的语句行数、单词个数和字符个数(4)检查源程序中存在的非法字符错误,并可以报告错误所在的行列位置。
注:
本程序未把注释中的单词符号,“”中的单词符号统计在单词个数中。
单词个数只包括了标示符,关键字,无符号数。
五.实验原理:
1.词法分析程序的功能:
输入源程序,输出单词符号的记号形式,如图所示:
源程序词法分析器单词符号的记号形式
2.处理过程:
每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直至整个源程序全部扫描完毕,并形成相应的单词串形式的源程序。
六.代码
#include
#include
#include
#include
usingnamespacestd;
stringkeyword[32]={"auto","break","case","char","const",//关键字
"continue","default","do","double","else","extern",
"enum","float","for","goto","if","int","long","return",
"register","static","short","signed","unsigned",
"struct","switch","sizeof","typedef","union",
"volatile","void","while"};
intcolumn=0,row=1,character=0,word=0;
ifstreaminf("test.txt",ios:
:
in);
charc;
intfind_key(stringword)//匹配关键字
{
for(inti=0;i<32;i++)
if(keyword[i].compare(word)==0)
return1;
return0;
}
voidchoice()
{
while(c=='\n'||c==''||c=='\t')//不计空白符
{
if(c=='\n')
{
row++;
column=0;//row清零,重新计数另一行
}
c=inf.get();
column++;
}
return;
}
voidget()//读取字符
{
character++;
c=inf.get();
column++;
return;
}
intprocess()
{
stringstr="";
if(inf.fail())
cout<<"请创建test.txt并输入程序"<else
{
ofstreamoutf("out.txt");
outf<c=inf.get();
column++;
while(c!
=EOF)
{
switch(c){//匹配字符对应记号
case'a'...'z':
case'A'...'Z':
case'_':
word++;
while(isalpha(c)||isdigit(c)||c=='_')
{
str+=c;
get();
}
if(c=='@'||c=='?
'||c=='$'||c=='#')
{
inttag=column;
while(isalpha(c)||isdigit(c)||c=='_'||c=='@'||c=='?
'||c=='$'||c=='#')
{
str+=c;
get();
}
outf<str="";
break;
}
if(find_key(str))
{
outf<str="";
}
else
{
outf<str="";
}
break;
case'0'...'9':
word++;
while(isdigit(c)||c=='.'||c=='e'||c=='E')
{
str+=c;
if(c=='e'||c=='E')
{
get();
str+=c;
}
get();
}
if(isalpha(c))
{
inttag=column;
while(isalpha(c)||c=='_'||isdigit(c)||c=='@'||c=='?
'||c=='$'||c=='#')
{
str+=c;
get();
}
outf<str="";
break;
}
outf<str="";
break;
case'>':
get();
if(c=='=')
outf<="<elseif(c=='>')
outf<>"<else
{
outf<"<break;
}
get();
break;
case'<':
get();
if(c=='=')
outf<elseif(c=='<')
outf<else
{
outf<break;
}
get();
break;
case'=':
get();
if(c=='=')
outf<else
{
outf<break;
}
get();
break;
case'!
':
get();
if(c=='=')
outf<="<else
{
outf<"<break;
}
get();
break;
case'|':
get();
if(c=='|')
outf<else
{
outf<break;
}
get();
break;
case'&':
get();
if(c=='&')
outf<else
{
outf<break;
}
get();
break;
case'+':
get();
if(c=='+')
outf<elseif(c=='=')
outf<else
{
outf<break;
}
get();
break;
case'-':
get();
if(c=='-')
outf<elseif(c=='=')
outf<else
{
outf<break;
}
get();
break;
case'*':
get();
if(c=='=')
outf<else
{
outf<break;
}
get();
break;
case'\"':
str+=c;
get();
while(c!
='\"')
{
str+=c;
get();
if(c==''||c=='\t')
character--;
}
str+='\"';
outf<str="";
get();
break;
case'/':
str+=c;
get();
if(c=='=')
outf<elseif(c=='/')
{
str+=c;
get();
while(c!
='\n'&&c!
=EOF)
{
str+=c;
get();
}
character--;
outf<}
elseif(c=='*')
{
str+=c;
get();
chartag=c;
while(tag!
='*'&&c!
='/'&&c!
=EOF)
{
str+=c;
tag=c;
choice();
get();
}
str+=c;
outf<}
else
{
outf<str="";
break;
}
str="";
get();
break;
case'':
case'\n':
caseEOF:
break;
default:
outf<get();
break;
}
choice();
}
outf<<"语句行数:
"<outf<<"单词个数:
"<outf<<"字符个数:
"<inf.close();
outf.close();
return1;
}
inf.close();
return0;
}
intmain()
{
intflag;
flag=process();
if(flag==1)
{
cout<<"词法分析源程序详见test.txt"<cout<<"词法分析结果及错误分析详见out.txt"<cout<<"语句行数:
"<cout<<"单词个数:
"<cout<<"字符个数:
"<}
system("pause");
return0;
}
七.测试数据:
(1)运行程序
(2)测试代码test.txt
(3)输出结果out.txt
|
|