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

📄 codegen.c

📁 用LEX和YACC实现词法分析和语法分析。剩余部分为C语言编写。
💻 C
📖 第 1 页 / 共 2 页
字号:
	fprintf(inter_code,"\tCMP\tAX , BX\n");
	fprintf(inter_code,"\tJNE\tLabel%d\n",label_num);
	fprintf(inter_code,"\tMOV\tAX , 0\n");
	fprintf(inter_code,"\tPUSH\tAX\n");
	fprintf(inter_code,"\tJMP\tLabel%d\n",label_num+1);
	fprintf(inter_code,"Label%d:",label_num);
	fprintf(inter_code,"\tMOV\tAX , 1\n");
	fprintf(inter_code,"\tPUSH\tAX\n");
	fprintf(inter_code,"Label%d:",label_num+1);
	label_num += 2;
}

void ori(void)
{
	fprintf(inter_code,"\tPOP\tBX\n");
	fprintf(inter_code,"\tPOP\tAX\n");
	fprintf(inter_code,"\tOR\tAX , BX\n");
	fprintf(inter_code,"\tPUSH\tAX\n");
}

void pop(void)
{
	fprintf(inter_code,"\tPOP\tAX\n");
}

void ret(int r,char * name)
{
	int addr = 0;
	FunEntry * pEntry = malloc(sizeof(FunEntry));
	if(r){//if the function has a return value
		fprintf(inter_code,"\tPOP\tAX\n");//get the return value from the top of the stack
		pEntry = Lookup_Fun(name);
		addr = pEntry ->ret_val;
		fprintf(inter_code,"\tPUSH\tBP\n");
		fprintf(inter_code,"\tADD\tBP , %d\n",addr);
		fprintf(inter_code,"\tMOV\tSS:[BP] , AX\n");
		fprintf(inter_code,"\tPOP\tBP\n");
	}
	fprintf(inter_code,"\tMOV\tSP , BP\n");//release local parameters
	fprintf(inter_code,"\tPOP\tBP\n");//pop bp
	fprintf(inter_code,"\tPOP\tDX\n");
	fprintf(inter_code,"\tPOP\tCX\n");
	fprintf(inter_code,"\tPOP\tBX\n");
	fprintf(inter_code,"\tPOP\tAX\n");

	fprintf(inter_code,"\tRET\n");		
}

void stn(char *name)
{
	if(pTable ->nestlevel == 0){
		fprintf(inter_code,"\tPOP\tBX\n");//get the value from the top of the stack
		fprintf(inter_code,"\tPOP\tAX\n");//get the actual address at STACK segment
		fprintf(inter_code,"\tMOV\tDS:[AX] , BX\n");//load value
		fprintf(inter_code,"\tPUSH\tBX\n");
	}
	else{
		fprintf(inter_code,"\tPOP\tBX\n");//get the value from the top of the stack
		fprintf(inter_code,"\tPOP\tAX\n");//get the actual address at STACK segment
		fprintf(inter_code,"\tPUSH\tBP\n");
		fprintf(inter_code,"\tMOV\tBP , AX\n");
		fprintf(inter_code,"\tMOV\tSS:[BP] , BX\n");//load value
		fprintf(inter_code,"\tPOP\tBP\n");
		fprintf(inter_code,"\tPUSH\tBX\n");
	}
}

void subi(void)
{
	fprintf(inter_code,"\tPOP\tDX\n");
	fprintf(inter_code,"\tPOP\tCX\n");
	fprintf(inter_code,"\tSUB\tCX , DX\n");
	fprintf(inter_code,"\tPUSH\tCX\n");
}

void ujp(char *label)
{
	fprintf(inter_code,"\tJMP\t%s\n",label);
}

