private Syntax.Statement ParseStmt() { Syntax.Statement node = null; const string NOT_CYCLE = "оператор можно использовать только внутри цикла"; switch (scan.Peek().type) { case Token.Type.KW_WHILE: this.parse_cycle = true; try { scan.Read(); CheckToken(scan.Peek(), Token.Type.LPAREN, true); Syntax.Expression cond = ParseExpression(); node = new Syntax.WHILE(cond); CheckToken(scan.Peek(), Token.Type.RPAREN, true); ((Syntax.WHILE)node).SetCycleStatement(ParseStmt()); } catch (Exception e) { this.parse_cycle = false; throw e; } break; case Token.Type.KW_DO: this.parse_cycle = true; try { scan.Read(); node = new Syntax.DO(ParseStmt()); CheckToken(scan.Peek(), Token.Type.KW_WHILE, true); CheckToken(scan.Peek(), Token.Type.LPAREN, true); ((Syntax.DO)node).SetCondition(ParseExpression()); CheckToken(scan.Peek(), Token.Type.RPAREN, true); CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); } catch (Exception e) { this.parse_cycle = false; throw e; } break; case Token.Type.KW_FOR: this.parse_cycle = true; try { scan.Read(); CheckToken(scan.Peek(), Token.Type.LPAREN, true); node = new Syntax.FOR(); ((Syntax.FOR)node).SetCounter( ((Syntax.StatementExpression)ParseStmExpression()).GetExpression() ); ((Syntax.FOR)node).SetCondition( ((Syntax.StatementExpression)ParseStmExpression()).GetExpression() ); if (scan.Peek().type != Token.Type.RPAREN) { ((Syntax.FOR)node).SetIncriment(ParseExpression()); } CheckToken(scan.Peek(), Token.Type.RPAREN, true); ((Syntax.FOR)node).SetCycleStatement(ParseStmt()); } catch (Exception e) { this.parse_cycle = false; throw e; } break; case Token.Type.KW_IF: scan.Read(); CheckToken(scan.Peek(), Token.Type.LPAREN, true); node = new Syntax.IF(ParseExpression()); CheckToken(scan.Peek(), Token.Type.RPAREN, true); ((Syntax.IF)node).SetBranchTrue(ParseStmt()); if (scan.Peek().type == Token.Type.KW_ELSE) { scan.Read(); ((Syntax.IF)node).SetBranchFalse(ParseStmt()); } break; case Token.Type.LBRACE: node = ParseCompound(); break; case Token.Type.KW_RETURN: scan.Read(); if (scan.Peek().type != Token.Type.SEMICOLON) { node = new Syntax.RETURN(this.ret_func_type); ((Syntax.RETURN)node).SetValue(ParseExpression()); } else { node = new Syntax.RETURN(this.ret_func_type); ((Syntax.RETURN)node).SetValue(new Syntax.EmptyExpression()); } CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); break; case Token.Type.KW_BREAK: if (!this.parse_cycle) { this.logger.Add(new Syntax.Exception(NOT_CYCLE, scan.GetPos(), scan.GetLine())); } try { scan.Read(); node = new Syntax.BREAK(); CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); } catch (Exception e) { if (this.parse_cycle) { throw e; } } break; case Token.Type.KW_CONTINUE: if (!this.parse_cycle) { this.logger.Add(new Syntax.Exception(NOT_CYCLE, scan.GetPos(), scan.GetLine())); } try { scan.Read(); node = new Syntax.CONTINUE(); CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); } catch (Exception e) { if (this.parse_cycle) { throw e; } } break; default: node = ParseStmExpression(); break; } return node; }
private Syntax.Statement ParseStmt() { Syntax.Statement node = null; const string NOT_CYCLE = "оператор можно использовать только внутри цикла"; switch (scan.Peek().type) { case Token.Type.KW_WHILE: this.parse_cycle = true; try { scan.Read(); CheckToken(scan.Peek(), Token.Type.LPAREN, true); Syntax.Expression cond = ParseExpression(); node = new Syntax.WHILE(cond); CheckToken(scan.Peek(), Token.Type.RPAREN, true); ((Syntax.WHILE)node).SetCycleStatement(ParseStmt()); } catch (Exception e) { this.parse_cycle = false; throw e; } break; case Token.Type.KW_DO: this.parse_cycle = true; try { scan.Read(); node = new Syntax.DO(ParseStmt()); CheckToken(scan.Peek(), Token.Type.KW_WHILE, true); CheckToken(scan.Peek(), Token.Type.LPAREN, true); ((Syntax.DO)node).SetCondition(ParseExpression()); CheckToken(scan.Peek(), Token.Type.RPAREN, true); CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); } catch (Exception e) { this.parse_cycle = false; throw e; } break; case Token.Type.KW_FOR: this.parse_cycle = true; try { scan.Read(); CheckToken(scan.Peek(), Token.Type.LPAREN, true); node = new Syntax.FOR(); ((Syntax.FOR)node).SetCounter( ((Syntax.StatementExpression)ParseStmExpression()).GetExpression() ); ((Syntax.FOR)node).SetCondition( ((Syntax.StatementExpression)ParseStmExpression()).GetExpression() ); if (scan.Peek().type != Token.Type.RPAREN) { ((Syntax.FOR)node).SetIncriment(ParseExpression()); } CheckToken(scan.Peek(), Token.Type.RPAREN, true); ((Syntax.FOR)node).SetCycleStatement(ParseStmt()); } catch (Exception e) { this.parse_cycle = false; throw e; } break; case Token.Type.KW_IF: scan.Read(); CheckToken(scan.Peek(), Token.Type.LPAREN, true); node = new Syntax.IF(ParseExpression()); CheckToken(scan.Peek(), Token.Type.RPAREN, true); ((Syntax.IF)node).SetBranchTrue(ParseStmt()); if (scan.Peek().type == Token.Type.KW_ELSE) { scan.Read(); ((Syntax.IF)node).SetBranchFalse(ParseStmt()); } break; case Token.Type.LBRACE: node = ParseCompound(); break; case Token.Type.KW_RETURN: scan.Read(); if (scan.Peek().type != Token.Type.SEMICOLON) { node = new Syntax.RETURN(this.ret_func_type); ((Syntax.RETURN)node).SetValue(ParseExpression()); } else { node = new Syntax.RETURN(this.ret_func_type); ((Syntax.RETURN)node).SetValue(new Syntax.EmptyExpression()); } CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); break; case Token.Type.KW_BREAK: if (!this.parse_cycle) { this.logger.Add(new Syntax.Exception(NOT_CYCLE, scan.GetPos(), scan.GetLine())); } try { scan.Read(); node = new Syntax.BREAK(); CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); } catch (Exception e) { if (this.parse_cycle) { throw e; } } break; case Token.Type.KW_CONTINUE: if (!this.parse_cycle) { this.logger.Add(new Syntax.Exception(NOT_CYCLE, scan.GetPos(), scan.GetLine())); } try { scan.Read(); node = new Syntax.CONTINUE(); CheckToken(scan.Peek(), Token.Type.SEMICOLON, true); } catch (Exception e) { if (this.parse_cycle) { throw e; } } break; default: node = ParseStmExpression(); break; } return(node); }