📄 赋值语句的翻译程序设计.cpp
字号:
#include<iostream>
#include<fstream>
#include<iomanip> //malloc.exit.realloc.strcmp.gets
#include"wordanalysis.h"//词法分析头文件
using namespace std;
#define OVERFLOW -2
#define OK 1
#define ERROR 0
#define STACK_INIT_SIZE 50
#define STACK_INCREMENT 10
typedef int Status;
#define n 10
int index,length;char *code[n][4];int error;ofstream rp;int m;
char *mid[n]={"t1","t2","t3","t4","t5","t6","t7","t8","t9","t10"};//四元式中的中间结果变量表明
/*赋值语句的文法为:
S->i:=E
E->E+E|E-E|E*E|E/E|(E)|i
*/
struct SElemType
{
char id;//用于归约
char *fword;//用于四元式
};//栈中元素的数据域为结构体
typedef struct{
SElemType *base; //栈基址
SElemType *top; //栈顶地址
int stacksize;
}SqStack;
Status initstack(SqStack &S)
//构造一个空栈
{
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base)
exit (OVERFLOW);//存储单元分配失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status push(SqStack &S,SElemType e)//插入新元素为栈顶元素
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType *)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(char));
if(!S.base)
exit (OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACK_INCREMENT;
}
*(S.top)=e;
S.top++;
return OK;
}
Status pop(SqStack &S)//删除栈顶元素
{
if(S.base==S.top)
return ERROR;
--S.top;
return OK;
}
SElemType gettop(SqStack S)// 获得栈顶元素
{
SElemType e,ir;
if(S.top==S.base)exit(0);
else{ir=*(S.top-1);
e.id=ir.id;e.fword=ir.fword;return e;}
}
void err(int e)//输出错误提示
{ if(e==1)
cout<<"赋值语句错误,不完整"<<endl;
if(e==2)
cout<<"赋值语句语法错误,不符合产生式归约条件!"<<endl;
exit(0);
}
char super(char a,char b)//运算符优先级.
{
switch(a)
{
case'+':
switch(b)
{ case'+':return '>';break;
case'-':return '>';break;
case'*':return '<';break;
case'/':return '<';break;
case'(':return '<';break;
case')':return '>';break;
case'=':return '>';break;
case'#':return '>';break;
case';':return '>';break;//因为输入时以";"结尾,将;设为优先级最低
default:return '#';break;
}
case'-':
switch(b)
{ case'+':return '>';break;
case'-':return '>';break;
case'*':return '<';break;
case'/':return '<';break;
case'(':return '<';break;
case')':return '>';break;
case'=':return '>';break;
case'#':return '>';break;
case';':return '>';break;
default:return '#';break;
}
case'*':
switch(b)
{ case'+':return '>';break;
case'-':return '>';break;
case'*':return '>';break;
case'/':return '>';break;
case'(':return '<';break;
case')':return '>';break;
case'=':return '>';break;
case'#':return '>';break;
case';':return '>';break;
default:return '#';break;
}
case'/':
switch(b)
{ case'+':return '>';break;
case'-':return '>';break;
case'*':return '>';break;
case'/':return '>';break;
case'(':return '<';break;
case')':return '>';break;
case'=':return '>';break;
case'#':return '>';break;
case';':return '>';break;
default:return '#';break;
}
case'(':
switch(b)
{ case'+':return '<';break;
case'-':return '<';break;
case'*':return '<';break;
case'/':return '<';break;
case'(':return '<';break;
case')':return '=';break;
case'=':return '>';break;
case'#':return '>';break;
case';':return '>';break;
default:return '#';break;
}
case')':
switch(b)
{ case'+':return '>';break;
case'-':return '>';break;
case'*':return '>';break;
case'/':return '>';break;
case')':return '>';break;
case'=':return '>';break;
case'#':return '>';break;
case';':return '>';break;
default:return '#';break;
}
case'#':
switch(b)
{ case'+':return '<';break;
case'-':return '<';break;
case'*':return '<';break;
case'/':return '<';break;
case'(':return '<';break;
case')':return '<';break;
case'=':return '<';break;
case';':return '>';break;
default:return '#';break;
}
case'=':
switch(b)
{ case'+':return '<';break;
case'-':return '<';break;
case'*':return '<';break;
case'/':return '<';break;
case'(':return '<';break;
case')':return '<';break;
case'#':return '>';break;
case';':return '>';break;
default:return '#';break;
}
default:return '#';break;
}
}
char trans(char *cc)//将单词进行转换,以匹配文法
{
char t;char ch;
ch=cc[0];
if( ch==':'){ t='=';return t;}//将":="转化为'='进栈,以简化栈中id为字符型
else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')'||ch==';')
{return ch;}
else return 'i';//输入的变量对应文法中的终结符'i'
}
int issuit(SElemType pro[])//是否为产生式右端
{
int q;
if(pro[0].id=='i'&&pro[2].id=='E')q=1;
else if(pro[0].id=='E'&&pro[2].id=='E') q=2;
else{};
if(pro[1].id=='='&&q==1)return 1;//i:=E时(前面已经将':='在栈中转化为'=')
else if(pro[1].id=='+'&&q==2)return 2;//E+E时
else if(pro[1].id=='-'&&q==2)return 3;//E-E时
else if(pro[1].id=='*'&&q==2)return 4;//E*E时
else if(pro[1].id=='/'&&q==2)return 5;//E/E时
else if(pro[0].id=='('&&pro[1].id=='E'&&pro[2].id==')')return 6;//(E)时
else return 0;
}
int gram(SqStack s)//语法分析(算符优先法)
{
int count=0;SElemType po[3];char getpre,ch;int keep;
getpre='#';//为第一个运算符设置优先级对比对象
index=0;SElemType nod,save;int ii=0;
ch=trans(word[index]);keep=index;index++;
do{
if(ch=='i')//运算对象终结符'i'移进
{ cout<<"动作:移进"<<endl;
nod.fword=word[keep];nod.id=ch;
push(s,nod);ch=trans(word[index]);keep=index;index++;count++;
if(count>1)//除了第一个产生式(此时count==1)的i不归约,其他的i由于优先级最高,进栈后立即归约
{ cout<<"动作:归约(7)"<<endl;
nod.id='E';nod.fword=gettop(s).fword;
pop(s);push(s,nod);}else{};
}
else//为运算符时
{
if(super(getpre,ch)=='<'||super(getpre,ch)=='=')//与前一个运算符对比优先级,比前者高则移进
{ nod.id=ch;nod.fword=word[keep];
push(s,nod);getpre=ch;ch=trans(word[index]);keep=index;index++;count++;
cout<<"动作:移进"<<endl;
}
else if(super(getpre,ch)=='>')//与前一个运算符对比,优先级要低,此时应该归约
{
if(count<3){error=1;return 0;}//归约时至少应该有三个字符(第一个产生式除外),否则错误
else
{
for(int i=2;i>=0;i--)//三个字符出栈进行归约
{
po[i].fword=gettop(s).fword;
po[i].id=gettop(s).id;
pop(s);
}
if(count>3)
{
if(issuit(po)==1||issuit(po)==2||issuit(po)==3||issuit(po)==4||issuit(po)==5||issuit(po)==6)
{ if(issuit(po)==6){nod.fword=po[1].fword;nod.id='E';//E->(E)归约不用记入四元式
cout<<"动作:归约("<<issuit(po)<<")"<<endl;}
else
{
nod.fword=mid[ii];ii++;nod.id='E';//记入四元式中
code[m][0]=po[1].fword;
code[m][1]=po[0].fword;
code[m][2]=po[2].fword;
code[m][3]=nod.fword;
m++;
cout<<"动作:归约("<<issuit(po)<<")"<<endl;}
push(s,nod);count=count-2;
save=gettop(s);pop(s);getpre=gettop(s).id;push(s,save);//取出栈中第一个运算以准备比较优先级
}
else{error=2;return 0;}
}
else if(count==3)//只剩三个字符时,为i=E(为方便归约,前面已将':='转化为'=')
{
if(issuit(po)==1)
{ cout<<"动作:归约(1)"<<endl;
nod.fword=mid[ii];ii++;nod.id='S';//归约到开始符'S'
push(s,nod);count=count-2;
code[m][1]=po[2].fword;
code[m][2]="-";
code[m][3]=po[0].fword;
code[m][0]=po[1].fword;
save=gettop(s);pop(s);getpre=gettop(s).id;push(s,save);
}
else{error=2;return 0;}
}
else {error=1;return 0;}
}
}
}
}while(count!=1||gettop(s).id=='i');
if(gettop(s).id!='S'){error=2;err(error);return 0;}
else{cout<<"接受"<<endl;}//栈顶为开始符S,则成功
pop(s);
return 1;
}
void printcode(char *code[n][4],ofstream &ofile)//将四元式写入文件
{ int j;char jj;
for(int i=0;i<=m;i++)
{j=i+1;jj=j+'0';
ofile.put('(');ofile.put(jj);ofile.put(')');
ofile.put('(');
ofile << code[i][0];
ofile.put(',');
ofile << code[i][1];
ofile.put(',');
ofile << code[i][2];
ofile.put(',');
ofile << code[i][3];
ofile.put(')');
ofile.put('\n');
}
}
void print()//打印文法
{
char a0='S';char a1='i';
char a2='E';char a3='+';
char a4='-';char a5='*';
char a6='/';char a7='(';
char a8=')';char a9[]=":=";
cout<<"赋值语句的文法为:"<<endl;
cout<<"(1)"<<a0<<"->"<<a1<<a9<<a2<<endl;
cout<<"(2)"<<a2<<"->"<<a2<<a3<<a2<<endl;
cout<<"(3)"<<a2<<"->"<<a2<<a4<<a2<<endl;
cout<<"(4)"<<a2<<"->"<<a2<<a5<<a2<<endl;
cout<<"(5)"<<a2<<"->"<<a2<<a6<<a2<<endl;
cout<<"(6)"<<a2<<"->"<<a7<<a2<<a8<<endl;
cout<<"(7)"<<a2<<"->"<<a1<<endl;
}
void readline()//获得输入的句子
{ char a;int le=0;
a=getchar();
while(a!='\n')
{
line[le]=a;
a=getchar();
le++;
}
linelen=le;
}
int main()
{
char resultfile[30];int t=0;
SqStack stack;
SElemType no;no.id='#';no.fword="nothing";
print();
initstack(stack);push(stack,no);
cout<<"\n请输入需进行分析的赋值语句(';'结尾):"<<endl;
readline();
anlysis();
cout<<"\n请输入分析后得到的输出文件名:";
gets(resultfile);//将中间代码(四元式)保存入文件中
rp.open(resultfile);
cout<<"\n语法分析(算符优先分析法)……"<<endl;
gram(stack);printcode(code,rp);
if(error!=0)err(error);
else{
cout<<"\n对赋值语句语法分析成功!!生成的中间代码(四元式)已存入文件:"<<resultfile<<endl;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -