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

📄 generate.java.svn-base

📁 北航编译原理课程设计成果——一个扩充的C0文法编译器
💻 SVN-BASE
字号:
package cn.edu.buaa.scse.liyi.test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Vector;

/**
 * 
 * @author liyi
 */
public class Generate
{
	private Vector<Constpair> topconst=null;
	public Vector<String> topvar=null;
	private LinkedList<Function> funclist=null;
	public Vector<String> assembler=null;		//汇编输出
	private Function ff=null;					//当前函数
	private int pcount=0;						//参数计数
	private String condition=null;
	public Vector<String> st=null;				//printf用字符串表
	private int stc=0;							//字符串计数
	private String path;
	public String warn=null;
	
	public Generate(Vector<Constpair> topconst,Vector<String> topvar,LinkedList<Function> funclist,String path)
	{
		this.funclist=funclist;
		this.topconst=topconst;
		this.topvar=topvar;
		this.assembler=new Vector<String>();
		this.st=new Vector<String>();
		this.path=path;
		st.add("@_IO_DATA dword ?");
		st.add("@_IO_STR byte \"%d\", 0");
		st.add("@_NEWLINE byte 0dh,0ah,0");
	}
	//给出该参数或变量的地址表示,若为全局变量则返回原字符串
	private String findadr(String ss)
	{
		Integer i;
		i=ff.pmap.get(ss);			  //在参数表里找
		if(i!=null)
		{
			return "[ebp + "+i+" ]";
		}
		i=ff.vmap.get(ss);
		if(i!=null)
		{					 //再在变量表里找
			return "[ebp - "+i+" ]";
		}
		if(ss.equals("@teax"))
		{		  //若去函数调用的返回值怎译为eax
			return "eax";
		}
		
		if(ss.charAt(0)>='0'&&ss.charAt(0)<='9')
		{	//当为全局常量时返回原数字
			return ss;					   
		}
		else
		{
			return "$"+ss;					//当为全局变量时直接返回加$的字符串
		}
											  
	}

