【编译】北京理工大学BITMINICC lab8+lab7 中间代码 & 目标代码生成

实验思路

  依然是在遍历抽象语法树的时候生成中间代码。
  因为四元式形式和 x86 汇编形式相差较多,为了相对简便的进行目标代码生成,因此中间代码构造时选择与 x86 汇编相近的形式。并且尽量使用伪指令,减少对代码的翻译。

四元式定义

  采用(operator,operand1,operand2,result)的基本形式。对于程序控制流的if 等语句,不使用断点和jmp。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

声明并归置临时变量

  在中间代码生成中使用的局部变量,必须在过程开始的时刻定义,因此需要在使用临时 变量时,将声明加入四元式中,并且在 visitor 遍历语法树时生成的局部变量放到当前临时变 量过程声明的下方,如下图所示。
在这里插入图片描述
  对 ICPrinter 进行打印顺序的改写,对一个函数首先打印参数四元式 (param,NULL,NULL,NULL)和局部变量定义四元式(var,NULL,NULL,NULL)部分,让局部变量的定义紧跟函数声明,最终在中间代码生成这样的格式。
函数声明后紧跟局部变量定义

数组的值访问和下标访问

  当数组在赋值语句右边时,需要知道ArrayAccess本身的值,但是如果在数组在左边,那么我们需要知道它的下标或者偏移量。
如代码中:A[i] = A[i + 1],对于右边我们想知道A[i + 1]是多少,但是左边我们想知道i是多少。

目标代码生成

  由于四元式在经过重排顺序后已经是正确汇编控制流代码了,在目标代码生成中,只需将每行的四元式翻译成对应的汇编代码即可。

  1. 全局整形变量, 判断当前变量是否有初始值,如果下一个 Quat 的操作符 是’= ’,那么当前变量有初始值,否则没有初始化为 0。
      有初值:(var,int,NULL,x) (=,1,NULL,x) -> x DWORD 1
      无初值:(var,int,NULL,x) -> x DWORD 0
  2. 字符串变量,需要去掉在字符串中显式定义的’\n ’,然后在字符串末 尾添加 0ah 作为换行符,否则会在运行时错误的输出不能解析的\n 换行符。也 要注意对仅为换行符的字符串的替换,不定义空字符串。
      有内容: (var,”string\n”,NULL,String1) ->
      String1 db“stirng”,0ah,0
      仅为换行符: (var,”\n”,NULL,String2) ->
      String2 db 0ah,0
  3. 数组声明 首先计算数组限定长度,因为 int 占 4 个字节,因此算出数组长度后×4 获 得数组大小。
      (array,int,[5, 5],A) -> A 100 DWORD DUP(0)
  4. 函数声明 需要在函数入口处声明参数,再检索到 FUNC_BEGIN 的四元式后, 向下检索连续的 param 的四元式,那么这些就是当前过程的参数列表。
      (FUNC_BEGIN,int,NULL,func)
      (param,int,NULL,x)
      -> func PROC x :DWORD
  5. 局部变量定义,在相同的声明函数下,需要打上 local 标签,并且汇编代码 有不同的声明形式。
      (var,int,NULL,x) -> local x :DWORD
      (array,int,[5, 5],A) -> local A[100]:DWORD
  6. 调用函数,先把当前参数栈内的所有参数取出,然后附加到 Invoke 伪指 令后面,通过 invoke 伪指令调用子过程。
      (arg,NULL,NULL,23) (invoke,f,NULL,t1) -> invoke f,23
  7. 四则运算示例在这里插入图片描述
  8. 控制流 所有控制流和逻辑表达式都使用伪指令解决,能省则省。
    在这里插入图片描述

代码:

ExampleICprinter:


package bit.minisys.minicc.icgen;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import bit.minisys.minicc.parser.ast.*;

public class ExampleICPrinter {
   
	private  List<Quat> quats;
	private HashSet<String> nameSpace;

	public ExampleICPrinter(List<Quat> quats) {
   
		this.quats = quats;
	}
	public void print(String filename) {
   

		nameSpace = new HashSet<>();

		StringBuilder sb = new StringBuilder();
		for (int i = 0;i < quats.size();++i) {
   
			Quat quat = quats.get(i);
			String op = quat.getOp();
			String res = astStr(quat.getRes());
			String opnd1 = astStr(quat.getOpnd1());
			String opnd2 = astStr(quat.getOpnd2());
			if(op.equals("FUNC_BEGIN")) {
   
				nameSpace.clear();
				sb.append("("+op+","+ opnd1+","+opnd2 +"," + res+")\n");

				//打印Var 和 param
				for(int j = i + 1;j < quats.size();++j) {
   
					Quat quat1 = quats.get(j);
					String op1 = quat1.getOp();
					String res1 = astStr(quat1.getRes());
					String opnd11 = astStr(quat1.getOpnd1());
					String opnd21 = astStr(quat1.getOpnd2());
					if(op1.equals("var") && !nameSpace.contains(res1)) {
   
						sb.append("(" + op1 + "," + opnd11 + "," + opnd21 + "," + res1 + ")\n");
						nameSpace.add(res1);
					} else if(op1.equals("param")) {
   
						sb.append("(" + op1 + "," + opnd11 + "," + opnd21 + "," + res1 + ")\n");
					}
					if(op1.equals("FUNC_END")) {
   
						break;
					}
				}

				//打印非Var
				for(int j = i + 1;j < quats.size();++j) {
   
					Quat quat1 = quats.get(j);
					String op1 = quat1.getOp();
					String res1 = astStr(quat1.getRes());
					String opnd11 = astStr(quat1.getOpnd1());
					String opnd21 = astStr(quat1.getOpnd2());
					if(!op1.equals("var") && !op1.equals("param")) {
   
						sb.append("(" + op1 + "," + opnd11 + "," + opnd21 + "," + res1 + ")\n");
					}
					if(op1.equals("FUNC_END")) {
   
						i = j;
						break;
					}
				}

			}
			else sb.append("("+op+","+ opnd1+","+opnd2 +"," + res+")\n");
		}
		// write
		try {
   
			FileWriter fileWriter = new FileWriter(new File(filename));
			fileWriter.write(sb.toString());
			fileWriter.close();
		} catch (IOException e) {
   
			e.printStackTrace();
		}
	}
	
	private String astStr(ASTNode node) {
   
		if (node == null) {
   
			return "";
		}else if (node instanceof ASTIdentifier) {
   
			return ((ASTIdentifier)node).value;
		}else if (node instanceof TemporaryValue) {
   
			return ((TemporaryValue)node).name();
		}else if (node instanceof DescribeNode){
   
			return node.getType();
		} else if (node instanceof ASTVariableDeclarator) {
   
			return ((ASTVariableDeclarator) node).getName();
		} else if (node instanceof ASTIntegerConstant) {
   
			return ((ASTIntegerConstant)node).value.toString();
		}  else if (node instanceof ASTStringConstant) {
   
			return ((ASTStringConstant)node).value;
		} else {
   
			return "";
		}
	}
}

ExampleIBuilder:

package bit.minisys.minicc.icgen;

import java.util.*;

import bit.minisys.minicc.parser.ast.*;
import bit.minisys.minicc.pp.internal.D;
import bit.minisys.minicc.pp.internal.I;
import bit.minisys.minicc.pp.internal.Q;
import bit.minisys.minicc.pp.internal.X;
import bit.minisys.minicc.semantic.XYSymbolTable;
import org.python.antlr.op.In;


public class ExampleICBuilder implements ASTVisitor{
   
	private XYSymbolTable globalTable;
	private XYSymbolTable localTable;
	private String declarationType;
	private String identifierOfArray;
	private Map<ASTNode, ASTNode> map;

	private List<Quat> quats;
	private int tmpId,StringId;
	private LinkedList <String> equalOps;

	public ExampleICBuilder() {
   
		globalTable = new XYSymbolTable();
		map = new HashMap<ASTNode, ASTNode>();
		localTable = globalTable;
		quats = new LinkedList<>();
		tmpId = 0;
		StringId = 0;

		equalOps = new LinkedList<>();
		equalOps.add("+="); equalOps.add("-="); equalOps.add("#="); equalOps.add("/=");
		equalOps.add("%="); equalOps.add("&="); equalOps.add("|="); equalOps.add(">>=");
		equalOps.add("<<=");

	}

	public List<Quat> getQuats() {
   
		return quats;
	}

	private String getType(List<ASTToken> specifiers) {
   
		StringBuilder type = new StringBuilder();
		if( specifiers != null ){
   
			for (ASTToken specifier : specifiers) {
   
				type.append(specifier.value);
			}
		}
		return type.toString();
	}

    //第一步进入CU
	@Override
	public void visit(ASTCompilationUnit program) throws Exception {
   

        program.scope = localTable;

		for (ASTNode node : program.items) {
   
			if(node instanceof ASTFunctionDefine) {
   
				visit((ASTFunctionDefine) node);
			}else if(node instanceof ASTDeclaration) {
   
				visit((ASTDeclaration)node);
			}
		}


	}

    //一个声明语句 (array, int , x , [3,2])
	@Override
	
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值