mips without optimize

This commit is contained in:
colden
2025-12-12 20:14:00 +08:00
parent 84827838e2
commit c94bebf37b
130 changed files with 5462 additions and 4182 deletions

0
frontend/ast/.DS_Store vendored Normal file → Executable file
View File

0
frontend/ast/CompUnit.java Normal file → Executable file
View File

0
frontend/ast/Node.java Normal file → Executable file
View File

46
frontend/ast/NodeStack.java Normal file → Executable file
View File

@@ -1,23 +1,23 @@
package frontend.ast;
import java.util.ArrayList;
public class NodeStack {
private ArrayList<Node> stack;
public NodeStack() {
stack = new ArrayList<Node>();
}
public void push(Node node) {
stack.add(node);
}
public Node pop() {
return stack.remove(stack.size() - 1);
}
public int size() {
return stack.size();
}
}
package frontend.ast;
import java.util.ArrayList;
public class NodeStack {
private ArrayList<Node> stack;
public NodeStack() {
stack = new ArrayList<Node>();
}
public void push(Node node) {
stack.add(node);
}
public Node pop() {
return stack.remove(stack.size() - 1);
}
public int size() {
return stack.size();
}
}

0
frontend/ast/SyntaxType.java Normal file → Executable file
View File

0
frontend/ast/block/Block.java Normal file → Executable file
View File

56
frontend/ast/block/BlockItem.java Normal file → Executable file
View File

@@ -1,28 +1,28 @@
package frontend.ast.block;
import error.Errors;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.decl.Decl;
public class BlockItem extends Node {
public BlockItem(TokenStream ts) {
super(SyntaxType.BLOCK_ITEM, ts);
}
public void parse(Errors errors) {
if (getCurrToken().getType() == TokenType.CONSTTK
|| getCurrToken().getType() == TokenType.STATICTK
|| getCurrToken().getType() == TokenType.INTTK) {
Decl decl = new Decl(this.ts);
decl.parse(errors);
addChild(decl);
} else {
Stmt stmt = new Stmt(this.ts);
stmt.parse(errors);
addChild(stmt);
}
}
}
package frontend.ast.block;
import error.Errors;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.decl.Decl;
public class BlockItem extends Node {
public BlockItem(TokenStream ts) {
super(SyntaxType.BLOCK_ITEM, ts);
}
public void parse(Errors errors) {
if (getCurrToken().getType() == TokenType.CONSTTK
|| getCurrToken().getType() == TokenType.STATICTK
|| getCurrToken().getType() == TokenType.INTTK) {
Decl decl = new Decl(this.ts);
decl.parse(errors);
addChild(decl);
} else {
Stmt stmt = new Stmt(this.ts);
stmt.parse(errors);
addChild(stmt);
}
}
}

114
frontend/ast/block/ForStmt.java Normal file → Executable file
View File

@@ -1,57 +1,57 @@
package frontend.ast.block;
import frontend.ast.SyntaxType;
import frontend.ast.token.TokenNode;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.Node;
import frontend.ast.exp.Exp;
import frontend.ast.exp.LVal;
import java.util.ArrayList;
import error.Errors;
public class ForStmt extends Node {
public ForStmt(TokenStream ts) {
super(SyntaxType.FOR_STMT, ts);
}
public void parse(Errors errors) {
handleAssign(errors);
while (getCurrToken().getType() == TokenType.COMMA) {
addChild(new TokenNode(ts)); // comma
handleAssign(errors);
}
}
public void handleAssign(Errors errors) {
LVal lval = new LVal(this.ts);
lval.parse(errors);
addChild(lval);
addChild(new TokenNode(ts)); // assign
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
}
public ArrayList<LVal> getLValList() {
ArrayList<LVal> lvalList = new ArrayList<>();
for (int i = 0; i < getChildren().size(); i++) {
if (getChild(i) instanceof LVal) {
lvalList.add((LVal) getChild(i));
}
}
return lvalList;
}
public ArrayList<Exp> getExpList() {
ArrayList<Exp> expList = new ArrayList<>();
for (int i = 0; i < getChildren().size(); i++) {
if (getChild(i) instanceof Exp) {
expList.add((Exp) getChild(i));
}
}
return expList;
}
}
package frontend.ast.block;
import frontend.ast.SyntaxType;
import frontend.ast.token.TokenNode;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.Node;
import frontend.ast.exp.Exp;
import frontend.ast.exp.LVal;
import java.util.ArrayList;
import error.Errors;
public class ForStmt extends Node {
public ForStmt(TokenStream ts) {
super(SyntaxType.FOR_STMT, ts);
}
public void parse(Errors errors) {
handleAssign(errors);
while (getCurrToken().getType() == TokenType.COMMA) {
addChild(new TokenNode(ts)); // comma
handleAssign(errors);
}
}
public void handleAssign(Errors errors) {
LVal lval = new LVal(this.ts);
lval.parse(errors);
addChild(lval);
addChild(new TokenNode(ts)); // assign
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
}
public ArrayList<LVal> getLValList() {
ArrayList<LVal> lvalList = new ArrayList<>();
for (int i = 0; i < getChildren().size(); i++) {
if (getChild(i) instanceof LVal) {
lvalList.add((LVal) getChild(i));
}
}
return lvalList;
}
public ArrayList<Exp> getExpList() {
ArrayList<Exp> expList = new ArrayList<>();
for (int i = 0; i < getChildren().size(); i++) {
if (getChild(i) instanceof Exp) {
expList.add((Exp) getChild(i));
}
}
return expList;
}
}

