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 getExpList() { ArrayList 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); } }