📄 第二题.cpp
字号:
#include<iostream.h>
#include<fstream.h>
#include<stdlib.h>
#include<string.h>
char *s[61]={" ","and","array","begin","bool","call","case","char","constant","dim","do",
"else","end","false","for","if","input","integer","not","of","or","output",
"procedure","program","read","real","repeat","set","stop","then","to","true",
"until","var","while","write"," "," "," ","(",")","*","*/","+",",","-",".","..",
"/","/*",":",":=",";","<","<=","<>","=",">",">=","[","]"}; //单词编码
struct two //二元式
{
int w1;
char w2[10];
two *next;
two *prio;
};
char *q[20]={" "},q1[20];
two *head,*y1,*y2;
int i1=1,i4=0,q2[20], i6=0,i7=1;
int check1();
void check2();
int check3();//分析表达式
int check4(int);//符号转换成array1数组的内容
void check5();//分析布尔表达式
int check6(int);//符号转换成array3数组的内容
int find(char*);
void print(); //输出四元式
void check7();
struct four //四元式
{
char p1[10],p2[5],p3[5],p4[10];
int p5; //p5记录i
four *next;
};
void modify(four*); //修改
four *he,*y3,*y4,*y5;
int cavil(); //找错,无错返回1,有错返回0,并输出出错信息
void main()
{
if(check1())
{
if(cavil())
{
cout<<"四元式:"<<endl;
y2=head->next;
y1=head;
he=new four;
he->next=NULL;
y3=he;
check2();
print();
cout<<"("<<i6<<")\t"<<"(sys,-,-,-)"<<endl;
}
}
}
int array1[6]={39,40,41,43,45,48},//array1数组用于转换操作符以便算符分析
array2[6][6]={{0,2,0,0,0,0},{3,3,3,3,3,3},{0,1,2,1,1,2},{0,1,0,2,2,0},{0,1,0,2,2,0},
{0,1,2,1,1,2}},//算符优先表,0代表<,1代表>,2代表=,3代表不存在的情况
array3[8]={1,18,20,53,54,56,57,58},//用于布尔式的转换
array4[8][8]={{3,0,1,0,0,0,0,0},{1,3,1,1,1,1,1,1},{0,0,3,0,0,0,0,0},{1,0,1,3,3,3,3,3},
{1,0,1,3,3,3,3,3},{1,0,1,3,3,3,3,3},{1,0,1,3,3,3,3,3},{1,0,1,3,3,3,3,3}};//布尔表达式优先关系
void check2()
{
four*y6;
int i,tr1,tr2,f3,d1=0,f6;
char *p,d[10];
while(y2!=NULL)
{
switch(y2->w1)
{
case 23: cout<<"("<<i6++<<")\t"<<"(program,"<<y2->next->w2<<",-,-)"<<endl; //输出程序名
break;
case 34:i=i6; //入口地址,while语句处理
y5=y3;
check5();//布尔表达式的处理
tr1=i6;
check7();//递归
y4=new four;y4->next=NULL;
y3->next=y4;y3=y4;
strcpy(y4->p1,"j");
strcpy(y4->p2,"-");
strcpy(y4->p3,"-");
if(i>9)
{
int f3,f4;
f3=i/10;f4=i%10;
y4->p4[0]=char(f3+48);y4->p4[1]=char(f4+48);y4->p4[2]='\0';
}
else
{
y4->p4[0]=char(i+48);y4->p4[1]='\0';
}
y4->p5=i6++;modify(y4);
y5=y5->next;
while(y5!=NULL)
{
if(!strcmp(y5->p4,"f")) //假出口回填
{
if(i6>9)
{
int f3,f4;f3=i6/10;f4=i6%10;
y5->p4[0]=char(f3+48);y5->p4[1]=char(f4+48);y5->p4[2]='\0';
}
else
{
y5->p4[0]=char(i6+48);y5->p4[1]='\0';
}
}
if(!strcmp(y5->p4,"tr")) //真出口回填
{
if(tr1>9)
{
int f3,f4;f3=tr1/10;f4=tr1%10;
y5->p4[0]=char(f3+48);y5->p4[1]=char(f4+48);y5->p4[2]='\0';
}
else
{
y5->p4[0]=char(tr1+48);y5->p4[1]='\0';
}
}
y5=y5->next;
}
break;
case 15:y5=y3;
check5(); //if语句处理
tr2=i6; //真出口
check7(); //递归
y5=y5->next;
/*if(y2!=NULL)
{
y2=y2->next;
y1=y1->next;
d1=1;
}*/
if(y2->w1==11)
{
while(y5!=NULL)
{
if(!strcmp(y5->p4,"f")) //假出口回填
{
y6=y5;
f6=i6;
if((i6+1)>9)
{
int f4,f5;
f4=(i6+1)/10;f5=(i6+1)%10;
y5->p4[0]=char(f4+48);y5->p4[1]=char(f5+48);y5->p4[2]='\0';
}
else
{
y5->p4[0]=char(i6+1+48);y5->p4[1]='\0';
}
}
if(!strcmp(y5->p4,"tr")) //真出口回填
{
if(tr2>9) //f3为两位数时,没有设计成更高位数
{
int f4,f5;
f4=tr2/10;f5=tr2%10;
y5->p4[0]=char(f4+48);y5->p4[1]=char(f5+48);y5->p4[2]='\0';
}
else
{
y5->p4[0]=char(tr2+48);y5->p4[1]='\0';
}
}
y5=y5->next;
}
y4=new four;y4->next=NULL;
y3->next=y4;y3=y4;
strcpy(y4->p1,"j");
strcpy(y4->p2,"-");
strcpy(y4->p3,"-");
y6=y4;
y4->p5=i6++;modify(y4);
check7();
if(i6>9)
{
int f3,f4;
f3=i6/10;f4=i6%10;
y6->p4[0]=char(f3+48);y6->p4[1]=char(f4+48);y6->p4[2]='\0';
}
else
{
y6->p4[0]=char(i6+48);y6->p4[1]='\0';
}
}
else
{
while(y5!=NULL)
{
if(!strcmp(y5->p4,"f")) //假出口回填
{
y6=y5;
f6=i6;
if(i6>9)
{
int f4,f5;
f4=i6/10;f5=i6%10;
y5->p4[0]=char(f4+48);y5->p4[1]=char(f5+48);y5->p4[2]='\0';
}
else
{
y5->p4[0]=char(i6+48);y5->p4[1]='\0';
}
}
if(!strcmp(y5->p4,"tr")) //真出口回填
{
if(tr2>9) //f3为两位数时,没有设计成更高位数
{
int f4,f5;
f4=tr2/10;f5=tr2%10;
y5->p4[0]=char(f4+48);y5->p4[1]=char(f5+48);y5->p4[2]='\0';
}
else
{
y5->p4[0]=char(tr2+48);y5->p4[1]='\0';
}
}
y5=y5->next;
}
}
break;
case 26:f3=i6; //入口地址,repeat语句处理
y5=y3;
if(y2!=NULL)
{
y2=y2->next;
y1=y1->next;
}
check7();
/*if(y2!=NULL)
{
y2=y2->next;
y1=y1->next;
}*/
check5();
y5=y5->next;
while(y5!=NULL)
{
if(!strcmp(y5->p4,"f")) //假出口回填
{
if(f3>9) //f3为两位数时,没有设计成更高位数
{
int f4,f5;
f4=f3/10;f5=f3%10;
y5->p4[0]=char(f4+48);y5->p4[1]=char(f5+48);y5->p4[2]='\0';
}
else
{
y5->p4[0]=char(f3+48);y5->p4[1]='\0';
}
}
if(!strcmp(y5->p4,"tr")) //真出口回填
{
if((i6+2)>9)
{
int f4,f5;
f4=(i6+2)/10;f5=(i6+2)%10;
y5->p4[0]=char(f4+48);y5->p4[1]=char(f5+48);y5->p4[2]='\0';
}
else
{
y5->p4[0]=char(i6+2+48);y5->p4[1]='\0';
}
}
y5=y5->next;
}
break;
case 51:p=y1->w2; //赋值语句处理
i=check3();
if(i==0)
{
y4=new four;y4->next=NULL;
y3->next=y4;y3=y4;
y4->p5=i6++;strcpy(y4->p1,":=");strcpy(y4->p2,y2->w2);
strcpy(y4->p3,"-");strcpy(y4->p4,p);
/*cout<<"("<<i6++<<")\t"<<"(:=,"<<y2->w2<<",-,"<<p<<")"<<endl;*/
}
else
{
y4=new four;y4->next=NULL;
y3->next=y4;y3=y4;
y4->p5=i6++;strcpy(y4->p1,":=");d[0]='T';d[1]=char(--i7+48);d[2]='\0';
strcpy(y4->p2,d);
strcpy(y4->p3,"-");strcpy(y4->p4,p);
/*cout<<"("<<i6++<<")\t"<<"(:=,T"<<--i7<<",-,"<<p<<")"<<endl;*/
i7++;
}
break;
}
if(y2!=NULL&&d1==0)
{
y2=y2->next;
y1=y1->next;
}
else
{
d1=0;
}
}
}
void check5()
{
int stack2[20],top2=-1,top1=-1,i;//stack2是算符栈
char *stack1[20];//stack1是符号栈
while(1)
{
y2=y2->next;
y1=y1->next;
i=-1;
if(y2!=NULL)
{
i=check6(y2->w1);
}
if(i!=-1)
{
if(top2==-1)
{
stack2[++top2]=i;
}
else
{
switch(array4[stack2[top2]][i])
{
case 0:if(i!=0&&i!=3)stack2[++top2]=i;break;
case 1:y4=new four;
y4->next=NULL;
y3->next=y4;
if(i==0) //and分析
{
strcpy(y4->p1,"j");
strcat(y4->p1,s[array3[stack2[top2--]]]);
strcpy(y4->p3,stack1[top1--]);
strcpy(y4->p2,stack1[top1--]);
if((i6+2)>9)
{
int f4,f5;
f4=(i6+2)/10;f5=(i6+2)%10;
y4->p4[0]=char(f4+48);y4->p4[1]=char(f5+48);y4->p4[2]='\0';
}
else
{
y4->p4[0]=char(i6+2+48);y4->p4[1]='\0';
}
y4->p5=i6++;
y3=y4; y4=new four;
y4->next=NULL;
y3->next=y4;
y3=y4;
strcpy(y4->p1,"j");
strcpy(y4->p3,"-");
strcpy(y4->p2,"-");
strcpy(y4->p4,"f"); //记录假出口
y4->p5=i6++;modify(y4);
}
if(i==2) //or分析
{
strcpy(y4->p1,"j");
strcat(y4->p1,s[array3[stack2[top2--]]]);
strcpy(y4->p3,stack1[top1--]);
strcpy(y4->p2,stack1[top1--]);
strcpy(y4->p4,"tr");//记录真出口
y4->p5=i6++;
y3=y4; y4=new four;
y4->next=NULL;
y3->next=y4;
y3=y4;
strcpy(y4->p1,"j");
strcpy(y4->p3,"-");
strcpy(y4->p2,"-");
if((i6+1)>9)
{
int f4,f5;
f4=(i6+1)/10;f5=(i6+1)%10;
y4->p4[0]=char(f4+48);y4->p4[1]=char(f5+48);y4->p4[2]='\0';
}
else
{
y4->p4[0]=char(i6+1+48); y4->p4[1]='\0';
}
y4->p5=i6++;modify(y4);
}
break;
case 3:break;
}
}
}
else
{
if(y2!=NULL&&(y2->w1==36||y2->w1==37||y2->w1==38||y2->w1==4||y2->w1==7||y2->w1==17)&&!(y1->w1==36||y1->w1==37||y1->w1==38))
{
stack1[++top1]=y2->w2;
}
else
{
if(top2!=-1)
{
y4=new four;
y4->next=NULL;
y3->next=y4;
y3=y4;
strcpy(y4->p1,"j");
strcat(y4->p1,s[array3[stack2[top2--]]]);
strcpy(y4->p3,stack1[top1--]);
strcpy(y4->p2,stack1[top1--]);
if((i6+2)>9)
{
int f4,f5;
f4=(i6+2)/10;f5=(i6+2)%10;
y4->p4[0]=char(f4+48);y4->p4[1]=char(f5+48);y4->p4[2]='\0';
}
else
{
y4->p4[0]=char(i6+2+48);y4->p4[1]='\0';
}
y4->p5=i6++;
y4=new four;
y4->next=NULL;
y3->next=y4;
y3=y4;
strcpy(y4->p1,"j");
strcpy(y4->p2,"-");
strcpy(y4->p3,"-");
strcpy(y4->p4,"f");
y4->p5=i6++;modify(y4);
}
break;
}
}
}
}
int check3()
{
int stack2[20],top2=-1,top1=-1,i,bzh=0;//stack2是算符栈
char *stack1[20],d[3];//stack1是符号栈
while(1)
{
y2=y2->next;
y1=y1->next;
i=-1;
if(y2!=NULL)
{
i=check4(y2->w1);
}
if(i!=-1)
{
bzh=1;
loop: if(top2==-1)
{
stack2[++top2]=i;
}
else
{
switch(array2[stack2[top2]][i])
{
case 0:stack2[++top2]=i;break;
case 1:y4=new four;y4->next=NULL;
y3->next=y4;y3=y4;
y4->p5=i6++;strcpy(y4->p1,s[array1[stack2[top2--]]]);strcpy(y4->p2,stack1[top1-1]);
strcpy(y4->p3,stack1[top1]);
/* cout<<"("<<i6++<<")\t"<<"("<<s[array1[stack2[top2--]]]<<","<<stack1[top1-1]
<<","<<stack1[top1]<<",T"<<i7++<<")"<<endl;*/
top1-=2;d[0]='T';d[1]=char(i7+48);d[2]='\0';strcpy(y4->p4,d);i7++;
stack1[++top1]=new char;strcpy(stack1[top1],d);
goto loop;
break;
case 2:if(i!=1)
{
y4=new four;y4->next=NULL;
y3->next=y4;y3=y4;
y4->p5=i6++;strcpy(y4->p1,s[array1[stack2[top2--]]]);strcpy(y4->p2,stack1[top1-1]);
strcpy(y4->p3,stack1[top1]);
/*cout<<"("<<i6++<<")\t"<<"("<<s[array1[stack2[top2--]]]<<","<<stack1[top1-1]
<<","<<stack1[top1]<<",T"<<i7++<<")"<<endl;*/
top1-=2;d[0]='T';d[1]=char(i7+48);d[2]='\0';strcpy(y4->p4,d);i7++;
stack1[++top1]=new char;strcpy(stack1[top1],d);
goto loop;
break;
}
else
{
top2--;
break;
}
case 3:break;
}
}
}
else
if(y2!=NULL&&(y2->w1==36||y2->w1==37||y2->w1==38||y2->w1==4||y2->w1==7||y2->w1==17)&&!(y1->w1==36||y1->w1==37||y1->w1==38))
{
stack1[++top1]=y2->w2;
}
else
{
if(top2==-1)
{
y2=y1;
y1=y1->prio;
return bzh;
}
else
{
while(top2!=-1)
{
y4=new four;y4->next=NULL;
y3->next=y4;y3=y4;
y4->p5=i6++;strcpy(y4->p1,s[array1[stack2[top2--]]]);strcpy(y4->p2,stack1[top1-1]);
strcpy(y4->p3,stack1[top1]);
/*cout<<"("<<i6++<<")\t"<<"("<<s[array1[stack2[top2--]]]<<","
<<stack1[top1-1]<<","<<stack1[top1]<<",T"<<i7++<<")"<<endl;*/
top1-=2;d[0]='T';d[1]=char(i7+48);d[2]='\0';strcpy(y4->p4,d);i7++;
stack1[++top1]=new char;strcpy(stack1[top1],d);
}
y2=y1;
y1=y1->prio;
return bzh;
}
}
}
}
int check4(int i)
{
for(int m=0;m<=6;m++)
{
if(array1[m]==i)
{
return m;
}
}
return -1;
}
int check6(int i)
{
for(int m=0;m<=8;m++)
{
if(array3[m]==i)
{
return m;
}
}
return -1;
}
int check1()//产生二元式,词法分析
{
cout<<"*******************"<<endl;
cout<<"姓名: 张 帆"<<endl;
cout<<"班级: 04(3)班"<<endl;
cout<<"学号: 200433101093"<<endl;
cout<<"*******************"<<endl;
char filename[10],c=' ',p[10];
int t,w,d=0,f1=0,i5=1; //i5记录识别文件时所在的行数
cout<<"请输入文件名:";
cin>>filename;
ifstream f(filename,ios::in);
if(!f)
{
cerr<<"文件没有打开!!";
abort();
}
cout<<endl<<"二元式:"<<endl;
t=0;
head=new two;
head->prio=NULL;
y1=y2=head;
while(!f.eof()) //eof()用于判断是否读到文件的末尾
{
if(48<=int(c)&&int(c)<=57) //识别整数
{
p[t++]=c;
while((65<=int(c)&&int(c)<=90||97<=int(c)&&int(c)<=122||48<=int(c)&&int(c)<=57)&&c!=' '&&c!='\n')
{
f.get(c);if(c=='\n')i5++;
if(65<=int(c)&&int(c)<=90||97<=int(c)&&int(c)<=122)
{f1=1;}
else if(48<=int(c)&&int(c)<=57&&c!=' '&&c!='\n') p[t++]=c;
}
if(f1==0)
{
p[t]='\0';
t=0;
y2=new two;
y2->w1=37;
strcpy(y2->w2,p);
y2->next=NULL;
y1->next=y2;
y2->prio=y1;
y1=y2;
}
else //记录错误
{
q1[i4]='1';
q2[i4]=i5;
i4++;
f1=0;
}
}
else
if(c=='\'') //识别字符常数
{
f.get(c);if(c=='\n')i5++;
while(c!='\'')
{
if(c=='\n')//报错
{
q1[i4]='\'';
q2[i4]=i5;
i4++;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -