mips without optimize
This commit is contained in:
0
frontend/.DS_Store
vendored
Normal file → Executable file
0
frontend/.DS_Store
vendored
Normal file → Executable file
0
frontend/ast/.DS_Store
vendored
Normal file → Executable file
0
frontend/ast/.DS_Store
vendored
Normal file → Executable file
0
frontend/ast/CompUnit.java
Normal file → Executable file
0
frontend/ast/CompUnit.java
Normal file → Executable file
0
frontend/ast/Node.java
Normal file → Executable file
0
frontend/ast/Node.java
Normal file → Executable file
46
frontend/ast/NodeStack.java
Normal file → Executable file
46
frontend/ast/NodeStack.java
Normal file → Executable 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
0
frontend/ast/SyntaxType.java
Normal file → Executable file
0
frontend/ast/block/Block.java
Normal file → Executable file
0
frontend/ast/block/Block.java
Normal file → Executable file
56
frontend/ast/block/BlockItem.java
Normal file → Executable file
56
frontend/ast/block/BlockItem.java
Normal file → Executable 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
114
frontend/ast/block/ForStmt.java
Normal file → Executable 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
548
frontend/ast/block/Stmt.java
Normal file → Executable 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
0
frontend/ast/decl/ConstDecl.java
Normal file → Executable file
0
frontend/ast/decl/ConstDef.java
Normal file → Executable file
0
frontend/ast/decl/ConstDef.java
Normal file → Executable file
0
frontend/ast/decl/Decl.java
Normal file → Executable file
0
frontend/ast/decl/Decl.java
Normal file → Executable file
0
frontend/ast/decl/VarDecl.java
Normal file → Executable file
0
frontend/ast/decl/VarDecl.java
Normal file → Executable file
0
frontend/ast/decl/VarDef.java
Normal file → Executable file
0
frontend/ast/decl/VarDef.java
Normal file → Executable file
146
frontend/ast/exp/AddExp.java
Normal file → Executable file
146
frontend/ast/exp/AddExp.java
Normal file → Executable 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
36
frontend/ast/exp/Cond.java
Normal file → Executable 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
0
frontend/ast/exp/ConstExp.java
Normal file → Executable file
98
frontend/ast/exp/EqExp.java
Normal file → Executable file
98
frontend/ast/exp/EqExp.java
Normal file → Executable 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
0
frontend/ast/exp/Exp.java
Normal file → Executable file
88
frontend/ast/exp/LAndExp.java
Normal file → Executable file
88
frontend/ast/exp/LAndExp.java
Normal file → Executable 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
88
frontend/ast/exp/LOrExp.java
Normal file → Executable 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
118
frontend/ast/exp/LVal.java
Normal file → Executable 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
150
frontend/ast/exp/MulExp.java
Normal file → Executable 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
42
frontend/ast/exp/NumberExp.java
Normal file → Executable 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
116
frontend/ast/exp/PrimaryExp.java
Normal file → Executable 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
100
frontend/ast/exp/RelExp.java
Normal file → Executable 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
248
frontend/ast/exp/UnaryExp.java
Normal file → Executable 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
34
frontend/ast/exp/UnaryOp.java
Normal file → Executable 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
0
frontend/ast/func/FuncDef.java
Normal file → Executable file
96
frontend/ast/func/FuncFParam.java
Normal file → Executable file
96
frontend/ast/func/FuncFParam.java
Normal file → Executable 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
0
frontend/ast/func/FuncFParams.java
Normal file → Executable file
114
frontend/ast/func/FuncRParams.java
Normal file → Executable file
114
frontend/ast/func/FuncRParams.java
Normal file → Executable 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
0
frontend/ast/func/FuncType.java
Normal file → Executable file
0
frontend/ast/func/MainFuncDef.java
Normal file → Executable file
0
frontend/ast/func/MainFuncDef.java
Normal file → Executable file
0
frontend/ast/token/TokenNode.java
Normal file → Executable file
0
frontend/ast/token/TokenNode.java
Normal file → Executable file
0
frontend/ast/val/ConstInitVal.java
Normal file → Executable file
0
frontend/ast/val/ConstInitVal.java
Normal file → Executable file
0
frontend/ast/val/InitVal.java
Normal file → Executable file
0
frontend/ast/val/InitVal.java
Normal file → Executable file
490
frontend/lexer/Lexer.java
Normal file → Executable file
490
frontend/lexer/Lexer.java
Normal file → Executable file
@@ -1,245 +1,245 @@
|
||||
package frontend.lexer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import error.Error;
|
||||
import error.ErrorType;
|
||||
import error.Errors;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Lexer {
|
||||
private String input;
|
||||
private ArrayList<Token> tokens;
|
||||
private int position;
|
||||
private int line;
|
||||
private char currentChar;
|
||||
|
||||
public Lexer(String input) {
|
||||
this.input = input;
|
||||
this.tokens = new ArrayList<Token>();
|
||||
this.position = 0;
|
||||
this.line = 1;
|
||||
}
|
||||
|
||||
public void lex(Errors errors) {
|
||||
int sigComment = 0;
|
||||
while (this.position < this.input.length()) {
|
||||
currentChar = this.input.charAt(this.position);
|
||||
if (currentChar == ' ' || currentChar == '\t') {
|
||||
this.position++;
|
||||
continue;
|
||||
}
|
||||
if (currentChar == '\n' || currentChar == '\r') {
|
||||
if (currentChar == '\r') {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '\n') {
|
||||
this.position++;
|
||||
}
|
||||
}
|
||||
this.line++;
|
||||
this.position++;
|
||||
if (sigComment == 1) {
|
||||
sigComment = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sigComment == 0) {
|
||||
if (currentChar == '/') {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '/') {
|
||||
sigComment = 1;
|
||||
this.position += 2;
|
||||
continue;
|
||||
}
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '*') {
|
||||
sigComment = 2;
|
||||
this.position += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (this.isIntCons()) {
|
||||
lexInt();
|
||||
continue;
|
||||
}
|
||||
if (this.isStrCons()) {
|
||||
lexStr();
|
||||
continue;
|
||||
}
|
||||
if (this.isIdenfr()) {
|
||||
lexIdenfr();
|
||||
continue;
|
||||
}
|
||||
lexOp(errors);
|
||||
}
|
||||
if (sigComment == 2) {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.currentChar == '*' && this.input.charAt(this.position + 1) == '/') {
|
||||
sigComment = 0;
|
||||
this.position += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (sigComment != 0) {
|
||||
this.position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIntCons() {
|
||||
return Character.isDigit(this.currentChar);
|
||||
}
|
||||
|
||||
public boolean isStrCons() {
|
||||
return this.currentChar == '"';
|
||||
}
|
||||
|
||||
public boolean isIdenfr() {
|
||||
return Character.isLowerCase(this.currentChar) || Character.isUpperCase(this.currentChar)
|
||||
|| this.currentChar == '_';
|
||||
}
|
||||
|
||||
public boolean isNotWp() {
|
||||
return !Character.isWhitespace(this.currentChar);
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
return !this.isIntCons() && !this.isStrCons() && !this.isIdenfr();
|
||||
}
|
||||
|
||||
public void lexInt() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (this.position < this.input.length() && this.isIntCons()) {
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
updateCurrentChar();
|
||||
}
|
||||
this.tokens.add(new Token(sb.toString(), this.line));
|
||||
}
|
||||
|
||||
public void lexStr() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
updateCurrentChar();
|
||||
while (this.position < this.input.length() && this.currentChar != '"') {
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
updateCurrentChar();
|
||||
}
|
||||
if (this.position < this.input.length() && this.currentChar == '"') {
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
}
|
||||
this.tokens.add(new Token(sb.toString(), this.line));
|
||||
}
|
||||
|
||||
public void lexIdenfr() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (this.position < this.input.length() && (this.isIdenfr() || this.isIntCons())) {
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
updateCurrentChar();
|
||||
}
|
||||
this.tokens.add(new Token(sb.toString(), this.line));
|
||||
}
|
||||
|
||||
public void lexOp(Errors errors) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (this.currentChar == '/' && this.position + 1 < this.input.length() &&
|
||||
(this.input.charAt(this.position + 1) == '/' ||
|
||||
this.input.charAt(this.position + 1) == '*')) {
|
||||
return;
|
||||
}
|
||||
sb.append(this.currentChar);
|
||||
switch (this.currentChar) {
|
||||
case '&':
|
||||
readAnd(sb);
|
||||
break;
|
||||
case '|':
|
||||
readOr(sb);
|
||||
break;
|
||||
case '<':
|
||||
readEq(sb);
|
||||
break;
|
||||
case '>':
|
||||
readEq(sb);
|
||||
break;
|
||||
case '=':
|
||||
readEq(sb);
|
||||
break;
|
||||
case '!':
|
||||
readEq(sb);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.position++;
|
||||
if (sb.toString().equals("&") || sb.toString().equals("|")) {
|
||||
errors.addError(new Error(this.line, ErrorType.a));
|
||||
}
|
||||
this.tokens.add(new Token(sb.toString(), this.line));
|
||||
}
|
||||
|
||||
public void readAnd(StringBuilder sb) {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '&') {
|
||||
this.position++;
|
||||
currentChar = this.input.charAt(this.position);
|
||||
sb.append(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
public void readOr(StringBuilder sb) {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '|') {
|
||||
this.position++;
|
||||
currentChar = this.input.charAt(this.position);
|
||||
sb.append(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
public void readEq(StringBuilder sb) {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '=') {
|
||||
this.position++;
|
||||
currentChar = this.input.charAt(this.position);
|
||||
sb.append(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCurrentChar() {
|
||||
if (this.position < this.input.length()) {
|
||||
currentChar = this.input.charAt(this.position);
|
||||
}
|
||||
}
|
||||
|
||||
public void printTokens() {
|
||||
for (Token token : this.tokens) {
|
||||
token.adjustType();
|
||||
System.out.println(token.getType() + " " + token.getValue() + " " + token.getLine());
|
||||
}
|
||||
}
|
||||
|
||||
public void writeToFile(String fileName) {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Token token : this.tokens) {
|
||||
token.adjustType();
|
||||
sb.append(token.toString());
|
||||
}
|
||||
Files.write(Paths.get(fileName), sb.toString().getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Token> getTokens() {
|
||||
for (Token token : this.tokens) {
|
||||
token.adjustType();
|
||||
}
|
||||
return this.tokens;
|
||||
}
|
||||
}
|
||||
package frontend.lexer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import error.Error;
|
||||
import error.ErrorType;
|
||||
import error.Errors;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Lexer {
|
||||
private String input;
|
||||
private ArrayList<Token> tokens;
|
||||
private int position;
|
||||
private int line;
|
||||
private char currentChar;
|
||||
|
||||
public Lexer(String input) {
|
||||
this.input = input;
|
||||
this.tokens = new ArrayList<Token>();
|
||||
this.position = 0;
|
||||
this.line = 1;
|
||||
}
|
||||
|
||||
public void lex(Errors errors) {
|
||||
int sigComment = 0;
|
||||
while (this.position < this.input.length()) {
|
||||
currentChar = this.input.charAt(this.position);
|
||||
if (currentChar == ' ' || currentChar == '\t') {
|
||||
this.position++;
|
||||
continue;
|
||||
}
|
||||
if (currentChar == '\n' || currentChar == '\r') {
|
||||
if (currentChar == '\r') {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '\n') {
|
||||
this.position++;
|
||||
}
|
||||
}
|
||||
this.line++;
|
||||
this.position++;
|
||||
if (sigComment == 1) {
|
||||
sigComment = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sigComment == 0) {
|
||||
if (currentChar == '/') {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '/') {
|
||||
sigComment = 1;
|
||||
this.position += 2;
|
||||
continue;
|
||||
}
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '*') {
|
||||
sigComment = 2;
|
||||
this.position += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (this.isIntCons()) {
|
||||
lexInt();
|
||||
continue;
|
||||
}
|
||||
if (this.isStrCons()) {
|
||||
lexStr();
|
||||
continue;
|
||||
}
|
||||
if (this.isIdenfr()) {
|
||||
lexIdenfr();
|
||||
continue;
|
||||
}
|
||||
lexOp(errors);
|
||||
}
|
||||
if (sigComment == 2) {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.currentChar == '*' && this.input.charAt(this.position + 1) == '/') {
|
||||
sigComment = 0;
|
||||
this.position += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (sigComment != 0) {
|
||||
this.position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isIntCons() {
|
||||
return Character.isDigit(this.currentChar);
|
||||
}
|
||||
|
||||
public boolean isStrCons() {
|
||||
return this.currentChar == '"';
|
||||
}
|
||||
|
||||
public boolean isIdenfr() {
|
||||
return Character.isLowerCase(this.currentChar) || Character.isUpperCase(this.currentChar)
|
||||
|| this.currentChar == '_';
|
||||
}
|
||||
|
||||
public boolean isNotWp() {
|
||||
return !Character.isWhitespace(this.currentChar);
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
return !this.isIntCons() && !this.isStrCons() && !this.isIdenfr();
|
||||
}
|
||||
|
||||
public void lexInt() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (this.position < this.input.length() && this.isIntCons()) {
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
updateCurrentChar();
|
||||
}
|
||||
this.tokens.add(new Token(sb.toString(), this.line));
|
||||
}
|
||||
|
||||
public void lexStr() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
updateCurrentChar();
|
||||
while (this.position < this.input.length() && this.currentChar != '"') {
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
updateCurrentChar();
|
||||
}
|
||||
if (this.position < this.input.length() && this.currentChar == '"') {
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
}
|
||||
this.tokens.add(new Token(sb.toString(), this.line));
|
||||
}
|
||||
|
||||
public void lexIdenfr() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (this.position < this.input.length() && (this.isIdenfr() || this.isIntCons())) {
|
||||
sb.append(this.currentChar);
|
||||
this.position++;
|
||||
updateCurrentChar();
|
||||
}
|
||||
this.tokens.add(new Token(sb.toString(), this.line));
|
||||
}
|
||||
|
||||
public void lexOp(Errors errors) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (this.currentChar == '/' && this.position + 1 < this.input.length() &&
|
||||
(this.input.charAt(this.position + 1) == '/' ||
|
||||
this.input.charAt(this.position + 1) == '*')) {
|
||||
return;
|
||||
}
|
||||
sb.append(this.currentChar);
|
||||
switch (this.currentChar) {
|
||||
case '&':
|
||||
readAnd(sb);
|
||||
break;
|
||||
case '|':
|
||||
readOr(sb);
|
||||
break;
|
||||
case '<':
|
||||
readEq(sb);
|
||||
break;
|
||||
case '>':
|
||||
readEq(sb);
|
||||
break;
|
||||
case '=':
|
||||
readEq(sb);
|
||||
break;
|
||||
case '!':
|
||||
readEq(sb);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.position++;
|
||||
if (sb.toString().equals("&") || sb.toString().equals("|")) {
|
||||
errors.addError(new Error(this.line, ErrorType.a));
|
||||
}
|
||||
this.tokens.add(new Token(sb.toString(), this.line));
|
||||
}
|
||||
|
||||
public void readAnd(StringBuilder sb) {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '&') {
|
||||
this.position++;
|
||||
currentChar = this.input.charAt(this.position);
|
||||
sb.append(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
public void readOr(StringBuilder sb) {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '|') {
|
||||
this.position++;
|
||||
currentChar = this.input.charAt(this.position);
|
||||
sb.append(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
public void readEq(StringBuilder sb) {
|
||||
if (this.position + 1 < this.input.length() &&
|
||||
this.input.charAt(this.position + 1) == '=') {
|
||||
this.position++;
|
||||
currentChar = this.input.charAt(this.position);
|
||||
sb.append(currentChar);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCurrentChar() {
|
||||
if (this.position < this.input.length()) {
|
||||
currentChar = this.input.charAt(this.position);
|
||||
}
|
||||
}
|
||||
|
||||
public void printTokens() {
|
||||
for (Token token : this.tokens) {
|
||||
token.adjustType();
|
||||
System.out.println(token.getType() + " " + token.getValue() + " " + token.getLine());
|
||||
}
|
||||
}
|
||||
|
||||
public void writeToFile(String fileName) {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Token token : this.tokens) {
|
||||
token.adjustType();
|
||||
sb.append(token.toString());
|
||||
}
|
||||
Files.write(Paths.get(fileName), sb.toString().getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Token> getTokens() {
|
||||
for (Token token : this.tokens) {
|
||||
token.adjustType();
|
||||
}
|
||||
return this.tokens;
|
||||
}
|
||||
}
|
||||
|
||||
84
frontend/lexer/Token.java
Normal file → Executable file
84
frontend/lexer/Token.java
Normal file → Executable file
@@ -1,42 +1,42 @@
|
||||
package frontend.lexer;
|
||||
|
||||
public class Token {
|
||||
private TokenType type;
|
||||
private String value;
|
||||
private int line;
|
||||
|
||||
public Token(String value, int line) {
|
||||
this.value = value;
|
||||
this.type = TokenType.isWhatType(value);
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
public void adjustType() {
|
||||
if (this.type == TokenType.IDENFR) {
|
||||
if (this.value.charAt(0) == '\"' &&
|
||||
this.value.charAt(this.value.length() - 1) == '\"') {
|
||||
this.type = TokenType.STRCON;
|
||||
}
|
||||
String regex = "^\\d+$";
|
||||
if (this.value.matches(regex)) {
|
||||
this.type = TokenType.INTCON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public TokenType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return this.line;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.type + " " + this.value + "\n";
|
||||
}
|
||||
}
|
||||
package frontend.lexer;
|
||||
|
||||
public class Token {
|
||||
private TokenType type;
|
||||
private String value;
|
||||
private int line;
|
||||
|
||||
public Token(String value, int line) {
|
||||
this.value = value;
|
||||
this.type = TokenType.isWhatType(value);
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
public void adjustType() {
|
||||
if (this.type == TokenType.IDENFR) {
|
||||
if (this.value.charAt(0) == '\"' &&
|
||||
this.value.charAt(this.value.length() - 1) == '\"') {
|
||||
this.type = TokenType.STRCON;
|
||||
}
|
||||
String regex = "^\\d+$";
|
||||
if (this.value.matches(regex)) {
|
||||
this.type = TokenType.INTCON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public TokenType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return this.line;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.type + " " + this.value + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
0
frontend/lexer/TokenStream.java
Normal file → Executable file
0
frontend/lexer/TokenStream.java
Normal file → Executable file
246
frontend/lexer/TokenType.java
Normal file → Executable file
246
frontend/lexer/TokenType.java
Normal file → Executable file
@@ -1,123 +1,123 @@
|
||||
package frontend.lexer;
|
||||
|
||||
public enum TokenType {
|
||||
IDENFR,
|
||||
INTCON,
|
||||
STRCON,
|
||||
CONSTTK,
|
||||
INTTK,
|
||||
STATICTK,
|
||||
BREAKTK,
|
||||
CONTINUETK,
|
||||
IFTK,
|
||||
MAINTK,
|
||||
ELSETK,
|
||||
NOT,
|
||||
AND,
|
||||
OR,
|
||||
FORTK,
|
||||
RETURNTK,
|
||||
VOIDTK,
|
||||
PLUS,
|
||||
MINU,
|
||||
PRINTFTK,
|
||||
MULT,
|
||||
DIV,
|
||||
MOD,
|
||||
LSS,
|
||||
LEQ,
|
||||
GRE,
|
||||
GEQ,
|
||||
EQL,
|
||||
NEQ,
|
||||
SEMICN,
|
||||
COMMA,
|
||||
LPARENT,
|
||||
RPARENT,
|
||||
LBRACK,
|
||||
RBRACK,
|
||||
LBRACE,
|
||||
RBRACE,
|
||||
ASSIGN;
|
||||
|
||||
public static TokenType isWhatType(String str) {
|
||||
switch (str) {
|
||||
case "const":
|
||||
return TokenType.CONSTTK;
|
||||
case "int":
|
||||
return TokenType.INTTK;
|
||||
case "static":
|
||||
return TokenType.STATICTK;
|
||||
case "break":
|
||||
return TokenType.BREAKTK;
|
||||
case "continue":
|
||||
return TokenType.CONTINUETK;
|
||||
case "if":
|
||||
return TokenType.IFTK;
|
||||
case "main":
|
||||
return TokenType.MAINTK;
|
||||
case "else":
|
||||
return TokenType.ELSETK;
|
||||
case "!":
|
||||
return TokenType.NOT;
|
||||
case "&&":
|
||||
return TokenType.AND;
|
||||
case "&":
|
||||
return TokenType.AND;
|
||||
case "||":
|
||||
return TokenType.OR;
|
||||
case "|":
|
||||
return TokenType.OR;
|
||||
case "for":
|
||||
return TokenType.FORTK;
|
||||
case "return":
|
||||
return TokenType.RETURNTK;
|
||||
case "void":
|
||||
return TokenType.VOIDTK;
|
||||
case "+":
|
||||
return TokenType.PLUS;
|
||||
case "-":
|
||||
return TokenType.MINU;
|
||||
case "printf":
|
||||
return TokenType.PRINTFTK;
|
||||
case "*":
|
||||
return TokenType.MULT;
|
||||
case "/":
|
||||
return TokenType.DIV;
|
||||
case "%":
|
||||
return TokenType.MOD;
|
||||
case "<":
|
||||
return TokenType.LSS;
|
||||
case "<=":
|
||||
return TokenType.LEQ;
|
||||
case ">":
|
||||
return TokenType.GRE;
|
||||
case ">=":
|
||||
return TokenType.GEQ;
|
||||
case "==":
|
||||
return TokenType.EQL;
|
||||
case "!=":
|
||||
return TokenType.NEQ;
|
||||
case ";":
|
||||
return TokenType.SEMICN;
|
||||
case ",":
|
||||
return TokenType.COMMA;
|
||||
case "(":
|
||||
return TokenType.LPARENT;
|
||||
case ")":
|
||||
return TokenType.RPARENT;
|
||||
case "[":
|
||||
return TokenType.LBRACK;
|
||||
case "]":
|
||||
return TokenType.RBRACK;
|
||||
case "{":
|
||||
return TokenType.LBRACE;
|
||||
case "}":
|
||||
return TokenType.RBRACE;
|
||||
case "=":
|
||||
return TokenType.ASSIGN;
|
||||
default:
|
||||
return TokenType.IDENFR;
|
||||
}
|
||||
}
|
||||
}
|
||||
package frontend.lexer;
|
||||
|
||||
public enum TokenType {
|
||||
IDENFR,
|
||||
INTCON,
|
||||
STRCON,
|
||||
CONSTTK,
|
||||
INTTK,
|
||||
STATICTK,
|
||||
BREAKTK,
|
||||
CONTINUETK,
|
||||
IFTK,
|
||||
MAINTK,
|
||||
ELSETK,
|
||||
NOT,
|
||||
AND,
|
||||
OR,
|
||||
FORTK,
|
||||
RETURNTK,
|
||||
VOIDTK,
|
||||
PLUS,
|
||||
MINU,
|
||||
PRINTFTK,
|
||||
MULT,
|
||||
DIV,
|
||||
MOD,
|
||||
LSS,
|
||||
LEQ,
|
||||
GRE,
|
||||
GEQ,
|
||||
EQL,
|
||||
NEQ,
|
||||
SEMICN,
|
||||
COMMA,
|
||||
LPARENT,
|
||||
RPARENT,
|
||||
LBRACK,
|
||||
RBRACK,
|
||||
LBRACE,
|
||||
RBRACE,
|
||||
ASSIGN;
|
||||
|
||||
public static TokenType isWhatType(String str) {
|
||||
switch (str) {
|
||||
case "const":
|
||||
return TokenType.CONSTTK;
|
||||
case "int":
|
||||
return TokenType.INTTK;
|
||||
case "static":
|
||||
return TokenType.STATICTK;
|
||||
case "break":
|
||||
return TokenType.BREAKTK;
|
||||
case "continue":
|
||||
return TokenType.CONTINUETK;
|
||||
case "if":
|
||||
return TokenType.IFTK;
|
||||
case "main":
|
||||
return TokenType.MAINTK;
|
||||
case "else":
|
||||
return TokenType.ELSETK;
|
||||
case "!":
|
||||
return TokenType.NOT;
|
||||
case "&&":
|
||||
return TokenType.AND;
|
||||
case "&":
|
||||
return TokenType.AND;
|
||||
case "||":
|
||||
return TokenType.OR;
|
||||
case "|":
|
||||
return TokenType.OR;
|
||||
case "for":
|
||||
return TokenType.FORTK;
|
||||
case "return":
|
||||
return TokenType.RETURNTK;
|
||||
case "void":
|
||||
return TokenType.VOIDTK;
|
||||
case "+":
|
||||
return TokenType.PLUS;
|
||||
case "-":
|
||||
return TokenType.MINU;
|
||||
case "printf":
|
||||
return TokenType.PRINTFTK;
|
||||
case "*":
|
||||
return TokenType.MULT;
|
||||
case "/":
|
||||
return TokenType.DIV;
|
||||
case "%":
|
||||
return TokenType.MOD;
|
||||
case "<":
|
||||
return TokenType.LSS;
|
||||
case "<=":
|
||||
return TokenType.LEQ;
|
||||
case ">":
|
||||
return TokenType.GRE;
|
||||
case ">=":
|
||||
return TokenType.GEQ;
|
||||
case "==":
|
||||
return TokenType.EQL;
|
||||
case "!=":
|
||||
return TokenType.NEQ;
|
||||
case ";":
|
||||
return TokenType.SEMICN;
|
||||
case ",":
|
||||
return TokenType.COMMA;
|
||||
case "(":
|
||||
return TokenType.LPARENT;
|
||||
case ")":
|
||||
return TokenType.RPARENT;
|
||||
case "[":
|
||||
return TokenType.LBRACK;
|
||||
case "]":
|
||||
return TokenType.RBRACK;
|
||||
case "{":
|
||||
return TokenType.LBRACE;
|
||||
case "}":
|
||||
return TokenType.RBRACE;
|
||||
case "=":
|
||||
return TokenType.ASSIGN;
|
||||
default:
|
||||
return TokenType.IDENFR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
76
frontend/parser/Parser.java
Normal file → Executable file
76
frontend/parser/Parser.java
Normal file → Executable file
@@ -1,38 +1,38 @@
|
||||
package frontend.parser;
|
||||
|
||||
import frontend.ast.CompUnit;
|
||||
import frontend.lexer.TokenStream;
|
||||
|
||||
import java.nio.file.Files;
|
||||
|
||||
import error.Errors;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Parser {
|
||||
private TokenStream ts;
|
||||
private CompUnit compUnit;
|
||||
|
||||
public Parser(TokenStream ts) {
|
||||
this.ts = ts;
|
||||
this.compUnit = new CompUnit(this.ts);
|
||||
}
|
||||
|
||||
public void parse(Errors errors) {
|
||||
compUnit.parse(errors);
|
||||
}
|
||||
|
||||
public CompUnit getCompUnit() {
|
||||
return compUnit;
|
||||
}
|
||||
|
||||
public void writeToFile(String fileName) {
|
||||
try {
|
||||
String info = this.compUnit.getInfo();
|
||||
Files.write(Paths.get(fileName), info.getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
package frontend.parser;
|
||||
|
||||
import frontend.ast.CompUnit;
|
||||
import frontend.lexer.TokenStream;
|
||||
|
||||
import java.nio.file.Files;
|
||||
|
||||
import error.Errors;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Parser {
|
||||
private TokenStream ts;
|
||||
private CompUnit compUnit;
|
||||
|
||||
public Parser(TokenStream ts) {
|
||||
this.ts = ts;
|
||||
this.compUnit = new CompUnit(this.ts);
|
||||
}
|
||||
|
||||
public void parse(Errors errors) {
|
||||
compUnit.parse(errors);
|
||||
}
|
||||
|
||||
public CompUnit getCompUnit() {
|
||||
return compUnit;
|
||||
}
|
||||
|
||||
public void writeToFile(String fileName) {
|
||||
try {
|
||||
String info = this.compUnit.getInfo();
|
||||
Files.write(Paths.get(fileName), info.getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user