package frontend.ast.func; import java.util.ArrayList; import error.Error; import error.ErrorType; import error.Errors; import frontend.ast.Node; import frontend.ast.SyntaxType; import frontend.ast.token.TokenNode; import frontend.lexer.TokenStream; import frontend.lexer.TokenType; import frontend.ast.block.Block; import frontend.ast.block.BlockItem; import frontend.ast.decl.Decl; import midend.symbol.Symbol; import midend.symbol.SymbolType; import midend.symbol.FuncSymbol; import midend.symbol.ArraySymbol; import midend.symbol.SymbolManager; public class FuncDef extends Node { public FuncDef(TokenStream ts) { super(SyntaxType.FUNC_DEF, ts); } public void parse(Errors errors) { FuncType ft = new FuncType(this.ts); ft.parse(errors); addChild(ft); TokenNode ident = new TokenNode(this.ts); addChild(ident); TokenNode lparen = new TokenNode(this.ts); addChild(lparen); if (getCurrToken().getType() != TokenType.RPARENT && getCurrToken().getType() != TokenType.LBRACE) { FuncFParams ffp = new FuncFParams(this.ts); ffp.parse(errors); addChild(ffp); if (getCurrToken().getType() == TokenType.RPARENT) { TokenNode rparen = new TokenNode(this.ts); addChild(rparen); } else { errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); } } else if (getCurrToken().getType() == TokenType.LBRACE) { errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); } else { TokenNode rparen = new TokenNode(this.ts); addChild(rparen); } Block block = new Block(this.ts); block.setIsFuncBlock(true); block.parse(errors); addChild(block); } public Symbol getSymbol() { if (((FuncType) getChild(0)).isVoid()) { TokenNode tn = (TokenNode) getChild(1); return new FuncSymbol(tn.getName(), SymbolType.VOID_FUNC, tn.getLine(), 0); } else { TokenNode tn = (TokenNode) getChild(1); return new FuncSymbol(tn.getName(), SymbolType.INT_FUNC, tn.getLine(), 1); } } public void addParamSymbol(Symbol funcSymbol, Errors errors) { if (getChild(3) instanceof FuncFParams) { FuncFParams ffp = (FuncFParams) getChild(3); ArrayList paramList = ffp.getParamList(); for (FuncFParam param : paramList) { Symbol paramSymbol = param.getSymbol(); SymbolManager.addSymbol(paramSymbol, errors); ((FuncSymbol) funcSymbol).addParamSymbol(paramSymbol); // 将形参存到函数的符号中 if (paramSymbol instanceof ArraySymbol) { ((FuncSymbol) funcSymbol).addParam(1); } else { ((FuncSymbol) funcSymbol).addParam(0); } } } } public void checkReturnNode(Errors errors) { Block block = (Block) getChild(getChildren().size() - 1); TokenNode rbrace = (TokenNode) block.getChild(block.getChildren().size() - 1); if (block.getChildren().size() == 2) { errors.addError(new Error(rbrace.getLine(), ErrorType.g)); } else { BlockItem bit = (BlockItem) block.getChild(block.getChildren().size() - 2); if (bit.getChild(0) instanceof Decl) { errors.addError(new Error(rbrace.getLine(), ErrorType.g)); } else { if (!(bit.getChild(0).getChild(0) instanceof TokenNode)) { errors.addError(new Error(rbrace.getLine(), ErrorType.g)); } else { TokenNode returnNode = (TokenNode) bit.getChild(0).getChild(0); if (returnNode.getType() != TokenType.RETURNTK) { errors.addError(new Error(rbrace.getLine(), ErrorType.g)); } } } } } }