编译原理预测分析法附源码.docx
《编译原理预测分析法附源码.docx》由会员分享,可在线阅读,更多相关《编译原理预测分析法附源码.docx(5页珍藏版)》请在冰豆网上搜索。
![编译原理预测分析法附源码.docx](https://file1.bdocx.com/fileroot1/2022-10/9/71e1c5f6-c3d1-4a1c-a002-ea4f04d9346c/71e1c5f6-c3d1-4a1c-a002-ea4f04d9346c1.gif)
预测分析法实验报告
一、实验项目名称
预测分析法
二、实验目的
根据某一LL
(1)文法编制调试预测分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对预测分析法的理解。
三、实验环境
Windows10
MicrosoftVisualStudio2015
四、实验内容
本次实验的LL
(1)文法为表达式文法:
E→E+T|T
T→T*F|F
F→i|(E)
编写识别表达式文法的合法句子的预测分析程序,对输入的任意符号串,给出分析过程及分析结果。
分析过程要求输出步骤、分析栈、剩余输入串和所用产生式。
如果该符号串不是表达式文法的合法句子,要给出尽量详细的错误提示
五、源程序清单、测试数据、结果
#include
#include
usingnamespacestd;
constintNUM=20;//初始化的栈的大小
//非终结符数组集
charVar[5]={'E','R','T','M','F'};
//终结符数组集
charTer[6]={'i','+','*','(',')','#'};
stringpred[5][6]={{"TR","","","TR","",""},{"","+TR","","","@","@"},{"FM","","","FM","",""},{"","@","*FM","","@","@"},{"i","","","(E)","",""}};
typedefstruct{
char*top;
char*base;
intstacksize;
intnum;
}Stack;//栈结构体
voidinit(Stack*ss){//初始化栈
ss->base=(char*)malloc(NUM*sizeof(char));
if(!
ss->base)
exit
(1);
ss->top=ss->base;
ss->stacksize=NUM;
ss->num=0;
}
voidpush(Stack*ss,charc){//入栈操作
if(ss->top-ss->base>=ss->stacksize)
exit
(1);
*(ss->top)=c;
ss->top++;
ss->num++;
}
voidpop(Stack*ss){//出栈操作
if(ss->top==ss->base)
exit
(1);
ss->top--;
ss->num--;
}
chargetTop(Stack*ss){//取得栈顶元素
if(ss->top==ss->base)
exit
(1);
return*(ss->top-1);
}
intisT(charc){//判断是否为终结符
inti=0;
intret=0;
for(i=0;i<6;i++){
if(Ter[i]==c)
{
ret=1;break;
}
}
returnret;
}
stringisInPred(charv,chart){//查找预测分析表,并返回产生式右部
inti,j;
for(i=0;i<5;i++)
{
if(Var[i]==v)
break;
}
for(j=0;j<6;j++)
{
if(Ter[j]==t)
break;
}
if(pred[i][j]!
="")
{
returnpred[i][j];
}
else
return"";
}
voiddisplayStack(Stack*stack){ //输出分析站的内容
stringstr;
inti=0;
Stackss=*stack;
while(ss.num!
=0)
{
str+=getTop(&ss);
pop(&ss);
}
for(i=str.length()-1;i>=0;i--)
{
cout< }
}
voidpredict(Stackstack,stringinput)//预测分析总函数
{
inta=1;
charb;
charctop;//当前栈顶符号
charcinput;//当前输入符号
inti=0,j=0,count=0;
interror=0;
cout<<"步骤"<<'\t'<<"栈"<<'\t'<<"输入缓冲区"<<'\t'<<"所用的产生式"< cout< displayStack(&stack);
cout<<'\t'<
while(getTop(&stack)!
='#')
{
stringproduce="";
ctop=getTop(&stack);
cinput=input.at(i);
if(isT(ctop))//栈顶符号为终结符
{
if(ctop==cinput)
{
pop(&stack);
i++;
}
else
{
error=1;break;
}
produce+="\"";
produce+=ctop;
produce+="\"匹配";
}
else//栈顶符号位非终结符
{
stringstr=isInPred(ctop,cinput);
if(str!
="")
{
pop(&stack);
if(str!
="@")
{
for(j=str.length()-1;j>=0;j--)
push(&stack,str.at(j));
}
produce+=ctop;
produce+="→";
produce+=str;
}
else
{
error=1;break;
}
}//栈顶符号位非终结符
cout< displayStack(&stack);
cout<<'\t'<
}
if(error)
cout<<"不接受"< else
cout<<"接受"<}
voidmain()
{
while
(1){
intsel;//继续或者退出程序选择
stringinput;//输入串
inti=0,j=0;
Stackstack;
init(&stack);
push(&stack,'#');
push(&stack,'E');
cout<<"----------------文法如下--------------"< cout<<"E→E+T|T"< cout<<"T→T*F|F"< cout<<"F→i|(E)"< cout<<"----------------请输入表达式(以#结尾)--------------"< cin>>input;
cout<<"“R表示“E'”,”M“表示“T'”,”@“表示“空”"< predict(stack,input);
sel=0;
if(sel==0)
exit(0);
else
system("cls");
}
}
六、实验小结和思考
本次实验的文法是写在程序中的,不可以自行输入,难度不是很难,并没有太大问题,只是一些未初始化的小问题。
以后要积极做实验,做的程序要更加灵活。