109 lines
4.0 KiB
Java
109 lines
4.0 KiB
Java
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<FuncFParam> 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));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|