package frontend.ast.decl; import error.Errors; import error.Error; import error.ErrorType; import frontend.ast.Node; import frontend.ast.SyntaxType; import frontend.ast.exp.ConstExp; import frontend.ast.token.TokenNode; import frontend.lexer.TokenStream; import frontend.lexer.TokenType; import frontend.ast.val.InitVal; import midend.symbol.Symbol; import midend.symbol.SymbolManager; import midend.symbol.SymbolType; import midend.symbol.ArraySymbol; public class VarDef extends Node { private boolean isArray; public VarDef(TokenStream ts) { super(SyntaxType.VAR_DEF, ts); isArray = false; } public void parse(Errors errors) { TokenNode ident = new TokenNode(this.ts); addChild(ident); if (getCurrToken().getType() == TokenType.LBRACK) { TokenNode lbrack = new TokenNode(this.ts); addChild(lbrack); isArray = true; ConstExp cep = new ConstExp(this.ts); cep.parse(errors); addChild(cep); if (getCurrToken().getType() == TokenType.RBRACK) { TokenNode rbrack = new TokenNode(this.ts); addChild(rbrack); } else { errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.k)); } } if (getCurrToken().getType() == TokenType.ASSIGN) { TokenNode assign = new TokenNode(this.ts); addChild(assign); InitVal itv = new InitVal(this.ts); itv.parse(errors); addChild(itv); } } public Symbol getSymbol(int isStatic) { if (isStatic == 1) { //static修饰的变量有初值 if (isArray) { TokenNode tn = (TokenNode) getChild(0); ArraySymbol arraySymbol = new ArraySymbol(tn.getName(), SymbolType.STATIC_INT_ARRAY, tn.getLine(), ((ConstExp) getChild(2)).getValue()); if (HaveInitVal()) { arraySymbol.addValue(((InitVal) getChild(getChildren().size() - 1)).getValue()); } arraySymbol.fullValue(); return arraySymbol; } else { TokenNode tn = (TokenNode) getChild(0); Symbol valueSymbol = new Symbol(tn.getName(), SymbolType.STATIC_INT, tn.getLine()); if (HaveInitVal()) { valueSymbol.addValue(((InitVal) getChild(getChildren().size() - 1)).getValue()); } else { valueSymbol.addValue(0); } return valueSymbol; } } else { //要判断是否为全局变量,如果为全局变量,也应该赋初值 if (isArray) { TokenNode tn = (TokenNode) getChild(0); ArraySymbol arraySymbol = new ArraySymbol(tn.getName(), SymbolType.INT_ARRAY, tn.getLine(), ((ConstExp) getChild(2)).getValue()); if (SymbolManager.IsGlobal()) { if (HaveInitVal()) { arraySymbol.addValue(((InitVal) getChild( getChildren().size() - 1)).getValue()); } arraySymbol.fullValue(); } return arraySymbol; } else { TokenNode tn = (TokenNode) getChild(0); Symbol symbol = new Symbol(tn.getName(), SymbolType.INT, tn.getLine()); if (SymbolManager.IsGlobal()) { if (HaveInitVal()) { symbol.addValue(((InitVal) getChild( getChildren().size() - 1)).getValue()); } else { symbol.addValue(0); } } return symbol; } } } public boolean HaveInitVal() { return getChild(getChildren().size() - 1) instanceof InitVal; } public InitVal getInitVal() { if (HaveInitVal()) { return (InitVal) getChild(getChildren().size() - 1); } return null; } }