private StmtNode parseStmt() { while (lex.Peek() == Token.EOL) { lex.Take(); } StmtNode stmt = null; if (lex.Peek() == Token.LET) { stmt = parseCnstDec(); } else if (lex.Peek() == Token.FNC) { stmt = parseFncDec(); } else if (lex.Peek() == Token.PRT) { stmt = parsePrintExp(); } else if (lex.Peek() != Token.EOL && lex.Peek() != Token.EOF) { stmt = new ExpStmtNode(); ((ExpStmtNode)stmt).exp = parseExp(); } if (lex.Peek() != Token.EOL && lex.Peek() != Token.EOF) { throw new ParseException(ref lex.unit, "invalid in expression"); } lex.Take(); return(stmt); }
private static void Check(StmtNode stmt) { if (stmt is FncDecStmtNode) { var fnc = stmt as FncDecStmtNode; var ff = funcs.Find(f => f.ID.lexeme == fnc.ID.lexeme); if (ff == null) { funcs.Add(fnc); } else { error(fnc.FNC, "'" + fnc.ID.lexeme + "' already declared"); } var prms = new List <string>(); foreach (var prm in fnc.paramList) { if (prms.Contains(prm.lexeme)) { error(fnc.FNC, " parameter " + prm.lexeme + " already declared"); } else { prms.Add(prm.lexeme); } } foreach (var prm in prms) { cnsts.Push(prm); } Check(fnc.exp); foreach (var prm in prms) { cnsts.Pop(); } } if (stmt is PrintStmtNode) { var print = stmt as PrintStmtNode; foreach (var exp in print.exps) { Check(exp); } } if (stmt is CnstDecStmtNode) { var cnst = stmt as CnstDecStmtNode; if (!cnsts.Contains(cnst.ID.lexeme)) { cnsts.Push(cnst.ID.lexeme); } else { error(cnst.LET, "'" + cnst.ID.lexeme + "' already defined"); } Check(cnst.exp); } }
public void Visit(StmtNode node) { if (node.AnchorToken.Category == TokenCategory.BREAK && whileLoopDepth == 0) { throw new SemanticError("Encountered break statement outside while loop declaration. ", node.AnchorToken); } foreach (var subnode in node) { Visit((dynamic)subnode); } }
public ProgNode Parse(string code) { lex.init(code); ProgNode prg = new ProgNode(); StmtNode stmt = parseStmt(); while (stmt != null) { prg.stmts.Add(stmt); stmt = parseStmt(); } return(prg); }
private void Block(BlockNode node) { RequiredToken(Tag.DL_LBRACE); while (!TagIs(Tag.DL_RBRACE) && !TagIs(Tag.NULL)) { if (Utils.IsTypeTag(next.Tag) || TagIs(Tag.KW_CONST)) { DeclNode decl = new DeclNode(); node.AddChild(decl); Decl(decl); } else { StmtNode stmt = new StmtNode(); node.AddChild(stmt); Stmt(stmt); } } RequiredToken(Tag.DL_RBRACE); }
public StmtNode_IfElse(int line, ExprNode expr, StmtNode ifStmt, StmtNode elseStmt) : base(line) { Expr = expr; IfStmt = ifStmt; ElseStmt = elseStmt; }
public StmtNode_For(int line, StmtNode first, ExprNode second, StmtNode third, StmtNode body) : base(line) { First = first; Second = second; Third = third; Body = body; }
public FuncMeta(string name, int argCount, StmtNode stmt) { Name = name; ArgCount = argCount; Stmt = stmt; }
internal abstract void Visit(StmtNode node);
private void Stmt(StmtNode node) { switch (next.Tag) { case Tag.KW_TRUE: case Tag.KW_FALSE: case Tag.DL_LPAR: case Tag.DL_PLUS: case Tag.DL_MINUS: case Tag.DL_NOT: case Tag.ID: case Tag.NUM: node.stmt = new ExprNode(); Expr(node.stmt as ExprNode); if ((node.stmt as ExprNode).Type() == VarType.TYPE_ERROR) { new Error().PrintErrMsg(); } RequiredToken(Tag.DL_SEM); break; case Tag.KW_IF: node.stmt = new IfStmtNode(); IfStmt(node.stmt as IfStmtNode); break; case Tag.KW_WHILE: node.stmt = new WhileStmtNode(); WhileStmt(node.stmt as WhileStmtNode); break; case Tag.KW_FOR: node.stmt = new ForStmtNode(); ForStmt(node.stmt as ForStmtNode); break; case Tag.KW_WRITE: node.stmt = new WriteStmtNode(); WriteStmt(node.stmt as WriteStmtNode); break; case Tag.KW_READ: node.stmt = new ReadStmtNode(); ReadStmt(node.stmt as ReadStmtNode); break; case Tag.KW_RETURN: node.stmt = new ReturnStmtNode(); ReturnStmt(node.stmt as ReturnStmtNode); break; case Tag.DL_LBRACE: node.stmt = new BlockNode(); Block(node.stmt as BlockNode); break; case Tag.DL_SEM: Move(); break; default: new UnknownTokenError().PrintErrMsg(); Move(); break; } }
public Node Stmt() { switch (CurrentToken) { case TokenCategory.IDENTIFIER: var idToken = Expect(TokenCategory.IDENTIFIER); switch (CurrentToken) { case TokenCategory.ASSIGN: Expect(TokenCategory.ASSIGN); var ass = new AssignmentNode() { AnchorToken = idToken }; ass.Add(Expr()); Expect(TokenCategory.SEMICOLON); return(ass); case TokenCategory.INCREMENT: Expect(TokenCategory.INCREMENT); var inc = new IncrementNode() { AnchorToken = idToken }; Expect(TokenCategory.SEMICOLON); return(inc); case TokenCategory.DECREMENT: Expect(TokenCategory.DECREMENT); var dec = new DecrementNode() { AnchorToken = idToken }; Expect(TokenCategory.SEMICOLON); return(dec); case TokenCategory.PARENTHESIS_OPEN: Expect(TokenCategory.PARENTHESIS_OPEN); var fun = new FunCallNode() { AnchorToken = idToken }; fun.Add(ExprList()); Expect(TokenCategory.PARENTHESIS_CLOSE); Expect(TokenCategory.SEMICOLON); return(fun); } break; case TokenCategory.IF: return(If()); case TokenCategory.WHILE: return(While()); case TokenCategory.BREAK: var bre = new StmtNode() { AnchorToken = Expect(TokenCategory.BREAK) }; Expect(TokenCategory.SEMICOLON); return(bre); case TokenCategory.RETURN: return(Return()); case TokenCategory.SEMICOLON: return(new StmtNode() { AnchorToken = Expect(TokenCategory.SEMICOLON) }); default: throw new SyntaxError(firstOfStmt, tokenStream.Current); } throw new SyntaxError(firstOfStmt, tokenStream.Current); }