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

📄 codegenerator.java

📁 SkipOOMiniJOOL教学语言的编译器前端
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package edu.ustc.cs.minijool.parser;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BooleanLiteral;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.NullLiteral;
import org.eclipse.jdt.core.dom.NumberLiteral;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.internal.corext.dom.GenericVisitor;

public class CodeGenerator extends GenericVisitor {
	
	private PrintStream out;
	private List strs = new ArrayList();
	private int strIndex = 2;
	private List codes = new ArrayList();
	private List staticdata=new ArrayList();
	private int jumpNum = 2   ;//为跳转命名之用
	private int paraNum;
	
	private int stackPos = -4;//记录当前函数中局部变量在栈中的偏移
	private Map posTable=null;//存储变量与他的存储位置(String)之间的对应
	private Map type = new HashMap();//记录变量的类型
	private Map sposTable = new HashMap();//记录静态数据
	private Map stype  = new HashMap();
	
	private int classNum = 0;
	private int mainNum = 0;
	private Map methods = new HashMap();
	private MethodDeclaration now;
	
	public CodeGenerator(PrintStream out) {
		if(out != null) {
			this.out = out;
		} else {
			this.out = System.out;
		}
		posTable = new HashMap();
	}
	public void emitCode() {
		//字符串常量数据输出
		/*out.println(".text");
		out.println(".def	___main;	.scl	2;	.type	32;	.endef");
		int i=0;
		out.println("LC"+(i++)+":");
		out.println("\t.ascii \"%s\\12\\0\"");
		out.println("LC"+(i++)+":");
		out.println("\t.ascii \"%d\\12\\0\"");
		for(Iterator iter=strs.iterator();iter.hasNext();){
			out.println("LC"+(i++)+":");
			out.println("\t.ascii \""+(String)(iter.next())+"\\0\"");
		}
		*/
		
		//代码部分输出
		
		for(Iterator iter=codes.iterator();iter.hasNext();)
			out.println("\t"+iter.next());
		
//		静态数据部分输出
		for(Iterator iter=staticdata.iterator();iter.hasNext();)
			out.println("\t"+iter.next());
		
	}