void write(void)
{
	fprintf(inter_code,"\tWRITE\tproc\tfar\n");//to code file
	fprintf(inter_code,"\tPUSH\tAX\n");
	fprintf(inter_code,"\tPUSH\tBX\n");
	fprintf(inter_code,"\tPUSH\tCX\n");
	fprintf(inter_code,"\tPUSH\tDX\n");	
	fprintf(inter_code,"\tPUSH\tBP\n");
	fprintf(inter_code,"\tMOV\tBP , SP\n");//begin to accept local variables
	fprintf(inter_code,"\tMOV\tBX , [BP + 14]\n");
	fprintf(inter_code,"\tMOV\tCX , 10000\n");
	fprintf(inter_code,"\tCMP\tBX , CX\n");
	fprintf(inter_code,"\tJL\tw_label1\n");
	fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
	fprintf(inter_code,"w_label1:\n");
	fprintf(inter_code,"\tMOV\tCX , 1000\n");
	fprintf(inter_code,"\tCMP\tBX , CX\n");
	fprintf(inter_code,"\tJL\tw_label2\n");
	fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
	fprintf(inter_code,"w_label2:\n");
	fprintf(inter_code,"\tMOV\tCX , 100\n");
	fprintf(inter_code,"\tCMP\tBX , CX\n");
	fprintf(inter_code,"\tJL\tw_label3\n");
	fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
	fprintf(inter_code,"w_label3:\n");
	fprintf(inter_code,"\tMOV\tCX , 10\n");
	fprintf(inter_code,"\tCMP\tBX , CX\n");
	fprintf(inter_code,"\tJL\tw_label4\n");
	fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
	fprintf(inter_code,"w_label4:\n");
	fprintf(inter_code,"\tMOV\tCX , 1\n");
	fprintf(inter_code,"\tCALL\tWRITE_SUB\n");
	fprintf(inter_code,"\tMOV\tSP , BP\n");//release local parameters
	fprintf(inter_code,"\tPOP\tBP\n");//pop bp
	fprintf(inter_code,"\tPOP\tDX\n");
	fprintf(inter_code,"\tPOP\tCX\n");
	fprintf(inter_code,"\tPOP\tBX\n");
	fprintf(inter_code,"\tPOP\tAX\n");
	fprintf(inter_code,"\tRET\n");		
	fprintf(inter_code,"\tWRITE\tendp\n\n");

	fprintf(inter_code,"\tWRITE_SUB\tproc\tnear\n");
	fprintf(inter_code,"\tMOV\tAX , BX\n");
	fprintf(inter_code,"\tMOV\tDX , 0\n");
	fprintf(inter_code,"\tDIV\tCX\n");
	fprintf(inter_code,"\tMOV\tBX , DX\n");
	fprintf(inter_code,"\tMOV\tDL , AL\n");
	fprintf(inter_code,"\tADD\tDL , '0'\n");
	fprintf(inter_code,"\tMOV\tAH , 02h\n");
	fprintf(inter_code,"\tINT\t21h\n");
	fprintf(inter_code,"\tRET\n");
	fprintf(inter_code,"\tWRITE_SUB\tendp\n\n");
}

void CodeGen_TreeNode(TreeNode * node)
{
	TreeNode * temp;
	int count;
	while (node != NULL) 
	{
	switch(node ->nodekind){
	case Dec:
		switch(node-> kind.dec){
		case FunDecK:
			//	more code to be filled
			break;
		case FunDefK:
			Fun = node;
			count = 0;
			temp = node-> child[0];
			while(temp)
			{
				count ++;
				temp = temp-> sibling;
			}
			ent(node ->attr.name, count, (node -> type != Void)? TRUE:FALSE);
			temp = node -> child[0];	// Param
			if(temp)
				CodeGen_TreeNode(temp);
			CodeGen_TreeNode(node ->child[1]);	// comp_dec
			if(node -> type == Void)
				ret(FALSE,node ->attr.name);
			else
				ret(TRUE,node ->attr.name);
			leave(node ->attr.name);
			break;
		case VarK:
			temp = node -> child[0];
			if(node ->kind.exp == NumK)
			while(temp)
			{
				if(temp -> nodekind == Stmt)	// AssignK ini
						VarDec_ini(temp ->child[0] ->attr.name, temp->child[1]->attr.val.i);
				else
				{
					if(temp ->child[0] == NULL)
						VarDec(temp ->attr.name);	
					else
						ArrDec(temp ->attr.name, temp ->child[0] ->attr.val.i);
				}
				temp = temp ->sibling;
			}
			break;
		case CompK:
			pTable = node ->attr.table;
			temp = node ->child[0];
			if(temp)	// Dec
				CodeGen_TreeNode(temp);
			temp = node ->child[1];
			if(temp)	//stmt
				CodeGen_TreeNode(temp);
			compound_exit();
			break;
		case ParamK:
			break;
		default:
			break;
		}
		break;
	case Stmt:
		switch(node ->kind.stmt){
		case IfK:
			temp = node ->child[0];
			GenLabel(pTable ->lab1);
			GenLabel(pTable ->lab2);
			if(temp ->kind.exp == NumK)	// optimize
			{
				if(temp -> attr.val.i == 0)
					ujp(pTable ->lab1);
			}
			else 
			{
				CodeGen_TreeNode(temp);
				fjp(pTable ->lab1);
			}
			pTable = node ->child[1] ->attr.table;
			if(node ->child[1])
				CodeGen_TreeNode(node ->child[1]);
			
			if(node ->child[2]) 
				ujp(pTable ->lab2);
			lab(pTable ->lab1);
			if(node ->child[2]) 
			{
				pTable = node ->child[2] ->attr.table;
				CodeGen_TreeNode(node ->child[2]);
				lab(pTable ->lab2);
			}
			break;
		case WhileK:
			GenLabel(pTable ->lab1);
			GenLabel(pTable ->lab2);
			lab(pTable ->lab1);
			temp = node ->child[0];
			if(temp ->kind.exp == NumK)	// optimize
			{
				if(temp ->attr.val.i == 0)
					ujp(pTable ->lab2);
			}
			else
			{
				CodeGen_TreeNode(temp);
				fjp(pTable ->lab2);
			}
			if(node -> child[1])
				CodeGen_TreeNode(node -> child[1]);
			ujp(pTable ->lab1);
			lab(pTable ->lab2);
			break;
		case CallK:
			mst(node -> attr.name);
			temp = node ->child[0];
			CodeGen_TreeNode(temp);
			cup(node ->attr.name, count);
			while(temp)		// Param
			{
				pop();
				temp = temp -> sibling;
			}
			
			if(node ->call_stmt == 1)
				pop();
			break;
		case ReturnK:
			temp = node -> child[0];
			if(temp)
			{
				CodeGen_TreeNode(temp);
				ret(TRUE,pTable ->funEntry ->name);
			}
			else ret(FALSE,pTable ->funEntry ->name);
			break;
		case BreakK:
			ujp(pTable ->parent ->lab2);
			break;
        case ContinueK:
			ujp(pTable ->parent ->lab1);			
			break;
		case AssignK:
			temp = node -> child[0];
			lda(temp ->attr.name);
			if(temp -> child[0])  //Arr
			{
				CodeGen_TreeNode(temp -> child[0]);
				ixa_elem_size();
			}
			CodeGen_TreeNode(node -> child[1]);
			stn(node -> child[0] ->attr.name);
			pop();
			break;
		default:
			break;
		}
		break;
	case Exp:
		switch(node -> kind.exp){
		case OpK:
			if(node -> child[0])
				CodeGen_TreeNode(node -> child[0]);
			if(node -> child[1])
				CodeGen_TreeNode(node -> child[1]);
			switch(node -> attr.op) {
			case PLUS:	adi();		break;
			case SUB:	subi();		break;
			case MUT:	multi();	break;
			case DIV:	divi();		break;
			case EQ:	equi();		break;
			case NEQ:	neqi();		break;
			case LE:	lorei();	break;
			case GE:	gorei();	break;
			case LT:	less();		break;
			case GT:	greater();	break;
			case AND:	andi();		break;
			case OR:	ori();		break;
			default:	yyerror("Unknown Operator!");
						break;
			}
			break;
		case FnumK:
			//  more code to be filled
			break;
		case NumK:
			ldc(node -> attr.val.i);
			break;
		case CharK:
//			ldc(node -> attr.val.i);
			break;
		case IdK:
			lod(node -> attr.name);
			break;
		case NotK:
			break;
		default:
			break;
		}
		break;
	default:
		break;
	}
    node = node->sibling;
	}
}

⌨️ 快捷键说明

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