llvmir some opt
This commit is contained in:
248
frontend/ast/Node.java
Normal file
248
frontend/ast/Node.java
Normal file
@@ -0,0 +1,248 @@
|
||||
package frontend.ast;
|
||||
|
||||
import frontend.ast.decl.Decl;
|
||||
import frontend.ast.func.MainFuncDef;
|
||||
import frontend.lexer.Token;
|
||||
import frontend.lexer.TokenStream;
|
||||
import frontend.ast.block.BlockItem;
|
||||
import frontend.ast.block.ForStmt;
|
||||
import frontend.ast.block.Block;
|
||||
import frontend.ast.decl.ConstDecl;
|
||||
import frontend.ast.decl.ConstDef;
|
||||
import frontend.ast.decl.VarDef;
|
||||
import frontend.ast.exp.UnaryExp;
|
||||
import frontend.ast.func.FuncDef;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import frontend.lexer.TokenType;
|
||||
import frontend.ast.exp.LVal;
|
||||
import frontend.ast.block.Stmt;
|
||||
import frontend.ast.exp.Exp;
|
||||
|
||||
import error.Errors;
|
||||
import error.Error;
|
||||
import error.ErrorType;
|
||||
|
||||
import midend.symbol.FuncSymbol;
|
||||
import midend.symbol.SymbolManager;
|
||||
import midend.symbol.SymbolType;
|
||||
import midend.symbol.Symbol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Node {
|
||||
private SyntaxType type;
|
||||
private ArrayList<Node> children;
|
||||
protected TokenStream ts;
|
||||
|
||||
public Node(SyntaxType type, TokenStream ts) {
|
||||
this.type = type;
|
||||
this.ts = ts;
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void addChild(Node child) {
|
||||
this.children.add(child);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "<" + type.toString() + ">\n";
|
||||
}
|
||||
|
||||
public Token getCurrToken() {
|
||||
return ts.peek(0);
|
||||
} // not change index in ts
|
||||
|
||||
public Token read() {
|
||||
return ts.read();
|
||||
} // change index in ts
|
||||
|
||||
public String getInfo() {
|
||||
String info = "";
|
||||
for (Node child : children) {
|
||||
info += child.getInfo();
|
||||
}
|
||||
if (!(this instanceof Decl || this instanceof BlockItem)) {
|
||||
info += this.toString();
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public ArrayList<Node> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public Node getChild(int index) {
|
||||
return children.get(index);
|
||||
}
|
||||
|
||||
public void fillSymbolTable(boolean isInFunc,
|
||||
boolean isInFor, Errors errors) {
|
||||
if (this instanceof CompUnit || (this instanceof Block && !isInFunc)) {
|
||||
SymbolManager.addSymbolTable();
|
||||
}
|
||||
if (this instanceof Decl) {
|
||||
handleDecl(errors);
|
||||
}
|
||||
if (this instanceof FuncDef) {
|
||||
handleFuncDef(errors);
|
||||
return;
|
||||
}
|
||||
if (this instanceof UnaryExp && children.get(0) instanceof TokenNode) {
|
||||
handleFuncCall(errors);
|
||||
return;
|
||||
}
|
||||
if (this instanceof Stmt && getChild(0) instanceof TokenNode
|
||||
&& ((TokenNode) getChild(0)).getType() == TokenType.FORTK) {
|
||||
for (Node child: children) {
|
||||
child.fillSymbolTable(false, true, errors);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (this instanceof Stmt && getChild(0) instanceof TokenNode
|
||||
&& (((TokenNode) getChild(0)).getType() == TokenType.BREAKTK
|
||||
|| ((TokenNode) getChild(0)).getType() == TokenType.CONTINUETK)) {
|
||||
if (!isInFor) {
|
||||
errors.addError(new Error(((TokenNode) getChild(0)).getLine(), ErrorType.m));
|
||||
}
|
||||
}
|
||||
if (this instanceof TokenNode) {
|
||||
handleTokenNode(errors);
|
||||
}
|
||||
if (this instanceof Stmt && getChild(0) instanceof LVal) { // error handle
|
||||
handleErrorhInStmt(errors);
|
||||
}
|
||||
if (this instanceof ForStmt) {
|
||||
handleErrorhInStmt(errors);
|
||||
}
|
||||
if (this instanceof Stmt && getChild(0) instanceof TokenNode
|
||||
&& ((TokenNode) getChild(0)).getType() == TokenType.PRINTFTK) {
|
||||
handleMatchFormat(errors);
|
||||
}
|
||||
if (this instanceof MainFuncDef) {
|
||||
((MainFuncDef) this).checkReturnNode(errors);
|
||||
}
|
||||
for (Node child : children) {
|
||||
child.fillSymbolTable(false, isInFor, errors);
|
||||
}
|
||||
if (this instanceof CompUnit || this instanceof Block) {
|
||||
SymbolManager.releaseSymbolTable();
|
||||
// System.out.println("release a symbol table");
|
||||
}
|
||||
// !注意哪些是直接return的,这些直接return的是否处理完整,因为他们直接省略了后续的递归,要么在子方法里重新递归了,要么没有递归的必要,仔细检查!!!
|
||||
}
|
||||
|
||||
public void handleDecl(Errors errors) {
|
||||
if (this.children.get(0) instanceof ConstDecl) {
|
||||
Node constdecl = this.children.get(0);
|
||||
for (int i = 2; i < constdecl.children.size(); i = i + 2) {
|
||||
SymbolManager.addSymbol(((ConstDef) constdecl.children.get(i)).getSymbol(), errors);
|
||||
}
|
||||
} else {
|
||||
Node vardecl = this.children.get(0);
|
||||
if (((TokenNode) vardecl.children.get(0)).getType() == TokenType.STATICTK) {
|
||||
for (int i = 2; i < vardecl.children.size(); i = i + 2) {
|
||||
SymbolManager.addSymbol(
|
||||
((VarDef) vardecl.children.get(i)).getSymbol(1), errors);
|
||||
// System.out.println(((VarDef)
|
||||
// vardecl.children.get(i)).getSymbol(1).toString());
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < vardecl.children.size(); i = i + 2) {
|
||||
SymbolManager.addSymbol(
|
||||
((VarDef) vardecl.children.get(i)).getSymbol(0), errors);
|
||||
// System.out.println(((VarDef)
|
||||
// vardecl.children.get(i)).getSymbol(0).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleFuncDef(Errors errors) {
|
||||
FuncDef funcdef = (FuncDef) this;
|
||||
Symbol funcSymbol = funcdef.getSymbol();
|
||||
// System.out.println(funcSymbol.toString());
|
||||
// System.out.println(SymbolManager.getSymbolTableSize());
|
||||
SymbolManager.addSymbol(funcSymbol, errors);
|
||||
SymbolManager.addSymbolTable();
|
||||
funcdef.addParamSymbol(funcSymbol, errors);
|
||||
if (funcSymbol.getType() == SymbolType.VOID_FUNC) {
|
||||
// int returnStatus = funcdef.getReturnStatus();
|
||||
// TokenNode returnNode = funcdef.getReturnNode();
|
||||
HashMap<TokenNode, Integer> returnNodes = new HashMap<>();
|
||||
funcdef.getReturnNodes(returnNodes);
|
||||
for (TokenNode returnNode : returnNodes.keySet()) {
|
||||
if (returnNodes.get(returnNode) == 2) {
|
||||
errors.addError(new Error(returnNode.getLine(), ErrorType.f));
|
||||
}
|
||||
}
|
||||
} else if (funcSymbol.getType() == SymbolType.INT_FUNC) {
|
||||
funcdef.checkReturnNode(errors);
|
||||
}
|
||||
// 填参数和块里定义的参数,一个问题是这时的释放是该如何判断
|
||||
for (Node child : children) {
|
||||
if (child instanceof Block) {
|
||||
((Block) child).fillSymbolTable(true, false, errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleTokenNode(Errors errors) {
|
||||
TokenNode tokenNode = (TokenNode) this;
|
||||
if (tokenNode.getType() == TokenType.IDENFR && !tokenNode.getName().equals("getint")) {
|
||||
Symbol symbol = SymbolManager.getSymbol(tokenNode.getName());
|
||||
if (symbol == null) {
|
||||
errors.addError(new Error(tokenNode.getLine(), ErrorType.c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleFuncCall(Errors errors) {
|
||||
UnaryExp ue = (UnaryExp) this;
|
||||
ue.handleFuncCall(errors);
|
||||
}
|
||||
|
||||
public void getReturnNodes(HashMap<TokenNode, Integer> returnNodess) { // 0: no return, 1: return void, 2: return int
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
if (getChild(i) instanceof TokenNode &&
|
||||
((TokenNode) getChild(i)).getType() == TokenType.RETURNTK) {
|
||||
if (i == children.size() - 1) {
|
||||
returnNodess.put((TokenNode) getChild(i), 1);
|
||||
}else if (getChild(i+1) instanceof TokenNode) {
|
||||
returnNodess.put((TokenNode) getChild(i), 1);
|
||||
}else {
|
||||
returnNodess.put((TokenNode) getChild(i), 2);
|
||||
}
|
||||
} else if (!(getChild(i) instanceof TokenNode)) {
|
||||
getChild(i).getReturnNodes(returnNodess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleErrorhInStmt(Errors errors) {
|
||||
for (int i = 0; 4 * i < children.size(); i++){
|
||||
TokenNode idenfr = (TokenNode) getChild(4 * i).getChild(0);
|
||||
Symbol symbol = SymbolManager.getSymbol(idenfr.getName());
|
||||
if (symbol != null) {
|
||||
if (symbol.getType() == SymbolType.CONST_INT
|
||||
|| symbol.getType() == SymbolType.CONST_INT_ARRAY) {
|
||||
errors.addError(new Error(idenfr.getLine(), ErrorType.h));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleMatchFormat(Errors errors) {
|
||||
TokenNode strCons = (TokenNode) getChild(2);
|
||||
int formatNum = strCons.getFormatNum();
|
||||
int expNum = 0;
|
||||
for (Node child : children) {
|
||||
if (child instanceof Exp) {
|
||||
expNum++;
|
||||
}
|
||||
}
|
||||
if (formatNum != expNum) {
|
||||
errors.addError(new Error(((TokenNode) getChild(0)).getLine(), ErrorType.l));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user