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

📄 interpreter.java

📁 SkipOOMiniJOOL教学语言的编译器前端
💻 JAVA
字号:
package edu.ustc.cs.minijool.interp;

import java.util.HashMap;
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.ExpressionStatement;
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.NumberLiteral;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.internal.corext.dom.GenericVisitor;

/**<p>
 * SimpleMiniJOOL语言的解释器
 * </p><p>
 * 在这个解释器中,我们只给出了一部分节点的访问方法,其余的请您在试验中添加
 * 适当的访问以完成实验,您可以添加适当适当的私有变量来辅助您的方法
 * </p>
 */
public class Interpreter extends GenericVisitor {

	/**
	 * 存储当前计算的整数值,为方便,布尔值也用整型数表示,0表示false,其它表示true
	 */
	private IntValue value;

	/**
	 * 符号表,存储变量和它的值之间的映射。
	 */
	private Map symTable;

	/**
	 * 一个整数值的类,方便解释器中value的空值检测
	 */
	private static class IntValue {
		private int value;
		
		public IntValue(int val) {
			value = val;
		}
		private int get() {
			return value;
		}
		private void set(int v) {
			value = v;
		}
		public String toString() {
			return Integer.toString(value);
		}
	}

	/**
	 * 构造函数,创建一个空的符号表。
	 */
	public Interpreter() {
		super();
		symTable = new HashMap();
	}


	/**
	 * 解释执行一个AST
	 * @param program 要解释的AST的根节点
	 */
	public void run(ASTNode program) {
		symTable.clear();
		program.accept(this);
	}

	public boolean visit(TypeDeclaration e) {
		List l = e.bodyDeclarations();
		ASTNode ch = (ASTNode) l.get(0);
		ch.accept(this);
		return false;
	}

	public boolean visit(MethodDeclaration e) {
		e.getBody().accept(this);
		return false;
	}

	public boolean visit(Block b) {
		List l = b.statements();
		for (int i = 0; i < l.size(); i++) {
			ASTNode s = (ASTNode) l.get(i);
			s.accept(this);
		}
		return false;
	}

	public boolean visit(NumberLiteral e) {
		value = new IntValue(Integer.parseInt(e.getToken()));
		return false;
	}

	public boolean visit(MethodInvocation e) {

		List args = e.arguments();
		ASTNode child = (ASTNode) args.get(0);
	
		child.accept(this);
		
		if (value == null) {
			throw new VoidReferenceException();
		}
		
		// 参数一定是一个,要么是个数值,要么是print函数的返回值即null
		System.out.println(value);
		return false;
	}

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

	public boolean visit(Assignment e) {
		ASTNode right = e.getRightHandSide();
		right.accept(this);
		SimpleName left = (SimpleName)e.getLeftHandSide();
		String opr = e.getOperator().toString();
		int temp;
		if(opr == "=")
			symTable.put(left.getIdentifier(), Integer.toString(value.value));	
		else 
		{	if(!symTable.containsKey(left.getIdentifier()))
				throw new VoidReferenceException();
			else
				temp = Integer.parseInt((String)symTable.get(left.getIdentifier()));
			if(opr == "+=")
				symTable.put(left.getIdentifier(), Integer.toString(temp+value.value));
			else if(opr == "-=")
				symTable.put(left.getIdentifier(), Integer.toString(temp-value.value));
			else if(opr == "*=")
				symTable.put(left.getIdentifier(), Integer.toString(temp*value.value));
			else if(opr == "/=")
			{
				if(value.value == 0)
					throw new DivideByZeroException();
				else
					symTable.put(left.getIdentifier(), Integer.toString(temp/value.value));
			}
			else if(opr == "%=")
			{
				if(value.value == 0)
					throw new DivideByZeroException();
				else
					symTable.put(left.getIdentifier(), Integer.toString(temp%value.value));
			}
			
			else
				throw new RuntimeException("error.");
		}
		return false;
	}

	/**
	 * 中缀表达式的访问函数
	 */
	public boolean visit(InfixExpression e) {
		ASTNode left = e.getLeftOperand();
		left.accept(this);
		int temp = value.value;
		ASTNode right = e.getRightOperand();
		right.accept(this);
		String opr = e.getOperator().toString();

		if(opr == "+")
			value.value = temp+value.value;
		else if(opr == "-")
			value.value = temp-value.value;
		else if(opr == "*")
			value.value = temp*value.value;
		else if(opr == "/")
		{
			if(value.value == 0)
				throw new DivideByZeroException();
			else
				value.value = temp/value.value;
		}
		else if(opr == "%")
		{
			if(value.value == 0)
				throw new DivideByZeroException();
			else
				value.value = temp%value.value;
		}
		else if(opr == "<<")
			value.value = temp<<value.value;
		else if(opr == ">>")
			value.value = temp>>value.value;
		else if(opr == ">")
		{
			if(temp > value.value)
				value.value = 1;
			else
				value.value = 0;
		}
		else if(opr == ">=")
		{
			if(temp >= value.value)
				value.value = 1;
			else
				value.value = 0;
		}
		else if(opr == "<")
		{
			if(temp < value.value)
				value.value = 1;
			else
				value.value = 0;
		}
		else if(opr == "<=")
		{
			if(temp <= value.value)
				value.value = 1;
			else
				value.value = 0;
		}
		else if(opr == "==")
		{
			if(temp == value.value)
				value.value = 1;
			else
				value.value = 0;
		}
		else if(opr == "!=")
		{
			if(temp != value.value)
				value.value = 1;
			else
				value.value = 0;
		}
		return false;
	}
	
	/**
	 * 前缀表达式的访问
	 */
	public boolean visit(PrefixExpression e) {
		ASTNode child = e.getOperand();
		child.accept(this);
		String opr = e.getOperator().toString();
		if(opr == "-")
			value.value = -value.value;
		else if(opr == "!")
		{
			if(value.value == 0)
				value.value = 1;
			else
				value.value = 0;
		}	
		return false;
	}
	
	/**
	 * 简单名字的访问函数
	 */
	public boolean visit(SimpleName e) {
		if(symTable.containsKey(e.getIdentifier()))
			value = new IntValue(Integer.parseInt((String)symTable.get(e.getIdentifier())));
		else
			throw new VoidReferenceException();
		return false;
		//throw new RuntimeException("SimpleName not implemented for this node.");
	}

	/**
	 * if语句的访问函数
	 */
	public boolean visit(IfStatement s) {
		ASTNode ifs = s.getExpression();
		ASTNode tns;
		ifs.accept(this);
		if(value.value == 0)
			tns = s.getElseStatement();
		else 
			tns = s.getThenStatement();
		
		if(tns != null)
			tns.accept(this);
		return false;
	}

	/**
	 * while语句的访问函数
	 */
	public boolean visit(WhileStatement s) {
		ASTNode ifs = s.getExpression();
		ASTNode exp = s.getBody();
		ifs.accept(this);
		while(value.value != 0)
		{
			exp.accept(this);
			ifs.accept(this);
		}
		return false;
	}
}

⌨️ 快捷键说明

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