本关任务:编写一个程序实现源语言转换为四元式中间代码。
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[10];
char type;//数据类型
} sem,*ptsem;
typedef struct
{
ptsem* base;
int utop;
} stack ; //语义信息栈
int i=1;
int j=0;
int n=0;
stack list;
char st[10],str1[10],*p;
ptsem yylist=new sem[10];
void initlist() //初始化
{
list.base=new ptsem[100];
list.utop=0;
}
void pop( ptsem &pt) //出栈
{
pt=list.base[list.utop--];
return;
}
void push(ptsem pt) //入栈
{
list.base[++list.utop]=pt;
return;
}
生成四元式中间代码
void gencode(ptsem top,ptsem subtop,char w)
{
ptsem pt=new sem;
if(top->type==subtop->type) {}
else if(top->type=='i'&subtop->type=='r')
{
//int与float数据类型转换
printf("(FLOAT,%s,t%d);\n",top->name,i);
char c=i+48;
top->name[0]='t';
top->name[1]=c;
top->name[2]='\0';
top->type='r';//转换第1个栈顶操作数类型为实型
i++;
}
else if(top->type=='r'&subtop->type=='i')
{
//float与int数据类型转换
printf("(FLOAT,%s,t%d);\n",subtop->name,i);
char c=i+48;
subtop->name[0]='t';
subtop->name[1]=c;
subtop->name[2]='\0';
subtop->type='r';//转换第2个栈顶操作数类型为实型
i++;
}
else if(top->type=='i'&subtop->type=='c')
{
//int与char数据类型转换
printf("(int,%s,t%d);\n",subtop->name,i);
char c=i+48;
subtop->name[0]='t';
subtop->name[1]=c;
subtop->name[2]='\0';
subtop->type='i';//转换第2个栈顶操作数类型为整型
i++;
}
else if(top->type=='c'&subtop->type=='i')
{
//char与int数据类型转换
printf("(int,%s,t%d);\n",top->name,i);
char c=i+48;
top->name[0]='t';
top->name[1]=c;
top->name[2]='\0';
top->type='i';//转换第2个栈顶操作数类型为实型
i++;
}
else if(top->type=='r'&subtop->type=='c')
{
//float与char数据类型转换
printf("(FLOAT,%s,t%d);\n",subtop->name,i);
char c=i+48;
subtop->name[0]='t';
subtop->name[1]=c;
subtop->name[2]='\0';
subtop->type='r';//转换第2个栈顶操作数类型为实型
i++;
}
else if(top->type=='c'&subtop->type=='r')
{
//char与float数据类型转换
printf("(FLOAT,%s,t%d);\n",top->name,i);
char c=i+48;
top->name[0]='t';
top->name[1]=c;
top->name[2]='\0';
top->type='r';//转换第2个栈顶操作数类型为实型
i++;
}
printf("(%c,%s,%s,t%d);\n",w,subtop->name,top->name,i);
char c=i+48;
pt->type=top->type;
pt->name[0]='t';
pt->name[1]=c;
pt->name[2]='\0';
i++;
push(pt);
return;
}
void identify()
{
//判断变量及其数据类型
while(*p>='a'&&*p<='z')
st[j++]=*p++;
st[j]='\0';
j=0;
int flag=0;
if(!strcmp(st,"float")||!strcmp(st,"int")||!strcmp(st,"char"))flag=1;
if(flag==1)
{
strcpy(str1,st);
return;
}
sem pp;
if(!strcmp(str1,"float"))
{
//strcmp()的意思为:str1=="float",返回0
strcpy(pp.name,st);
pp.type='r';
}
if(!strcmp(str1,"int"))
{
strcpy(pp.name,st);
pp.type='i';
}
if(!strcmp(str1,"char"))
{
strcpy(pp.name,st);
pp.type='c';
}
if(strcmp(str1,"float")&&strcmp(str1,"int")&&strcmp(str1,"char"))
{
//str1不属于float、int、char
printf("the identify is not defined");
getchar();
exit(0);
}
yylist[n++]=pp;
}
void conid()
{
//常数匹配
ptsem pt=new sem;
int flag=0,k=0;
do
{
pt->name[k++]=*p;
if(*p++=='.')flag=1;
}
while(*p>='0'&&*p<='9'||*p=='.');
pt->type=flag?'r':'i';
if(*p>'9'&&*p<'0')
{
printf("the const data you inputed is wrong");
getchar();
exit(0);
}
pt->name[k]='\0';
push(pt);
}
void varid()
{
//变量名匹配
ptsem pt=new sem;
int flag=0,k=0;
do
{
pt->name[k++]=*p++;
}
while(*p>='a'&&*p<='z'||*p>='A'&&*p<='Z');
pt->name[k]='\0';
for(int i=0; i<n; i++)
if(!strcmp(pt->name,yylist[i].name))
{
flag=1;
pt->type=yylist[i].type;
push(pt);
}
if(flag==0)
{
printf(" \" %s\" is not defined!",pt->name);
getchar();
exit(0);
}
}
int main()
{
initlist();
char str[100];
//gets(str);//输入变量定义 ps:这种用法在DEV上可以使用,不会报错,但是放在头歌上会报错
scanf("%[^\n]%*c",str);
//输入变量定义,如果只用scanf("%c",&str)读取字符串的话,遇到空格会停止报错
p=str;
while(*p!='\0')
{
if(!(*p>='a'&&*p<='z'||*p>='A'&&*p<='Z'||*p==';'||*p==' '||*p==','))
{
printf("this define is wrong!");
getchar();
exit(0);
}
switch(*p)
{
case ',':
p++;
break;
case ' ':
p++;
break;
case ';':
p++;
strcpy(str1,"");
break;
default:
identify();
}
}
char strpds[100];
//gets(strpds);//输入后缀式算术表达式
scanf("%[^\n]%*c",str);//同上
p=strpds;
char ch=*p,a;
ptsem top,subtop;
while(*p!='\0')
{
if(ch>='0'&&ch<='9')a='0';
else if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')a='1';
else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^')a='2';
else if(ch==';')break;
else if(ch==' ')a='4';
else a='3';
switch(a)
{
case'0':
conid();
ch=*p;
break;//常数
case'1':
varid();
ch=*p;
break;//变量
case'2':
pop(top);
pop(subtop);
gencode(top,subtop,ch);
ch=*++p;
break;//运算符
case'3':
printf("%c is a illegal letter!\n",ch);
getchar();
getchar();
exit(0);
case'4':
ch=*++p;//空格
}
}
if(*p!='\0')
printf("this setense is illegal!");
}
因为编译器的不同,导致一些输入输出的语无法使用报错,需要读者自行修改。这里就不赘述了,祝好!