编译原理之中间代码生成

本关任务:编写一个程序实现源语言转换为四元式中间代码。

 

#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!");
}

 因为编译器的不同,导致一些输入输出的语无法使用报错,需要读者自行修改。这里就不赘述了,祝好!

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值