Exemplo n.º 1
0
        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;
        }
Exemplo n.º 2
0
        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);
        }