编译原理词法分析器语法分析器实验报告.docx
- 文档编号:6729349
- 上传时间:2023-01-09
- 格式:DOCX
- 页数:8
- 大小:19.35KB
编译原理词法分析器语法分析器实验报告.docx
《编译原理词法分析器语法分析器实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析器语法分析器实验报告.docx(8页珍藏版)》请在冰豆网上搜索。
编译原理词法分析器语法分析器实验报告
编译原理词法分析器语法分析器实验报告
班级网络0802学号
姓名叶晨舟指导老师朱玉全
2021年7月4日
一、目的
编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。
从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
二、任务及要求
基本要求:
1.词法分析器产生下述小语言的单词序列
这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:
对于这个小语言,有几点重要的限制:
首先,所有的关键字(如IFpWHILE等)都是“保留字”。
所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。
例如,下面的写法是绝对禁止的:
IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。
也就是说,对于关键字不专设对应的转换图。
但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。
当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。
例如,一个条件语句应写为
IFi0i=1;而绝对不要写成
IFi0i=1;
因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。
这个小语言的单词符号的状态转换图,如下图:
2.语法分析器能识别由加+减-乘*除/乘方^括号()操作数所组成的
算术表达式,其文法如下:
E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i
使用的算法可以是:
预测分析法;递归下降分析法;算符优先分析法;
LR分析法等。
3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)
三、实现过程
给出各题目的详细算法描述,数据结构和函数说明,流程图。
1、词法分析器的流程图
2、语法分析器主程序图
3、中间代码生成器流程图:
四、源程序
词法分析器:
#includestring.h#includemalloc.h
#includeiostreamusingnamespacestd;
typedefstructtable//分析表存储结构{
charm;}table;
tableM;//定义分析表
typedefstructstacknode//定义栈内元素节点(带头结点(为空)的){
chardata;
structstacknode*next;}stackk;
voidinitlink(stackk*s)//初始化新栈{
s=(stackk*)malloc(sizeof(stackk));s-next=NULL;}
voidpoplink(stackk*s)//顶元素出栈{
stackk*p;charv;
if(s-next!
=NULL){
p=s-next;
v=p-data;s-next=p-next;}free(p);}
voidpushlink(stackk*s,charx)//新元素入栈{
stackk*p;
p=(stackk*)malloc(sizeof(stackk));p-data=x;
p-next=s-next;s-next=p;}
voiddisplay(stackk*s)//打印现实显示栈内元素{
inti=0,j;charst;p=s-next;
while(p!
=NULL){
st[i++]=p-data;p=p-next;}for(j=i-1;jj--)printf(“%c“,st[j]);
for(j=0;j16-i;j++)//打印对齐格式printf("%c",'');}
chargettop(stackk*s)//返回栈顶元素值{
if(s-next==NULL)return0;else
returns-next-data;}
intfind(charc,chararray[])//查找函数,{inti;
intflag=0;
for(i=0;ii++){
if(c==array[i])flag=1;}
returnflag;}
intlocation(charc,chararray[])//定位函数,指出字符所在位置{inti;
for(i=0;ii++){
if(c==array[i])
}}
voiderror()//出错函数定义{
printf("%15c出错!
\n",'');}
voidanalyse(charVn[],charVt[]){
inti,j,m,p,q,length,t,h;charw,X;charstr;opt0:
scanf("%s",str);
for(i=0;istrlen(str);i++){
if(!
find(str[i],Vt)){
printf("输入字符串有误!
请重新输入!
");gotoopt0;break;}}
stackk*st;initlink(st);
pushlink(st,'#');pushlink(st,Vn);//#与识别符号入栈j=0;
h=1;w=str;
printf("步骤%-12c分析栈%-24c剩余输入串%-12c所用产生式\n",'','','');opt1:
printf("%-16d",h);//显示步骤h++;
display(st);//显示分析栈中内容X=gettop(st);//上托栈顶符号放入Xpoplink(st);
for(intk=0;k14+j;k++)//打印对齐格式
printf("%c",'');
for(t=j;tstrlen(str);t++)
{
printf("%c",str[t]);//显示剩余字符串}
if(find(X,Vt)X!
='#')//分析栈的栈顶元素和剩余输入串的第一个元素相比较{
if(X==w){printf("%15c匹配\n",X);j++;w=str[j];gotoopt1;}else
error();}else{
if(X=='#'){
if(X==w){
printf("%8c是该文法的句子!
\n",'');}else
error();}else{
p=location(X,Vn);q=location(w,Vt);
char*S1="null",*S2="NULL";
if(strcmp(M[p][q].m,S1)==0||strcmp(M[p][q].m,S2)==0)//查找产生式error();else
{
charstr0;
strcpy(str0,M[p][q].m);
printf("%15c--%s\n",X,str0);//显示对应的产生式if(strcmp(str0,"$")==0)gotoopt1;else{
length=strlen(str0);//逆序进栈for(m=length-1;mm--){
pushlink(st,str0[m]);}
gotoopt1;}}}}}
intmain(){
inti,k,n,r;
charVn,Vt,select;
printf("******************************************************************\n");printf("对任意输入LL
(1)文法的分析表,判断验证字符串是否为该文法的句子\n");printf("并能给出分析和演示过程。
\n");
printf("******************************************************************\n");opt2:
printf("请输入各终结符(#号表示结束)Vt[i]:
\n");for(i=0;ii++){
scanf("%c",Vt[i]);if(Vt[i]=='#'){
r=i;break;}}
printf("请输入非终结符个数:
\n");scanf("%d",getchar();
for(i=0;ii++){
printf("请输入非终结符Vn[%d]:
\n",i);scanf("%c",Vn[i]);getchar();
printf("请输入此非终结符对应各终结符的产生式右部(null或NULL表示出错;$表示空串):
\n");
for(k=0;kk++){
scanf("%s",M[i][k].m);getchar();}}opt3:
printf("请输入要分析的字符串,且以#结束:
\n");analyse(Vn,Vt);
printf("********************请选择***********************\n");printf("1:
输入字符串\n");printf("2:
输入新分析表\n");printf("0:
退出\n");printf("*************************************************\n");opt4:
cinselect;switch(select){
case'1':
{gotoopt3;break;}case'2':
{gotoopt2;}case'0':
{break;}
default:
{printf("输入错误!
请重新选择:
");gotoopt4;break;}}
return0;}
运行结果:
语法分析器源程序:
#includestring.h#includeiostreamusingnamespacestd;charprog,token;charch;
intsyn,p,m=0,n,row,sum=0;
char*rwtab={"dim","if","do","stop","end","and","begin","bool","case","char","false","for","int","not","or","set","then","true","until","while"};
voidscaner(){for(n=0;nn++)token[n]=NULL;ch=prog[p++];while(ch==''){ch=prog[p];p++;}if((ch='a'ch='z')||(ch='A'ch='Z'))
{m=0;while((ch='0'ch='9')||(ch='a'ch='z')||(ch='A'ch='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=21;for(n=0;nn++){if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}}elseif((ch='0'ch='9')){{sum=0;while((ch='0'ch='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=7+15;if(sum*****)syn=-1;}elseswitch(ch){
case'=':
syn=8+15;token=ch;break;case'+':
syn=9+15;token=ch;break;case'*':
m=0;token[m++]=ch;ch=prog[p++];if(ch=='*'){
syn=11+15;token[m++]=ch;}else{syn=10+15;p--;}
break;
case',':
syn=12+15;token=ch;break;case'(':
syn=13+15;token=ch;break;case')':
syn=14+15;token=ch;break;case'#':
syn=0;token=ch;break;case'':
m=0;token[m++]=ch;ch=prog[p++];if(ch==''){syn=17+15;token[m++]=ch;}elseif(ch=='='){syn=16+15;token[m++]=ch;}else{syn=15+15;p--;}break;
case'':
m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=19+15;token[m++]=ch;}else{syn=18+15;p--;
}break;
case':
':
m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=21+15;token[m++]=ch;}else{syn=20+15;p--;}break;
case'/':
syn=22+15;token=ch;break;case'-':
syn=23+15;token=ch;break;case';':
syn=24+15;token=ch;break;default:
syn=-1;break;}}
voidmain(){p=0;row=1;coutendlendlendl;cout"***************************小型词法**********************************"endlendl;cout"请输入一段程序(以#结束):
";do{cin.get(ch);prog[p++]=ch;}while(ch!
='#');p=0;coutendl"**************************词法分析*********************************"endl;cout"种别编码自身值"endl;do{scaner();switch(syn)
分析结果如器
下
{case22:
cout"("syn","sum")"endl;break;case-1:
cout"Errorinrow"row"!
"endl;break;
default:
cout"("syn","token")"endl;break;}}while(syn!
=0);}
运行结果:
}
中间代码生成器源程序:
表达式生成四元式递归子程序法
#includestring#includeiostreamusingnamespacestd;
#define*****_SIZE100
charEMachine(charw);//表达式E的自动机charTMachine(charw);//表达式T的自动机charFMachine(charw);//表达式F的自动机boolZMachine();//表达式Z的自动机stringintToString(inta);//整形变成字符串形函数
classstack//栈类定义{
private:
inttop;
string*stacka;intmaxsize;public:
stack(intsize=*****_SIZE);~stack(){delete[]stacka;}voidpush(conststringitem);stringpop(void);
stringgettop(void)const;
boolempty(void)const{return(top==-1);}
boolfull(void)const{return(top==maxsize-1);}voidclear(void){top=-1;}};
stack:
:
stack(intsize)//栈类的构造函数{
top=-1;
maxsize=size;
stacka=newstring[maxsize];if(!
stacka){
cerr"allocatememoryfailed."endl;exit
(1);}}
voidstack:
:
push(conststringitem)//压栈操作{
if(full()){
cerr"stackfull,cannotpush."endl;return;}
top++;
stacka[top]=item;}
stringstack:
:
pop(void)//出栈操作{
if(empty()){
cerr"stackempty,cannotpop."endl;exit
(1);}
stringitem=stacka[top];top--;
returnitem;}
stringstack:
:
gettop(void)const//取栈顶操作{
if(empty()){
cerr"stackempty,cannotgettop."endl;exit
(1);}
returnstacka[top];}
staticstackwordStack;//符号栈staticintnoOfQuet=0;//静态四元式个数记录staticintnoOfT=1;//静态状态个数记录
voidmain(){//主函数charyesOrNo;//进行一个循环操作控制do{cout"请输入算术表达式:
"endl;noOfT=1;//每次结束询问ZMachine();coutendl"Continue?
YesorNot:
";cinyesOrNo;//输入“Y”则继续}while(yesOrNo=='y');//否则程序结束}
boolZMachine(){//Z自动机charw;cinw;w=EMachine(w);//调用E自动机
if(w=='#'){//遇到“#”则结束returntrue;}else{returnfalse;}}
charEMachine(charw){//E自动机stringoperate,a,b,c;stringstate;w=TMachine(w);//调用T自动机while(w=='+'||w=='-'){//是加或减符号operate=w;cinw;//读入下一字符w=TMachine(w);//调用T自动机b=wordStack.pop();//字符栈弹出a=wordStack.pop();//两个操作字符cout"(\""operate"\","a","b",t"noOfT")"endl;c="t"+intToString(noOfT);//输出四元式wordStack.push(c);//新状态压栈noOfT++;//状态计数加一}returnw;}
charTMachine(charw){stringoperate,a,b,c;stringstate;w=FMachine(w);//调用F自动机while(w=='*'||w=='/'){//是乘除号operate=w;cinw;//读取下一字符w=FMachine(w);//调用F自动机b=wordStack.pop();//符号栈弹出a=wordStack.pop();//两个操作字符cout"(\""operate"\","a","b",t"noOfT")"endl;c="t"+intToString(noOfT);//输出四元式wordStack.push(c);//新状态压栈noOfT++;//状态计数加1}returnw;}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 词法 分析器 语法 实验 报告