编译原理实验语法器递归下降子程序实现解析.docx
《编译原理实验语法器递归下降子程序实现解析.docx》由会员分享,可在线阅读,更多相关《编译原理实验语法器递归下降子程序实现解析.docx(14页珍藏版)》请在冰豆网上搜索。
![编译原理实验语法器递归下降子程序实现解析.docx](https://file1.bdocx.com/fileroot1/2022-10/9/bb2cae11-c67c-4f5a-a7e0-0a91bc2744f4/bb2cae11-c67c-4f5a-a7e0-0a91bc2744f41.gif)
编译原理实验语法器递归下降子程序实现解析
编译原理程序设计实验报告
——表达式语法分析器的设计
班级:
计算机1306班姓名:
张涛学号:
20133967
实验目标:
用递归下降子程序设计实现表达式语法分析器
实验内容:
⑴概要设计:
通过对实验一的此法分析器的程序稍加改造,使其能够输出正确的表达式的token序列。
然后利用LL
(1)分析法实现语法分析。
⑵数据结构:
intop=0;//当前判断进度
charch;//当前字符
charnowword[10]="";//当前单词
charoperate[4]={'+','-','*','/'};//运算符
charbound[2]={'(',')'};//界符
structToken
{
intcode;
charch[10];
};//Token定义
structTokentokenlist[50];//Token数组
structTokentokentemp;//临时Token变量
⑶流程图:
⑷关键函数:
intIsLetter(charch)//判断ch是否为字母
intIsDigit(charch)//判断ch是否为数字
intIskey(char*string)//判断是否为关键字
intIsbound(charch)//判断是否为界符
intIsboundnum(charch)//给出界符所在token值
voidT();//分析子程序
voidF();//分析子程序
voidE1();//分析子程序
voidE();//分析子程序
voidT1();//分析子程序
源程序代码:
(加入注释)
#include
#include
#include
#include
intop=0;//当前判断进度
charch;//当前字符
charnowword[10]="";//当前单词
charoperate[4]={'+','-','*','/'};
charbound[2]={'(',')'};
structToken
{
intcode;
charch[10];
};
structTokentokenlist[50];
structTokentokentemp;
voidT();
voidF();
voidE1();
voidE();
voidT1();
intIsLetter(charch)//判断ch是否为字母
{
inti;
for(i=0;i<=45;i++)
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
return1;
return0;
}
intIsDigit(charch)//判断ch是否为数字
{
inti;
for(i=0;i<=10;i++)
if(ch>='0'&&ch<='9')
return1;
return0;
}
intIsbound(charch)
{
inti;
for(i=0;i<2;i++)
{
if(ch==bound[i])
{
returni+1;
}
}
return0;
}
intIsoperate(charch)
{
inti;
for(i=0;i<4;i++)
{
if(ch==operate[i])
{
returni+3;
}
}
return0;
}
intmain()
{
FILE*fp;
intq=0,m=0;
charsour[200]="";
printf("请将源文件置于以下位置并按以下方式命名:
F:
\\2.txt\n");
if((fp=fopen("F:
\\2.txt","r"))==NULL)
{
printf("文件未找到!
\n");
}
else{
while(!
feof(fp)){
if(isspace(ch=fgetc(fp)));
else{
sour[q]=ch;
q++;
}
}
}
intp=0;
printf("输入句子为:
\n");
for(p;p<=q;p++)
{
printf("%c",sour[p]);
}
printf("\n");
intstate=0,nowlen=0;
BOOLEANOK=TRUE,ERR=FALSE;
inti,flagpoint=0;
for(i=0;i{
switch(state)
{
case0:
ch=sour[i];
if(Isbound(ch))
{
if(ERR)
{
printf("无法识别\n");
ERR=FALSE;
OK=TRUE;
}
elseif(!
OK)
{
printf("<10,%s>标识符\n",nowword);
tokentemp.code=10;
inti=0;
tokentemp.ch[10]=nowword[10];
tokenlist[m]=tokentemp;
m++;
OK=TRUE;
}
state=4;
}
elseif(IsDigit(ch))
{
if(OK)
{
memset(nowword,0,strlen(nowword));
nowlen=0;
nowword[nowlen]=ch;
nowlen++;
state=3;
OK=FALSE;
break;
}else
{
nowword[nowlen]=ch;
nowlen++;
}
}
elseif(IsLetter(ch))
{
if(OK)
{
memset(nowword,0,strlen(nowword));
nowlen=0;
nowword[nowlen]=ch;
nowlen++;
OK=FALSE;
if(sour[i+1]=='#')
{
printf("<10,%s>标识符\n",nowword);
structTokentokentemp;
tokentemp.code=10;
inti=0;
for(i;i<=nowlen;i++)
tokentemp.ch[i]=nowword[i];
tokenlist[m]=tokentemp;
m++;
}
}else
{
nowword[nowlen]=ch;
nowlen++;
}
}
elseif(Isoperate(ch))
{
if(!
OK)
{
printf("<10,%s>标识符\n",nowword);
tokentemp.code=10;
tokentemp.ch[10]=nowword[10];
tokenlist[m]=tokentemp;
m++;
OK=TRUE;
}
printf("<%d,%c>运算符\n",Isoperate(ch),ch);
tokentemp.code=Isoperate(ch);
tokentemp.ch[10]=ch;
tokenlist[m]=tokentemp;
m++;
}
break;
case3:
if(IsLetter(ch))
{
printf("错误\n");
nowword[nowlen]=ch;
nowlen++;
ERR=FALSE;
state=0;
break;
}
if(IsDigit(ch=sour[i]))
{
nowword[nowlen]=ch;
nowlen++;
}
elseif(sour[i]=='.'&&flagpoint==0)
{
flagpoint=1;
nowword[nowlen]=ch;
nowlen++;
}
else
{
printf("<20,%s>数字\n",nowword);
i--;
state=0;
OK=TRUE;
tokentemp.code=20;
tokentemp.ch[10]=nowword[10];
tokenlist[m]=tokentemp;
m++;
}
break;
case4:
i--;
printf("<%d,%c>界符\n",Isbound(ch),ch);
tokentemp.code=Isbound(ch);
tokentemp.ch[10]=ch;
tokenlist[m]=tokentemp;
m++;
state=0;
OK=TRUE;
break;
}
}
intio=0;
for(io;io<=m;io++)
{
printf("tokenlist%d.code值为%d\n",io,tokenlist[io].code);
}
E();
if(op==m)
printf("OK!
!
!
");
else
printf("WRONG!
!
!
");
return0;
}
voidE()
{
T();
E1();
}
voidE1()
{
if(tokenlist[op].code==3||tokenlist[op].code==4)
{
tokenlist[op++];
T();
E1();
}
}
voidT1()
{
if(tokenlist[op].code==5||tokenlist[op].code==6)
{
tokenlist[op++];
F();
T1();
}
}
voidT()
{
F();
T1();
}
voidF()
{
if(tokenlist[op].code==10||tokenlist[op].code==20)
{
tokenlist[op++];
}
else
{
if(tokenlist[op].code==1)
{
tokenlist[op++];
E();
if(tokenlist[op].code==2)
{
tokenlist[op++];
}
else
{
printf("WRONG!
!
!
!
!
!
");
//exit
(1);
}
}
else
{
printf("WRONG!
!
!
!
!
!
");
//exit
(1);
}
}
}
程序运行结果:
(截屏)
输入:
((Aa+Bb)*(88.2/3))#
注:
如需运行请将文件放置F盘,并命名为:
2.txt
输出:
思考问题回答:
在递归下降子程序中要注意对于错误情况的处理,以防程序无限循环,无法结束。
解决这个问题的方法就是设置两个位移变量进行判断即可。