	public boolean visit(Assignment a) {
		/*
		 * 将赋值语句右边的表达式值计算出后放入
		 */
		/*
		 * 检查赋值语句的左边的标识符是否已经定义(因为SimpleName中的
		 * 检查不到这个位置的标识符使用)
		 */
		if(!posTable.containsKey(((SimpleName)a.getLeftHandSide()).getIdentifier())){
			SemanticError.error_2_NoDeclaration(null,((SimpleName)a.getLeftHandSide()).getIdentifier());
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		a.getRightHandSide().accept(this);
		/*
		 * 检查赋值语句两边的类型是否相同
		 */
		if(!(a.getRightHandSide().getProperty("type").equals(type.get(((SimpleName)a.getLeftHandSide()).getIdentifier())))){
			SemanticError.error_12_AssignmentType(null);
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		/*
		 * 寻找赋值语句左边变量的存储位置
		 */
		String position = (String)posTable.get(((SimpleName)a.getLeftHandSide()).getIdentifier());
		//codes.add("movl	%eax, "+position);
		
		return false;
	}

	public boolean visit(Block b) {
		for(Iterator iter = b.statements().iterator();iter.hasNext();)
			((Statement)iter.next()).accept(this);
		return false;
	}

	public boolean visit(BooleanLiteral e) {
		int num = 0;
		if(e.booleanValue())
			num = 1;
		//codes.add("movl	$"+num+", %eax");
		e.setProperty("type","boolean");
		
		return false;
	}

	public boolean visit(ClassInstanceCreation e) {
		//TODO:Lab5
		return false;
	}

	public boolean visit(ExpressionStatement s) {
		s.getExpression().accept(this);
		
		return false;
	}

	public boolean visit(FieldAccess e) {
		//TODO:Lab5
		return false;
	}

	public boolean visit(FieldDeclaration d) {
		
		//assert d.getModifiers()==Modifier.STATIC;
		List l = d.fragments();
		/*for(Iterator iter = l.iterator();iter.hasNext();){
			VariableDeclarationFragment f = (VariableDeclarationFragment)iter.next();
			staticdata.add(".lcomm	_"+f.getName().getIdentifier()+", 32");
			sposTable.put(f.getName().getIdentifier(),"_"+f.getName().getIdentifier());
			stype.put(f.getName().getIdentifier(),d.getType().toString());
			
		}*/
		return false;
	}

	public boolean visit(IfStatement s) {
		s.getExpression().accept(this);
		/*
		 * 检查if语句中的判断表达式的类型是否为boolean
		 */
		if(!(s.getExpression().getProperty("type").equals("boolean"))){
			SemanticError.error_8_BooleanExpression(null);
			//System.err.println("Code generation halted");
			System.exit(0);
		}
		//codes.add("cmpl	$0, %eax");
		//codes.add("je L"+jumpNum);
		s.getThenStatement().accept(this);
		if(s.getElseStatement()!=null)
			//codes.add("jmp L"+(jumpNum+1));
		//codes.add("L"+(jumpNum++)+":");
		if(s.getElseStatement()!=null){
			s.getElseStatement().accept(this);
			//codes.add("L"+(jumpNum++)+":");
		}

		return false;
	}

	public boolean visit(InfixExpression e) {
		e.getLeftOperand().accept(this);//计算左边,值在eax中
		codes.add("movl %eax, %ecx");//将左表达式值移到ecx中
		e.getRightOperand().accept(this);//计算右边
		if (e.getOperator() == InfixExpression.Operator.PLUS) {
			//codes.add("addl %ecx, %eax");
			/*
			 * 检查操作符+的两边操作数是否为int类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","int");
		} else if (e.getOperator() == InfixExpression.Operator.MINUS) {
			codes.add("subl %ecx, %eax");
			/*
			 * 检查操作符-的两边操作数是否为int类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","int");
		} else if (e.getOperator() == InfixExpression.Operator.TIMES) {
			codes.add("imull %ecx, %eax");
			/*
			 * 检查操作符×的两边操作数是否为int类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","int");
		} else if (e.getOperator() == InfixExpression.Operator.DIVIDE) {
			//codes.add("movl %eax, %edx");
			//codes.add("movl %ecx, %eax");
			//codes.add("movl %edx, %ecx");
			//codes.add("cltd");
			//codes.add("idivl %ecx");
			/*
			 * 检查操作符/的两边操作数是否为int类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","int");
		} else if (e.getOperator() == InfixExpression.Operator.CONDITIONAL_AND){
			codes.add("and	%ecx, %eax");
			/*
			 * 检查操作符&&的两边操作数是否为boolean类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("boolean")||!e.getRightOperand().getProperty("type").equals("boolean")){
				SemanticError.error_11_CondTypes(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","boolean");
		} else if (e.getOperator() == InfixExpression.Operator.CONDITIONAL_OR){
			//codes.add("or	%ecx, %eax");
			/*
			 * 检查操作符||的两边操作数是否为boolean类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("boolean")||!e.getRightOperand().getProperty("type").equals("boolean")){
				SemanticError.error_11_CondTypes(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","boolean");
		} else if (e.getOperator() == InfixExpression.Operator.EQUALS){
			//codes.add("cmpl	%ecx, %eax");
			//codes.add("je	L"+jumpNum);
			//codes.add("movl	$0, %eax");
			//codes.add("jmp L"+(jumpNum+1));
			//codes.add("L"+(jumpNum++)+":");
			//codes.add("movl	$1, %eax");
			//codes.add("L"+(jumpNum++)+":");
			/*
			 * 检查操作符==的两边操作数类型是否相同
			 */
			if(!e.getLeftOperand().getProperty("type").equals(e.getRightOperand().getProperty("type"))){
				SemanticError.error_10_EqConformingTypes(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","boolean");
		} else if (e.getOperator() == InfixExpression.Operator.GREATER){
			
			//codes.add("cmpl	%ecx, %eax");
			//codes.add("jg	L"+jumpNum);
			//codes.add("movl	$0, %eax");
			//codes.add("jmp L"+(jumpNum+1));
			//codes.add("L"+(jumpNum++)+":");
			//codes.add("movl	$1, %eax");
			//codes.add("L"+(jumpNum++)+":");
			/*
			 * 检查操作符>的两边操作数是否为int类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
				
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			
			e.setProperty("type","boolean");
		} else if (e.getOperator() == InfixExpression.Operator.GREATER_EQUALS){
			//codes.add("cmpl	%ecx, %eax");
			//codes.add("jge	L"+jumpNum);
			//codes.add("movl	$0, %eax");
			//codes.add("jmp L"+(jumpNum+1));
			//codes.add("L"+(jumpNum++)+":");
			//codes.add("movl	$1, %eax");
			//codes.add("L"+(jumpNum++)+":");
			/*
			 * 检查操作符>=的两边操作数是否为int类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","boolean");
		} else if (e.getOperator() == InfixExpression.Operator.LESS){
			
			//codes.add("cmpl	%ecx, %eax");
			//codes.add("jl	L"+jumpNum);
			//codes.add("movl	$0, %eax");
			//codes.add("jmp L"+(jumpNum+1));
			//codes.add("L"+(jumpNum++)+":");
			//codes.add("movl	$1, %eax");
			//codes.add("L"+(jumpNum++)+":");
			/*
			 * 检查操作符<的两边操作数是否为int类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","boolean");
		} else if (e.getOperator() == InfixExpression.Operator.LESS_EQUALS){
			//codes.add("cmpl	%ecx, %eax");
			//codes.add("jle	L"+jumpNum);
			//codes.add("movl	$0, %eax");
			//codes.add("jmp L"+(jumpNum+1));
			//codes.add("L"+(jumpNum++)+":");
			//codes.add("movl	$1, %eax");
			//codes.add("L"+(jumpNum++)+":");
			/*
			 * 检查操作符<=的两边操作数是否为int类型
			 */
			if(!e.getLeftOperand().getProperty("type").equals("int")||!e.getRightOperand().getProperty("type").equals("int")){
				SemanticError.error_9_IntExpression(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","boolean");
		} else if (e.getOperator() == InfixExpression.Operator.NOT_EQUALS){
			//codes.add("cmpl	%ecx, %eax");
			//codes.add("jne	L"+jumpNum);
			//codes.add("movl	$0, %eax");
			//codes.add("jmp L"+(jumpNum+1));
			//codes.add("L"+(jumpNum++)+":");
			//codes.add("movl	$1, %eax");
			//codes.add("L"+(jumpNum++)+":");
			/*
			 * 检查操作符!=的两边操作数类型是否相同
			 */
			if(!e.getLeftOperand().getProperty("type").equals(e.getRightOperand().getProperty("type"))){
				SemanticError.error_10_EqConformingTypes(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			e.setProperty("type","boolean");
		} else {
			throw new RuntimeException("Unknown Operator: "
					+ e.getOperator().toString());
		}

			return false;
		
	}

	public boolean visit(MethodDeclaration m) {
		stackPos=-4;//复位
		posTable.clear();//将记录临时变量的栈表置空
		type.clear();
		posTable.putAll(sposTable);
		type.putAll(stype);
		
		now = m;
		codes.add(".align 2");
		/*
		 * main函数单独处理
		 */
		if(m.getName().getIdentifier().equals("Main")){
			
			
			mainNum++;
			/*
			 * 检查Main函数是否被定义了两次或者两次以上
			 */
			if(mainNum>1){
				SemanticError.error_1_DoubleDeclaration(null,"Main");
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			/*
			 * 检查主函数类型是否为static
			 */
			if(m.getModifiers()!=Modifier.STATIC){
				SemanticError.error_3_ProgramClassError(null);
				//System.err.println("Code generation halted");
				System.exit(0);
			}
			/*codes.add(".global _main");
			codes.add(".def	_main;	.scl	2;	.type	32;	.endef");
			codes.add("_main:");
			codes.add("pushl	%ebp");
			codes.add("movl	%esp, %ebp");
			codes.add("subl	$24, %esp");

⌨️ 快捷键说明

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