📄 预测分析.cpp
字号:
void add_four(siyuanshi temp)//加一个四元式
{
stable[s_ptr]=temp;
s_ptr++;
}
void add_true(void)//加一个true链结点
{ L *temp;
temp=new L;
temp->a=s_ptr-1;
temp->next=NULL;
if(Ltrue==NULL)
{ Ltrue=temp;
}
else
{ temp->next=Ltrue;
Ltrue=temp;}
}
void add_false()//加一个false链结点
{
/*temp->Lfalse=L_false_head->Lfalse;
L_false_head->Lfalse=temp;*/
L *temp;
temp=new L;
temp->a=s_ptr-1;
temp->next=NULL;
if(Lfalse==NULL)
{ Lfalse=temp;
}
else
{ temp->next=Lfalse;
Lfalse=temp;
}
}
void backpatch(L *temp,int b) //回填函数;
{ if(temp==Ltrue)
{ while(temp!=NULL)
{
stable[temp->a].result='L'+newop(b);
b=temp->a;
temp=temp->next;
}
}
if(temp==Lfalse)
{ while(temp!=NULL)
{
stable[temp->a].result='L'+newop(b);
temp=temp->next;
}
}
}
void yuyifenxi(int m) //语义分析过程;
{ siyuanshi temp;
temp.op="";
temp.arg1="";
temp.arg2="";
temp.result="";
// temp.Ltrue=NULL;
// temp.Lfalse=NULL;
// P_addr=M_addr;
// string a;
if(m==1||m==2||m==3||m==6||m==0)
{ }
if(m==4)//变量声明时加入符号表
{
/* symb *Stemp;
Stemp=new symb;
id_name=id_numtoname(id_num);
Stemp->word=id_name;
Stemp->next=NULL;
add_symb(Stemp);
*/
int a=search(id_name);
symtable[a].type=1;
}
if(m==5)//分析V→+TV
{
temp.op="+";
temp.arg1=plus_name;
temp.arg2=T_name;
V_name="t"+newop(tval_ptr);
tval_ptr++;//申请临时变量
tval_table[tval_ptr-1]=V_name;
temp.result=V_name;
add_four(temp);//加一个四元式结点
T_name=temp.result;
}
if(m==7)//分析E→TV
{
E_name=T_name;
}
if(m==8)//分析W→*FW
{
temp.op="*";
temp.arg1=mul_name;
temp.arg2=F_name;
W_name="t"+newop(tval_ptr);
tval_ptr++;//申请临时变量
tval_table[tval_ptr-1]=W_name;
temp.result=W_name;
add_four(temp);//加一个四元式结点
F_name=temp.result;
}
if(m==10)//分析T→FW
{
T_name=F_name;
}
if(m==11)//分析F→(E)
{
F_name=E_name;
}
if(m==12)//分析F→id
{
F_name=id_name;
int k=lookup(id_name);//检查变量是否声明
if(k==0)
{
err=2;
cout<<"语义分析出错!变量"<<id_name<<"未声明!"<<endl;
}
}
if(m==23)//分析F→n
{ F_name=id_name;
}
if(m==24)//分析X→F>F
{ id2_name=F_name;
temp.op="J>";
temp.result="-1";
temp.arg1=id1_name;
temp.arg2=id2_name;
add_four(temp);//加一个四元式结点
add_true();//加一个true链结点
siyuanshi temp2;
temp2.op="J";
temp2.arg1=" ";
temp2.arg2=" ";
temp2.result="-1";
add_four(temp2);//加一个四元式结点
add_false();//加一个false链结点
}
if(m==16)//翻译 M→id=E
{
temp.op="=";
temp.arg1=E_name;
temp.arg2=" ";
temp.result=id0_name;
add_four(temp);//加一个四元式结点
// tval_ptr=0;//临时变量开始重新计数
}
if(m==17)//分析S→if B then M
{
int a=id_then;
backpatch(Ltrue,a);
backpatch(Lfalse,s_ptr);
Ltrue=NULL;
Lfalse=NULL;
/* temp=L_true_head->Ltrue;
while(temp!=NULL)
{
temp->result="L"+newop(a);
a=temp->k;
temp=temp->Ltrue;
}
a=L_four_tail->k+1;
temp=L_false_head->Lfalse;
while(temp!=NULL)
{
temp->result="L"+newop(a);
temp=temp->Lfalse;
}
L_true_head->Ltrue=NULL;
L_false_head->Lfalse=NULL;//回填并清空true链和false链
*/
}
if(m==18)//分析S→while B do M
{
int a=id_do;
backpatch(Ltrue,a);
backpatch(Lfalse,s_ptr+1);
temp.op="J";
temp.arg1=" ";
temp.arg2=" ";
temp.result="L"+newop(id_while);
add_four(temp);//加一个四元式结点
Ltrue=NULL;
Lfalse=NULL;
/* temp=L_true_head->Ltrue;
while(temp!=NULL)
{
temp->result="L"+newop(a);
a=temp->k;
temp=temp->Ltrue;
}
a=L_four_tail->k+2;
temp=L_false_head->Lfalse;
while(temp!=NULL)
{
temp->result="L"+newop(a);
temp=temp->Lfalse;
}
L *temp1;
temp1=new L;
temp1->op="J";
temp1->op1=" ";
temp1->op2=" ";
temp1->next=NULL;
temp1->result="L"+newop(id_while);
add_L_four(temp1);//加一个四元式结点
L_true_head->Ltrue=NULL;
L_false_head->Lfalse=NULL;//回填并清空true链和false链
*/
}
stack_ptr--;
}
void output_siyuanshi(void) //输出函数;
{ cout<<"语义分析中生成的四元式如下:"<<endl;
for(int i=0;i<s_ptr;i++)
{ cout<<"L"<<i<<":\t("<<stable[i].op<<","<<stable[i].arg1<<","<<stable[i].arg2<<","<<stable[i].result<<')'<<endl;
}
cout<<"语义分析中生成的符号表如下:"<<endl;
cout<<"编码\t变量内容\t内存地址\t标识符类型"<<endl;
for(i=0;i<symnum;i++)
{ cout<<symtable[i].id<<'\t'<<symtable[i].var<<"\t\t"<<symtable[i].addr<<"\t\t"<<symtable[i].type<<endl;
}
}
int link(char c)
{ int i;
int a=strlen(row);
for(i=0;i<a;i++)
if(row[i]==c) return i;
a=strlen(collumn);
for(i=0;i<a;i++)
if(collumn[i]==c) return i;
return -1;
}
int ifterminal(char c)
{ int i;
int a=strlen(row);
for(i=0;i<a;i++)
if(row[i]==c) return 0;
a=strlen(collumn);
for(i=0;i<a;i++)
if(collumn[i]==c) return 1;
return -1;
}
void yufamain()
{ cifamain();
token_x temp[max_in];
char filename[40];
// cout<<"请输入语法分析源文件的文件名及路径:";
// cin>>filename;
// ifstream infile(filename,ios::in);
cout<<"请输入语法分析过程描述文件的文件名及路径:";
cin>>filename;
ofstream outfile(filename,ios::out);
// infile>>temp.id>>temp.val;
char stack[stack_size]={'$','P'};
int top_ptr=1;
char inbuff[max_in]={'\0'};
int in_ptr=0;
outfile<<"栈"<<'\t'<<'\t'<<'\t'<<'\t'<<"输入"<<'\t'<<'\t'<<'\t'<<'\t'<<'\t'<<"输出"<<endl;
int i=0;
// char ch;
do{ //infile>>temp[i].id>>temp[i].val;
entry *temp_ptr;
temp[i].id=toktable[i].id;
if(temp[i].id=='i'||temp[i].id=='n')
{ temp_ptr=toktable[i].ptr;
strcpy(temp[i].val,temp_ptr->var);
}
else
{ char temp_ch[5]={"NUL"};
strcpy(temp[i].val,temp_ch);
}
if(temp[i].id=='#') break;
inbuff[i]=temp[i].id;
i++;
}while(1);
inbuff[i]='$';
outfile<<stack<<'\t'<<'\t'<<'\t'<<inbuff<<'\t'<<'\t'<<'\t'<<endl;
cout<<inbuff<<endl;
while(top_ptr!=0)
{ //outfile<<stack<<'\t'<<inbuff<<'\t';
int b=-1;
int a=ifterminal(stack[top_ptr]);
if(a==1) //栈顶是终结符或$;
{
if(stack[top_ptr]==inbuff[in_ptr])
{
stack[top_ptr]='\0';
top_ptr--;
inbuff[in_ptr]=' ';
in_ptr++;
}
else
{ cout<<"出错!栈顶符号与输入符号不匹配!"<<endl;
break;
}
}
else
{ int m=link(stack[top_ptr]);
int n=link(inbuff[in_ptr]);
b=M[m][n];
if(b!=-1)
{ //char temp=stack[top_ptr];
// outfile<<stack[top_ptr]<<"->"<<q[b]<<endl;
stack[top_ptr]='\0';
top_ptr--;
strcat(stack,p[b]);
top_ptr+=strlen(p[b]);
}
else
{ cout<<"出错!预测分析表中无匹配的产生式!"<<endl;
break;}
}
if(b!=-1)
outfile<<stack<<'\t'<<'\t'<<'\t'<<inbuff<<'\t'<<'\t'<<q[b]<<endl;
else
outfile<<stack<<'\t'<<'\t'<<'\t'<<inbuff<<'\t'<<'\t'<<endl;
}
}
void yuyimain()
{ cifamain();
// token_x temp[max_in];
// char filename[40];
// cout<<"请输入语法分析源文件的文件名及路径:";
// cin>>filename;
// ifstream infile(filename,ios::in);
// cout<<"请输入语法分析过程描述文件的文件名及路径:";
// cin>>filename;
// ofstream outfile(filename,ios::out);
// infile>>temp.id>>temp.val;
char stack[stack_size]={'$','P'};
int top_ptr=1;
token_x inbuff[max_in];
char temp_ch[5]={"NUL"};
// char inbuff[max_in]={'\0'};
int in_ptr=0;
// outfile<<"栈"<<'\t'<<'\t'<<'\t'<<'\t'<<"输入"<<'\t'<<'\t'<<'\t'<<'\t'<<'\t'<<"输出"<<endl;
int i=0;
// char ch;
do{ //infile>>temp[i].id>>temp[i].val;
entry *temp_ptr;
inbuff[i].id=toktable[i].id;
if(inbuff[i].id=='i'||inbuff[i].id=='n')
{ temp_ptr=toktable[i].ptr;
strcpy(inbuff[i].val,temp_ptr->var);
}
else
{ strcpy(inbuff[i].val,temp_ch);
}
if(inbuff[i].id=='#') break;
i++;
}while(1);
inbuff[i].id='$';
// outfile<<stack<<'\t'<<'\t'<<'\t'<<inbuff<<'\t'<<'\t'<<'\t'<<endl;
// cout<<inbuff<<endl;
while(top_ptr!=0)
{ //outfile<<stack<<'\t'<<inbuff<<'\t';
int b=-1;
int a=ifterminal(stack[top_ptr]);
if(a==1) //栈顶是终结符或$;
{
if(stack[top_ptr]==inbuff[in_ptr].id)
{ if(stack[top_ptr]=='>') id1_name=F_name;
if(stack[top_ptr]=='c') id_then=s_ptr;
if(stack[top_ptr]=='5') id_while=s_ptr;
if(stack[top_ptr]=='4') id_do=s_ptr;
if(stack[top_ptr]=='+') plus_name=T_name;
if(stack[top_ptr]=='*') mul_name=F_name;
stack[top_ptr]='\0';
top_ptr--;
// inbuff[in_ptr].id=' ';
in_ptr++;
}
else
{ cout<<"出错!栈顶符号与输入符号不匹配!"<<endl;
break;
}
}
else
{ int m=link(stack[top_ptr]);
int n=link(inbuff[in_ptr].id);
b=M[m][n];
if(b!=-1)
{ //char temp=stack[top_ptr];
// outfile<<stack[top_ptr]<<"->"<<q[b]<<endl;
// yuyi_stack[uniq_ptr]=-1;
stack[top_ptr]='\0';
top_ptr--;
yuyi_stack[stack_ptr].num=b;
if(yuyi_stack[stack_ptr].num==16)
id0_name=inbuff[in_ptr].val;
if(b==3||b==6||b==9||b==14||b==20)
yuyi_stack[stack_ptr].position=top_ptr;
else
yuyi_stack[stack_ptr].position=top_ptr;
stack_ptr++;
strcat(stack,p[b]);
top_ptr+=strlen(p[b]);
}
else
{ cout<<"出错!预测分析表中无匹配的产生式!"<<endl;
break;
}
}
while(top_ptr==yuyi_stack[stack_ptr-1].position)
{ if(yuyi_stack[stack_ptr-1].num==12||yuyi_stack[stack_ptr-1].num==23)
id_name=inbuff[in_ptr-1].val;
if(yuyi_stack[stack_ptr-1].num==4)
id_name=inbuff[in_ptr-2].val;
yuyifenxi(yuyi_stack[stack_ptr-1].num);
}
// if(b!=-1)
// outfile<<stack<<'\t'<<'\t'<<'\t'<<inbuff<<'\t'<<'\t'<<q[b]<<endl;
// else
// outfile<<stack<<'\t'<<'\t'<<'\t'<<inbuff<<'\t'<<'\t'<<endl;
}
output_siyuanshi();
}
void main()
{ yuyimain();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -