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

📄 cgen.c

📁 根据编译器的基本原理
💻 C
字号:
#include "globals.h"
#include "symtab.h"
#include "cgen.h"
#include "string.h"

static int currenttemp=0;
static int currentlabel=0;
static int currentline=0;
char*c=NULL;

void codeGen(TreeNode*syntaxTree);
void cGen(TreeNode*tree);
void genStmt(TreeNode*tree);
void genExp(TreeNode*tree);
int connect(char**c1,char*c2);
int spaceconnect(char**c1,char*c2);
int lineconnect(char**c1,char*c2);
char*newtemp();
char*newlabel(char**l);
void newline();


void codeGen(TreeNode*syntaxTree)
{
	cGen(syntaxTree);
	fprintf(code,"%s",c);
}

void cGen(TreeNode*tree)
{
	if (tree != NULL)
	{ 
		switch (tree->nodekind) 
		{
		case StmtK:
			genStmt(tree);
			break;
		case ExpK:
			genExp(tree);
			break;
		default:
			break;
		}
		cGen(tree->sibling);
	}
}

void genStmt(TreeNode*tree)
{
	TreeNode * p1, * p2, * p3;
	char*label1=NULL;
	char*label2=NULL;
	char*label3=NULL;
	char*label4=NULL;
	char*l1=NULL;
	char*l2=NULL;
	char*l3=NULL;
	char*l4=NULL;
	switch (tree->kind.stmt)
	{
	case IfK:
		p1=tree->child[0];
		p2=tree->child[1];
		if(tree->child[2]==NULL)
		{
			label1=newlabel(&l1);
			label2=newlabel(&l2);
			label3=newlabel(&l3);
			newline();
			spaceconnect(&c,label1);
			cGen(p1);
			newline();
			spaceconnect(&c,"if");
			spaceconnect(&c,p1->tempname);
			spaceconnect(&c,"goto");
			spaceconnect(&c,l2);
			newline();
			spaceconnect(&c,"goto");
			spaceconnect(&c,l3);
			newline();
			spaceconnect(&c,label2);
			cGen(p2);
			newline();
			spaceconnect(&c,label3);
		}
		else
		{
			p3=tree->child[2];
			label1=newlabel(&l1);
			label2=newlabel(&l2);
			label3=newlabel(&l3);
			label4=newlabel(&l4);
			newline();
			spaceconnect(&c,label1);
			cGen(p1);
			newline();
			spaceconnect(&c,"if");
			spaceconnect(&c,p1->tempname);
			spaceconnect(&c,"goto");
			spaceconnect(&c,l2);
			newline();
			spaceconnect(&c,"goto");
			spaceconnect(&c,l3);
			newline();
			spaceconnect(&c,label2);
			cGen(p2);
			newline();
			spaceconnect(&c,"goto");
			spaceconnect(&c,l4);
			newline();
			spaceconnect(&c,label3);
			cGen(p3);
			newline();
			spaceconnect(&c,label4);
		}
		break;
	case RepeatK:
		p1=tree->child[0];
		p2=tree->child[1];
		label1=newlabel(&l1);
		label2=newlabel(&l2);
		newline();
		spaceconnect(&c,label1);
		cGen(p1);
		cGen(p2);
		newline();
		spaceconnect(&c,"if");
		spaceconnect(&c,p2->tempname);
		spaceconnect(&c,"goto");
		spaceconnect(&c,l2);
		newline();
		spaceconnect(&c,"goto");
		spaceconnect(&c,l1);
		newline();
		spaceconnect(&c,label2);
		break;
	case AssignK:
		cGen(tree->child[0]);
		newline();
		spaceconnect(&c,tree->attr.name);
		connect(&c,":=");
		connect(&c,tree->child[0]->tempname);
		break;
	case ReadK:
		newline();
		spaceconnect(&c,"read");
		spaceconnect(&c,tree->attr.name);
		break;
	case WriteK:
		cGen(tree->child[0]);
		newline();
		spaceconnect(&c,"write");
		spaceconnect(&c,tree->child[0]->tempname);
		break;
	case WhileK:
		p1=tree->child[0];
		p2=tree->child[1];
		label1=newlabel(&l1);
		label2=newlabel(&l2);
		label3=newlabel(&l3);
        newline();
		spaceconnect(&c,label1);
		cGen(p1);
        newline();
		spaceconnect(&c,"goto");
		spaceconnect(&c,l2);
        newline();
		spaceconnect(&c,label2);
		cGen(p2);
		newline();
		spaceconnect(&c,"if");
		spaceconnect(&c,p2->tempname);
		spaceconnect(&c,"goto");
		spaceconnect(&c,l1);
		newline();
		spaceconnect(&c,"goto");
		spaceconnect(&c,l3);
		newline();
		spaceconnect(&c,label3);
		break;
	default:
		break;
	}
}

void genExp(TreeNode*tree)
{
	TreeNode * p1, * p2;
	char*op=NULL;
	char*t1=NULL;
	char*t2=NULL;
	int n=0;
	switch (tree->kind.exp)
	{
	case OpK:
		p1=tree->child[0];
		if(tree->attr.op==NOT)
		{
			cGen(p1);
			if(p1->kind.exp==OpK)
			{
				t1=newtemp();
				newline();
				spaceconnect(&c,t1);
				connect(&c,"=");
				connect(&c,p1->tempname);
			}
			else
			{
				t1=p1->tempname;
			}
			tree->tempname=(char*)malloc(3*sizeof

(char));
			strcpy(tree->tempname,"not ");
			connect(&tree->tempname,t1);
		}
		else if(tree->attr.op==OR||tree->attr.op==AND||
			tree->attr.op==PLUS||tree->attr.op==MINUS||
			tree->attr.op==TIMES||tree->attr.op==OVER||
			tree->attr.op==LT||tree->attr.op==EQ||
			tree->attr.op==GT||tree->attr.op==NGT||
			tree->attr.op==NLT)
		{
			p2=tree->child[1];
			switch (tree->attr.op)
			{
			case OR:
				connect(&op," or ");
				break;
			case AND:
				connect(&op," and ");
				break;
			case PLUS:
				connect(&op,"+");
				break;
			case MINUS:
				connect(&op,"-");
				break;
			case TIMES:
				connect(&op,"*");
				break;
			case OVER:
				connect(&op,"/");
				break;
			case LT:
				connect(&op,"<");
				break;
			case EQ:
				connect(&op,"=");
				break;
			case GT:
				connect(&op,">");
				break;
			case NGT:
				connect(&op,"<=");
				break;
			case NLT:
				connect(&op,">=");
				break;
			default:
				break;
			}
			cGen(p1);
			cGen(p2);
			if(p1->kind.exp==OpK||p2->kind.exp==OpK)
			{
				if(p1->kind.exp==OpK)
				{
					t1=newtemp();
					newline();
					spaceconnect(&c,t1);
					connect(&c,"=");
					connect(&c,p1->tempname);
				}
				else t1=p1->tempname;
				if(p2->kind.exp==OpK)
				{
					t2=newtemp();
					newline();
					spaceconnect(&c,t2);
					connect(&c,"=");
					connect(&c,p2->tempname);
				}
				else t2=p2->tempname;
			}
			else
			{
				t1=p1->tempname;
				t2=p2->tempname;
			}
			connect(&tree->tempname,t1);
			connect(&tree->tempname,op);
			connect(&tree->tempname,t2);
		}
		break;
	case ConstK:
		tree->tempname=(char*)malloc(10*sizeof(char));
		itoa(tree->attr.val,tree->tempname,10);
		break;
	case IdK:
		n=strlen(tree->attr.name);
		tree->tempname=(char*)malloc(n*sizeof(char));
		strcpy(tree->tempname,tree->attr.name);
		break;
	case StrK:
		n=strlen(tree->attr.str);
		n=n+2;
		tree->tempname=(char*)malloc(n*sizeof(char));
		strcpy(tree->tempname,"\"");
		strcat(tree->tempname,tree->attr.str);
		strcat(tree->tempname,"\"");
		break;
	case BK:
		tree->tempname=(char*)malloc(sizeof(char));
		if(tree->attr.val>1) strcpy(tree->tempname,"1");
		else strcpy(tree->tempname,"0");
		break;
	default:
		break;
	}
}

int connect(char**c1,char*c2)
{
	int l1,l2,l=0;
	char*buf;
	if(*c1==NULL) 
	{
		*c1=(char*)malloc(sizeof(char));
		strcpy(*c1,"");
	}
	if(c2==NULL) 
	{
		c2=(char*)malloc(sizeof(char));
		strcpy(c2,"");
	}
	l1=strlen(*c1);
	l2=strlen(c2);
	l=l1+l2;
	buf=(char*)malloc(l*sizeof(char));
	strcpy(buf,*c1);
	strcat(buf,c2);
	*c1=buf;
	return l;
}
int spaceconnect(char**c1,char*c2)
{
	int l1,l2,l=0;
	char*buf;
	if(*c1==NULL) 
	{
		*c1=(char*)malloc(sizeof(char));
		strcpy(*c1,"");
	}
	if(c2==NULL) 
	{
		c2=(char*)malloc(sizeof(char));
		strcpy(c2,"");
	}
	l1=strlen(*c1);
	l2=strlen(c2);
	l=l1+l2+1;
	buf=(char*)malloc(l*sizeof(char));
	strcpy(buf,*c1);
	strcat(buf," ");
	strcat(buf,c2);
	*c1=buf;
	return l;
}
int lineconnect(char**c1,char*c2)
{
	int l1,l2,l=0;
	char*buf;
	if(*c1==NULL) 
	{
		*c1=(char*)malloc(sizeof(char));
		strcpy(*c1,"");
	}
	if(c2==NULL) 
	{
		c2=(char*)malloc(sizeof(char));
		strcpy(c2,"");
	}
	l1=strlen(*c1);
	l2=strlen(c2);
	l=l1+l2+1;
	buf=(char*)malloc(l*sizeof(char));
	strcpy(buf,*c1);
	strcat(buf,"\n");
	strcat(buf,c2);
	*c1=buf;
	return l;
}
char*newtemp()
{
	char*n=NULL;
	char*nt=NULL;
	nt=(char*)malloc(4*sizeof(char));
	n=(char*)malloc(3*sizeof(char));
	strcpy(nt,"t");
	itoa(currenttemp,n,10);
	currenttemp++;
	strcat(nt,n);
	return nt;
}
char*newlabel(char**l)
{
	char*n=NULL;
	char*nl=NULL;
	nl=(char*)malloc(10*sizeof(char));
	n=(char*)malloc(3*sizeof(char));
	strcpy(nl,"Label L");
	itoa(currentlabel++,n,10);
	strcat(nl,n);
	*l=(char*)malloc(4*sizeof(char));
	strcpy(*l,"L");
	strcat(*l,n);
	return nl;
}
void newline()
{
	char*n=NULL;
	char*nl=NULL;
	nl=(char*)malloc(5*sizeof(char));
	n=(char*)malloc(4*sizeof(char));
	itoa(currentline++,n,10);
	strcpy(nl,n);
	strcat(nl,")");
	lineconnect(&c,nl);
}

⌨️ 快捷键说明

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