⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pas.c

📁 PASCAL语言子集编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
	getch();
	printf("\n**************变量表****************************\n");
	for(tttt=0;tttt<tt1;tttt++)
		printf("%d\t%s\n",tttt,ntab1[tttt]);
	getch();
}





/*************************************************/
//文件:read.c
//从源文件中读取四元式,或从键盘输入四元式
/***************************************************/

//#include "globals.h"
m1 m1_line;//中间语言变量名
//char spelling[10]={""};//存放识别的字符
//从文件读取一个字到内存单元
void getword()
{
	int i=0;
	char ch;
	ch=getc(source);
	while(ch!='\t')
	{
		spelling[i]=ch;
		i++;
		ch=getc(source);
	}
	spelling[i]='\0';
}
//从文件读取四元式,输入到内存

void read_file(char *sourcefile)
{
	int line;//四元式行号从100开始
	m1 k,l;
	char ch;
	printf("\n正在读取四元式源文件%s!……",sourcefile);
	m1_line=(m1)malloc(sizeof(struct MLanguage));
	fscanf(source,"%d",&line);
	m1_line->line=line;
	fseek(source,2,1);
	getword();
	strcpy(m1_line->op,spelling);
	fseek(source,1,1);
	getword();
	strcpy(m1_line->opv1,spelling);
	fseek(source,1,1);
	getword();
	strcpy(m1_line->opv2,spelling);
	fseek(source,1,1);
	getword();
	strcpy(m1_line->result,spelling);
	m1_line->next=NULL;
	ch=getc(source);
	while((ch!='\n')&&(!feof(source)))
		ch=getc(source);
	k=m1_line;
	while(!feof(source))
	{
		line++;
		l=(m1)malloc(sizeof(struct MLanguage));
		l->line=line;
		ch=getc(source);
		while(ch!='(')
			ch=getc(source);
		getword();
		strcpy(l->op,spelling);
		fseek(source,1,1);
		getword();
		strcpy(l->opv1,spelling);
		fseek(source,1,1);
		getword();
		strcpy(l->opv2,spelling);
		fseek(source,1,1);
		getword();
		strcpy(l->result,spelling);
		l->next=k->next;
		k->next=l;
		k=l;
		ch=getc(source);
		while((ch!='\n')&&(!feof(source)))
			ch=getc(source);
	}
}

/*****************************************/
//文件:symtab.c
//为四元式代码变量产生符号表和建立汇编语言的数据段 
//生成代码时选择寄存器的依据存储在符号表中
//符号表以链式的哈希表实现
/*****************************************/

//#include "globals.h"
//SHIFT是作为哈希函数乘数的权值
#define SHIFT 4
vr HashTable[26];//符号表的哈希表结构
vr HashTable_1[26];//临时变量的符号表
//extern m1 m1_line;

//产生键值的哈希函数
static int hash(char key[])
{
	int temp=0;
	int i=0;
	while(key[i]!='\0')
	{
		temp=((temp<<SHIFT)+key[i])%26;
		++i;
	}
	return temp;
}

//过程st_insert把程序变量插入符号表
void st_insert(char name[],vr Table[])
{
	int h=hash(name);
	vr l=Table[h];
	while((l!=NULL)&&(strcmp(name,l->name)!=0))
	{
		l=l->next;
	}
	if(l==NULL)  //变量还没有登记到符号表中
	{
		l=(vr)malloc(sizeof(struct VariableRec));
		strcpy(l->name,name);
		l->regstats=0;
		l->regnum=0;
		//以上三行是变量在符号表中的进行初始化
		l->next=Table[h];
		Table[h]=l;//把变量登记到符号表相应位置
	}
	else
		return;//如果已经在符号表中存在,则返回
}//st_insert

//过程insert根据变量是变量还是临时变量,然后执行st_insert过程
//把不同的变量插入相应的符号表
void insert(char name[])
{
	if((name[0]>='a')&&(name<='z'))
	{
		st_insert(name,HashTable);
	}
	else if((name[0]>='A')&&(name[0]<='Z'))
	{
		st_insert(name,HashTable_1);
	}
	else return;//如为其他,则不插入符号表中
}

//建立符号表的函数,变量和临时变量保存在不同的符号表中
void buildsymtab()
{
	m1 l;
	int i;
	l=m1_line;
	printf("\n正在进行一遍扫描,以提取变量,建立符号表!……");
	for(i=0;i<26;i++)
	{
		HashTable[i]=NULL;
		HashTable_1[i]=NULL;
	}
	while(l!=NULL)
	{
		insert(l->opv1);
		insert(l->opv2);
		insert(l->result);
		l=l->next;
	}
}

//在符号表中查找变量,返回所需变量在符号表中的地址
vr st_lookup(char name[],vr Table[])
{
	int h=hash(name);
	vr l=Table[h];
	while((l!=NULL)&&(strcmp(name,l->name)!=0))
	{
		l=l->next;
	}
	return l;
}

//判断是变量还是临时变量,然后选择不同的参数查找符号表
vr lookup(char name[])
{
	vr l;
	if((name[0]>='a')&&(name[0]<='z'))
	{
		l=st_lookup(name,HashTable);
	}
	else if((name[0]>='A')&&(name[0]<='Z'))
	{
		l=st_lookup(name,HashTable_1);
	}
	else l=NULL;
	return l;
}

//建立数据段的主程序,临时变量不存入数据段
void create_dataseg()
{
	int i;
	vr l;
	printf("\n正在生成汇编语言的数据段!……");
	for(i=0;i<26;i++)
	{
		l=HashTable[i];
		while(l!=NULL)
		{
			fprintf(code,"    %-10s  DW",l->name);//定义字变量
			fprintf(code,"\n");
			l=l->next;
		}
	}
}

/**********************************************************8/
//文件:block.c
//为中间语言建立基本块
/********************************************************/
//#include "globals.h"
int Block[100];//保存基本块的行号
//extern m1 m1_line;
int i,j=0,k;//n=0;
char *m;
m1 l;
//划分基本块的函数,产生基本块入口的四元式行地址,并按照行地址从小到大排列
void create_basicblock()
{
	l=m1_line;
	printf("\n正在进行二遍扫描,以生成基本块的入口地址!……");
	for(i=0;i<100;i++)
	{
		Block[i]=-1;
	}
	Block[0]=1;
	while(l!=NULL)
	{
		if(l->op[0]=='j')
		{
			m=l->result;
			while(*m!='\0')
			{
				j=j*10+(*m-48);
				m++;
			}
			Block[j%100]=1;
			j=0;
			i++;
			Block[(l->next->line)%100]=1;
		}
		l=l->next;
	}
}

/*********************************************/
//文件:code.c
//这里存放生成各类型代码的函数
//被cgen.c文件中的create_codeseg函数调用
/*********************************************/
//#include "globals.h"
//emitcomment函数在目标语言文件中添加注释
void emitcomment(char *c)
{
	fprintf(code,"    %s",c);
}

//产生寄存器<-->寄存器的汇编指令
void emitRR(char *op,char *r1,char *r2,char *comment)
{
	fprintf(code,"    %s    %s,%s",op,r1,r2);
	emitcomment(comment);
	fprintf(code,"\n");
}

//产生寄存器<-->存储器的汇编指令
void emitRM(char *op,char *r,char *m,char *comment)
{
	fprintf(code,"    %s    %s,%s",op,r,m);
	emitcomment(comment);
	fprintf(code,"\n");
}

//产生立即数<-->寄存器的汇编指令
void emitRC(char *op,char *r,char *con,char *comment)
{
	fprintf(code,"    %s    %s,%s",op,r,con);
	emitcomment(comment);
	fprintf(code,"\n");
}

//产生乘法,除法的汇编指令
void emitTO(char *op,char *s,char *comment)
{
	fprintf(code,"    %s    %s,%s",op,s);
	emitcomment(comment);
	fprintf(code,"\n");
}

//产生跳转和条件跳转的汇编指令
void emitJ(char *op,char *s,char *comment)
{
	fprintf(code,"    %s    %s,%s",op,s);
	emitcomment(comment);
	fprintf(code,"\n");
}

/********************************************/
/*文件cgen.c								*/
/*执行中间语言的分析,调用相应的子程序,		*/
/*来完成汇编代码的产生						*/
/********************************************/

//#include	"globals.h"
//#include	"symtab.h"
//#include	"code.h"

/*保存CPU四个通用寄存器AX、BX、CX、DX的使用状态。*/
typedef struct Register
{
char	reg[3];
int		stats;
int		alter;
char	varname[10];
}reg;
reg	regstats[4];

extern	m1	m1_line;/*四元式中间语言代码的指针*/
extern	vr	HashTable[26];/*保存变量的符号表*/
extern	vr	HashTable_1[26];/*保存临时变量的符号表*/
extern	int	Block[100];/*保存基本快的行号*/

vr	v1,v2,re,temp;

/*函数assign在生成汇编语言代码时为变量分配寄存器,返回所分配寄存器的名字*/
int		assign(vr	variable)
{
int  i;
for(i=0;i<=3;i++)/*一次分配*/
	{
	if(regstats[i].stats==0)
		{
		variable->regstats=1;
		variable->regnum=i;
		regstats[i].stats=1;
		strcpy(regstats[i].varname,variable->name);
		return i;
		}
	}
if(variable->regstats==0)/*二次分配*/
	{
	for(i=0;i<=3;i++)
		{
		if((regstats[i].varname[0]>='A')&&(regstats[i].varname[0]<='Z'))
			{
			if((strcmp(regstats[i].varname,v1->name)!=0)&&(strcmp(regstats[i].varname,v2->name)!=0)&&(strcmp(regstats[i].varname,re->name)!=0))
				{
				temp=st_lookup(regstats[i].varname,HashTable_1);
				temp->regstats=0;
				variable->regstats=1;
				variable->regnum=i;
				regstats->stats=1;
				strcpy(regstats[i].varname,variable->name);
				return i;
				}
			}
		}
	}
if(variable->regstats==0)/*三次分配*/
	{
	for(i=0;i<=3;i++)
		{
		if((strcmp(regstats[i].varname,v1->name)!=0)&&(strcmp(regstats[i].varname,v2->name)!=0)&&(strcmp(regstats[i].varname,re->name)!=0))
			{
			temp=st_lookup(regstats[i].varname,HashTable);
			if(regstats[i].alter==1)
				{
				emitRM("mov",temp->name,regstats[i].reg,";保存不用的变量,以空出寄存器供变量使用");
				temp->regstats=0;
				}
			variable->regstats=1;
			variable->regnum=i;
			regstats[i].stats=1;
			strcpy(regstats[i].varname,variable->name);
			return i;
			}
		}
	}
}


/*函数assign_1在生成汇编语言代码时为常数分配寄存器,返回 所分配寄存器的名字*/
/*只在生成算法、除法和条件跳转指令时可能需要*/
int assign_1()
{
vr con=(vr)malloc(sizeof(struct VariableRec));
int  i;
for(i=1;i<=2;i++)/*一次分配*/
	{
	if(regstats[i].stats==0)
		{
		con->regstats=1;
		return	i;	
		}
	}
if(con->regstats==0)/*二次分配*/
	{
	for(i=1;i<=2;i++)
		{
		if((regstats[i].varname[0]>='A')&&(regstats[i].varname[0]<='Z'))
			{
			if((strcmp(regstats[i].varname,v1->name)!=0)&&(strcmp(regstats[i].varname,v2->name)!=0)&&(strcmp(regstats[i].varname,re->name)!=0))
				{
				temp=st_lookup(regstats[i].varname,HashTable_1);
				temp->regstats=0;
				con->regstats=1;
				regstats[i].stats=0;
				return i;
				}
			}
		}
	}
if(con->regstats==0)/*三次分配*/
	{
	for(i=1;i<=2;i++)
		{
		if((strcmp(regstats[i].varname,v1->name)!=0)&&(strcmp(regstats[i].varname,v2->name)!=0)&&(strcmp(regstats[i].varname,re->name)!=0))
			{
			temp=st_lookup(regstats[i].varname,HashTable);
			if(regstats[i].alter==1)
				{
				emitRM("mov",temp->name,regstats[i].reg,";保存不用的变量,以空出寄存器供变量使用");
				temp->regstats=0;
				}
			con->regstats=1;
			regstats[i].stats=0;
			return i;
			}
		}
	}
free(con);
}

/*产生代码段的主程序,通过对变量寄存器的分配,调用不同的函数来产生汇编语言*/
/*代码*/
void emit_code(m1 medline)
{
int j,reg;
switch(medline->op[0])
	{
	case '+':
		v1=lookup(medline->opv1);	
		v2=lookup(medline->opv2);
		re=lookup(medline->result);	
		/*以上三行是三个操作数在符号表中的定位*/
		if(re->regstats==1)
			reg=re->regnum;
		else
			reg=assign(re);
		if(v1!=NULL)
			{
			if(v1->regstats==1)
				emitRR("mov",regstats[reg].reg,regstats[v1->regnum].reg,";把在寄存器中的被加数赋给结果寄存器");
			else
				emitRM("mov",regstats[reg].reg,v1->name,";把在存储器中的被加数赋给结果寄存器");
			}
		else
			{
			emitRC("mov",regstats[reg].reg,medline->opv1,";把被加数立即数赋给结果寄存器");
			}/*为结果寄存器赋被加数的值*/
		if(v2!=NULL)
			{
			if(v2->regstats==1)
				emitRR("add",regstats[reg].reg,regstats[v2->regnum].reg,";把被加数和在寄存器中的加数相加");
			else
				emitRM("add",regstats[reg].reg,v2->name,";把被加数和在存储器中的加数相加");
			}
		else
			{
			emitRC("add",regstats[reg].reg,medline->opv2,";把被加数和加数立即数相加");
			}/*完成对加法的四元式编译。*/
		regstats[reg].alter=1;
		break;
	case '-':
		v1=lookup(medline->opv1);	
		v2=lookup(medline->opv2);
		re=lookup(medline->result);	
		/*以上三行是三个操作数在符号表中的定位*/
		if(re->regstats==1)
			reg=re->regnum;
		else
			reg=assign(re);
		if(v1!=NULL)
			{
			if(v1->regstats==1)
				emitRR("mov",regstats[reg].reg,regstats[v1->regnum].reg,";把在寄存器中的被减数赋给结果寄存器");
			else
				emitRM("mov",regstats[reg].reg,v1->name,";把在存储器中的被减数赋给结果寄存器");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -