📄 实验3.cpp
字号:
void prior_analysis()//自下而上分析
{
int i,j,m;
char q,str,ch[10];
push('#');//设置符号栈初值
print(0,-1);
u: readvt(&a);//当前输入符号读入a
if(IsVT(stack[top]))//判断是否为终结符
j=top;
else
j=top-1;
do
{
while(big(j,a)&&strcmp(stack,"#N")!=0)//j优先级高于a
{
do
{
q=stack[j];
if(IsVT(stack[j-1]))//判断是否为终结符
j=j-1;
else
j=j-2;
}while(!less(j,q));
i=-1;
while((top-j)!=0)
{
ch[++i]=pop();
}
ch[i+1]='\0';
for (m=0;m<=5;m++)//把最左素短语归约为某个N
{
if(strcmp(word[m],ch)==0)
str='N';
}
push(str);
print(1,1);
}
if(less(j,a))//j优先级低于a
{
push(a);
print(0,-1);
if(stack[top]!='#')
goto u;
}
else
{
if(equal(j,a))//j优先级等于a
{
push(a);
print(0,0);
if(stack[top]!='#')
goto u;
}
else
{
error1(j);//调用错误分析函数
a='#';
}
}
}while(a!='#');
}
//////////////////////////////////////////////////////////////////////////////////////////
void suanfu()//算符优先语法主函数
{
cout<<"\n******************************算符优先语法分析程序******************************"<<endl;
cout<<" E->E+T|E-T|T"<<endl;
cout<<" T->T*F|T/F|F"<<endl;
cout<<" F->(E)|i"<<endl;
cout<<" E表示算术表达式.T表示项.F表示因子.i表示变量或常数."<<endl;
cout<<" 优先表"<<endl;
cout<<" + - * / ( ) i #"<<endl;
cout<<" + > > < < < > < >"<<endl;
cout<<" - > > < < < > < >"<<endl;
cout<<" * > > > > < > < >"<<endl;
cout<<" / > > > > < > < >"<<endl;
cout<<" ( < < < < < = < e1"<<endl;
cout<<" ) > > > > e2 > e2 >"<<endl;
cout<<" i > > > > e2 > e2 >"<<endl;
cout<<" # < < < < < e3 < ="<<endl;
ff=fopen("预处理.txt","r");
char ch=fgetc(ff);
char ch1;
while(ch!='#')
{
int i=-1,j=0,m=-1;
while(ch!='='&&ch!='#')
{
ch1=ch;
ch=fgetc(ff);
if((ch1=='>'||ch1=='<')&&ch=='=')
ch=fgetc(ff);
}
if(ch=='#')
{
cout<<endl;
fclose(ff);
return;
}
while(ch!=' '&&ch!='#')//得到算数表达式
{
ch=fgetc(ff);
oldstrings[++i]=ch;
}
oldstrings[i]='\0';
if(isalnum(oldstrings[j]))
strings[++m]='i';
else
strings[++m]=oldstrings[j];
j++;
while(oldstrings[j]!='\0')//转换为输入串
{
if(isalnum(oldstrings[j]))
{
if(isalnum(oldstrings[j-1])==0)
strings[++m]='i';
}
else
strings[++m]=oldstrings[j];
j++;
}
strings[m+1]='#';
strings[m+2]='\0';
cout<<"算术表达式"<<id<<"为: "<<oldstrings<<endl;
cout<<"转换为输入串: "<<strings<<endl;
cout<<" 步骤号 符号栈 优先关系 当前分析符 剩余输入串 动作";
prior_analysis();//自下而上分析
n=0;
cout<<endl;
cout<<"算术表达式"<<id++<<"的"<<"归约产生式步骤号为:";
while(No[n])//记录归约产生式步骤号
{
cout<<" "<<No[n];
n++;
}
cout<<endl;
//回归各全局变量初值
while(stack[0]!='\0')
pop();
while(No[--n])
{
No[n]='\0';
}
top=-1;
a='\0';
k=0;
step=1;
n=0;
}
}
/***********************************以下是语义分析部分***********************************/
//////////////////////////////////////////////////////////////////////////////////////////
void error(char *strError)//输出扫描发现的错误
{
fprintf(fw,"错误: %s\n",strError);
printf("错误: %s\n",strError);
return;
}
//////////////////////////////////////////////////////////////////////////////////////////
int Match(char syn,char *strError)//匹配当前识别出的单词
{
if(syn==uWord.syn&&(strcmp(strError,uWord.value.T1)==0)||strError[0]==uWord.value.T3)
{
Scaner();
return 1;
}
else
{
error(strError);
return 0;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void gen(char *op,char *argv1,char *argv2,char *result)//生成一个四元式
{
sprintf(pQuad[nNXQ].op,op);
sprintf(pQuad[nNXQ].argv1,argv1);
sprintf(pQuad[nNXQ].argv2,argv2);
sprintf(pQuad[nNXQ].result,result);
nNXQ++;
return;
}
//////////////////////////////////////////////////////////////////////////////////////////
void PrintQuaternion()//打印四元式数组
{
int nLoop;
printf("********************************中间代码生成程序********************************");
for(nLoop=1;nLoop<nNXQ;nLoop++)
{
fprintf(fw,"\n%d:(%s,\t%s,\t%s,\t%s)",
nLoop,pQuad[nLoop].op,pQuad[nLoop].argv1,
pQuad[nLoop].argv2,pQuad[nLoop].result);
printf("\n%d:(%s,\t%s,\t%s,\t%s)",
nLoop,pQuad[nLoop].op,pQuad[nLoop].argv1,
pQuad[nLoop].argv2,pQuad[nLoop].result);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
char *Newtemp()//产生一个临时变量
{
char *strTempID=(char *)malloc(MAXLENGTH);
sprintf(strTempID,"T%d",++nSuffix);
return strTempID;
}
//////////////////////////////////////////////////////////////////////////////////////////
int merge(int p1,int p2)//合并p1和p2
{
int p,nResult;
if(p2==0)
nResult=p1;
else
{
nResult=p=p2;
while(atoi(pQuad[p].result))
{
p=atoi(pQuad[p].result);
sprintf(pQuad[p].result,"%d",p1);
}
}
return nResult;
}
//////////////////////////////////////////////////////////////////////////////////////////
void backpatch(int p,int t)//将t回填到以p为首的四元式中
{
int w,q=p;
while(q)
{
w=atoi(pQuad[q].result);
sprintf(pQuad[q].result,"%d",t);
q=w;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
char *Expression()//分析算术表达式函数
{
char opp[MAXLENGTH],*eplace,*eplace1,*eplace2;
eplace=eplace1=Term();
while(uWord.syn=='O'&&(strcmp(uWord.value.T1,"+")==0||strcmp(uWord.value.T1,"-")==0))
{
sprintf(opp,"%s",uWord.value.T1);
Scaner();
eplace2=Term();
eplace=Newtemp();
gen(opp,eplace1,eplace2,eplace);
eplace1=eplace;
}
return eplace;
}
//////////////////////////////////////////////////////////////////////////////////////////
char *Term()//分析项函数
{
char opp[2],*eplace1,*eplace2,*eplace;
eplace=eplace1=Factor();
while(uWord.syn=='O'&&(strcmp(uWord.value.T1,"*")==0||strcmp(uWord.value.T1,"/")==0))
{
sprintf(opp,"%s",uWord.value.T1);
Scaner();
eplace2=Factor();
eplace=Newtemp();
gen(opp,eplace1,eplace2,eplace);
eplace1=eplace;
}
return eplace;
}
//////////////////////////////////////////////////////////////////////////////////////////
char *Factor()//分析因子函数
{
char *eplace=(char *)malloc(MAXLENGTH);
if(uWord.syn=='I'||uWord.syn=='C')
{
if(uWord.syn=='I')
sprintf(eplace,"%s",uWord.value.T1);
else
sprintf(eplace,"%d",uWord.value.T2);
Scaner();
}
else
{
Match('P',"(");
eplace=Expression();
Match('P',")");
}
return eplace;
}
//////////////////////////////////////////////////////////////////////////////////////////
void Condition(int *etc,int *efc)//分析布尔表达式函数
{
char opp[3],*eplace1,*eplace2;
char strTemp[4];
eplace1=Expression();
if(uWord.syn=='O'&&(strcmp(uWord.value.T1,"+")!=0&&strcmp(uWord.value.T1,"-")!=0
&&strcmp(uWord.value.T1,"*")!=0&&strcmp(uWord.value.T1,"/")!=0))
{
sprintf(opp,"%s",uWord.value.T1);
Scaner();
eplace2=Expression();
*etc=nNXQ;
*efc=nNXQ+1;
sprintf(strTemp,"j%s",opp);
gen(strTemp,eplace1,eplace2,"0");
gen("j","","","0");
}
else
error("关系运算符");
}
//////////////////////////////////////////////////////////////////////////////////////////
void Statement(int nChain)//语句分析函数
{
char strTemp[MAXLENGTH],eplace[MAXLENGTH];
int nChainTemp=0,nChainTemp1=0,nWQUAD,Temp,tag2;
switch(uWord.syn)
{
case 'I'://赋值语句分析
strcpy(strTemp,uWord.value.T1);
Scaner();
Match('O',"=");
strcpy(eplace,Expression());
gen("=",eplace,"",strTemp);
nChain=0;
break;
case 'L'://带标号的赋值语句分析
Scaner();
Match('P',":");
strcpy(strTemp,uWord.value.T1);
Scaner();
Match('O',"=");
tag1=nNXQ;
strcpy(eplace,Expression());
gen("=",eplace,"",strTemp);
nChain=0;
break;
case 'K':
if(strcmp(uWord.value.T1,"IF")==0)//IF-THEN条件语句分析
{
Match('K',"IF");
Match('P',"(");
Condition(&ntc,&nfc);
backpatch(ntc,nNXQ);
Match('P',")");
Match('K',"THEN");
Statement(nChainTemp);
if(strcmp(uWord.value.T1,"ELSE")!=0)
backpatch(nfc,nNXQ);
nChain=merge(nChainTemp,nfc);
}
if(strcmp(uWord.value.T1,"ELSE")==0)//IF-THEN-ELSE条件语句分析
{
gen("j","","","0");
nWQUAD=nNXQ;
tag2=nNXQ-1;
backpatch(nfc,nWQUAD);
Temp=merge(nWQUAD,nChainTemp);
Match('K',"ELSE");
Statement(nChainTemp);
backpatch(tag2,nNXQ);
nChain=merge(Temp,nChainTemp1);
}
if(strcmp(uWord.value.T1,"GOTO")==0)//转移语句分析
{
Match('K',"GOTO");
nWQUAD=nNXQ;
gen("j","","","0");
backpatch(nWQUAD,tag1);
nChain=0;
}
break;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void Statement_Sequence(int nChain)//语句串分析函数
{
Statement(nChain);
while((uWord.syn=='I'||uWord.syn=='L'
||(uWord.syn=='K'&&strcmp(uWord.value.T1,"IF")==0)
||(uWord.syn=='K'&&strcmp(uWord.value.T1,"ELSE")==0)
||(uWord.syn=='K'&&strcmp(uWord.value.T1,"GOTO")==0))&&strcmp(uWord.value.T1,"end")!=0)
{
Statement(nChain);
}
}
//////////////////////////////////////////////////////////////////////////////////////////
void Parse()//分析生成中间代码
{
int nChain=0;
str=fgetc(fp);
Scaner();
Statement_Sequence(nChain);
if(strcmp(uWord.value.T1,"end")!=0)
{
printf("\n源程序非正常结束");
fprintf(fw,"\n源程序非正常结束");
}
suanfu();//调用算符优先语法主函数
PrintQuaternion();//打印四元式数组
}
/************************************以下是主函数部分************************************/
//////////////////////////////////////////////////////////////////////////////////////////
void main()//主函数
{
pQuad=(QUATERNION *)malloc(4*MAXLENGTH);
nSuffix=0;
nfc=ntc=nNXQ=1;
char buf[4048]={'\0'};
int i=0;
out=fopen("二元式表.txt","w");
in=fopen("预处理.txt","w");
printf("请输入源文件路径及名称:");
scanf("%s",filename);
if ((fp=fopen(filename,"rt"))==NULL)
{
printf("源文件无法打开!\n");
system("pause");
exit(0);
}
else
{
printf("**********************************词法分析程序**********************************\n");
printf("K:关键字 I:标识符 C:常数 O:运算符 P:界符 L:标号\n");
pro_process(buf);//生成预处理文件
while (buf[i]!='#')
{
fputc(buf[i],in);
i++;
}
fputc('#',in);
fclose(in);
fp=fopen("预处理.txt","r");
}
fw=fopen("四元式表.txt","w");
Parse();//分析生成中间代码
cout<<endl;
fclose(fw);
fclose(fp);
cout<<"输出结果保存在二元式表.txt和四元式表.txt文件中,请打开查看。"<<endl;
system("pause");
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -