📄 bianyi.cpp
字号:
#include<iostream.h>
#include<stdio.h>
/*定义的原始产生式的类型号,以后程序通过它进行检索
#define id 1
#define const 10
#define := 2
#define + 3
#define - 4
#define * 5
#define / 6
#define ( 21
#define ) 22
#define > 23
#define < 24
#define = 25
#define if 100
#define then 101
#define while 102
#define do 103
#define else 104
#define S->id:=E 1
#define E->E+E 2
#define E->E-E 3
#define E->E*E 4
#define E->E/E 5
#define E->-E 6
#define E->(E) 7
#define E->id 8
#define E->num 9
#define C->E>E 10
#define C->E<E 11
#define S->if C then S 12
#define C->E=E 13
#define S->if C then S else S 14
#define S->while C do S 15*/
int lookhead; //当前待分析的单词
/*保存语法分析产生的树结构数组,在构造分析树的过程中为
每个产生式赋予一个唯一的编号,该数组的
www[][1]第一唯数表示哪个编号的产生式
www[][2]……右部第一个非终结符产生的产生式编号,第二个……产生式编号*/
int w[20][20];
/*保存各产生式的有关标号
[][0]begin,[][1]next,[][2]true,[][3]false标号的符号表序号*/
int label[20][4];
/*符号表,数组中每一个元素存储输入的标识符和数字,以及在程序中产生的
临时变量newtemp()和标号newlabel()的字符串表示形式,可通过序号检索*/
char chart[70][40];
int number, //产生式的编号
code=0, //符号表序号
/*生新的临时变量名中起作用chart[30]~char[50]保存产生的临时变量名*/
temp=30,
temp1='0', //用来生成不同临时变量的chart[][*]
/*在新的标号名中起作用,同temp,temp1*/
stemp=50,stemp1='0';
/*====================词法分析子程序==================*/
/*每次调用可以从输入流中划分出一个单词
返值int:单词的属性值
结尾返回 0
错误字符返回-1
输入ch: 当前读入字符*/
int cifa() //这是一个全局函数
{
int ch,i=0;
int isletter(int);
int isdigit(int);
int rightchar(char);
int key(char *a);
ch=getc(stdin);
while ((ch==' ')||(ch==10))
ch=getc(stdin);
if(ch==-1) return(0);
if ((!rightchar(ch))&&(ch!=-1))
{
cout<<"\nerror %c isn't in my language"<<ch;
return(-1);
}
if (isdigit(ch))
{
code++;
while(isdigit(ch))
{
chart[code][i]=ch;
ch=getc(stdin);
i++;
}
chart[code][i]=0;
ungetc(ch,stdin);
return(10);
}
if(isletter(ch))
{
code++;
while (isletter(ch)||isdigit(ch))
{
chart[code][i]=ch;
ch=getc(stdin);
i++;
}
chart[code][i]=0;
ungetc(ch,stdin);
return(key(chart[code]));
}
if(ch==':')
{
ch=getc(stdin);
if(ch=='=')
return (2);
else
return(0);
}
if(ch=='+') return (3);
if(ch=='-') return (4);
if(ch=='*') return (5);
if(ch=='/') return (6);
if(ch=='(') return (21);
if(ch==')') return (22);
if(ch=='>') return (23);
if(ch=='<') return (24);
if(ch=='=') return (25);
}
//--------------cifa()的子函数--------------
int isletter(int ch) //是否为字母 true 1 false 0
{
if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z')))
return(1);
else return(0);
}
int isdigit(int ch) //是否为数字 true 1 false 0
{
if((ch>='0')&&(ch<='9'))
return(1);
else return(0);
}
int rightchar(char ch) //是否合法的字符 true 1 false 0
{
if (((ch>='0')&&(ch<='9'))
||((ch>='a')&&(ch<='z'))
||((ch>='A')&&(ch<='Z'))
||(ch==10)||(ch==':')||(ch=='=')
||(ch=='+')||(ch=='-')||(ch=='*')||(ch=='/')
||(ch=='(')||(ch==')')||(ch=='>')||(ch=='<'))
return(1);
else return(0);
}
int key(char *a) //是否关键字 true 关键字属性值 false 1
{
if ((a[0]=='i')&&(a[1]=='f')&&(a[2]==0))//if
return(100);
if ((a[0]=='t')&&(a[1]=='h')&&(a[2]=='e')&&(a[3]=='n')&&(a[4]==0))
return(101); //then
if ((a[0]=='w')&&(a[1]=='h')&&(a[2]=='i')&&(a[3]=='l')&&(a[4]=='e')&&(a[5]==0))
return(102); //while
if ((a[0]=='d')&&(a[1]=='o')&&(a[2]==0))
return(103); //else
if ((a[0]=='e')&&(a[1]=='l')&&(a[2]=='s')&&(a[3]=='e')&&(a[4]==0))
return(104);
return(1);
}
/*=====================语法分析======================*/
/*匹配一个单词,并且调用下一个单词
参数:匹配的单词——用属性值表示
返值:成功 1 失败 0*/
int match(int t) //全局函数!
{
int cifa();
if (lookhead==t)
{
lookhead=cifa();
return(1);
}
else return(0);
}
//语法分析递归子程序之一
int s1()
{
int c1();
int e1();
//int match(int);
int a,b,c,d,a1,i,j;
switch(lookhead)
{
case 1:
a1=code;
a=match(1);
b=match(2);
c=e1();
number++;
if(a&&b&&c)
{
/*cout<<("S->id:=E");*/
w[number][0]=1;
w[number][1]=c;
w[number][2]=a1;
w[number][3]=0;
/*cout<<(" number=%d, style=%d, next1=%d, id=%s\n", number,1,c,chart[a1]);*/
if((lookhead==0)||(lookhead==104))
return(number);
else return(0);
}
else
return(0);
case 100:
a=match(100);
b=c1();
c=match(101);
d=s1();
if (lookhead!=104)
{
if(lookhead!=0) return(0);
number++;
if(a&&b&&c&&d)
{
/*cout<<("S->if C then S");*/
w[number][0]=12;
w[number][1]=b;
w[number][2]=d;
w[number][3]=0;
/*cout<<(" number=%d, style=%d, next1=%d, next2=%d\n",number,12,b,d);*/
return(number);
}
else
return(0);
}
else
{
i=match(104);
if (lookhead==0) return(0);
j=s1();
number++;
if(a&&b&&c&&d&&i&&j)
{
if(lookhead!=0) return(0);
/*cout<<("S->if C then S else S");*/
w[number][0]=14;
w[number][1]=b;
w[number][2]=d;
w[number][3]=j;
w[number][4]=0;
/*cout<<(" number=%d, style=%d, next1=%d,next2=%d,next3=%d\n",number,14,b,d,j);*/
return(number);
}
else
return(0);
}
case 102:
a=match(102);
b=c1();
c=match(103);
d=s1();
number++;
if(a&&b&&c&&d)
{
/*cout<<("S->while C do S");*/
w[number][0]=15;
w[number][1]=b;
w[number][2]=d;
w[number][3]=0;
/*cout<<(" number=%d, style=%d, next1=%d, next2=%d\n",number,15,b,d);*/
return(number);
}
else
return(0);
}
return(0);
}
int c1()
{
int e1();
//int match();
int a=0,c=0,d=0,i1=0,i2=0,i3=0;
a=e1();
if((lookhead==23)||(lookhead==24)||(lookhead==25))
{
d=lookhead;
if(lookhead==23) i1=match(23);
if(lookhead==24) i2=match(24);
if(lookhead==25) i3=match(25);
c=e1();
if((i1==0)&&(i2==0)&&(i3==0)||(c==0))
return(0);
if(d==23)
{
number++;
/*cout<<("C->E>E");*/
w[number][0]=10;
w[number][1]=a;
w[number][2]=c;
w[number][3]=0;
}
if(d==24)
{
number++;
/*cout<<("C->E<E");*/
w[number][0]=11;
w[number][1]=a;
w[number][2]=c;
w[number][3]=0;
}
if(d==25)
{
number++;
/*cout<<("C->E=E");*/
w[number][0]=13;
w[number][1]=a;
w[number][2]=c;
w[number][3]=0;
}
return(number);
}
}
int e1 ()
{
int t1();
//int match();
int a,b=0,c,d,g=0,k=1,h=0;
if(lookhead!=4)
{
a=t1();
if(a==0)
return (0);
}
else
a=0;
while((lookhead==3)||(lookhead==4))
{
d=lookhead;
if(lookhead==3) g=match(3);
if(lookhead==4) b=match(4);
c=t1();
if(((g==0)&&(b==0))||(c==0))
return(0);
if(d==3)
{
number++;
/*cout<<("E->E+E");*/
w[number][0]=2;
if(k==1)
{
w[number][1]=a;
k++;
}
else
w[number][1]=h;
w[number][2]=c;
w[number][3]=0;
h=number;
/*cout<<(" number=%d, style=%d, next1=%d,
next2=%d\n",number,2,w[number][1],c);*/
}
if(d==4)
{
number++;
if(a!=0)
{
/*cout<<("E->E-E");*/
w[number][0]=3;
if(k==1)
{
w[number][1]=a;
k++;
}
else
w[number][1]=h;
w[number][2]=c;
w[number][3]=0;
h=number;
/*cout<<(" number=%d, style=%d, next1=%d,
next2=%d\n",number,3,w[number][1],c);*/
}
else
{
/*cout<<("E->-E");*/
w[number][0]=6;
w[number][1]=c;
w[number][2]=0;
h=number;
k++;
a=1;
/*cout<<(" number=%d, style=%d,
next1=%d\n",number,6,w[number][1]);*/
}
}
}
return(number);
}
int t1()
{
int f1();
//int match();
int a,b=0,c,d,g=0,k=1,h=0;
a=f1();
if(a==0)
return(0);
while((lookhead==5)||(lookhead==6))
{
d=lookhead;
if(lookhead==5) g=match(5);
if(lookhead==6) b=match(6);
c=f1();
if(((g==0)&&(b==0))||(c==0))
return(0);
if(d==5)
{
number++;
/*cout<<("E->E*E");*/
w[number][0]=4;
if(k==1)
{
w[number][1]=a;
k++;
}
else
w[number][1]=h;
w[number][2]=c;
w[number][3]=0;
h=number;
/*cout<<(" number=%d, style=%d, next1=%d, next2=%d\n",number,4,w[number][1],c);*/
}
if(d==6)
{
number++;
/*cout<<("E->E/E");*/
w[number][0]=5;
if(k==1)
{
w[number][1]=a;
k++;
}
else
w[number][1]=h;
w[number][2]=c;
w[number][3]=0;
h=number;
/*cout<<(" number=%d, style=%d, next1=%d,
next2=%d\n",number,5,w[number][1],c);*/
}
}
return(number);
}
int f1()
{
int e1();
//int match();
int a,b,c,a1;
switch(lookhead)
{
case 1:
a1=code;
a=match(1);
number++;
if(a)
{
/*cout<<("E->id");*/
w[number][0]=8;
w[number][1]=a1;
w[number][2]=0;
/*cout<<(" number=%d, style=%d, id=%s\n",number,8,chart[a1]);*/
return(number);
}
else
return(0);
case 21:
a=match(21);
b=e1();
c=match(22);
number++;
if(a&&b&&c)
{
/*cout<<("E->(E)");*/
w[number][0]=7;
w[number][1]=b;
w[number][2]=0;
/*cout<<(" number=%d, style=%d, next1=%d\n",number,7,b);*/
return(number);
}
else
return(0);
case 10:
a1=code;
a=match(10);
number++;
if(a)
{
/*cout<<("E->num");*/
w[number][0]=9;
w[number][1]=a1;
w[number][2]=0;
/*cout<<(" number=%d, style=%d, num=%s\n",number,9,chart[a1]);*/
return(number);
}
else
return(0);
}
return(0);
}
/*====================语义分析=====================*/
/*语义分析递归子程序之一
参数:第一个参数为该产生式的编号
第二个参数为该产生式父产生式的编号
返值:临时变量的符号表入口序号*/
int s2(int m,int m1)
{
int e2(int,int);
int a;
int newlabel();
switch(w[m][0])
{
case 1:
a=e2(w[m][1],0);
cout<<chart[w[m][2]]<<":="<<chart[a]<<"\n";
return(1);
case 12:
label[m][2]=newlabel();
label[m][3]=label[m][1];
label[w[m][2]][1]=label[m][1];
e2(w[m][1],m);
cout<<chart[label[m][2]]<<":\n";//
s2(w[m][2],m);
return(1);
case 14:
label[m][2]=newlabel();
label[m][3]=newlabel();
label[w[m][2]][1]=label[m][1];
label[w[m][3]][1]=label[m][1];
e2(w[m][1],m);
cout<<chart[label[m][2]]<<":\n";//
s2(w[m][2],m);
cout<<" goto "<<chart[label[m][1]]<<":\n";
cout<<chart[label[m][3]]<<":\n";//
s2(w[m][3],m);
return(1);
case 15:
switch(w[m1][0])
{
case 12:
label[m][0]=label[m1][2];
break;
case 15:
label[m][0]=label[m1][2];
break;
case 14:
if (m==w[m1][2])
label[m][0]=label[m1][2];
else
label[m][0]=label[m1][3];
break;
default:
label[m][0]=newlabel();
cout<<chart[label[m][0]]<<":\n";
}
label[m][2]=newlabel();
label[m][3]=label[m][1];
label[w[m][2]][1]=label[m][0];
e2(w[m][1],m);
cout<<chart[label[m][2]]<<":\n";//
s2(w[m][2],m);
cout<<" goto "<<chart[label[m][0]]<<":\n";
return(1);
}
}
int e2(int m,int m1)
{
int a,b,t;
int newtemp();
switch(w[m][0])
{
case 2:
t=newtemp();
a=e2(w[m][1],m);
b=e2(w[m][2],m);
cout<<chart[t]<<":="<<chart[a]<<"+"<<chart[b]<<endl;
return(t);
case 3:
t=newtemp();
a=e2(w[m][1],m);
b=e2(w[m][2],m);
cout<<chart[t]<<":="<<chart[a]<<"-"<<chart[b]<<endl;
return(t);
case 4:
t=newtemp();
a=e2(w[m][1],m);
b=e2(w[m][2],m);
cout<<chart[t]<<":="<<chart[a]<<"*"<<chart[b]<<endl;
return(t);
case 5:
t=newtemp();
a=e2(w[m][1],m);
b=e2(w[m][2],m);
cout<<chart[t]<<":="<<chart[a]<<"/"<<chart[b]<<endl;
return(t);
case 6:
t=newtemp();
a=e2(w[m][1],m);
cout<<chart[t]<<":=0-"<<chart[a]<<endl;
return(t);
case 7:
a=e2(w[m][1],m);
return(a);
case 8:
return(w[m][1]);
case 9:
return(w[m][1]);
case 10:
a=e2(w[m][1],m);
b=e2(w[m][2],m);
cout<<"if "<<chart[a]<<">"<<chart[b]<<" goto "<<chart[label[m1][2]]<<endl;
cout<<" goto "<<chart[label[m1][3]]<<endl;
return(-1);
case 11:
a=e2(w[m][1],m);
b=e2(w[m][2],m);
cout<<"if "<<chart[a]<<"<"<<chart[b]<<" goto "<<chart[label[m1][2]]<<endl;
cout<<" goto "<<chart[label[m1][3]]<<endl;
return(-1);
case 13:
a=e2(w[m][1],m);
b=e2(w[m][2],m);
cout<<"if "<<chart[a]<<"="<<chart[b]<<" goto "<<chart[label[m1][2]]<<endl;
cout<<" goto "<<chart[label[m1][3]]<<endl;
return(-1);
}
}
//产生新的临时变量名
//返值:临时变量的符号表入口序号
int newtemp()
{
temp++;
chart[temp][0]='t';
chart[temp][1]=temp1;
chart[temp][2]=0;
temp1++;
return(temp);
}
//产生新的标号
//返值:标号的符号表入口序号
int newlabel()
{
stemp++;
chart[stemp][0]='L';
chart[stemp][1]=stemp1;
chart[stemp][2]=0;
stemp1++;
return(stemp);
}
/*========================主函数========================*/
void main()
{
int cifa();
int j;
// int s1();
// int match();
// int s2(int,int);
// int newlabel();
lookhead=cifa();
j=s1();
if(j!=0)
cout<<"\n 语法正确!";
else
cout<<"\n 语法有错误?";
cout<<"\n\n 3 address:\n";
label[j][1]=newlabel();
s2(j,0);
cout<<chart[label[j][1]]<<":";
cout<<"\nend\n";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -