自制编译器:后端代码生成(一)

本文探讨编译器后端如何将语法树转换为虚拟机的机器码,介绍后端架构与关键数据结构,包括genCode方法、Class文件生成、局部变量表槽映射等。同时,详述了从classdef到memberfundeclare等节点的代码生成过程,强调了在expr的genCode中保持栈顶元素作为返回值的约定。
摘要由CSDN通过智能技术生成


后端早就已经弄的差不多了,因为学校论文的事情耽搁的比较久,一直到现在才发博客。

所谓的编译器后端的作用就是将语法树翻译成目标机器码。所谓目标机器码,考虑到直接翻译成具体平台(如X86,ARM等)过于复杂,因此先设计一个虚拟机,并翻译成这个虚拟机的机器码。

对于虚拟机以及其指令格式可参考这篇文章http://blog.csdn.net/roger__wong/article/details/8947720,如何去尝试实现这个虚拟机是在我的另外一个系列的博客里进行论述。


本篇文章从以下是那个方面来论述:后端架构与关键数据结构、节点翻译方式。

1、后端架构和关键数据结构

后端接受前端的语法树作为输入,对于其每一个节点根据节点类型的不同产生不同的代码。但在实现过程中为了简单方便,我并没有把后端抽象出一个单独的模块,而是在语法树每一个节点的基础上增加了一个genCode方法,通过调用这个方法来生成该节点及其所有孩子节点(通过递归)的代码。

其次编译器后端直接生成Class文件(文件结构也在上文提到的博客中有说明),程序中后端首先构造一个ClassOfClass的实体,然后再调用此类的方法生成Class文件:

public class ClassOfClass {
	public static int isPublic=1;
	public static int isStatic=2;
	public ArrayList<field> fields;
	public ArrayList<function> functions;
	public ArrayList<String> constPool;
	public String name;
	public ClassOfClass()
	{
		constPool=new ArrayList<String>();
		fields=new ArrayList<field>();
		functions=new ArrayList<function>();
		
	}
	public void WriteClassFile(String path)
	{
		try {
			PrintWriter pw=new PrintWriter(new FileOutputStream(path));
			pw.println(name);
			pw.println(fields.size());
			for(field f:fields)
			{
				pw.println(f.toString());
			}
			pw.println(functions.size());
			for(function f:functions)
			{
				pw.println(f.toString());
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
其中field结构:

public class field {
	public int head;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值