编译报告词法分析器.docx
- 文档编号:28727947
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:22
- 大小:107.75KB
编译报告词法分析器.docx
《编译报告词法分析器.docx》由会员分享,可在线阅读,更多相关《编译报告词法分析器.docx(22页珍藏版)》请在冰豆网上搜索。
编译报告词法分析器
基本词法分析程序报告
班级:
软件74
学号:
07161081
姓名:
徐杨
1.词法形式化描述
a代表26个字母
b代表1-9,9个数字
标识符:
整形常数
2.单词种别定义:
(1)保留字
Program
(1),begin
(2),end(3),var(4),integer(5),if(6),then(7),else(8),do(9),while(10)
(2)标识符(11)
(3)整形常数(12)
(4)界符,运算符
+(13),—(14),((15),)(16),=(17),>(18),<(19)
;(20)(分号,语句结束时使用),(21)(定义变量时分隔多个变量)
:
(22)(冒号,定义变量时使用):
=(23)(冒号+等号,赋值号)
*(24)乘,/(25)除
3.状态转换图
4.词法分析程序
#include
#include"fstream.h"
#include
classPro_Process
{
private:
intsta_stack;
public:
Pro_Process()
{
sta_stack=0;
}
public:
voidProcess(char*ptr)
{
char*temp2=ptr;
while((int)*temp2!
=0)//去掉//和/*
{
if(sta_stack!
=0)//进入夹逼注释阶段
{
//寻找下一个标记符号
if((int)*temp2=='*'&&(int)*(temp2+1)=='/')//寻找到
{
sta_stack--;
*temp2=32;
*(temp2+1)=32;
}
if((int)*temp2=='/'&&(int)*(temp2+1)=='*')
{
sta_stack++;
*temp2=32;
*(temp2+1)=32;
}
else//否则在注释中置为空格
{
*temp2=32;
}
}
else//正常进行阶段
{
if((int)*temp2=='/')
{
if((int)*(temp2+1)=='/')
{
Pro_process1(temp2);
return;
}
if((int)*(temp2+1)=='*')
{
*temp2=32;
sta_stack++;
}
}
}
temp2++;
}
}
private:
/*将当前符号置为0
*
*/
voidPro_process1(char*temp2)
{
*temp2=0;
}
};
classTwo_pass
{
private:
charptr[20];
intindex;
intstate;//确定返回的是否带有字符串,如果有为1;没有为0;
public:
Two_pass()
{
index=0;
}
voidTwo_copy(char*p,intdex)
{
state=1;
intcount=0;
while(*p!
='\0')
{
ptr[count]=*p;
count++;
p++;
}
ptr[count]='\0';
index=dex;
}
voidTwo_copy(intdex)//返回值没有字符串
{
index=dex;
state=0;
}
char*get_String()
{
char*p=ptr;
returnp;
}
intgetIndex()
{
returnindex;
}
intgetState()
{
returnstate;
}
};
classAccidenceAnalyse
{
private:
ifstreamifs;
private:
Pro_Processpro;
charch;
charstrInstream[257];//存储文件的行,最后一位为回车
charstrToken[257];//新生成的单词
intcount;//标记strToken[]数组下一个方位
char*p;//标记strInstream[]数组方位
public:
AccidenceAnalyse()
{
ch=32;
p=NULL;
count=0;
ifs.open("KK.txt",ios:
:
in);
//init_map();
}
private:
voidGetchar()//取当前字符,指针向下移位
{
ch=*p;
p++;
}
voidgetNBC()
{
while(ch==32)
{
Getchar();
}
}
voidConcat()
{
strToken[count]=ch;
count++;
}
voidAppend()
{
strToken[count]='\0';
}
boolisLetter()
{
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
returntrue;
returnfalse;
}
boolisDigit()
{
if(ch>='0'&&ch<='9')
returntrue;
returnfalse;
}
voidRetract()
{
ch=32;
p--;
}
public:
intreserve()
{
switch(strToken[0])
{
case'p':
{
if(strcmp(strToken,"program")==0)
{
return1;
}
return0;
}
break;
case'b':
{
if(strcmp(strToken,"begin")==0)
{
return2;
}
return0;
}
break;
case'e':
{
if(strcmp(strToken,"end")==0)
{
return3;
}
if(strcmp(strToken,"else")==0)
{
return8;
}
return0;
}
break;
case'v':
{
if(strcmp(strToken,"var")==0)
{
return4;
}
return0;
}
break;
case'i':
{
if(strcmp(strToken,"integer")==0)
{
return5;
}
if(strcmp(strToken,"if")==0)
{
return6;
}
return0;
}
break;
case't':
{
if(strcmp(strToken,"then")==0)
{
return7;
}
return0;
}
break;
case'd':
{
if(strcmp(strToken,"do")==0)
{
return9;
}
return0;
}
break;
case'w':
{
if(strcmp(strToken,"whlie")==0)
{
return10;
}
return0;
}
break;
default:
{
return0;
}
}
}
public:
boolProcess(Two_pass*pass)//处理程序返回二值对
{
if(ifs.eof()!
=0)
{
returnfalse;
}
if(p==NULL||(int)ch==0)//第一次初始化,或者指针为末尾,引进新的行
{
ifs.getline(strInstream,sizeof(strInstream),'\n');
p=strInstream;//指针指到首位
pro.Process(strInstream);
Getchar();
}
getNBC();
//////////////跨行注释代码
if((int)ch==0)
{
ifs.getline(strInstream,sizeof(strInstream),'\n');
p=strInstream;//指针指到首位
pro.Process(strInstream);
Getchar();
}
getNBC();
//////////////
count=0;//每一次取值的时候新的单词放到缓冲数组的第一位
intcode;
if(isLetter())
{
while(isLetter()||isDigit())
{
Concat();
Getchar();
Append();
}
code=reserve();
if(code==0)//为一般的标识符
{
pass->Two_copy(strToken,11);
returntrue;
}
else
{
pass->Two_copy(code);
returntrue;
}
}
else
{
if(isDigit())
{
while(isDigit())
{
Concat();
Getchar();
}
Append();
pass->Two_copy(strToken,12);
returntrue;
}
else
{
if(ch=='+')
{
pass->Two_copy(13);
Getchar();
returntrue;
}
if(ch=='-')
{
pass->Two_copy(14);
Getchar();
returntrue;
}
if(ch=='(')
{
pass->Two_copy(15);
Getchar();
returntrue;
}
if(ch==')')
{
pass->Two_copy(16);
Getchar();
returntrue;
}
if(ch=='=')
{
pass->Two_copy(17);
Getchar();
returntrue;
}
if(ch=='>')
{
pass->Two_copy(18);
Getchar();
returntrue;
}
if(ch=='<')
{
pass->Two_copy(19);
Getchar();
returntrue;
}
if(ch==';')
{
pass->Two_copy(20);
Getchar();
returntrue;
}
if(ch==',')
{
pass->Two_copy(21);
Getchar();
returntrue;
}
if(ch==':
')
{
Getchar();
if(ch=='=')
{
pass->Two_copy(23);
Getchar();
returntrue;
}
else
{
pass->Two_copy(22);
returntrue;
}
}
}
}
//returnfalse;
}
};
intmain()
{
ofstreamout("result.txt");
Two_passpss;
AccidenceAnalysesss;
while(sss.Process(&pss)==true)
{
if(pss.getState()==1)//带有字符串
{
out<<'('< cout<<'('< } else { out<<'('< cout<<'('< } } return0; } 5.关键算法的文字解释 Pro_Process类 成员 Privateintsta_stack; 记录/**/嵌套层次,处理多层嵌套注释 函数 (1)voidPro_Process: : Process(char*ptr) 对ptr缓冲区进行//,/**/注释符预处理 Two_pass类 成员 Privatecharptr[20];如果返回时有标识符或者整形常数,则记录在其中 Privateintindex;如果返回为非标识符和整形常数,该值返回单词种别ID Privateintstate;确定返回的是否带有字符串,如果有为1;没有为0; 函数 (1)publicvoidTwo_copy(char*p,intdex) 将p指针中的字符拷贝到charptr[20]中 并将种别拷贝到index中 (2)publicvoidTwo_copy(intdex) 返回值没有字符串的对象 AccidenceAnalyse类(词法分析器) 成员 Private: ifstreamifs;文件输入输出流 Pro_Processpro;预处理对象 charch;ch字符 charstrInstream[257];//存储文件的行的缓冲区域,最后一位为回车 charstrToken[257];//新生成的单词的缓冲区域 intcount;//标记strToken[]数组下一个方位 char*p;//标记strInstream[]数组正在处理位置 函数 PublicboolProcess(Two_pass*pass)//主处理程序返回二值对象 6.测试样例 输入 输出 输入 输出 输入 输出 7.实验总结 通过本次实验,充分的对编译的第一个阶段(词法分析阶段)有了深刻的了解,了解了词法分析程序的具体运行步骤,使得词法分析程序以及编译器的运行机制不再是那么的神秘。 通过本次的实验,同时也了解了C++的文件输入输出类以及函数。 与此同时,考虑到程序的大小不同,以及效率问题,处理的时候没有开动态数据结构,全部为静态预先规定的缓冲区,同时,在输出属性,值对的时候考虑速度问题,完全为对象指针的传递。 对效率提高方面,只能做到这一地步,是否能进一步的改进效率,这个问题仍然是一个遗留问题,仍然留给我去思考。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 报告 词法 分析器