コード例 #1
0
        public void ToString_OfForNext_Converts()
        {
            var forNext = new ForNext(new ScalarVariable("I"),
                                      new Constant("1"),
                                      new Constant("5"),
                                      new Constant("1"),
                                      new PrintLine(new[] { new ScalarVariable("I") }));

            var actual = forNext.ToString();

            Assert.AreEqual("FOR I = 1 TO 5 STEP 1 PRINT I NEXT", actual);
        }
コード例 #2
0
        public void Execute_OfForNext_RepeatsInnerStatement()
        {
            var rte              = MakeRunTimeEnvironment();
            var i                = new ScalarVariable("I");
            var from             = new Constant(1);
            var to               = new Constant(10);
            var step             = new Constant(1);
            var shoudBeEqualTo50 = 0;
            var forNext          = new ForNext(i, from, to, step, MakeStatement(() => { shoudBeEqualTo50 += 5; }));

            forNext.Execute(rte);

            Assert.AreEqual(50, shoudBeEqualTo50);
        }
コード例 #3
0
        public static bool TryReadFor(this Scanner scanner, out IStatement result)
        {
            if (scanner.TryReadToken(Token.For))
            {
                ILValue loopVariable = scanner.ReadLValue();
                scanner.ReadToken(Token.Eq);
                IExpression from = scanner.ReadExpression();
                scanner.ReadToken(Token.To);
                IExpression to = scanner.ReadExpression();

                IExpression step = null;
                if (scanner.TryReadToken(Token.Step))
                {
                    step = scanner.ReadExpression();
                }

                if (scanner.CurrentToken == Token.Next)
                {
                    throw new ParserException(ErrorMessages.MissingStatement);
                }

                IStatement statement;
                if (scanner.TryReadStatementExcludingNext(out statement))
                {
                    scanner.ReadToken(Token.Next);
                    result = new ForNext(loopVariable, from, to, step, statement);
                }
                else
                {
                    result = new For(loopVariable, from, to, step);
                }

                return(true);
            }

            result = null;
            return(false);
        }
