编译原理实验二语法分析器LL1实现.docx
《编译原理实验二语法分析器LL1实现.docx》由会员分享,可在线阅读,更多相关《编译原理实验二语法分析器LL1实现.docx(16页珍藏版)》请在冰点文库上搜索。
编译原理实验二语法分析器LL1实现
编译原理程序设计实验报告
——表达式语法分析器的设计
班级:
计算机1306班姓名:
张涛学号:
实验目标:
用LL
(1)分析法设计实现表达式语法分析器
实验内容:
⑴概要设计:
通过对实验一的此法分析器的程序稍加改造,使其能够输出正确的表达式的token序列。
然后利用LL
(1)分析法实现语法分析。
⑵数据结构:
intop=0;
ase=(char*)malloc(100*sizeof(char));
if(!
(*s).base)
exit(0);
(*s).top=(*s).base;
(*s).stacksize=100;
printf("初始化栈\n");
return0;
}
intpop(STack*s,char*ch)op==(*s).base)
{
printf("弹栈失败\n");
return0;
}
(*s).top--;
*ch=*((*s).top);
printf("%c",*ch);
return1;
}
intpush(STack*s,charch)op-(*s).base>=(*s).stacksize)
{
(*s).base=(char*)realloc((*s).base,((*s).stacksize+10)*sizeof(char));
if(!
(*s).base)
exit(0);
(*s).top=(*s).base+(*s).stacksize;
(*s).stacksize+=10;
}
*(*s).top=ch;
*(*s).top++;
return1;
}
voidLL1();
intIsLetter(charch)ode=='#';
switch(state)
{
case0:
ch=sour[i];
if(Isbound(ch))
{
if(ERR)
{
printf("无法识别\n");
ERR=FALSE;
OK=TRUE;
}
elseif(!
OK)
{
printf("<10,%s>标识符\n",nowword);
=10;
[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;
}else
{
nowword[nowlen]=ch;
nowlen++;
}
}
elseif(Isoperate(ch))
{
if(!
OK)
{
printf("<10,%s>标识符\n",nowword);
=10;
[10]=nowword[10];
tokenlist[m]=tokentemp;
m++;
OK=TRUE;
}
printf("<%d,%c>运算符\n",Isoperate(ch),ch);
=Isoperate(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;
=20;
[10]=nowword[10];
tokenlist[m]=tokentemp;
m++;
}
break;
case4:
i--;
printf("<%d,%c>界符\n",Isbound(ch),ch);
=Isbound(ch);
[10]=ch;
tokenlist[m]=tokentemp;
m++;
state=0;
OK=TRUE;
break;
}
}
printf("tokenlist值为%d\n",m);
intt=0;
tokenlist[m+1].code='r';
m++;
for(t;t{
printf("tokenlist%d值为%d\n",t,tokenlist[t].code);
}
LL1();
printf("tokenlist值为%d\n",m);
if(op+1==m)
printf("OK!
!
!
");
else
printf("WRONG!
!
!
");
return0;
}
voidLL1()
{
STacks;
init(&s);
push(&s,'#');
push(&s,'E');
charch;
intflag=1;
do
{
pop(&s,&ch);
printf("输出栈顶为%c\n",ch);
printf("输出栈顶为%d\n",ch);
printf("当前p值为%d\n",op);
if((ch=='(')||(ch==')')||(ch=='+')||(ch=='-')||(ch=='*')||(ch=='/')||(ch==10)||(ch==20))
{
if(tokenlist[op].code==1||tokenlist[op].code==20||tokenlist[op].code==10||tokenlist[op].code==2||tokenlist[op].code==3||tokenlist[op].code==4||tokenlist[op].code==5||tokenlist[op].code==6)
op++;
else
{
printf("WRONG!
!
!
");
exit(0);
}
}
elseif(ch=='#')
{
if(tokenlist[op].code==0)
flag=0;
else
{
printf("WRONG!
!
!
@@@@@@@@@");
exit(0);
}
}
elseif(ch=='E')
{
printf("进入E\n");
if(tokenlist[op].code==10||tokenlist[op].code==20||tokenlist[op].code==1)
{
push(&s,'R');
printf("将R压入栈\n");
push(&s,'T');
}
}
elseif(ch=='R')
{
printf("进入R\n");
if(tokenlist[op].code==3||tokenlist[op].code==4)
{
push(&s,'R');
push(&s,'T');
printf("将T压入栈\n");
push(&s,'+');
}
if(tokenlist[op].code==2||tokenlist[op].code==0)
{
}
}
elseif(ch=='T')
{
printf("进入T\n");
if(tokenlist[op].code==10||tokenlist[op].code==20||tokenlist[op].code==1)
{
push(&s,'Y');
push(&s,'F');
}
}
elseif(ch=='Y')
{
printf("进入Y\n");
if(tokenlist[op].code==5||tokenlist[op].code==6)
{
push(&s,'Y');
push(&s,'F');
push(&s,'*');
}
elseif(tokenlist[op].code==3||tokenlist[op].code==2||tokenlist[op].code==0||tokenlist[op].code==4)
{
}
}
elseif(ch=='F')
{
printf("进入F\n");
if(tokenlist[op].code==10||tokenlist[op].code==20)
{
push(&s,10);
}
if(tokenlist[op].code==1)
{
push(&s,')');
push(&s,'E');
push(&s,'(');
}
}
else
{
printf("WRONG!
!
!
!
");
exit(0);
}
}while(flag);
}
程序运行结果:
(截屏)
输入:
((Aa+Bb)*3))#
注:
如需运行请将文件放置F盘,并命名为:
输出:
思考问题回答:
LL
(1)分析法的主要问题就是要正确的将文法化为LL
(1)文法。
在程序实现时将分析表的动作逐一实现即可。