diff options
author | Iru Cai <mytbk920423@gmail.com> | 2014-10-10 06:34:52 +0800 |
---|---|---|
committer | Iru Cai <mytbk920423@gmail.com> | 2014-10-10 06:34:52 +0800 |
commit | 31aac86103f0c05fbaaf1e690ec27b23cfeea9c0 (patch) | |
tree | cd79cf031f3b45f8296b9cc10ae98ff2962b6536 | |
parent | fea5f8c5c0137c85f86bafb45f512abeac2e78a7 (diff) | |
download | minijava-31aac86103f0c05fbaaf1e690ec27b23cfeea9c0.tar.xz |
nearly finished
-rw-r--r-- | src/minijava/symboltable/MClass.java | 47 | ||||
-rw-r--r-- | src/minijava/symboltable/MClasses.java | 64 | ||||
-rw-r--r-- | src/minijava/symboltable/MExpression.java | 87 | ||||
-rw-r--r-- | src/minijava/symboltable/MIdentifier.java | 2 | ||||
-rw-r--r-- | src/minijava/symboltable/MMethod.java | 71 | ||||
-rw-r--r-- | src/minijava/symboltable/MPrimaryExpr.java | 44 | ||||
-rw-r--r-- | src/minijava/symboltable/MStatement.java | 84 | ||||
-rw-r--r-- | src/minijava/symboltable/MStatementList.java | 7 | ||||
-rw-r--r-- | src/minijava/typecheck/Main.java | 13 | ||||
-rw-r--r-- | src/minijava/visitor/BuildSymbolTableVisitor.java | 59 |
10 files changed, 448 insertions, 30 deletions
diff --git a/src/minijava/symboltable/MClass.java b/src/minijava/symboltable/MClass.java index 37bfcfb..10354a8 100644 --- a/src/minijava/symboltable/MClass.java +++ b/src/minijava/symboltable/MClass.java @@ -6,9 +6,11 @@ package minijava.symboltable; import minijava.typecheck.PrintError; public class MClass extends MLocalVarType { - public MClasses all_classes; // 所有类的列表 + public MClasses all_classes; // 所有类的列表,在建立符号表时完成 public boolean isDeclared = false; // 是否已声明,用于检查符号表 - public String extend_class_name = null; // 所继承的类 + public String extend_class_name = null; // 所继承的类名 + public MClass extend_class = null; // 所继承的类,在符号表建立完成后才能求得 + public int extend_tag = 0; // 检测循环继承时用,0表示未检测 public MMethodList methods; public MClass(String v_name, MClasses all, int m_line, int m_column) { @@ -36,9 +38,50 @@ public class MClass extends MLocalVarType { return "Method double declaration " + "\"" + method_name + "\"."; } methods.addMethod(method); + method.method_class = this; return null; } + // 检测类型名是否有效 + public boolean validType(String s_type) { + if (s_type==MIdentifier.intType + || s_type==MIdentifier.boolType + || s_type==MIdentifier.arrType + || s_type==MIdentifier.voidType + || s_type==MIdentifier.sArrayType) { + return true; + } + + if (all_classes.findClassByName(s_type)!=null) { + return true; + } + + return false; + } + + // 对类进行类型检查 + public boolean classVarCheck() { + boolean result = true; + for (int i=0; i<methods.size(); i++) { + result &= methods.methods.elementAt(i).validVars(); + } + return result; + } + + public boolean classFuncCheck() { + boolean result = true; + for (int i=0; i<methods.size(); i++) { + result &= methods.methods.elementAt(i).validFunc(); + } + return result; + } + + public void classStatementCheck() { + for (int i=0; i<methods.size(); i++) { + methods.methods.elementAt(i).checkStatements(); + } + } + // 调试输出: 打印该类的信息 public void printClass(int spaces) { String ps = OutputFormat.spaces(spaces); diff --git a/src/minijava/symboltable/MClasses.java b/src/minijava/symboltable/MClasses.java index 2df2ba8..10bd009 100644 --- a/src/minijava/symboltable/MClasses.java +++ b/src/minijava/symboltable/MClasses.java @@ -5,9 +5,20 @@ package minijava.symboltable; import java.util.Vector; +import minijava.typecheck.PrintError; + public class MClasses extends MType { public Vector<MClass> mj_classes = new Vector<MClass>(); // 用于存放类 + MClass findClassByName(String c_name) { + for (int i=0; i<mj_classes.size(); i++) { + if (mj_classes.elementAt(i).getName().equals(c_name)) { + return mj_classes.elementAt(i); + } + } + return null; + } + // 在表中插入类 public String InsertClass(MClass v_class) { String class_name = v_class.getName(); @@ -28,6 +39,59 @@ public class MClasses extends MType { return false; } + public void buildClassRelation() { + // 通过extend_class_name确定extend_class, 并查找循环继承 + for (int i=0; i<mj_classes.size(); i++) { + MClass m_class = mj_classes.elementAt(i); + String ext_name = m_class.extend_class_name; + if (ext_name!=null) { + m_class.extend_class = findClassByName(ext_name); + } + } + int tag = 1; // 扫描循环继承的标记 + for (int i=0; i<mj_classes.size(); i++) { + MClass m_class = mj_classes.elementAt(i); + if (m_class.extend_tag==0) { + m_class.extend_tag = tag; + while (m_class.extend_class!=null) { + m_class = m_class.extend_class; + if (m_class.extend_tag==tag) { // 循环继承 + PrintError.print(m_class.line, m_class.column, + "Circular extend in class"+m_class.name); + break; // error + } else if (m_class.extend_tag==0) { + m_class.extend_tag = tag; + } else { + break; // no error + } + } + tag++; + } + } + } + + public boolean checkAllVars() { + boolean result = true; + for (int i=0; i<mj_classes.size(); i++) { + result &= mj_classes.elementAt(i).classVarCheck(); + } + return result; + } + + public boolean checkAllFuncs() { + boolean result = true; + for (int i=0; i<mj_classes.size(); i++) { + result &= mj_classes.elementAt(i).classFuncCheck(); + } + return result; + } + + public void checkAllStatements() { + for (int i=0; i<mj_classes.size(); i++) { + mj_classes.elementAt(i).classStatementCheck(); + } + } + // 调试输出: 打印所有的类的信息 public void printClasses(int spaces) { for (int i=0; i<mj_classes.size(); i++) { diff --git a/src/minijava/symboltable/MExpression.java b/src/minijava/symboltable/MExpression.java index 17d6db8..4cf4724 100644 --- a/src/minijava/symboltable/MExpression.java +++ b/src/minijava/symboltable/MExpression.java @@ -1,5 +1,8 @@ package minijava.symboltable; +import minijava.syntaxtree.Identifier; +import minijava.typecheck.PrintError; + public class MExpression extends MType { public enum Operator { And, Smaller, Plus, Minus, Times, ArrayLookup, @@ -15,12 +18,90 @@ public class MExpression extends MType { // Expression value (for primary expression) public String e_val; - public MExpression(Operator op) { + public MExpression(int line, int column, Operator op) { + super(line, column); e_op = op; e_exp = new MPrimaryExpr(); e_list = new MExpressionList(); } + public String exprType(MMethod m) { + switch (e_op) { + case And: + if (first.exprType(m)==MIdentifier.boolType + && second.exprType(m)==MIdentifier.boolType) { + return MIdentifier.boolType; + } else { + PrintError.print(line, column, "Type mismatch"); + return null; + } + case ArrayLen: + if (first.exprType(m)==MIdentifier.arrType) { + return MIdentifier.intType; + } else { + PrintError.print(line, column, "Type mismatch"); + return null; + } + case ArrayLookup: + if (first.exprType(m)==MIdentifier.arrType + && second.exprType(m)==MIdentifier.intType) { + return MIdentifier.intType; + } else { + PrintError.print(line, column, "Type mismatch"); + return null; + } + case Smaller: + if (first.exprType(m)==MIdentifier.intType + && second.exprType(m)==MIdentifier.intType) { + return MIdentifier.boolType; + } else { + PrintError.print(line, column, "Type mismatch"); + return null; + } + case Plus: + case Minus: + case Times: + if (first.exprType(m)==MIdentifier.intType + && second.exprType(m)==MIdentifier.intType) { + return MIdentifier.intType; + } else { + PrintError.print(line, column, "Type mismatch"); + return null; + } + case MsgSend: + // expr.id(expr*) + String c_type = first.exprType(m); + MClass m_class = m.method_class.all_classes.findClassByName(c_type); + if (m_class==null) { + PrintError.print(line, column, "no class found in a message send expression"); + return null; + } + int idx = m_class.methods.findMethod(e_id.name); + if (idx==-1) { + PrintError.print(line, column, "method " + e_id.name + " not found"); + return null; + } + MMethod m_method = m_class.methods.methods.elementAt(idx); + if (e_list.size()!=m_method.paramList.size()) { + PrintError.print(line, column, "Method param size mismatch!"); + return null; + } + for (int i=0; i<e_list.size(); i++) { + String t1 = e_list.e_list.elementAt(i).exprType(m); + String t2 = m_method.paramList.varlist.elementAt(i).typename; + if (!t1.equals(t2)) { + PrintError.print(line, column, "Method param type mismatch!"); + return null; + } + } + return m_method.ret_type_name; + case Primary: + return e_exp.primExprType(m); + default: + return null; + } + } + public void printExpr(int spaces) { System.err.print(OutputFormat.spaces(spaces)); @@ -54,6 +135,10 @@ public class MExpression extends MType { second.printExpr(0); break; case ArrayLookup: + first.printExpr(0); + System.err.print("["); + second.printExpr(0); + System.err.print("]"); case ArrayLen: case MsgSend: } diff --git a/src/minijava/symboltable/MIdentifier.java b/src/minijava/symboltable/MIdentifier.java index 45340ac..5b3f88a 100644 --- a/src/minijava/symboltable/MIdentifier.java +++ b/src/minijava/symboltable/MIdentifier.java @@ -8,6 +8,8 @@ public class MIdentifier extends MType { public static final String arrType = "int[]"; public static final String intType = "int"; public static final String boolType = "boolean"; + public static final String voidType = "void"; + public static final String sArrayType = "String[]"; public MIdentifier(String v_name, int v_line, int v_column) { super(v_line, v_column); diff --git a/src/minijava/symboltable/MMethod.java b/src/minijava/symboltable/MMethod.java index 7f57a40..2d2dc24 100644 --- a/src/minijava/symboltable/MMethod.java +++ b/src/minijava/symboltable/MMethod.java @@ -1,9 +1,11 @@ package minijava.symboltable; +import minijava.typecheck.PrintError; + public class MMethod extends MLocalVarType { MVarList params; String ret_type_name; - MClass method_class; + public MClass method_class; MVarList paramList; public MStatementList statements; public MExpression ret_expr; @@ -37,6 +39,73 @@ public class MMethod extends MLocalVarType { return null; } + // 检测函数的返回类型,参数类型,局部变量类型是否为有效类型 + public boolean validVars() { + if (method_class.validType(ret_type_name)==false) { + PrintError.print(this.line, this.column, "Return type of method "+this.name+" invalid"); + return false; + } + + for (int i=0; i<paramList.size(); i++) { + MVariable p_var = paramList.varlist.elementAt(i); + if (method_class.validType(p_var.typename)==false) { + PrintError.print(p_var.line, p_var.column, "Type "+p_var.typename+" invalid"); + return false; + } + } + + for (int i=0; i<vars.size(); i++) { + MVariable m_var = vars.varlist.elementAt(i); + if (method_class.validType(m_var.typename)==false) { + PrintError.print(m_var.line, m_var.column, "Type "+m_var.typename+" invalid"); + return false; + } + } + + return true; + } + + // 检查方法自身是否复合方法覆盖条件 + public boolean validFunc() { + MClass m_class = method_class; + while (m_class.extend_class!=null) { + m_class = m_class.extend_class; + int idx = m_class.methods.findMethod(this.name); + if (idx!=-1) { + // 找到同名方法,检测是否能覆盖 + if (this.ret_type_name. + equals(m_class.methods.methods.elementAt(idx))==false) { + PrintError.print(line, column, "Method " + + this.name + " has type different from the one in its parent class"); + return false; + } + } + } + return true; + } + + // 从局部变量,参数表,类变量中查找变量 + public MVariable findVarByName(String s) { + int idx; + idx = vars.findVar(s); + if (idx!=-1) { + return vars.varlist.elementAt(idx); + } + idx = paramList.findVar(s); + if (idx!=-1) { + return paramList.varlist.elementAt(idx); + } + idx = method_class.vars.findVar(s); + if (idx!=-1) { + return method_class.vars.varlist.elementAt(idx); + } + return null; + } + + public void checkStatements() { + statements.checkStatements(this); + } + public void printMethod(int spaces) { String ps = OutputFormat.spaces(spaces); System.err.print(ps + this.ret_type_name + " " + this.name + "("); diff --git a/src/minijava/symboltable/MPrimaryExpr.java b/src/minijava/symboltable/MPrimaryExpr.java index ce4113c..ba233b5 100644 --- a/src/minijava/symboltable/MPrimaryExpr.java +++ b/src/minijava/symboltable/MPrimaryExpr.java @@ -1,5 +1,7 @@ package minijava.symboltable; +import minijava.typecheck.PrintError; + public class MPrimaryExpr extends MType { /** * f0 -> IntegerLiteral() @@ -35,6 +37,40 @@ public class MPrimaryExpr extends MType { } } + public String primExprType(MMethod m) { + switch (e_type) { + case Int: + return MIdentifier.intType; + case Alloc: + return e_id.getName(); + case ArrayAlloc: + return MIdentifier.arrType; + case Braket: + return e_exp.exprType(m); + case True: + case False: + return MIdentifier.boolType; + case Id: + MVariable m_var = m.findVarByName(e_id.name); + if (m_var!=null) { + return m_var.typename; + } else { + return null; + } + case Not: + if (e_exp.exprType(m)==MIdentifier.boolType) { + return MIdentifier.boolType; + } else { + PrintError.print(getLine(), getColumn(), "A non boolean expr after '!' operator"); + return null; + } + case This: + return m.method_class.name; + default: + return null; + } + } + public void printPrimExpr(int spaces) { System.err.print(OutputFormat.spaces(spaces)); @@ -49,6 +85,14 @@ public class MPrimaryExpr extends MType { case Id: System.err.print(e_id.getName()); break; + case Alloc: + System.err.print("new "+e_id.getName()+"()"); + break; + case ArrayAlloc: + System.err.print("new int["); + e_exp.printExpr(0); + System.err.print("]"); + break; } } } diff --git a/src/minijava/symboltable/MStatement.java b/src/minijava/symboltable/MStatement.java index 6410ca0..3610719 100644 --- a/src/minijava/symboltable/MStatement.java +++ b/src/minijava/symboltable/MStatement.java @@ -1,5 +1,7 @@ package minijava.symboltable; +import minijava.typecheck.PrintError; + public class MStatement extends MType { public enum Keyword { Block, Assign, ArrAssign, If, While, Print; @@ -10,7 +12,8 @@ public class MStatement extends MType { public MExpression e_first, e_second; // for assign(e_first), array assign, if, while, print public MStatement s_first, s_second; // for if, while - public MStatement(Keyword keyw) { + public MStatement(int s_line, int s_column, Keyword keyw) { + super(s_line, s_column); s_type = keyw; s_list = null; s_id = null; @@ -18,6 +21,63 @@ public class MStatement extends MType { s_first = s_second = null; } + public void checkStatement(MMethod m) { + switch (s_type) { + case ArrAssign: + // id[expr] = expr + if (m.findVarByName(s_id.name).typename==MIdentifier.arrType + && e_first.exprType(m)==MIdentifier.intType + && e_second.exprType(m)==MIdentifier.intType) { + return; + } else { + PrintError.print(line, column, "type mismatch in array assign statement"); + } + break; + case Assign: + // id = expr + MVariable m_var = m.findVarByName(s_id.name); + if (m_var==null) { + PrintError.print(line, column, "variable "+s_id.name+" not exist!"); + return; + } else if (m_var.typename.equals(e_first.exprType(m))) { + return; + } else { + PrintError.print(line, column, "type mismatch in assign statement"); + } + break; + case Block: + s_list.checkStatements(m); + break; + case If: + if (e_first.exprType(m)==MIdentifier.boolType) { + s_first.checkStatement(m); + s_second.checkStatement(m); + } else { + PrintError.print(line, column, "invalid type in if statement."); + } + break; + case Print: + if (e_first.exprType(m)!=null) { + return; + } else { + PrintError.print(line, column, "Invalid type in print statement"); + } + break; + case While: + // while (expr) state + if (e_first.exprType(m)==MIdentifier.boolType) { + s_first.checkStatement(m); + } else { + PrintError.print(line, column, "invalid type in while statement."); + } + break; + default: + break; + + } + + } + public void printStatement(int spaces) { String sp = OutputFormat.spaces(spaces); @@ -31,17 +91,31 @@ public class MStatement extends MType { System.err.println(")"); break; case ArrAssign: - System.err.println(sp+"[]="); + System.err.println(sp+"[]= ("+s_id.getName()+") ("); + e_first.printExpr(0); + System.err.print(") ("); + e_second.printExpr(0); + System.err.println(")"); break; case If: - System.err.println(sp+"if"); + System.err.println(sp+"if ("); + e_first.printExpr(0); + System.err.println(")"); + s_first.printStatement(spaces+2); + s_second.printStatement(spaces+2); break; case While: - System.err.println(sp+"while"); + System.err.println(sp+"while ("); + e_first.printExpr(0); + System.err.println(")"); + s_first.printStatement(spaces+2); break; case Print: - System.err.println(sp+"print"); + System.err.println(sp+"print ("); + e_first.printExpr(0); + System.err.println(")"); break; } } + } diff --git a/src/minijava/symboltable/MStatementList.java b/src/minijava/symboltable/MStatementList.java index 034bc8b..3cb3b02 100644 --- a/src/minijava/symboltable/MStatementList.java +++ b/src/minijava/symboltable/MStatementList.java @@ -23,4 +23,11 @@ public class MStatementList extends MType { s_list.elementAt(i).printStatement(spaces); } } + + public void checkStatements(MMethod m) { + for (int i=0; i<s_list.size(); i++) { + s_list.elementAt(i).checkStatement(m); + } + } + } diff --git a/src/minijava/typecheck/Main.java b/src/minijava/typecheck/Main.java index 7319fe4..1c069ba 100644 --- a/src/minijava/typecheck/Main.java +++ b/src/minijava/typecheck/Main.java @@ -12,7 +12,7 @@ import minijava.syntaxtree.Node; import minijava.visitor.BuildSymbolTableVisitor; public class Main { - + public static void main(String[] args) { try { @@ -30,6 +30,17 @@ public class Main { my_classes.printClasses(0); } + // 建立类的继承关系,寻找循环继承 + my_classes.buildClassRelation(); + + // 检查类型名有效性 + my_classes.checkAllVars(); + + // 检查方法错误覆盖 + my_classes.checkAllFuncs(); + + my_classes.checkAllStatements(); + // 打印错误信息 PrintError.printAll(); } catch (TokenMgrError e) { diff --git a/src/minijava/visitor/BuildSymbolTableVisitor.java b/src/minijava/visitor/BuildSymbolTableVisitor.java index 768c905..c99d0ab 100644 --- a/src/minijava/visitor/BuildSymbolTableVisitor.java +++ b/src/minijava/visitor/BuildSymbolTableVisitor.java @@ -110,9 +110,10 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { PrintError.print(m_class.getLine(), m_class.getColumn(), error_msg); // 往main class中添加main方法 - MMethod main_method = new MMethod("main", "void", n.f6.beginLine, n.f6.beginColumn); + MMethod main_method = new MMethod("main", MIdentifier.voidType, + n.f6.beginLine, n.f6.beginColumn); MIdentifier argid = (MIdentifier) n.f11.accept(this, null); - MVariable param = new MVariable(argid.getName(), "String[]", + MVariable param = new MVariable(argid.getName(), MIdentifier.sArrayType, argid.getLine(), argid.getColumn()); main_method.addParam(param); m_class.insertMethod(main_method); @@ -247,7 +248,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { MClass m_class = (MClass)argu; String ret_type = n.f1.accept(this, null).getName(); String method_name = n.f2.accept(this, null).getName(); - MMethod m_method = new MMethod(method_name, ret_type, n.f2.f0.beginLine, n.f2.f0.beginColumn); + MMethod m_method = new MMethod(method_name, ret_type, + n.f2.f0.beginLine, n.f2.f0.beginColumn); // 将定义的方法插入类中,如果出错则打印错误信息 String _err = m_class.insertMethod(m_method); @@ -364,7 +366,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f2 -> "}" */ public MType visit(Block n, MType argu) { - MStatement s = new MStatement(MStatement.Keyword.Block); + MStatement s = new MStatement(n.f0.beginLine, n.f0.beginColumn, + MStatement.Keyword.Block); s.s_list = new MStatementList(); if (argu!=null) { // should be a statement list ((MStatementList)argu).addStatement(s); @@ -381,8 +384,10 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { */ public MType visit(AssignmentStatement n, MType argu) { MStatementList m_list = (MStatementList) argu; - MStatement s = new MStatement(MStatement.Keyword.Assign); - s.s_id = (MIdentifier) n.f0.accept(this, null); + MIdentifier st_id = (MIdentifier) n.f0.accept(this, null); + MStatement s = new MStatement(st_id.getLine(), st_id.getColumn(), + MStatement.Keyword.Assign); + s.s_id = st_id; s.e_first = (MExpression) n.f2.accept(this, null); if (m_list!=null) { // a statement list m_list.addStatement(s); @@ -401,8 +406,10 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { */ public MType visit(ArrayAssignmentStatement n, MType argu) { MStatementList m_list = (MStatementList) argu; - MStatement s = new MStatement(MStatement.Keyword.ArrAssign); - s.s_id = (MIdentifier) n.f0.accept(this, null); + MIdentifier st_id = (MIdentifier) n.f0.accept(this, null); + MStatement s = new MStatement(st_id.getLine(), st_id.getColumn(), + MStatement.Keyword.ArrAssign); + s.s_id = st_id; s.e_first = (MExpression) n.f2.accept(this, null); s.e_second = (MExpression) n.f5.accept(this, null); if (m_list!=null) { // a statement list @@ -422,7 +429,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { */ public MType visit(IfStatement n, MType argu) { MStatementList m_list = (MStatementList) argu; - MStatement s = new MStatement(MStatement.Keyword.If); + MStatement s = new MStatement(n.f0.beginLine, n.f0.beginColumn, + MStatement.Keyword.If); s.e_first = (MExpression) n.f2.accept(this, null); s.s_first = (MStatement) n.f4.accept(this, null); s.s_second = (MStatement) n.f6.accept(this, null); @@ -441,7 +449,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { */ public MType visit(WhileStatement n, MType argu) { MStatementList m_list = (MStatementList)argu; - MStatement s = new MStatement(MStatement.Keyword.While); + MStatement s = new MStatement(n.f0.beginLine, n.f0.beginColumn, + MStatement.Keyword.While); s.e_first = (MExpression) n.f2.accept(this, null); s.s_first = (MStatement) n.f4.accept(this, null); if (m_list!=null) { @@ -459,7 +468,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { */ public MType visit(PrintStatement n, MType argu) { MStatementList m_list = (MStatementList)argu; - MStatement s = new MStatement(MStatement.Keyword.Print); + MStatement s = new MStatement(n.f0.beginLine, n.f0.beginColumn, + MStatement.Keyword.Print); s.e_first = (MExpression) n.f2.accept(this, null); if (m_list!=null) { m_list.addStatement(s); @@ -488,7 +498,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f2 -> PrimaryExpression() */ public MType visit(AndExpression n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.And); + MExpression e = new MExpression(n.f1.beginLine, n.f1.beginColumn, + MExpression.Operator.And); e.first = (MExpression) n.f0.accept(this, null); e.second = (MExpression) n.f2.accept(this, null); if (argu!=null) { @@ -503,7 +514,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f2 -> PrimaryExpression() */ public MType visit(CompareExpression n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.Smaller); + MExpression e = new MExpression(n.f1.beginLine, n.f1.beginColumn, + MExpression.Operator.Smaller); e.first = (MExpression) n.f0.accept(this, null); e.second = (MExpression) n.f2.accept(this, null); if (argu!=null) { @@ -518,7 +530,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f2 -> PrimaryExpression() */ public MType visit(PlusExpression n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.Plus); + MExpression e = new MExpression(n.f1.beginLine, n.f1.beginColumn, + MExpression.Operator.Plus); e.first = (MExpression) n.f0.accept(this, null); e.second = (MExpression) n.f2.accept(this, null); if (argu!=null) { @@ -533,7 +546,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f2 -> PrimaryExpression() */ public MType visit(MinusExpression n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.Minus); + MExpression e = new MExpression(n.f1.beginLine, n.f1.beginColumn, + MExpression.Operator.Minus); e.first = (MExpression) n.f0.accept(this, null); e.second = (MExpression) n.f2.accept(this, null); if (argu!=null) { @@ -548,7 +562,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f2 -> PrimaryExpression() */ public MType visit(TimesExpression n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.Times); + MExpression e = new MExpression(n.f1.beginLine, n.f1.beginColumn, + MExpression.Operator.Times); e.first = (MExpression) n.f0.accept(this, null); e.second = (MExpression) n.f2.accept(this, null); if (argu!=null) { @@ -564,7 +579,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f3 -> "]" */ public MType visit(ArrayLookup n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.ArrayLookup); + MExpression e = new MExpression(n.f1.beginLine, n.f1.beginColumn, + MExpression.Operator.ArrayLookup); e.first = (MExpression) n.f0.accept(this, null); e.second = (MExpression) n.f2.accept(this, null); if (argu!=null) { @@ -579,7 +595,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f2 -> "length" */ public MType visit(ArrayLength n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.ArrayLen); + MExpression e = new MExpression(n.f1.beginLine, n.f1.beginColumn, + MExpression.Operator.ArrayLen); e.first = (MExpression) n.f0.accept(this, null); if (argu!=null) { ((MExpressionList)argu).add_expr(e); @@ -596,7 +613,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * f5 -> ")" */ public MType visit(MessageSend n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.MsgSend); + MExpression e = new MExpression(n.f1.beginLine, n.f1.beginColumn, + MExpression.Operator.MsgSend); e.first = (MExpression) n.f0.accept(this, null); e.e_id = (MIdentifier) n.f2.accept(this, null); // 将表达式列表的内容添加至e.e_list @@ -638,7 +656,8 @@ public class BuildSymbolTableVisitor extends GJDepthFirst<MType, MType> { * | BracketExpression() */ public MType visit(PrimaryExpression n, MType argu) { - MExpression e = new MExpression(MExpression.Operator.Primary); + // FIXME: cannot get line and column + MExpression e = new MExpression(0, 0, MExpression.Operator.Primary); n.f0.accept(this, e.e_exp); if (argu!=null) { // a expression list ((MExpressionList)argu).add_expr(e); |