コード例 #4
0
    private Stmt ParseStmt()
    {
        Stmt result;

        if (this.index == this.tokens.Count)
        {
            throw new System.Exception("expected statement, got EOF");
        }

        // <stmt> := print <expr>

        // <expr> := <string>
        // | <int>
        // | <arith_expr>
        // | <ident>
        if (this.tokens[this.index].Equals("print"))
        {
            this.index++;
            Print print = new Print();

            //Если есть текстовое описание
            if (this.index < this.tokens.Count &&
                this.tokens[this.index] is Text.StringBuilder)
            {
                print.Expression = this.ParseExpr();
            }

            if (this.index < this.tokens.Count &&
                this.tokens[this.index] is string)
            {
                print.VarExpression = this.ParseExpr();
            }

            result = print;
        }
        else if (this.tokens[this.index].Equals("var"))
        {
            this.index++;
            DeclareVar declareVar = new DeclareVar();

            if (this.index < this.tokens.Count &&
                this.tokens[this.index] is string)
            {
                declareVar.Ident = (string)this.tokens[this.index];
            }
            else
            {
                throw new System.Exception("expected variable name after 'var'");
            }

            this.index++;

            if (this.index == this.tokens.Count ||
                this.tokens[this.index] != Scanner.Equal)
            {
                throw new System.Exception("expected = after 'var ident'");
            }

            this.index++;

            declareVar.Expression = this.ParseExpr();
            result = declareVar;
        }
        else if (this.tokens[this.index].Equals("input"))
        {
            this.index++;
            ReadValue readValue = new ReadValue();

            //Если есть текстовое описание
            if (this.index < this.tokens.Count &&
                this.tokens[this.index] is Text.StringBuilder)
            {
                readValue.Exp = this.ParseExpr();
            }

            if (this.index < this.tokens.Count &&
                this.tokens[this.index] is string)
            {
                readValue.Ident = (string)this.tokens[this.index++];
                result          = readValue;
            }
            else
            {
                throw new System.Exception("expected variable name after 'input'");
            }
        }

        /*else if (this.tokens[this.index].Equals("read_int"))
         *      {
         *              this.index++;
         *              ReadValue readValue = new ReadValue();
         *
         *              if (this.index < this.tokens.Count &&
         *                      this.tokens[this.index] is string)
         *              {
         *                      readValue.Ident = (string)this.tokens[this.index++];
         *                      result = readValue;
         *              }
         *              else
         *              {
         *                      throw new System.Exception("expected variable name after 'read_int'");
         *              }
         *      }*/
        else if (this.tokens[this.index].Equals("for"))
        {
            this.index++;
            ForNext forNext = new ForNext();

            if (this.index < this.tokens.Count &&
                this.tokens[this.index] is string)
            {
                forNext.Ident = (string)this.tokens[this.index];
            }
            else
            {
                throw new System.Exception("expected identifier after 'for'");
            }

            this.index++;

            if (this.index == this.tokens.Count ||
                this.tokens[this.index] != Scanner.Equal)
            {
                throw new System.Exception("for missing '='");
            }

            this.index++;

            forNext.From = this.ParseExpr();

            if (this.index == this.tokens.Count ||
                !this.tokens[this.index].Equals("to"))
            {
                throw new System.Exception("expected 'to' after for");
            }

            this.index++;

            forNext.To = this.ParseExpr();

            /*if (this.index == this.tokens.Count ||
             *      !this.tokens[this.index].Equals("do"))
             * {
             *      throw new System.Exception("expected 'do' after from expression in for next");
             * }*/

            this.index++;

            forNext.Body = this.ParseStmt();
            result       = forNext;

            if (this.index == this.tokens.Count ||
                !this.tokens[this.index].Equals("next"))
            {
                throw new System.Exception("unterminated 'for' loop body");
            }

            this.index++;
        }
        else if (this.tokens[this.index].Equals("if"))
        {
            this.index++;
            IfElse ifthen = new IfElse();
            ifthen.Condition = new ConExpression();

            //Запишем первый операнд в условии
            if (this.index < this.tokens.Count &&
                this.tokens[this.index] is string)
            {
                ifthen.Condition.Left = this.ParseExpr();
            }
            else
            {
                throw new System.Exception("expected identifier after 'if'");
            }

            // Запишем условный оператор
            if (this.tokens[this.index] == Scanner.More) //Больше
            {
                ifthen.Condition.Operation = ConOperation.More;
            }
            else if (this.tokens[this.index] == Scanner.MoreEqual) //Больше-равно
            {
                ifthen.Condition.Operation = ConOperation.MoreEqual;
            }
            else if (this.tokens[this.index] == Scanner.Less) //Меньше
            {
                ifthen.Condition.Operation = ConOperation.Less;
            }
            else if (this.tokens[this.index] == Scanner.LessEqual) //Меньше-равно
            {
                ifthen.Condition.Operation = ConOperation.LessEqual;
            }
            else if (this.tokens[this.index] == Scanner.Equal) //Равенство
            {
                ifthen.Condition.Operation = ConOperation.Equal;
            }
            else
            {
                throw new System.Exception("missing condition operator");
            }

            //Запишем второй операнд в условии
            this.index++;
            ifthen.Condition.Right = this.ParseExpr();

            if (this.index == this.tokens.Count ||
                !this.tokens[this.index].Equals("then"))
            {
                throw new System.Exception("expected 'then' after if");
            }

            this.index++;
            ifthen.BodyThen = this.ParseStmt();

            if (this.index < this.tokens.Count && this.tokens[this.index].Equals("else"))
            {
                this.index++;
                ifthen.BodyElse = this.ParseStmt();
            }

            result = ifthen;

            if (this.index == this.tokens.Count ||
                !this.tokens[this.index].Equals("endif"))
            {
                throw new System.Exception("unterminated 'if' body");
            }

            this.index++;
        }
        else if (this.tokens[this.index] is string)
        {
            //---------------------------------------------------------
            // assignment
            Assign assign = new Assign();
            assign.Ident = (string)this.tokens[this.index++];

            if (this.index == this.tokens.Count ||
                this.tokens[this.index] != Scanner.Equal)
            {
                throw new System.Exception("expected '='");
            }

            this.index++;

            assign.Expression = this.ParseExpr();

            //Проверим наличие операции

            if (this.tokens[this.index] != Scanner.Semi)
            {
                assign.Expression = this.ParseBinExpr(assign.Expression);
            }

            result = assign;
        }
        else
        {
            throw new System.Exception("parse error at token " + this.index + ": " + this.tokens[this.index]);
        }


        if (this.index < this.tokens.Count && this.tokens[this.index] == Scanner.Semi)
        {
            this.index++;

            if (this.index < this.tokens.Count &&
                !this.tokens[this.index].Equals("next") && !this.tokens[this.index].Equals("endif") && !this.tokens[this.index].Equals("else"))
            {
                Sequence sequence = new Sequence();
                sequence.First  = result;
                sequence.Second = this.ParseStmt();
                result          = sequence;
            }
        }

        return(result);
    }