	public void Generate()
	{
		FileWriter fw=null;


		for (Function func:this.funclist)
		{	 //遍历所有函数
			ff=func;							//ff存当前函数,以为后面方法调用从中获得数据
			int space=(ff.vmap.size()+4)*4;   //算出函数调用需要的保留区大小,存为space
			assembler.add("@f"+func.name+":");  //写入汇编函数头
			assembler.add("push ebp");
			assembler.add("mov ebp,esp");
			assembler.add("sub esp,"+space);

			for (Quadruple quadruple:func.fourlist)
			{	  //遍历该函数的所有四元式
				switch (quadruple.op)
				{				 //根据四元式的操作符op,转入相应的方法去添加对应的汇编代码
					case Compile.ADD:
						add(quadruple);
						break;
					case Compile.SUB:
						sub(quadruple);
						break;
					case Compile.MUL:
						mul(quadruple);
						break;
					case Compile.DIV:
						div(quadruple);
						break;
					case Compile.MOV:
						mov(quadruple);
						break;
					case Compile.CALL:
						call(quadruple);
						break;
					case Compile.CMP:
						cmp(quadruple);
						break;
					case Compile.CONDITION:
						condition(quadruple);
						break;
					case Compile.J:
						j(quadruple);
						break;
					case Compile.JFALSE:
						jfalse(quadruple);
						break;
					case Compile.PRINTF:
						print(quadruple);
						break;
					case Compile.PUSHPARA:
						pushpara(quadruple);
						break;
					case Compile.RETURN:
						ret(quadruple);
						break;
					case Compile.SCANF:
						scan(quadruple);
						break;
					case Compile.STAMP:
						stamp(quadruple);
						break;
					}
			}
			if (func.fourlist.getLast().op!=Compile.RETURN)
			{	//检查是否有返回语句,若没有自动添加,并向用户发出警告
				warn="Warning:Return Missing!";
				assembler.add("mov esp,ebp");
				assembler.add("pop ebp");
				assembler.add("ret");
			}
		}

		File ofile=new File(path);		//汇编输出文件
		try
		{
			ofile.createNewFile();
		}
		catch (IOException exc)
		{
		}
		try
		{
			fw=new FileWriter(ofile);
			fw.write(".386\n");
			fw.write(".MODEL FLAT\n");
			fw.write("includelib msvcrt.lib\n");
			fw.write("puts proto C\n");
			fw.write("printf proto C\n");
			fw.write("scanf proto C\n");
			fw.write(".STACK 4096\n");
			fw.write(".DATA\n");
			for(String s:this.topvar)
			{
				fw.write("$"+s+" DWORD 0\n");
			}
			for(String s:st)
			{
				fw.write(s+'\n');
			}
			
			fw.write(".CODE\n");
			for(String s:assembler)
			{
				fw.write(s+'\n');
			}
			fw.write("_main:\n");
			fw.write("jmp near ptr @fmain\n");
			fw.write("end _main\n");
			fw.flush();
		}
		catch(FileNotFoundException ex)
		{
		}
		catch(IOException ex)
		{
		}

	}
//加法操作
	private void add(Quadruple quadruple)
	{
		assembler.add("mov eax, "+findadr(quadruple.first));
		assembler.add("add eax, "+findadr(quadruple.last));
		assembler.add("mov "+findadr(quadruple.result)+", eax");
	}
//函数调用操作
	private void call(Quadruple quadruple)
	{
		assembler.add("call "+"@f"+quadruple.first);
		assembler.add("add esp, "+(pcount*4));
		pcount=0;
	}
//比较操作
	private void cmp(Quadruple quadruple)
	{
		assembler.add("mov eax, "+findadr(quadruple.first));
		assembler.add("cmp eax, "+findadr(quadruple.last));
	}
//把应满足的条件存入condition字段,使后面的跳转语句可以确定其条件
	private void condition(Quadruple quadruple)
	{
		condition=quadruple.first;
	}
//除法操作
	private void div(Quadruple quadruple)
	{
		assembler.add("mov eax, "+findadr(quadruple.first));
		assembler.add("cdq");
		assembler.add("mov ecx, "+findadr(quadruple.last));
		assembler.add("idiv ecx");
		assembler.add("mov "+findadr(quadruple.result)+", eax");
	}
//无条件跳转操作
	private void j(Quadruple quadruple)
	{
		assembler.add("jmp near ptr @l"+quadruple.first);
	}
//当不满足condition时跳转的操作
	private void jfalse(Quadruple quadruple)
	{
		switch(new Integer(condition).intValue())
		{
			case Lex.EE:
				assembler.add("jne near ptr @l"+quadruple.first);
				break;
			case Lex.NE:
				assembler.add("je near ptr @l"+quadruple.first);
				break;
			case Lex.G:
				assembler.add("jle near ptr @l"+quadruple.first);
				break;
			case Lex.L:
				assembler.add("jge near ptr @l"+quadruple.first);
				break;
			case Lex.GE:
				assembler.add("jl near ptr @l"+quadruple.first);
				break;
			case Lex.LE:
				assembler.add("jg near ptr @l"+quadruple.first);
				break;
		}
		condition=null;
	}
//赋值操作
	private void mov(Quadruple quadruple)
	{
		assembler.add("mov eax, "+findadr(quadruple.first));
		assembler.add("mov "+findadr(quadruple.result)+", eax");
	}
//乘法操作
	private void mul(Quadruple quadruple)
	{
		assembler.add("mov eax, "+findadr(quadruple.first));
		assembler.add("mov ecx, "+findadr(quadruple.last));
		assembler.add("imul ecx");
		assembler.add("mov "+findadr(quadruple.result)+", eax");
	}
//打印操作
	private void print(Quadruple quadruple)
	{
		String strname="@str"+stc;
		switch (new Integer(quadruple.result))
		{
			case 0:
				// string
				st.add(strname+" byte "+quadruple.first+",0");
				stc++;
				assembler.add("lea eax, "+strname);
				assembler.add("push eax");
				assembler.add("call puts");
				assembler.add("add esp, 4");
				break;
			case 1:
				// integer
				assembler.add("mov eax,"+findadr(quadruple.last));
				assembler.add("push eax");
				assembler.add("lea eax, @_IO_STR");
				assembler.add("push eax");
				assembler.add("call printf");
				assembler.add("add esp, 8");
				break;
			case 2:
				// both
				/*
				st.add(strname+" BYTE "+four.first+",0");
				stc++;
				assembler.add("mov eax,"+findadr(four.last));
				assembler.add("push eax");
				assembler.add("lea eax, "+strname);
				assembler.add("push eax");
				assembler.add("call printf");
				assembler.add("add esp, 8");
				 */
				st.add(strname+" BYTE "+quadruple.first+",0");
				stc++;
				assembler.add("lea eax, "+strname);
				assembler.add("push eax");
				assembler.add("call puts");
				assembler.add("add esp, 4");

				assembler.add("mov eax, "+findadr(quadruple.last));
				assembler.add("push eax");
				assembler.add("lea eax, @_IO_STR");
				assembler.add("push eax");
				assembler.add("call printf");
				assembler.add("add esp, 8");
				break;
		}
		assembler.add("lea eax,@_NEWLINE");
		assembler.add("push eax");
		assembler.add("call printf");
		assembler.add("add esp, 4");
	}
//推参数操作
	private void pushpara(Quadruple quadruple)
	{
		assembler.add("push "+findadr(quadruple.first));
		pcount++;
	}
//返回操作
	private void ret(Quadruple quadruple)
	{
		if (quadruple.first != null)
		{
			assembler.add("mov eax, "+findadr(quadruple.first));
		}
		assembler.add("mov esp,ebp");
		assembler.add("pop ebp");
		assembler.add("ret");
	}
//读取操作
	private void scan(Quadruple quadruple)
	{
		assembler.add("lea eax, @_IO_DATA");
		assembler.add("push eax");
		assembler.add("lea eax, @_IO_STR");
		assembler.add("push eax");
		assembler.add("call scanf");
		assembler.add("add esp, 8");

		assembler.add("mov eax, @_IO_DATA");
		assembler.add("mov "+findadr(quadruple.first)+", eax");
	}
//标签
	private void stamp(Quadruple quadruple)
	{
		assembler.add("@l"+quadruple.first+" :");
	}
//减法操作
	private void sub(Quadruple quadruple)
	{
		assembler.add("mov eax, "+findadr(quadruple.first));
		assembler.add("sub eax, "+findadr(quadruple.last));
		assembler.add("mov "+findadr(quadruple.result)+", eax");
	}
}

⌨️ 快捷键说明

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