实现功能 
本次实验完成了以下功能:
类型检查 
重命名 
 
实验设计 
笔者参考老师上课的演示代码和助教在文档中的提示,做出如下类设计。该设计采取了依赖倒置原则。
在实现功能方面,笔者采用了如下思路:
通过 Visitor 对语法树进行遍历,遍历过程中输出语义错误; 
在 visitTerminal 方法中,对每个 Symbol 记录变量名、函数名的出现位置,并存储待输出语法树内容; 
如果语法树中无语义错误,则输出语法树的内容,输出过程中对待重命名的变量、函数进行重命名。 
 
整个过程总共遍历语法树一遍 。
调用入口设计 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public  class  Main  {public  static  void  main (String[] args)  throws  IOException {ParseTree  tree  =  sysYParser.program();Visitor  visitor  =  new  Visitor ();if  (!visitor.getErrorFound()) {for  (Object obj : visitor.getMsgToPrint()) {if  (obj instanceof  Symbol) {if  (((Symbol) obj).findUsage(lineNo, columnNo)) {else  {else  {
遍历过程 Visitor 设计 
该类在项目中共 471 行,以下是 Visitor 类实现遍历的核心逻辑:
获得报错行号的方法:第 47 行 
获得行号列号的方法:第 8 行 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 public  class  Visitor  extends  SysYParserBaseVisitor <Void> {@Override public  Void visitTerminal (TerminalNode node)  {if  (ruleName.equals("INTEGR_CONST" )) {else  if  (ruleName.equals("IDENT" )) {int  lineNO  =  token.getLine();int  columnNO  =  token.getCharPositionInLine();if  (symbol != null ) {if  (!color.equals("no color" )) {return  super .visitTerminal(node);@Override public  Void visitProgram (SysYParser.ProgramContext ctx)  {Void  ret  =  super .visitProgram(ctx);return  ret;@Override public  Void visitFuncDef (SysYParser.FuncDefContext ctx)  {Void  ret  =  super .visitFuncDef(ctx);return  ret;@Override public  Void visitBlock (SysYParser.BlockContext ctx)  {Void  ret  =  super .visitBlock(ctx);return  ret;int  getLineNo (ParserRuleContext ctx)  {return  ctx.getStart().getLine();@Override public  Void visitVarDecl (SysYParser.VarDeclContext ctx)  {for  (SysYParser.VarDefContext varDefContext : ctx.varDef()) {if  (varDefContext.ASSIGN() != null ) {return  super .visitVarDecl(ctx);@Override public  Void visitConstDecl (SysYParser.ConstDeclContext ctx)  {return  super .visitConstDecl(ctx);@Override public  Void visitFuncFParam (SysYParser.FuncFParamContext ctx)  {return  super .visitFuncFParam(ctx);private  Type getLValType (SysYParser.LValContext ctx)  {return  varType;@Override public  Void visitLVal (SysYParser.LValContext ctx)  {for  (int  i  =  0 ; i < arrayDimension; ++i) {return  super .visitLVal(ctx);@Override public  Void visitStmt (SysYParser.StmtContext ctx)  {if  (ctx.ASSIGN() != null ) {else  if  (ctx.RETURN() != null ) {return  super .visitStmt(ctx);private  Type getExpType (SysYParser.ExpContext ctx)  {if  (ctx.IDENT() != null ) { else  if  (ctx.L_PAREN() != null ) { else  if  (ctx.unaryOp() != null ) { else  if  (ctx.lVal() != null ) { else  if  (ctx.number() != null ) { else  if  (ctx.MUL() != null  || ctx.DIV() != null  || ctx.MOD() != null  || ctx.PLUS() != null  || ctx.MINUS() != null ) {return  new  BasicTypeSymbol ("noType" );@Override public  Void visitExp (SysYParser.ExpContext ctx)  {if  (ctx.IDENT() != null ) { else  if  (ctx.unaryOp() != null ) { else  if  (ctx.MUL() != null  || ctx.DIV() != null  || ctx.MOD() != null  || ctx.PLUS() != null  || ctx.MINUS() != null ) {return  super .visitExp(ctx);@Override public  Void visitCond (SysYParser.CondContext ctx)  {return  super .visitCond(ctx);
测试用例 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 int  globalVar;int  globalArray[2 ];void  voidFunc1 ()  {return ;void  voidFunc2 (int  param1)  {return  1 ; void  voidFunc3 (int  param1, int  param2[])  {return  param1; int  intFunc1 ()  {return  1 ;int  intFunc1 (int  param)  { return  intFunc1(); int  intFunc2 (int  param1)  {return  intFunc2(param1); int  intFunc3 (int  param1, int  param2[])  {return  param2; int  voidFunc1 ()  { int  test (int  i, int  i) { return  test(i + 1 ); int  main () {3 ; int  b = func(); int  b; int  c[3 ][3 ][3 ];int  d[2 ][2 ];1 ] = d; 1 ][1 ] = d; 1 ][1 ] = d; int  f = voidFunc1() + intFunc1(); int  g = intFunc3(b); int  h = intFunc3(b, globalArray); int  i = b[5 ]; int  j = c(); 6 ; 6 ; if  (1  || globalArray || 2  || d) { int  k = voidFunc1(); int  l = voidFunc(); int  m = k;return  z();