📄 语法带注释版.txt
字号:
#include<iostream.h>
#include<stdio.h>
#include <string.h>
char arrow0[]=" -------";
char arrow1[]=" ";
char arrow2[]=" ";
char arrow3[]=" ";
char Vt[10][10]={"+","@","*","i","(",")"};
char Vn[20][10]={"E0","A12","T3","B45","F67"};
char Vnfollow[20][10]={"E7","A01","T01","B34","F34"};
char C[10][10]={"ETA","A+TA","A@","TFB","B*FB","B@","Fi","F(E)"};
char B[10][10]={"TA","+TA","@","FB","*FB","@","i","(E)"};
char Vnf[10][10];
char Vnl[10][10];
char Vns[10][10];
int Print(int i){
cout<<C[i][0]<<"-->"<<B[i]<<endl;
return 0;
}
int Scaning(char a){
int r;
for(int i=0;i<=10;i++){
if(a==Vn[i][0])
r=i;
}
return r;
}
void Input(char v[][10],int i,char a){
int m=strlen(v[i]);
int flag=0;
for(int k=0;k<m;k++){
if(v[i][k]==a)flag=1;//有就不加
}
if(flag==0)v[i][m]=a;//没有就加到这个数组的最后一个
}
bool WhetherEmpty(char a[]){//某数组中是否含有@这个元素
int m=strlen(a);
bool flag=false;
for(int i=0;i<m;i++){
if(a[i]=='@')flag=true;
}
return flag;
}
bool WhetherIn(char a[],char b){
int m=strlen(a);
bool flag=false;
for(int i=0;i<m;i++){
if(a[i]==b)flag=true;
}
return flag;
}
bool WhetherVt(char a){
bool flag=false;
for(int i=0;i<6;i++){
if(a==Vt[i][0]){
flag=true;
return flag;
}
}
return flag;
}
bool WhetherVn(char a){
bool flag=false;
for(int i=0;i<6;i++){
if(a==Vn[i][0]){
flag=true;
return flag;
}
}
return flag;
}
void First(char V[][10],int i){
int flag[10];
if(flag[i]==1)return;
else{
int m1=strlen(V[i]);
for(int j=1;j<=m1-1;j++){
int vn=V[i][j]-'0';//求得此非终结符在左边的第几个,求First用
int m2=strlen(C[vn]);
int t,r;
for(t=1;t<=m2-1;t++){//从右边第一个开始做
char a=C[vn][1];
if(WhetherVt(a)){Input(Vnf,i,C[vn][1]);break;}
else{ r=Scaning(C[vn][1]);
First(V,r);
int m3=strlen(Vnf[r]);
for(int y=0;y<m3;y++){
if(Vnf[r][y]!='@')Input(Vnf,i,Vnf[r][y]);
}
} if(!WhetherEmpty(Vnf[r]))break;//如果求出来的那个里面不含空,结束,含空就继续求右边下一个的First
}if(t==m2)if(WhetherEmpty(Vnf[r]))Input(Vnf,i,'@');//如果加到最右边的还是含有空,那么就把空加进去
}
flag[i]=1;
}
}
void Follow(char Vnfollow1[][10],int i){
int flag[10];
if(flag[i]==1)return;
else{
if(i==0)Input(Vnl,i,'#');
int m1=strlen(Vnfollow1[i]);
for(int j=1;j<=m1-1;j++){
int vn=Vnfollow1[i][j]-'0';//求得此非终结符在右边的第几个,求Follow用,确定是第几行
int m2=strlen(C[vn]);
int t;
for(t=1;t<=m2-1;t++){ //右边第t个字符
if(Vnfollow1[i][0]==C[vn][t])break;
}
if(t==m2-1){//如果右边没有了
if(!(C[vn][0]==Vnfollow1[i][0])){//如果左边的非终结符和右边要求的的不一样
int r=Scaning(C[vn][0]);
Follow(Vnfollow1,r);
int m3=strlen(Vnl[r]);
for(int y=0;y<m3;y++){
Input(Vnl,i,Vnl[r][y]);
}
}
}
else{
int w=t+1;
char a=C[vn][w];//确定右边的那一个
if(WhetherVt(a)){Input(Vnl,i,C[vn][w]);}
for(;w<=m2-1;w++){
int r2=Scaning(C[vn][w]);
int m4=strlen(Vnf[r2]);
for(int q=0;q<m4;q++){
if(Vnf[r2][q]!='@')Input(Vnl,i,Vnf[r2][q]);
}//把右边那一个First集的非空的加进去
if(!WhetherEmpty(Vnf[r2]))break;
}
if(w==m2){//最右边一个都还含有空
int r3=Scaning(C[vn][w-1]);//判断到右边最后一个
if(WhetherEmpty(Vnf[r3])){//若还是有空
int r4=Scaning(C[vn][0]);
Follow(Vnfollow1,r4);
int m3=strlen(Vnl[r4]);
for(int y=0;y<m3;y++){
Input(Vnl,i,Vnl[r4][y]);
}
}
}
}
}flag[i]=1;
}
}
void Select(int i){
int m=strlen(C[i]);
for(int j=1;j<m;j++){
char a=C[i][j];
if(WhetherVn(a)){
int r=Scaning(C[i][j]);
int mm=strlen(Vnf[r]);
for(int k=0;k<mm;k++){
if(Vnf[r][k]!='&')Input(Vns,i,Vnf[r][k]);
}
if(!WhetherEmpty(Vnf[r]))break;
}
else {Input(Vns,i,C[i][j]);break;//是非终结符
}
}
if(j==m){
int r2=Scaning(C[i][j-1]);
if(WhetherEmpty(Vnf[r2])){//如果右边最后一个能推出空
Input(Vns,i,'@');
}
}
if(WhetherEmpty(Vns[i])){
int r=Scaning(C[i][0]);
int mm=strlen(Vnl[r]);
for(int g=0;g<mm;g++){
Input(Vns,i,Vnl[r][g]);
}
}
}
void Translate(char s[]){
int P=0;
int Begin=0;
char stack[20];
stack[P++]='#';
stack[P]=C[0][0];
bool flag=false;
bool find=false;
char X;
while(!flag){
X=stack[P--];
if(WhetherVt(X)){
if(X==s[Begin]){Begin++;cout<<arrow1<<X<<arrow2<<s[Begin-1]<<arrow3<<s[Begin-1]<<"成功匹配"<<endl;}
else{cout<<"error"<<endl;return;}
}
else {
if(X=='#'){
if(s[Begin]==X)flag=true;
else{cout<<"error"<<endl;return;}
}
else{
for(int j=0;j<8;j++){
if(X==C[j][0]&&WhetherIn(Vns[j],s[Begin])){//非终结符的话,查表,在的话逆序压入
find=true;
int mm=strlen(C[j]);
for(int k=mm-1;k>=1;k--){
if(C[j][k]!='@')stack[++P]=C[j][k];
}
cout<<arrow1<<X<<arrow2<<s[Begin]<<arrow3;
Print(j);
break;
}
}
if(!find){
cout<<"error"<<endl;return;
}
}
}
}
if(flag==true)cout<<"接受"<<endl;
}
void Print2(int i,int y,int x){
cout<<"\t"<<"===========================预测分析表==========================="<<endl;
cout<<"---------------------------------------------------------------------------"<<endl;
cout<<"\t";
for(int g=0;g<y;g++)cout<<Vt[g]<<"\t";
cout<<endl;
cout<<"---------------------------------------------------------------------------"<<endl;
for(int j=0;j<i;j++){
cout<<Vn[j][0]<<"\t";
for(int k=0;k<y;k++){
for(int f=0;f<x;f++){
if(WhetherIn(Vns[f],Vt[k][0])&&C[f][0]==Vn[j][0]){
int m1=strlen(C[f]);
for(int y1=1;y1<m1;y1++){
cout<<C[f][y1];
}
}
}cout<<"\t";
}
cout<<endl;
}
cout<<"---------------------------------------------------------------------------"<<endl;
}
void main()
{
cout<<"非终结符:"<<arrow1;
for(int q=0;q<5;q++){
cout<<Vn[q][0]<<arrow1;
};
cout<<endl;
cout<<"终结符:"<<arrow1;
for(int p=0;p<6;p++){
cout<<Vt[p][0]<<arrow1;
};
cout<<endl;
cout<<"开始符:"<<arrow1<<Vn[0][0];
cout<<endl;
cout<<"产生式如下:"<<endl;
for(int w=0;w<=7;w++){
Print(w);}
cout<<endl;
cout<<"First集如下:"<<endl;
for(int i=0;i<=4;i++){
First(Vn,i);
cout<<"first("<<Vn[i][0]<<")={"<<Vnf[i]<<"}"<<endl;
}
cout<<endl;
cout<<"Follow集如下:"<<endl;
for(int j=0;j<=4;j++){
Follow(Vnfollow,j);
cout<<"follow("<<Vn[j][0]<<")={"<<Vnl[j]<<"}"<<endl;
}
cout<<endl;
cout<<"Select集如下:"<<endl;
for(int k=0;k<8;k++){
Select(k);
cout<<C[k]<<arrow0<<"{"<<Vns[k]<<"}"<<endl;
}
Print2(8,8,8);
char c[10];
int m;
cout<<endl;
cout<<"请输入测试字符串(以#结束):"<<endl;
do{
cin>>c;
m=strlen(c);
}while(c[m-1]!='#');
cout<<"对测试字串的分析过程如下:"<<endl;
cout<<"分析栈栈顶"<<arrow1<<"剩余输入串首个字符"<<arrow1<<"所用产生式"<<endl;
Translate(c);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -