llvmir some opt
This commit is contained in:
108
frontend/ast/func/FuncDef.java
Normal file
108
frontend/ast/func/FuncDef.java
Normal file
@@ -0,0 +1,108 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
49
frontend/ast/func/FuncFParam.java
Normal file
49
frontend/ast/func/FuncFParam.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package frontend.ast.func;
|
||||
|
||||
import frontend.ast.Node;
|
||||
import frontend.ast.SyntaxType;
|
||||
import frontend.lexer.TokenStream;
|
||||
import frontend.lexer.TokenType;
|
||||
|
||||
import midend.symbol.Symbol;
|
||||
import midend.symbol.SymbolType;
|
||||
import midend.symbol.ArraySymbol;
|
||||
|
||||
import error.Errors;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import error.ErrorType;
|
||||
import error.Error;
|
||||
|
||||
public class FuncFParam extends Node {
|
||||
public FuncFParam(TokenStream ts) {
|
||||
super(SyntaxType.FUNC_FORMAL_PARAM, ts);
|
||||
}
|
||||
|
||||
public void parse(Errors errors) {
|
||||
TokenNode intkk = new TokenNode(this.ts);
|
||||
addChild(intkk);
|
||||
TokenNode ident = new TokenNode(this.ts);
|
||||
addChild(ident);
|
||||
if (getCurrToken().getType() == TokenType.LBRACK) {
|
||||
TokenNode lbrack = new TokenNode(this.ts);
|
||||
addChild(lbrack);
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Symbol getSymbol() {
|
||||
if (getChildren().size() == 2) {
|
||||
TokenNode tn = (TokenNode) getChild(1);
|
||||
return new Symbol(tn.getName(), SymbolType.INT, tn.getLine());
|
||||
} else {
|
||||
TokenNode tn = (TokenNode) getChild(1);
|
||||
return new ArraySymbol(tn.getName(), SymbolType.INT_ARRAY, tn.getLine(), -1);
|
||||
//这里不求维数,因为函数形参为数组只是相当于一个指针
|
||||
}
|
||||
}
|
||||
}
|
||||
38
frontend/ast/func/FuncFParams.java
Normal file
38
frontend/ast/func/FuncFParams.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package frontend.ast.func;
|
||||
|
||||
import error.Errors;
|
||||
import frontend.ast.Node;
|
||||
import frontend.ast.SyntaxType;
|
||||
import frontend.lexer.TokenStream;
|
||||
import frontend.lexer.TokenType;
|
||||
import frontend.ast.token.TokenNode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class FuncFParams extends Node {
|
||||
public FuncFParams(TokenStream ts) {
|
||||
super(SyntaxType.FUNC_FORMAL_PARAM_S, ts);
|
||||
}
|
||||
|
||||
public void parse(Errors errors) {
|
||||
while (true) {
|
||||
FuncFParam ffp = new FuncFParam(this.ts);
|
||||
ffp.parse(errors);
|
||||
addChild(ffp);
|
||||
if (getCurrToken().getType() == TokenType.COMMA) {
|
||||
TokenNode comma = new TokenNode(this.ts);
|
||||
addChild(comma);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<FuncFParam> getParamList() {
|
||||
ArrayList<FuncFParam> paramList = new ArrayList<>();
|
||||
for (int i = 0; i < getChildren().size(); i += 2) {
|
||||
paramList.add((FuncFParam) getChild(i));
|
||||
}
|
||||
return paramList;
|
||||
}
|
||||
}
|
||||
57
frontend/ast/func/FuncRParams.java
Normal file
57
frontend/ast/func/FuncRParams.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package frontend.ast.func;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import frontend.ast.Node;
|
||||
import frontend.ast.SyntaxType;
|
||||
import frontend.lexer.TokenStream;
|
||||
import frontend.lexer.TokenType;
|
||||
import error.Errors;
|
||||
import error.Error;
|
||||
import error.ErrorType;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import frontend.ast.exp.Exp;
|
||||
import midend.symbol.FuncSymbol;
|
||||
|
||||
public class FuncRParams extends Node {
|
||||
public FuncRParams(TokenStream ts) {
|
||||
super(SyntaxType.FUNC_REAL_PARAM_S, ts);
|
||||
}
|
||||
|
||||
public void parse(Errors errors) {
|
||||
while (true) {
|
||||
Exp ep = new Exp(ts);
|
||||
ep.parse(errors);
|
||||
addChild(ep);
|
||||
if (getCurrToken().getType() == TokenType.COMMA) {
|
||||
addChild(new TokenNode(ts)); // comma
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getParamNum() {
|
||||
return (getChildren().size() + 1) / 2;
|
||||
}
|
||||
|
||||
public void checkParamType(FuncSymbol funcSymbol, Errors errors, int line) {
|
||||
int fparaNum = funcSymbol.getParamNum();
|
||||
int rparaNum = getParamNum();
|
||||
int size = rparaNum < fparaNum ? rparaNum : fparaNum;
|
||||
for (int i = 0; i < size; i++) {
|
||||
Exp exp = (Exp) getChild(i * 2);
|
||||
if (exp.getType() != funcSymbol.getParamType(i)) {
|
||||
errors.addError(new Error(line, ErrorType.e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Exp> getParamList() {
|
||||
ArrayList<Exp> paramList = new ArrayList<Exp>();
|
||||
for (int i = 0; i < getChildren().size(); i += 2) {
|
||||
paramList.add((Exp) getChild(i));
|
||||
}
|
||||
return paramList;
|
||||
}
|
||||
}
|
||||
27
frontend/ast/func/FuncType.java
Normal file
27
frontend/ast/func/FuncType.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package frontend.ast.func;
|
||||
|
||||
import error.Errors;
|
||||
import frontend.ast.Node;
|
||||
import frontend.ast.SyntaxType;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import frontend.lexer.TokenStream;
|
||||
import frontend.lexer.TokenType;
|
||||
|
||||
public class FuncType extends Node {
|
||||
public FuncType(TokenStream ts) {
|
||||
super(SyntaxType.FUNC_TYPE, ts);
|
||||
}
|
||||
|
||||
public void parse(Errors errors) {
|
||||
TokenNode ident = new TokenNode(this.ts);
|
||||
addChild(ident);
|
||||
}
|
||||
|
||||
public boolean isVoid() {
|
||||
return ((TokenNode) getChild(0)).getType() == TokenType.VOIDTK;
|
||||
}
|
||||
|
||||
public boolean isInt() {
|
||||
return ((TokenNode) getChild(0)).getType() == TokenType.INTTK;
|
||||
}
|
||||
}
|
||||
60
frontend/ast/func/MainFuncDef.java
Normal file
60
frontend/ast/func/MainFuncDef.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package frontend.ast.func;
|
||||
|
||||
import error.ErrorType;
|
||||
import error.Errors;
|
||||
import error.Error;
|
||||
import frontend.ast.Node;
|
||||
import frontend.ast.SyntaxType;
|
||||
import frontend.ast.block.BlockItem;
|
||||
import frontend.ast.decl.Decl;
|
||||
import frontend.lexer.TokenStream;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import frontend.lexer.TokenType;
|
||||
import frontend.ast.block.Block;
|
||||
|
||||
public class MainFuncDef extends Node {
|
||||
public MainFuncDef(TokenStream ts) {
|
||||
super(SyntaxType.MAIN_FUNC_DEF, ts);
|
||||
}
|
||||
|
||||
public void parse(Errors errors) {
|
||||
TokenNode intkk = new TokenNode(this.ts);
|
||||
addChild(intkk);
|
||||
TokenNode mainkk = new TokenNode(this.ts);
|
||||
addChild(mainkk);
|
||||
TokenNode lparent = new TokenNode(this.ts);
|
||||
addChild(lparent);
|
||||
if (getCurrToken().getType() != TokenType.RPARENT) {
|
||||
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j));
|
||||
} else {
|
||||
TokenNode rparent = new TokenNode(this.ts);
|
||||
addChild(rparent);
|
||||
}
|
||||
Block block = new Block(this.ts);
|
||||
block.setIsFuncBlock(true);
|
||||
block.parse(errors);
|
||||
addChild(block);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user