package frontend.ast.exp; import java.util.ArrayList; import frontend.ast.Node; import frontend.ast.SyntaxType; import frontend.lexer.TokenStream; import frontend.lexer.TokenType; import frontend.ast.token.TokenNode; import frontend.ast.func.FuncRParams; import midend.symbol.FuncSymbol; import midend.symbol.SymbolManager; import error.Errors; import error.Error; import error.ErrorType; public class UnaryExp extends Node { public UnaryExp(TokenStream ts) { super(SyntaxType.UNARY_EXP, ts); } public void parse(Errors errors) { if (isUnaryOp()) { UnaryOp uop = new UnaryOp(ts); uop.parse(errors); addChild(uop); UnaryExp uep = new UnaryExp(ts); uep.parse(errors); addChild(uep); } else if (getCurrToken().getType() == TokenType.IDENFR && this.ts.peek(1).getType() == TokenType.LPARENT) { addChild(new TokenNode(ts)); // idenfr addChild(new TokenNode(ts)); // lparent if (isExp()) { FuncRParams frp = new FuncRParams(ts); frp.parse(errors); addChild(frp); } if (getCurrToken().getType() == TokenType.RPARENT) { addChild(new TokenNode(ts)); // rparent } else { errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); } } else { PrimaryExp pme = new PrimaryExp(ts); pme.parse(errors); addChild(pme); } } public boolean isUnaryOp() { return getCurrToken().getType() == TokenType.PLUS || getCurrToken().getType() == TokenType.MINU || getCurrToken().getType() == TokenType.NOT; } public boolean isExp() { TokenType t = getCurrToken().getType(); return t == TokenType.PLUS || t == TokenType.MINU || t == TokenType.NOT || t == TokenType.IDENFR || t == TokenType.LPARENT || t == TokenType.INTCON; } public void handleFuncCall(Errors errors) { // 当其为函数调用形式时才会调用 TokenNode funcIdenfr = (TokenNode) getChild(0); if (funcIdenfr.getName().equals("getint")) { if (getChildren().size() == 4) { errors.addError(new Error(funcIdenfr.getLine(), ErrorType.d)); } return; } FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol(funcIdenfr.getName()); if (funcSymbol == null) { errors.addError(new Error(funcIdenfr.getLine(), ErrorType.c)); return; } int fparaNum = funcSymbol.getParamNum(); int rparaNum = 0; if (getChildren().size() >= 3 && getChild(2) instanceof FuncRParams) { FuncRParams frp = (FuncRParams) getChild(2); rparaNum = frp.getParamNum(); if (rparaNum == fparaNum) { frp.checkParamType(funcSymbol, errors, funcIdenfr.getLine()); } } if (fparaNum != rparaNum) { errors.addError(new Error(funcIdenfr.getLine(), ErrorType.d)); } } public int getType() { if (getChild(0) instanceof PrimaryExp) { return ((PrimaryExp) getChild(0)).getType(); } else if (getChild(0) instanceof TokenNode) { return 0; } else { return ((UnaryExp) getChild(1)).getType(); } } public int getValue() { if (getChild(0) instanceof UnaryOp) { UnaryOp uop = (UnaryOp) getChild(0); TokenNode opToken = (TokenNode) uop.getChild(0); return opToken.getType() == TokenType.PLUS ? ((UnaryExp) getChild(1)).getValue() : -((UnaryExp) getChild(1)).getValue(); } else if (getChild(0) instanceof PrimaryExp) { return ((PrimaryExp) getChild(0)).getValue(); } else { return 0; // 0表示这个是函数,getvalue只是对于常量或常量表达式取值,所以正常情况调用getvalue函数时是不会跳转到这个分支的 } } public ArrayList getParamList() { if (!(getChild(0) instanceof TokenNode)) { return null; } else { if (getChildren().size() >= 3 && (getChild(2) instanceof FuncRParams)) { return ((FuncRParams) getChild(2)).getParamList(); } return new ArrayList(); } } }