548
frontend/ast/block/Stmt.java Normal file → Executable file
View File

@@ -1,274 +1,274 @@
package frontend.ast.block;
import error.Errors;
import java.util.ArrayList;
import error.Error;
import error.ErrorType;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import frontend.ast.exp.Exp;
import frontend.ast.exp.Cond;
import frontend.ast.exp.LVal;
public class Stmt extends Node {
private boolean getint;
public Stmt(TokenStream ts) {
super(SyntaxType.STMT, ts);
getint = false;
}
public void parse(Errors errors) {
if (getCurrToken().getType() == TokenType.LBRACE) {
Block block = new Block(this.ts);
block.parse(errors);
addChild(block);
} else if (getCurrToken().getType() == TokenType.IFTK) {
handleIf(errors);
} else if (getCurrToken().getType() == TokenType.FORTK) {
handleFor(errors);
} else if (getCurrToken().getType() == TokenType.BREAKTK) {
TokenNode breakkk = new TokenNode(this.ts);
addChild(breakkk);
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
} else if (getCurrToken().getType() == TokenType.CONTINUETK) {
TokenNode continuekk = new TokenNode(this.ts);
addChild(continuekk);
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
} else if (getCurrToken().getType() == TokenType.RETURNTK) {
handleReturn(errors);
} else if (getCurrToken().getType() == TokenType.PRINTFTK) {
handlePrintf(errors);
} else {
handleAssign(errors);
}
}
public void handleIf(Errors errors) {
TokenNode ifkk = new TokenNode(this.ts);
addChild(ifkk);
TokenNode lparent = new TokenNode(this.ts);
addChild(lparent);
Cond cond = new Cond(this.ts);
cond.parse(errors);
addChild(cond);
if (getCurrToken().getType() == TokenType.RPARENT) {
TokenNode rparent = new TokenNode(this.ts);
addChild(rparent);
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j));
}
Stmt stmt = new Stmt(this.ts);
stmt.parse(errors);
addChild(stmt);
if (getCurrToken().getType() == TokenType.ELSETK) {
TokenNode elsekk = new TokenNode(this.ts);
addChild(elsekk);
Stmt elseStmt = new Stmt(this.ts);
elseStmt.parse(errors);
addChild(elseStmt);
}
}
public void handleFor(Errors errors) {
TokenNode forkk = new TokenNode(this.ts);
addChild(forkk);
TokenNode lparent = new TokenNode(this.ts);
addChild(lparent);
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
ForStmt fst = new ForStmt(this.ts);
fst.parse(errors);
addChild(fst);
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
}
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
Cond cond = new Cond(this.ts);
cond.parse(errors);
addChild(cond);
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
}
if (getCurrToken().getType() == TokenType.RPARENT) {
TokenNode rparent = new TokenNode(this.ts);
addChild(rparent);
} else {
ForStmt fst = new ForStmt(this.ts);
fst.parse(errors);
addChild(fst);
TokenNode rparent = new TokenNode(this.ts);
addChild(rparent);
}
Stmt stmt = new Stmt(this.ts);
stmt.parse(errors);
addChild(stmt);
}
public void handleReturn(Errors errors) {
TokenNode returnkk = new TokenNode(this.ts);
addChild(returnkk);
if (currentIsExp()) {
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
}
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
}
public void handlePrintf(Errors errors) {
TokenNode printfkk = new TokenNode(this.ts);
addChild(printfkk);
addChild(new TokenNode(this.ts)); // lparent
addChild(new TokenNode(this.ts)); // strconst
while (getCurrToken().getType() == TokenType.COMMA) {
addChild(new TokenNode(this.ts)); // comma
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
}
if (getCurrToken().getType() != TokenType.RPARENT) {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j));
} else {
addChild(new TokenNode(this.ts)); // rparent
}
if (getCurrToken().getType() != TokenType.SEMICN) {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
} else {
addChild(new TokenNode(this.ts)); // semicolon
}
}
public void handleAssign(Errors errors) {
if (getCurrToken().getType() == TokenType.IDENFR) {
if (this.ts.peek(1).getType() == TokenType.ASSIGN) {
LVal lval = new LVal(this.ts);
lval.parse(errors);
addChild(lval);
addChild(new TokenNode(this.ts)); // assign
if (getCurrToken().getValue().equals("getint")) {
getint = true;
}
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
if (getCurrToken().getType() == TokenType.SEMICN) {
addChild(new TokenNode(this.ts)); // semicolon
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
} else if (this.ts.peek(1).getType() == TokenType.LBRACK) {
int start = this.ts.getCurrentIndex();
LVal lval = new LVal(this.ts);
lval.parse(errors);
if (getCurrToken().getType() == TokenType.ASSIGN) {
addChild(lval);
addChild(new TokenNode(this.ts)); // assign
if (getCurrToken().getValue().equals("getint")) {
getint = true;
}
handleExpInAssign(errors);
} else {
this.ts.resetIndex(start);
// parse exp ;
handleExpInAssign(errors);
}
} else {
handleExpInAssign(errors);
}
} else {
if (currentIsExp()) {
handleExpInAssign(errors);
} else {
if (getCurrToken().getType() == TokenType.SEMICN) {
addChild(new TokenNode(this.ts)); // semicolon
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
}
}
}
public void handleExpInAssign(Errors errors) {
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
if (getCurrToken().getType() == TokenType.SEMICN) {
addChild(new TokenNode(this.ts)); // semicolon
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
}
public boolean currentIsExp() {
TokenType t = getCurrToken().getType();
return t == TokenType.PLUS || t == TokenType.MINU || t == TokenType.NOT
|| t == TokenType.IDENFR || t == TokenType.LPARENT || t == TokenType.INTCON;
}
public boolean isGetint() {
return getint;
}
public ArrayList<Exp> getExpList() {
ArrayList<Exp> expList = new ArrayList<>();
for (int i = 0; i < getChildren().size(); i++) {
if (getChild(i) instanceof Exp) {
expList.add((Exp) getChild(i));
}
}
return expList;
}
public Cond getCond() { //just for fortype stmt
for (int i = 0; i < getChildren().size(); i++) {
if (getChild(i) instanceof Cond) {
return (Cond) getChild(i);
}
}
return null;
}
public ForStmt getinitStmt() {
if (getChild(2) instanceof ForStmt) {
return (ForStmt) getChild(2);
}
return null;
}
public ForStmt getStepStmt() {
if (getChild(getChildren().size() - 3) instanceof ForStmt) {
return (ForStmt) getChild(getChildren().size() - 3);
}
return null;
}
public Stmt getBodyStmt() {
return (Stmt) getChild(getChildren().size() - 1);
}
}
package frontend.ast.block;
import error.Errors;
import java.util.ArrayList;
import error.Error;
import error.ErrorType;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import frontend.ast.exp.Exp;
import frontend.ast.exp.Cond;
import frontend.ast.exp.LVal;
public class Stmt extends Node {
private boolean getint;
public Stmt(TokenStream ts) {
super(SyntaxType.STMT, ts);
getint = false;
}
public void parse(Errors errors) {
if (getCurrToken().getType() == TokenType.LBRACE) {
Block block = new Block(this.ts);
block.parse(errors);
addChild(block);
} else if (getCurrToken().getType() == TokenType.IFTK) {
handleIf(errors);
} else if (getCurrToken().getType() == TokenType.FORTK) {
handleFor(errors);
} else if (getCurrToken().getType() == TokenType.BREAKTK) {
TokenNode breakkk = new TokenNode(this.ts);
addChild(breakkk);
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
} else if (getCurrToken().getType() == TokenType.CONTINUETK) {
TokenNode continuekk = new TokenNode(this.ts);
addChild(continuekk);
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
} else if (getCurrToken().getType() == TokenType.RETURNTK) {
handleReturn(errors);
} else if (getCurrToken().getType() == TokenType.PRINTFTK) {
handlePrintf(errors);
} else {
handleAssign(errors);
}
}
public void handleIf(Errors errors) {
TokenNode ifkk = new TokenNode(this.ts);
addChild(ifkk);
TokenNode lparent = new TokenNode(this.ts);
addChild(lparent);
Cond cond = new Cond(this.ts);
cond.parse(errors);
addChild(cond);
if (getCurrToken().getType() == TokenType.RPARENT) {
TokenNode rparent = new TokenNode(this.ts);
addChild(rparent);
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j));
}
Stmt stmt = new Stmt(this.ts);
stmt.parse(errors);
addChild(stmt);
if (getCurrToken().getType() == TokenType.ELSETK) {
TokenNode elsekk = new TokenNode(this.ts);
addChild(elsekk);
Stmt elseStmt = new Stmt(this.ts);
elseStmt.parse(errors);
addChild(elseStmt);
}
}
public void handleFor(Errors errors) {
TokenNode forkk = new TokenNode(this.ts);
addChild(forkk);
TokenNode lparent = new TokenNode(this.ts);
addChild(lparent);
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
ForStmt fst = new ForStmt(this.ts);
fst.parse(errors);
addChild(fst);
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
}
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
Cond cond = new Cond(this.ts);
cond.parse(errors);
addChild(cond);
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
}
if (getCurrToken().getType() == TokenType.RPARENT) {
TokenNode rparent = new TokenNode(this.ts);
addChild(rparent);
} else {
ForStmt fst = new ForStmt(this.ts);
fst.parse(errors);
addChild(fst);
TokenNode rparent = new TokenNode(this.ts);
addChild(rparent);
}
Stmt stmt = new Stmt(this.ts);
stmt.parse(errors);
addChild(stmt);
}
public void handleReturn(Errors errors) {
TokenNode returnkk = new TokenNode(this.ts);
addChild(returnkk);
if (currentIsExp()) {
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
}
if (getCurrToken().getType() == TokenType.SEMICN) {
TokenNode semicolon = new TokenNode(this.ts);
addChild(semicolon);
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
}
public void handlePrintf(Errors errors) {
TokenNode printfkk = new TokenNode(this.ts);
addChild(printfkk);
addChild(new TokenNode(this.ts)); // lparent
addChild(new TokenNode(this.ts)); // strconst
while (getCurrToken().getType() == TokenType.COMMA) {
addChild(new TokenNode(this.ts)); // comma
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
}
if (getCurrToken().getType() != TokenType.RPARENT) {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j));
} else {
addChild(new TokenNode(this.ts)); // rparent
}
if (getCurrToken().getType() != TokenType.SEMICN) {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
} else {
addChild(new TokenNode(this.ts)); // semicolon
}
}
public void handleAssign(Errors errors) {
if (getCurrToken().getType() == TokenType.IDENFR) {
if (this.ts.peek(1).getType() == TokenType.ASSIGN) {
LVal lval = new LVal(this.ts);
lval.parse(errors);
addChild(lval);
addChild(new TokenNode(this.ts)); // assign
if (getCurrToken().getValue().equals("getint")) {
getint = true;
}
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
if (getCurrToken().getType() == TokenType.SEMICN) {
addChild(new TokenNode(this.ts)); // semicolon
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
} else if (this.ts.peek(1).getType() == TokenType.LBRACK) {
int start = this.ts.getCurrentIndex();
LVal lval = new LVal(this.ts);
lval.parse(errors);
if (getCurrToken().getType() == TokenType.ASSIGN) {
addChild(lval);
addChild(new TokenNode(this.ts)); // assign
if (getCurrToken().getValue().equals("getint")) {
getint = true;
}
handleExpInAssign(errors);
} else {
this.ts.resetIndex(start);
// parse exp ;
handleExpInAssign(errors);
}
} else {
handleExpInAssign(errors);
}
} else {
if (currentIsExp()) {
handleExpInAssign(errors);
} else {
if (getCurrToken().getType() == TokenType.SEMICN) {
addChild(new TokenNode(this.ts)); // semicolon
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
}
}
}
public void handleExpInAssign(Errors errors) {
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
if (getCurrToken().getType() == TokenType.SEMICN) {
addChild(new TokenNode(this.ts)); // semicolon
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i));
}
}
public boolean currentIsExp() {
TokenType t = getCurrToken().getType();
return t == TokenType.PLUS || t == TokenType.MINU || t == TokenType.NOT
|| t == TokenType.IDENFR || t == TokenType.LPARENT || t == TokenType.INTCON;
}
public boolean isGetint() {
return getint;
}
public ArrayList<Exp> getExpList() {
ArrayList<Exp> expList = new ArrayList<>();
for (int i = 0; i < getChildren().size(); i++) {
if (getChild(i) instanceof Exp) {
expList.add((Exp) getChild(i));
}
}
return expList;
}
public Cond getCond() { //just for fortype stmt
for (int i = 0; i < getChildren().size(); i++) {
if (getChild(i) instanceof Cond) {
return (Cond) getChild(i);
}
}
return null;
}
public ForStmt getinitStmt() {
if (getChild(2) instanceof ForStmt) {
return (ForStmt) getChild(2);
}
return null;
}
public ForStmt getStepStmt() {
if (getChild(getChildren().size() - 3) instanceof ForStmt) {
return (ForStmt) getChild(getChildren().size() - 3);
}
return null;
}
public Stmt getBodyStmt() {
return (Stmt) getChild(getChildren().size() - 1);
}
}

0
frontend/ast/decl/ConstDecl.java Normal file → Executable file
View File

0
frontend/ast/decl/ConstDef.java Normal file → Executable file
View File

0
frontend/ast/decl/Decl.java Normal file → Executable file
View File

0
frontend/ast/decl/VarDecl.java Normal file → Executable file
View File

0
frontend/ast/decl/VarDef.java Normal file → Executable file
View File

146
frontend/ast/exp/AddExp.java Normal file → Executable file
View File

@@ -1,73 +1,73 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import midend.symbol.SymbolManager;
import error.Errors;
public class AddExp extends Node {
public AddExp(TokenStream ts) {
super(SyntaxType.ADD_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
MulExp mep = new MulExp(this.ts);
mep.parse(errors);
stack.push(mep);
if (isAddOp()) {
stack.push(new TokenNode(ts)); // addop
} else {
break;
}
}
if (stack.size() == 1) {
this.addChild((MulExp) stack.pop());
} else {
AddExp temp = this;
while (stack.size() > 1) {
AddExp ae = new AddExp(this.ts);
MulExp mep = (MulExp) stack.pop();
TokenNode op = (TokenNode) stack.pop();
temp.addChild(ae);
temp.addChild(op);
temp.addChild(mep);
temp = ae;
}
temp.addChild((MulExp) stack.pop());
}
}
public boolean isAddOp() {
TokenType t = getCurrToken().getType();
return t == TokenType.PLUS || t == TokenType.MINU;
}
public int getType() {
if (getChildren().size() == 1) {
return ((MulExp) getChild(0)).getType();
} else {
return ((AddExp) getChild(0)).getType()
| ((MulExp) getChild(2)).getType();
}
}
public int getValue() {
if (getChild(0) instanceof MulExp) {
return ((MulExp) getChild(0)).getValue();
} else {
int left = ((AddExp) getChild(0)).getValue();
int right = ((MulExp) getChild(2)).getValue();
if (((TokenNode) getChild(1)).getType() == TokenType.PLUS) {
return left + right;
} else {
return left - right;
}
}
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import midend.symbol.SymbolManager;
import error.Errors;
public class AddExp extends Node {
public AddExp(TokenStream ts) {
super(SyntaxType.ADD_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
MulExp mep = new MulExp(this.ts);
mep.parse(errors);
stack.push(mep);
if (isAddOp()) {
stack.push(new TokenNode(ts)); // addop
} else {
break;
}
}
if (stack.size() == 1) {
this.addChild((MulExp) stack.pop());
} else {
AddExp temp = this;
while (stack.size() > 1) {
AddExp ae = new AddExp(this.ts);
MulExp mep = (MulExp) stack.pop();
TokenNode op = (TokenNode) stack.pop();
temp.addChild(ae);
temp.addChild(op);
temp.addChild(mep);
temp = ae;
}
temp.addChild((MulExp) stack.pop());
}
}
public boolean isAddOp() {
TokenType t = getCurrToken().getType();
return t == TokenType.PLUS || t == TokenType.MINU;
}
public int getType() {
if (getChildren().size() == 1) {
return ((MulExp) getChild(0)).getType();
} else {
return ((AddExp) getChild(0)).getType()
| ((MulExp) getChild(2)).getType();
}
}
public int getValue() {
if (getChild(0) instanceof MulExp) {
return ((MulExp) getChild(0)).getValue();
} else {
int left = ((AddExp) getChild(0)).getValue();
int right = ((MulExp) getChild(2)).getValue();
if (((TokenNode) getChild(1)).getType() == TokenType.PLUS) {
return left + right;
} else {
return left - right;
}
}
}
}

36
frontend/ast/exp/Cond.java Normal file → Executable file
View File

@@ -1,18 +1,18 @@
package frontend.ast.exp;
import frontend.ast.SyntaxType;
import error.Errors;
import frontend.lexer.TokenStream;
import frontend.ast.Node;
public class Cond extends Node {
public Cond(TokenStream ts) {
super(SyntaxType.COND_EXP, ts);
}
public void parse(Errors errors) {
LOrExp lep = new LOrExp(this.ts);
lep.parse(errors);
addChild(lep);
}
}
package frontend.ast.exp;
import frontend.ast.SyntaxType;
import error.Errors;
import frontend.lexer.TokenStream;
import frontend.ast.Node;
public class Cond extends Node {
public Cond(TokenStream ts) {
super(SyntaxType.COND_EXP, ts);
}
public void parse(Errors errors) {
LOrExp lep = new LOrExp(this.ts);
lep.parse(errors);
addChild(lep);
}
}

0
frontend/ast/exp/ConstExp.java Normal file → Executable file
View File

98
frontend/ast/exp/EqExp.java Normal file → Executable file
View File

@@ -1,49 +1,49 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
public class EqExp extends Node {
public EqExp(TokenStream ts) {
super(SyntaxType.EQ_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
RelExp relexp = new RelExp(this.ts);
relexp.parse(errors);
stack.push(relexp);
if (isEqOp()) {
stack.push(new TokenNode(ts)); // eqop
} else {
break;
}
}
if(stack.size() == 1) {
this.addChild((RelExp)stack.pop());
} else {
EqExp temp = this;
while (stack.size() > 1) {
EqExp eep = new EqExp(this.ts);
RelExp relexp = (RelExp)stack.pop();
TokenNode eqop = (TokenNode)stack.pop();
temp.addChild(eep);
temp.addChild(eqop);
temp.addChild(relexp);
temp = eep;
}
temp.addChild((RelExp)stack.pop());
}
}
public boolean isEqOp() {
TokenType t = getCurrToken().getType();
return t == TokenType.EQL || t == TokenType.NEQ;
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
public class EqExp extends Node {
public EqExp(TokenStream ts) {
super(SyntaxType.EQ_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
RelExp relexp = new RelExp(this.ts);
relexp.parse(errors);
stack.push(relexp);
if (isEqOp()) {
stack.push(new TokenNode(ts)); // eqop
} else {
break;
}
}
if(stack.size() == 1) {
this.addChild((RelExp)stack.pop());
} else {
EqExp temp = this;
while (stack.size() > 1) {
EqExp eep = new EqExp(this.ts);
RelExp relexp = (RelExp)stack.pop();
TokenNode eqop = (TokenNode)stack.pop();
temp.addChild(eep);
temp.addChild(eqop);
temp.addChild(relexp);
temp = eep;
}
temp.addChild((RelExp)stack.pop());
}
}
public boolean isEqOp() {
TokenType t = getCurrToken().getType();
return t == TokenType.EQL || t == TokenType.NEQ;
}
}

0
frontend/ast/exp/Exp.java Normal file → Executable file
View File

88
frontend/ast/exp/LAndExp.java Normal file → Executable file
View File

@@ -1,44 +1,44 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
public class LAndExp extends Node {
public LAndExp(TokenStream ts) {
super(SyntaxType.LAND_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
EqExp eep = new EqExp(this.ts);
eep.parse(errors);
stack.push(eep);
if (getCurrToken().getType() == TokenType.AND) {
stack.push(new TokenNode(ts)); // landop
} else {
break;
}
}
if (stack.size() == 1) {
this.addChild((EqExp)stack.pop());
} else {
LAndExp temp = this;
while(stack.size() > 1) {
LAndExp lae = new LAndExp(this.ts);
EqExp eep = (EqExp)stack.pop();
TokenNode landop = (TokenNode)stack.pop();
temp.addChild(lae);
temp.addChild(landop);
temp.addChild(eep);
temp = lae;
}
temp.addChild((EqExp)stack.pop());
}
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
public class LAndExp extends Node {
public LAndExp(TokenStream ts) {
super(SyntaxType.LAND_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
EqExp eep = new EqExp(this.ts);
eep.parse(errors);
stack.push(eep);
if (getCurrToken().getType() == TokenType.AND) {
stack.push(new TokenNode(ts)); // landop
} else {
break;
}
}
if (stack.size() == 1) {
this.addChild((EqExp)stack.pop());
} else {
LAndExp temp = this;
while(stack.size() > 1) {
LAndExp lae = new LAndExp(this.ts);
EqExp eep = (EqExp)stack.pop();
TokenNode landop = (TokenNode)stack.pop();
temp.addChild(lae);
temp.addChild(landop);
temp.addChild(eep);
temp = lae;
}
temp.addChild((EqExp)stack.pop());
}
}
}

88
frontend/ast/exp/LOrExp.java Normal file → Executable file
View File

@@ -1,44 +1,44 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
public class LOrExp extends Node {
public LOrExp(TokenStream ts) {
super(SyntaxType.LOR_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
LAndExp andexp = new LAndExp(this.ts);
andexp.parse(errors);
stack.push(andexp);
if (getCurrToken().getType() == TokenType.OR) {
stack.push(new TokenNode(ts)); // lorop
} else {
break;
}
}
if (stack.size() == 1) {
this.addChild((LAndExp)stack.pop());
} else {
LOrExp temp = this;
while(stack.size() > 1) {
LOrExp loe = new LOrExp(this.ts);
LAndExp lae = (LAndExp)stack.pop();
TokenNode lorop = (TokenNode)stack.pop();
temp.addChild(loe);
temp.addChild(lorop);
temp.addChild(lae);
temp = loe;
}
temp.addChild((LAndExp)stack.pop());
}
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
public class LOrExp extends Node {
public LOrExp(TokenStream ts) {
super(SyntaxType.LOR_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
LAndExp andexp = new LAndExp(this.ts);
andexp.parse(errors);
stack.push(andexp);
if (getCurrToken().getType() == TokenType.OR) {
stack.push(new TokenNode(ts)); // lorop
} else {
break;
}
}
if (stack.size() == 1) {
this.addChild((LAndExp)stack.pop());
} else {
LOrExp temp = this;
while(stack.size() > 1) {
LOrExp loe = new LOrExp(this.ts);
LAndExp lae = (LAndExp)stack.pop();
TokenNode lorop = (TokenNode)stack.pop();
temp.addChild(loe);
temp.addChild(lorop);
temp.addChild(lae);
temp = loe;
}
temp.addChild((LAndExp)stack.pop());
}
}
}

118
frontend/ast/exp/LVal.java Normal file → Executable file
View File

@@ -1,59 +1,59 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.ast.token.TokenNode;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import midend.symbol.SymbolManager;
import midend.symbol.Symbol;
import midend.symbol.ArraySymbol;
import error.Errors;
import error.Error;
import error.ErrorType;
public class LVal extends Node {
public LVal(TokenStream ts) {
super(SyntaxType.LVAL_EXP, ts);
}
public void parse(Errors errors) {
addChild(new TokenNode(this.ts)); // idenfr
if (getCurrToken().getType() == TokenType.LBRACK) {
addChild(new TokenNode(this.ts)); // lbrack
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
if (getCurrToken().getType() == TokenType.RBRACK) {
addChild(new TokenNode(this.ts)); // rbrack
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.k));
}
}
}
public int getType() {
if (getChildren().size() == 1) {
TokenNode idenfr = (TokenNode) getChild(0);
Symbol symbol = SymbolManager.getSymbol(idenfr.getName());
if (symbol instanceof ArraySymbol) {
return 1;
}
return 0;
} else {
return 0;
}
}
public int getValue() {
TokenNode idenfr = (TokenNode) getChild(0); //idenfr一定是个常量可在符号表找到且有值
if (getChildren().size() == 1) {
Symbol symbol = SymbolManager.getSymbol(idenfr.getName());
return symbol.getValue(0);
} else {
int index = ((Exp) getChild(2)).getValue();
Symbol symbol = SymbolManager.getSymbol(idenfr.getName());
return symbol.getValue(index);
}
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.ast.token.TokenNode;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import midend.symbol.SymbolManager;
import midend.symbol.Symbol;
import midend.symbol.ArraySymbol;
import error.Errors;
import error.Error;
import error.ErrorType;
public class LVal extends Node {
public LVal(TokenStream ts) {
super(SyntaxType.LVAL_EXP, ts);
}
public void parse(Errors errors) {
addChild(new TokenNode(this.ts)); // idenfr
if (getCurrToken().getType() == TokenType.LBRACK) {
addChild(new TokenNode(this.ts)); // lbrack
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
if (getCurrToken().getType() == TokenType.RBRACK) {
addChild(new TokenNode(this.ts)); // rbrack
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.k));
}
}
}
public int getType() {
if (getChildren().size() == 1) {
TokenNode idenfr = (TokenNode) getChild(0);
Symbol symbol = SymbolManager.getSymbol(idenfr.getName());
if (symbol instanceof ArraySymbol) {
return 1;
}
return 0;
} else {
return 0;
}
}
public int getValue() {
TokenNode idenfr = (TokenNode) getChild(0); //idenfr一定是个常量可在符号表找到且有值
if (getChildren().size() == 1) {
Symbol symbol = SymbolManager.getSymbol(idenfr.getName());
return symbol.getValue(0);
} else {
int index = ((Exp) getChild(2)).getValue();
Symbol symbol = SymbolManager.getSymbol(idenfr.getName());
return symbol.getValue(index);
}
}
}

150
frontend/ast/exp/MulExp.java Normal file → Executable file
View File

@@ -1,75 +1,75 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import frontend.ast.NodeStack;
import midend.symbol.SymbolManager;
import error.Errors;
public class MulExp extends Node {
public MulExp(TokenStream ts) {
super(SyntaxType.MUL_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
UnaryExp uep = new UnaryExp(this.ts);
uep.parse(errors);
stack.push(uep);
if (isMulOp()) {
stack.push(new TokenNode(ts)); // mulop
} else {
break;
}
}
if (stack.size() == 1) {
addChild((UnaryExp)stack.pop());
} else {
MulExp temp = this;
while (stack.size() > 1) {
MulExp mep = new MulExp(this.ts);
UnaryExp uep = (UnaryExp) stack.pop();
TokenNode mulop = (TokenNode) stack.pop();
temp.addChild(mep);
temp.addChild(mulop);
temp.addChild(uep);
temp = mep;
}
temp.addChild((UnaryExp)stack.pop());
}
}
public boolean isMulOp() {
TokenType t = getCurrToken().getType();
return t == TokenType.MULT || t == TokenType.DIV || t == TokenType.MOD;
}
public int getType() {
if (getChildren().size() == 1) {
return ((UnaryExp) getChild(0)).getType();
} else {
return ((MulExp) getChild(0)).getType()
| ((UnaryExp) getChild(2)).getType();
}
}
public int getValue() {
if (getChild(0) instanceof UnaryExp) {
return ((UnaryExp) getChild(0)).getValue();
} else {
int left = ((MulExp) getChild(0)).getValue();
int right = ((UnaryExp) getChild(2)).getValue();
if (((TokenNode) getChild(1)).getType() == TokenType.MULT) {
return left * right;
} else if (((TokenNode) getChild(1)).getType() == TokenType.DIV) {
return left / right;
} else {
return left % right;
}
}
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import frontend.ast.NodeStack;
import midend.symbol.SymbolManager;
import error.Errors;
public class MulExp extends Node {
public MulExp(TokenStream ts) {
super(SyntaxType.MUL_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
UnaryExp uep = new UnaryExp(this.ts);
uep.parse(errors);
stack.push(uep);
if (isMulOp()) {
stack.push(new TokenNode(ts)); // mulop
} else {
break;
}
}
if (stack.size() == 1) {
addChild((UnaryExp)stack.pop());
} else {
MulExp temp = this;
while (stack.size() > 1) {
MulExp mep = new MulExp(this.ts);
UnaryExp uep = (UnaryExp) stack.pop();
TokenNode mulop = (TokenNode) stack.pop();
temp.addChild(mep);
temp.addChild(mulop);
temp.addChild(uep);
temp = mep;
}
temp.addChild((UnaryExp)stack.pop());
}
}
public boolean isMulOp() {
TokenType t = getCurrToken().getType();
return t == TokenType.MULT || t == TokenType.DIV || t == TokenType.MOD;
}
public int getType() {
if (getChildren().size() == 1) {
return ((UnaryExp) getChild(0)).getType();
} else {
return ((MulExp) getChild(0)).getType()
| ((UnaryExp) getChild(2)).getType();
}
}
public int getValue() {
if (getChild(0) instanceof UnaryExp) {
return ((UnaryExp) getChild(0)).getValue();
} else {
int left = ((MulExp) getChild(0)).getValue();
int right = ((UnaryExp) getChild(2)).getValue();
if (((TokenNode) getChild(1)).getType() == TokenType.MULT) {
return left * right;
} else if (((TokenNode) getChild(1)).getType() == TokenType.DIV) {
return left / right;
} else {
return left % right;
}
}
}
}

42
frontend/ast/exp/NumberExp.java Normal file → Executable file
View File

@@ -1,21 +1,21 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import error.Errors;
import frontend.ast.token.TokenNode;
public class NumberExp extends Node {
public NumberExp(TokenStream ts) {
super(SyntaxType.NUMBER, ts);
}
public void parse(Errors errors) {
addChild(new TokenNode(ts)); //intconst
}
public int getValue() {
return Integer.parseInt(((TokenNode) getChild(0)).getValue());
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import error.Errors;
import frontend.ast.token.TokenNode;
public class NumberExp extends Node {
public NumberExp(TokenStream ts) {
super(SyntaxType.NUMBER, ts);
}
public void parse(Errors errors) {
addChild(new TokenNode(ts)); //intconst
}
public int getValue() {
return Integer.parseInt(((TokenNode) getChild(0)).getValue());
}
}

116
frontend/ast/exp/PrimaryExp.java Normal file → Executable file
View File

@@ -1,58 +1,58 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
import error.Error;
import error.ErrorType;
public class PrimaryExp extends Node {
public PrimaryExp(TokenStream ts) {
super(SyntaxType.PRIMARY_EXP, ts);
}
public void parse(Errors errors) {
if (getCurrToken().getType() == TokenType.LPARENT) {
addChild(new TokenNode(ts)); // lparent
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
if (getCurrToken().getType() == TokenType.RPARENT) {
addChild(new TokenNode(ts)); // rparent
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j));
}
} else if (getCurrToken().getType() == TokenType.IDENFR) {
LVal lval = new LVal(this.ts);
lval.parse(errors);
addChild(lval);
} else {
NumberExp num = new NumberExp(this.ts);
num.parse(errors);
addChild(num);
}
}
public int getType() {
if (getChild(0) instanceof TokenNode) {
return ((Exp) getChild(1)).getType();
} else if (getChild(0) instanceof LVal) {
return ((LVal) getChild(0)).getType();
} else {
return 0;
}
}
public int getValue() {
if (getChild(0) instanceof TokenNode) {
return ((Exp) getChild(1)).getValue();
} else if (getChild(0) instanceof LVal) {
return ((LVal) getChild(0)).getValue();
} else {
return ((NumberExp) getChild(0)).getValue();
}
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
import error.Error;
import error.ErrorType;
public class PrimaryExp extends Node {
public PrimaryExp(TokenStream ts) {
super(SyntaxType.PRIMARY_EXP, ts);
}
public void parse(Errors errors) {
if (getCurrToken().getType() == TokenType.LPARENT) {
addChild(new TokenNode(ts)); // lparent
Exp exp = new Exp(this.ts);
exp.parse(errors);
addChild(exp);
if (getCurrToken().getType() == TokenType.RPARENT) {
addChild(new TokenNode(ts)); // rparent
} else {
errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j));
}
} else if (getCurrToken().getType() == TokenType.IDENFR) {
LVal lval = new LVal(this.ts);
lval.parse(errors);
addChild(lval);
} else {
NumberExp num = new NumberExp(this.ts);
num.parse(errors);
addChild(num);
}
}
public int getType() {
if (getChild(0) instanceof TokenNode) {
return ((Exp) getChild(1)).getType();
} else if (getChild(0) instanceof LVal) {
return ((LVal) getChild(0)).getType();
} else {
return 0;
}
}
public int getValue() {
if (getChild(0) instanceof TokenNode) {
return ((Exp) getChild(1)).getValue();
} else if (getChild(0) instanceof LVal) {
return ((LVal) getChild(0)).getValue();
} else {
return ((NumberExp) getChild(0)).getValue();
}
}
}

100
frontend/ast/exp/RelExp.java Normal file → Executable file
View File

@@ -1,50 +1,50 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
public class RelExp extends Node {
public RelExp(TokenStream ts) {
super(SyntaxType.REL_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
AddExp addexp = new AddExp(this.ts);
addexp.parse(errors);
stack.push(addexp);
if (isRelOp()) {
stack.push(new TokenNode(ts)); // relop
} else {
break;
}
}
if (stack.size() == 1) {
this.addChild((AddExp)stack.pop());
} else {
RelExp temp = this;
while(stack.size() > 1) {
RelExp rexp = new RelExp(this.ts);
AddExp addexp = (AddExp)stack.pop();
TokenNode relop = (TokenNode)stack.pop();
temp.addChild(rexp);
temp.addChild(relop);
temp.addChild(addexp);
temp = rexp;
}
temp.addChild((AddExp)stack.pop());
}
}
public boolean isRelOp() {
TokenType t = getCurrToken().getType();
return t == TokenType.LSS || t == TokenType.GRE
|| t == TokenType.LEQ || t == TokenType.GEQ;
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.NodeStack;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import frontend.lexer.TokenType;
import frontend.ast.token.TokenNode;
import error.Errors;
public class RelExp extends Node {
public RelExp(TokenStream ts) {
super(SyntaxType.REL_EXP, ts);
}
public void parse(Errors errors) {
NodeStack stack = new NodeStack();
while (true) {
AddExp addexp = new AddExp(this.ts);
addexp.parse(errors);
stack.push(addexp);
if (isRelOp()) {
stack.push(new TokenNode(ts)); // relop
} else {
break;
}
}
if (stack.size() == 1) {
this.addChild((AddExp)stack.pop());
} else {
RelExp temp = this;
while(stack.size() > 1) {
RelExp rexp = new RelExp(this.ts);
AddExp addexp = (AddExp)stack.pop();
TokenNode relop = (TokenNode)stack.pop();
temp.addChild(rexp);
temp.addChild(relop);
temp.addChild(addexp);
temp = rexp;
}
temp.addChild((AddExp)stack.pop());
}
}
public boolean isRelOp() {
TokenType t = getCurrToken().getType();
return t == TokenType.LSS || t == TokenType.GRE
|| t == TokenType.LEQ || t == TokenType.GEQ;
}
}

248
frontend/ast/exp/UnaryExp.java Normal file → Executable file
View File

@@ -1,124 +1,124 @@
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>();
}
}
}
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>();
}
}
}

34
frontend/ast/exp/UnaryOp.java Normal file → Executable file
View File

@@ -1,17 +1,17 @@
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import error.Errors;
import frontend.ast.token.TokenNode;
public class UnaryOp extends Node {
public UnaryOp(TokenStream ts) {
super(SyntaxType.UNARY_OP, ts);
}
public void parse(Errors errors) {
addChild(new TokenNode(ts)); // unary op
}
}
package frontend.ast.exp;
import frontend.ast.Node;
import frontend.ast.SyntaxType;
import frontend.lexer.TokenStream;
import error.Errors;
import frontend.ast.token.TokenNode;
public class UnaryOp extends Node {
public UnaryOp(TokenStream ts) {
super(SyntaxType.UNARY_OP, ts);
}
public void parse(Errors errors) {
addChild(new TokenNode(ts)); // unary op
}
}

0
frontend/ast/func/FuncDef.java Normal file → Executable file
View File

96
frontend/ast/func/FuncFParam.java Normal file → Executable file
View File

@@ -1,49 +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);
//这里不求维数,因为函数形参为数组只是相当于一个指针
}
}
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);
//这里不求维数,因为函数形参为数组只是相当于一个指针
}
}
}

0
frontend/ast/func/FuncFParams.java Normal file → Executable file
View File

114
frontend/ast/func/FuncRParams.java Normal file → Executable file
View File

@@ -1,57 +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;
}
}
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;
}
}

0
frontend/ast/func/FuncType.java Normal file → Executable file
View File

0
frontend/ast/func/MainFuncDef.java Normal file → Executable file
View File

0
frontend/ast/token/TokenNode.java Normal file → Executable file
View File

0
frontend/ast/val/ConstInitVal.java Normal file → Executable file
View File

0
frontend/ast/val/InitVal.java Normal file → Executable file
View File