编译原理实验1.docx
《编译原理实验1.docx》由会员分享,可在线阅读,更多相关《编译原理实验1.docx(11页珍藏版)》请在冰豆网上搜索。
编译原理实验1
实验一编写词法实验程序
(题目字体为华文中宋,三号字体)
一.实验小组成员及任务分解(黑体,小四)
本组共有4个成员,本组全总成员参与程序代码的输入,每人输入2到3张程序代码不等,最后合并每个成员输入的程序段进行编译连接,修改错误,最终改正了程序,得到了正确的运行结果,最后制作出了实验报告电子文档。
实验过程中每一个成员的任务如下:
姓名
任务
杨成凡
程序代码输入、编译、报告制作
刘春香
程序代码输入、编译、报告制作
曹卓
程序代码输入、编译、报告制作
李论
编译、报告制作
二.实验目的和要求(黑体,小四)
通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。
掌握文法转换成自动机的技术及有穷自动机实现的方法。
确定词法分析器的输出形式及标识符与关键字的区分方法。
加深对课堂教学的理解;提高此法分析方法的实践能力。
通过本实验达到一下目标:
1、掌握从源程序文件中读取有效字符的方法和生产源程序的内部表示文件的方法。
2、掌握此法分析的实现方法。
3、上机调试编出的词法分析程序。
三.背景知识(黑体,小四)
词法分析的背景知识:
词法分析就是把组成说明和语句的单词逐个识别出来,给出单词的类别及其他属性,以供语法分析用。
执行词法分析功能的程序称为词法分析程序,也称为词法分析器或词法扫描器,词法分析器可借助于有限自动机等工具手工构造或自动生成。
词法分析器的作用:
词法分析器(也称词法分析程序)的主要作用是根据单词的文法,把源程序中的单词逐个识别出来,并给出各个单词包括类别在内的属性。
一般的高级语言中,单词由如下几个类别:
(1)标识符;
(2)关键字*(从文法上看,关键字集合是标识符集合的子集合);
(3)常数,包括整常数、实常数(或称浮点数)、字符常数、字符串常数等;
(4)运算符,如+,—,*,/等;
(5)分隔符,如逗号(,)、冒号(:
)、分号(;)等。
词法分析器每识别出一个单词,要给出该单词所属的类别,此外还要给出该单词(语法分析需的)其他属性。
对于标识符来说,还要给出它的源程序表示(即构成标识符的字符串);对于关键字来说,还要给出它在关键字表中的地址或序号;对常数来说,还要给出它在常数表中的地址或序号;对于运算符和分隔符,还要给出它的源程序表示(即源程序中的形式)或编号。
词法分析器还提供单词在源程序中的位置信息,即行号和列号,也供错误处理部分使用。
在分析过程中,词法分析器要略掉源程序中的注释。
词法分析器的构造方法:
构造词法分析器既可以手工完成,也可以利用LEX处理系统自动完成。
手工构造词法分析器一般都借助于状态转移图。
状态转移图是一个有穷有向图,它关联一个入字母表。
图中的结点代表状态,状态之间的有向边标有取自输入字母表中的字母。
图中的状态有一个是初始状态,还有若干个终止状态。
在描述单词识别过程的转移图中,当尚未读取构成单词的任何字符时,处于初始状态;处于某个终止状态时,表示识别出一个单词。
通常,在初始状态左边加一个箭头,以表示它是初始状态;终止状态用双圆圈表示,非终止状态用单圆圈表示。
状态0是初始状态,处于状态0时,表示尚未读入构成标识符的任何字符;到状态1时,表示已读入了若干个字母、数字,并且读入的第1个字符一定是字母;到状态2时,表示已识别出一个标识符,即读入的字符序列恰好构成了一个标识符。
状态2右边加一个*,表示到达该状态时,多读了一个不属于标识符的字符。
LEX是一个词法分析器的自动生成系统。
LEX语言可用于描述单词的结构,LEX处理系统根据LEX语言源程序提能吸供单词结构信息,自动生成分析这些单词的词法分析程序。
LEX语言用正则表达式描述单词的结构,LEX处理系统根据LEX语言中的描述单词结构正则式R生成相应的有限状态自动机M,满足L(R)=L(M),再根据M生成相应的词法分析程序。
此法分析师作为相对独立的阶段来完成的。
在词法分析的过程中,编译程序是通过操作系统从外部介质中读取源程序文件中的各个字符的。
同时为正确的识别单词,有时还需进行超前搜索和回退字符等操作。
因此,为了提高读盘效率和便于扫描器进行工作,通常可以采取缓冲输入的方案,即在内存中设置一个适当大小的输入缓冲区,让操作系统直接将磁盘上的源程序字符串分批送入此缓冲区中,供扫描器进行处理。
四.实验内容及算法设计
#include
#include
char*KeyWord[32]={"auto","break","case","char",
"const","continue","default",
"do","double","else","enum","extern","float","for","goto",
"if","int","long","register","return","short","signed","sizeof",
"static","struct","switch","typedef","union","unsigned",
"void","volatile","while"};
inti=0,j=0,k=0,t=0;
charch;
charstrToken[20];
char*chr_form[100];
char*int_form[100];
charform[1000];
intq=0;
voidGetChar()
{
ch=form[k];
k++;
}
voidGetBC()
{
while(ch==''){
GetChar();
}
}
voidConcat()
{
strToken[i]=ch;
i++;
}
boolisLetter()
{
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
returntrue;
else
returnfalse;
}
boolisDigit()
{
if(ch>='0'&&ch<='9')
returntrue;
else
returnfalse;
}
//第3,4篇
//第5,6页
intSearchKeyWord(){
for(intq=0;q<32;q++){
if(strcmp(strToken,KeyWord[q]))
returnq;//是关键字
if(q==32)return-1;//是字符串
}
}
voidReset(){
k--;
ch=NULL;
}
char*InsertChar(){//将strToken中的标识符插入符号表,返回符号表的指针
chr_form[j]=strToken;
j++;returnchr_form[0];
}
char*InsertInt(){//将strToken中的常数插入长鼠标,返回常数表指针
int_form[t]=strToken;
t++;
returnint_form[0];
}
intcode;
voidanalyze()
{
GetChar();
GetBC();
if(isLetter())
{//如果是字符
while(isLetter()||isDigit())
{
Concat();
GetChar();
}
Reset();
code=SearchKeyWord();
switch(code){
case-1:
cout<<"<字符串,"<"<default:
cout<<"<关键字"<<","<"<}
else
{
if(isDigit())//是数字
{
while(isDigit()||ch=='.'){
Concat();
GetChar();
}
Reset();
cout<<"<是数字,"<"<}
else
{
switch(ch){
case'=':
case'*':
case'%':
cout<<"运算符,"<"<case'_':
GetChar();
if(ch=='_')cout<<"<运算符,__>"<else{Reset();cout<<"<运算符,_>"<break;
//第7页
case'+':
GetChar();
if(ch=='+')cout<<"<运算符,++>"<else{Reset();cout<<"<运算符,+>"<break;
case'|':
GetChar();
if(ch=='|')cout<<"<运算符,||>"<else{Reset();cout<<"非法符号"<break;
case'&':
GetChar();
if(ch=='&')cout<<"<运算符,&&>"<break;
case'/':
GetChar();
if(ch=='/'){
do{GetChar();}
while(ch!
='\n');
cout<<"<注释,//>"<}
else{Reset();cout<<"<注释,/>"<break;
case';':
case'(':
case')':
case'{':
case'}':
case'[':
case']':
case':
':
case',':
case'"':
cout<<"<界符,"<"<case'<':
GetChar();
//第8页
if(ch=='<')cout<<"<运算符,<<>"<else{Reset();cout<<"<界符,>>"<break;
case'>':
GetChar();
if(ch=='+')cout<<"<运算符,>>"<else{Reset();cout<<"<界符,>>"<break;
}
}
}
while(k{
for(intp=0;p<20;p++)
strToken[p]='\0';
i=0;
analyze();
}
}
voidmain()
{
cout<<"请输入一段C语言程序,以符号@结尾:
"<form[0]=cin.get();
for(q=1;form[q-1]!
='@';q++){
form[q]=cin.get();
if(form[q]='@'){
cout<<"你输入的程序段为:
"<cout.write(form,q);
cout<break;
}
}
analyze();
}
五.上机实现情况及运行结果(包括中间和最终结果)
本组发扬团结互助精神,分工合作,每一位同学都积极参与本门课程的实验,优秀的完成了