summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2014-10-10 06:34:52 +0800
committerIru Cai <mytbk920423@gmail.com>2014-10-10 06:34:52 +0800
commit31aac86103f0c05fbaaf1e690ec27b23cfeea9c0 (patch)
treecd79cf031f3b45f8296b9cc10ae98ff2962b6536
parentfea5f8c5c0137c85f86bafb45f512abeac2e78a7 (diff)
downloadminijava-31aac86103f0c05fbaaf1e690ec27b23cfeea9c0.tar.xz
nearly finished
-rw-r--r--src/minijava/symboltable/MClass.java47
-rw-r--r--src/minijava/symboltable/MClasses.java64
-rw-r--r--src/minijava/symboltable/MExpression.java87
-rw-r--r--src/minijava/symboltable/MIdentifier.java2
-rw-r--r--src/minijava/symboltable/MMethod.java71
-rw-r--r--src/minijava/symboltable/MPrimaryExpr.java44
-rw-r--r--src/minijava/symboltable/MStatement.java84
-rw-r--r--src/minijava/symboltable/MStatementList.java7
-rw-r--r--src/minijava/typecheck/Main.java13
-rw-r--r--src/minijava/visitor/BuildSymbolTableVisitor.java59
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);