コード例 #5
0
ファイル: CodeGen.cs プロジェクト: Lexus1982/Translator
    private void GenStmt(Stmt stmt)
    {
        //Обработка элемента последовательности дерева
        if (stmt is Sequence)
        {
            Sequence seq = (Sequence)stmt;
            //Выполним обработку левой части дерева
            this.GenStmt(seq.First);
            //Выполним обработку правой части дерева
            this.GenStmt(seq.Second);
        }

        //Обработка элемента дерева - "Объявление"
        else if (stmt is DeclareVar)
        {
            // Добавим переменную в список переменных
            DeclareVar declare = (DeclareVar)stmt;
            this.varTable[declare.Ident] = this.TypeOfExpr(declare.Expression);

            //Приведем элемент типа "Объевление" к типу "Присвоение"
            Assign assign = new Assign();
            assign.Ident      = declare.Ident;
            assign.Expression = declare.Expression;

            //Запишем тип переменной
            accum.Append(string.Format("\n{0} ", this.TypeOfExpr(declare.Expression).Name));
            //Запустим на обработку
            this.GenStmt(assign);
        }

        //Обработка элемента дерева - "Присвоение"
        else if (stmt is Assign)
        {
            Assign assign = (Assign)stmt;
            accum.Append(string.Format("{0}=", assign.Ident));

            //Обработка правой части элемента
            this.GenAssign(assign.Expression);
            accum.Append(";");
        }

        //Обработка элемента дерева - "Вывод данных"
        else if (stmt is Print)
        {
            Print print = (Print)stmt;
            accum.Append(print.VarExpression != null
                             ? string.Format("\nConsole.WriteLine(\"{0}\", {1});", this.GetExprValue(print.Expression),
                                             this.GetExprValue(print.VarExpression))
                             : string.Format("\nConsole.WriteLine(\"{0}\");", this.GetExprValue(print.Expression)));
        }

        //Обработка элемента дерева - "Ввод данных"
        else if (stmt is ReadValue)
        {
            ReadValue readValue = (ReadValue)stmt;
            accum.Append(readValue.Exp != null
                             ? string.Format("\n{0} = Console.ReadLine(\"{1}\");", readValue.Ident, this.GetExprValue(readValue.Exp))
                             : string.Format("\n{0} = Console.ReadLine();", readValue.Ident));

            //Проверка, что переменная объявлена ранее
            //CheckVariable
        }
        else if (stmt is IfElse)
        {
            IfElse ifElse    = (IfElse)stmt;
            string operation = string.Empty;

            switch (ifElse.Condition.Operation)
            {
            case ConOperation.Equal: operation = "="; break;

            case ConOperation.Less: operation = "<"; break;

            case ConOperation.LessEqual: operation = "<="; break;

            case ConOperation.More: operation = ">"; break;

            case ConOperation.MoreEqual: operation = ">="; break;
            }
            accum.Append(string.Format("\nif ({0}{1}{2})", this.GetExprValue(ifElse.Condition.Left), operation, this.GetExprValue(ifElse.Condition.Right)));


            if (ifElse.BodyThen != null)
            {
                accum.Append("\n{\n");
                this.GenStmt(ifElse.BodyThen);
                accum.Append("\n}");
            }

            if (ifElse.BodyElse != null)
            {
                if (ifElse.BodyThen == null)
                {
                    throw new System.Exception("error if - else");
                }
                accum.Append("\nelse\n{\n");
                this.GenStmt(ifElse.BodyElse);
                accum.Append("\n}");
            }
        }
        else if (stmt is ForNext)
        {
            ForNext forNext = (ForNext)stmt;

            accum.Append(string.Format("\nfor("));
            Assign assign = new Assign();
            assign.Ident      = forNext.Ident;
            assign.Expression = forNext.From;
            this.GenStmt(assign);
            accum.Append(string.Format("{0}<{1};{2}++)", forNext.Ident, this.GetExprValue(forNext.To), forNext.Ident));

            this.varTable[forNext.Ident] = typeof(int);

            if (forNext.Body != null)
            {
                accum.Append("\n{");
                this.GenStmt(forNext.Body);
                accum.Append("\n}");
            }
        }
        else
        {
            throw new System.Exception("Отсутствует инструкция для генерирования операции: " + stmt.GetType().Name);
        }
    }