Files
MY_COMPILER/frontend/ast/exp/UnaryExp.java
2025-12-10 17:58:17 +08:00

125 lines
4.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<Exp> 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<Exp>();
}
}
}