📄 interpreter.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 + -