Пример #1
0
        private bool ProceedUnary(OperatorAst op, long[][] mtx, List <string> vars, out int vu, out long c)
        {
            vu = 0;
            c  = 1L;

            if (op == null)
            {
                return(true);
            }

            bool isError = false;

            if (op.Token == TokenTypes.MinusMinus)
            {
                c = var_m - 1;
            }

            if ((op.Left != null) && (op.Left.AstType == AstNodeTypes.Variable) && (op.Right == null))
            {
                vu         = vars.IndexOf(op.Left.TokenText) + 1;
                mtx[0][vu] = (mtx[0][vu] + c) % var_m;
            }
            else if ((op.Right != null) && (op.Right.AstType == AstNodeTypes.Variable) && (op.Left == null))
            {
                vu         = vars.IndexOf(op.Right.TokenText) + 1;
                mtx[0][vu] = (mtx[0][vu] + c) % var_m;
            }
            else
            {
                isError = true;
            }

            return(!isError);
        }
Пример #2
0
        private bool ProceedUnary(OperatorAst op, int sign, long[][] mtx, int vi, List <string> vars)
        {
            int  vu;
            long c;
            bool isError = false;

            if (!(isError = !ProceedUnary(op, mtx, vars, out vu, out c)))
            {
                long s = 1;
                if (sign < 0)
                {
                    s = var_m - 1;
                }
                mtx[vu][vi] = (mtx[vu][vi] + s) % var_m;
                if ((op.Right != null) && (op.Right.AstType == AstNodeTypes.Variable))
                {
                    if (vu != vi)
                    {
                        if (((c == 1) && (s == 1)) || ((c > 1) && (s > 1)))
                        {
                            s = 1;
                        }
                        else
                        {
                            s = var_m - 1;
                        }
                        mtx[0][vi] = (mtx[0][vi] + s) % var_m;
                    }
                }
            }

            return(!isError);
        }
        private string PrintSAExpr(BaseAst node)
        {
            if ((node is BaseAst) && (node.AstType == AstNodeTypes.Variable))
            {
                return(node.TokenText);
            }
            if (node is NumberAst)
            {
                return((node as NumberAst).Number.ToString());
            }
            if (node is OperatorAst)
            {
                OperatorAst oper = node as OperatorAst;
                switch (oper.Token)
                {
                case TokenTypes.PlusPlus:
                case TokenTypes.MinusMinus:
                    if (oper.Right != null)
                    {
                        return(string.Format("{0}{1}", oper.TokenText, PrintSAExpr(oper.Right)));
                    }
                    return(string.Format("{0}{1}", PrintSAExpr(oper.Left), oper.TokenText));

                case TokenTypes.Neg:
                    return(string.Format("{0}({1})", oper.TokenText, PrintSAExpr(oper.Right)));

                default:
                    return(string.Format("({0} {1} {2})", PrintSAExpr(oper.Left), oper.TokenText, PrintSAExpr(oper.Right)));
                }
            }

            return("...");
        }
        private BaseAst GetAssignmentAST(BaseAst var)
        {
            if ((var == null) || (var.AstType != AstNodeTypes.Variable))
            {
                return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetAssignmentAST(BaseAst var)', parametr 'var' je null"));
            }
            if (!program.VarsDecl.Keys.Contains(var.TokenText))
            {
                return(BaseAst.GetErrorAstNode(string.Format("Promenna '{0}' doposud nebyla deklarovana, radek {1}, sloupec {2}", var.TokenText, var.TokenStartLine, var.TokenStartColumn)));
            }

            ReadNextAst();
            OperatorAst cmd = actualNode as OperatorAst;

            if ((cmd == null) || (cmd.Token != TokenTypes.Equals))
            {
                return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan operator '=', radek {0}, sloupec {1}", cmd.TokenStartLine, cmd.TokenStartColumn)));
            }

            cmd.Left = var;

            BaseAst expr;
            BaseAst tmp = GetExprAST(out expr);

            if (tmp.IsError)
            {
                return(tmp);
            }
            cmd.Right = expr;

            return(cmd);
        }
        private string GetExpr(BaseAst ast)
        {
            if (ast == null)
                throw new ApplicationException();

            if (ast.AstType == AstNodeTypes.Number)
                return ast.TokenText;
            if (ast.AstType == AstNodeTypes.Variable)
                return ast.TokenText;
            if (ast is OperatorAst)
            {
                OperatorAst op = ast as OperatorAst;
                if ((op.Token == TokenTypes.PlusPlus) || (op.Token == TokenTypes.MinusMinus))
                {
                    if (op.Left != null)
                        return GetExpr(op.Left) + op.TokenText;
                    return op.TokenText + GetExpr(op.Right);
                }

                if (op.Token == TokenTypes.Neg)
                {
                    return string.Format("!({0})", GetExpr(op.Right));
                }

                OperatorAst leftOp = op.Left as OperatorAst;
                string left = ((leftOp != null) && (leftOp.Priority > op.Priority)) ? "(" + GetExpr(op.Left) + ")" : GetExpr(op.Left);

                OperatorAst rightOp = op.Right as OperatorAst;
                string right = ((rightOp != null) && (rightOp.Priority > op.Priority)) ? "(" + GetExpr(op.Right) + ")" : GetExpr(op.Right);

                return string.Format("{0} {1} {2}", left, op.TokenText, right);
            }
            throw new ApplicationException();
        }
Пример #6
0
        public void GetMatrix(List <string> vars)
        {
            OperatorAst expr = parent.Ast as OperatorAst;

            if (expr != null)
            {
                if (expr.Token == TokenTypes.Equals)
                {
                    int vi = vars.IndexOf(expr.Left.TokenText) + 1;
                    if ((vi > 0) && (vi <= vars.Count))
                    {
                        long[][] mtx = b.GetIdentity(var_n);

                        mtx[vi][vi] = 0;
                        if (ProceedExpr(expr.Right, mtx, vi, vars))
                        {
                            TMatrixes.Add(mtx);
                        }
                        else
                        {
                            AddMatrixesForUnknownExpr(vi);
                        }
                    }
                }
                else if ((expr.Token == TokenTypes.PlusPlus) || (expr.Token == TokenTypes.MinusMinus))
                {
                    long[][] mtx = b.GetIdentity(var_n);
                    int      vu;
                    long     c;
                    if (ProceedUnary(expr as OperatorAst, mtx, vars, out vu, out c))
                    {
                        TMatrixes.Add(mtx);
                    }
                    else
                    {
                        AddMatrixesForUnknownExpr(vu);
                    }
                }
            }
            else if (parent.Ast is ConditionAst)
            {
                long[][] mtx = b.GetIdentity(var_n);
                if (ProceedCondition(parent.Ast as ConditionAst, mtx, vars))
                {
                    TMatrixes.Add(mtx);
                }
                else
                {
                    TMatrixes.Add(b.GetIdentity(var_n));
                }
            }
            else if ((parent.Ast == null) || (parent.Ast.AstType != AstNodeTypes.FunctionCall))
            {
                TMatrixes.Add(b.GetIdentity(var_n));
            }
        }
        private void SetOperatorPriority(OperatorAst token)
        {
            int priority;

            if (!OP.TryGetValue(token.Token, out priority))
            {
                priority = 0;
            }
            token.Priority = priority;
        }
        private BaseAst GetVariables()
        {
            ReadNextAst();
            while ((actualNode.Token != TokenTypes.Semicolon) && !(actualNode.IsError))
            {
                if (actualNode.Token != TokenTypes.Identifier)
                {
                    return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan identifikator promenne, radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn)));
                }

                if (program.VarsDecl.Keys.Contains(actualNode.TokenText))
                {
                    return(BaseAst.GetErrorAstNode(string.Format("Promenna '{0}' j*z byla deklarovana, radek {1}, sloupec {2}", actualNode.TokenText, actualNode.TokenStartLine, actualNode.TokenStartColumn)));
                }

                BaseAst var = actualNode;

                BaseAst expr = null;
                if (nextNode.Token == TokenTypes.Equals)
                {
                    ReadNextAst();
                    OperatorAst op   = actualNode as OperatorAst;
                    BaseAst     node = GetExprAST(out expr);
                    if (node.IsError)
                    {
                        return(node);
                    }
                    op.Left  = var;
                    op.Right = expr;
                    expr     = op;
                }

                program.Vars.Add(var.TokenText);
                program.VarsDecl.Add(var.TokenText, expr);

                ReadNextAst();
                switch (actualNode.Token)
                {
                case TokenTypes.Comma:
                    ReadNextAst();
                    break;

                case TokenTypes.Semicolon:
                    break;

                default:
                    return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan znak oddeleni ',' nebo ';' nebo znak prirazeni '=', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn)));
                }
            }

            return(actualNode);
        }
Пример #9
0
        private bool ProceedCondition(ConditionAst cond, long[][] mtx, List <string> vars)
        {
            bool isError = false;

            if (cond != null)
            {
                OperatorAst op = cond.Condition as OperatorAst;
                if (op != null)
                {
                    isError = !ProceedPartCondition(op, mtx, vars);
                }
            }

            return(!isError);
        }
        private BaseAst GetUnaryOpAST(OperatorAst cmd)
        {
            if (cmd == null)
            {
                return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetUnaryOpAST(OperatorAst cmd)', parametr 'cmd' je null"));
            }

            ReadNextAst();
            if (actualNode.Token != TokenTypes.Identifier)
            {
                return(BaseAst.GetErrorAstNode(string.Format("Je ocekavano navesti, radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn)));
            }

            cmd.Right = actualNode;

            return(cmd);
        }
        private void PrintSAOper(OperatorAst oper)
        {
            switch (oper.Token)
            {
            case TokenTypes.Equals:
                Console.WriteLine("    {0} = {1};", oper.Left.TokenText, PrintSAExpr(oper.Right));
                break;

            case TokenTypes.PlusPlus:
            case TokenTypes.MinusMinus:
                Console.WriteLine("    {0};", PrintSAExpr(oper));
                break;

            default:
                Console.WriteLine("Toto neni znamy vyraz");
                break;
            }
        }
        private BaseAst GetUnaryOpAST(BaseAst var)
        {
            if ((var == null) || (var.AstType != AstNodeTypes.Variable))
            {
                return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetUnaryOpAST(BaseAst var)', parametr 'var' je null"));
            }

            ReadNextAst();
            OperatorAst cmd = actualNode as OperatorAst;

            if ((cmd == null) || ((cmd.Token != TokenTypes.PlusPlus) && (cmd.Token != TokenTypes.MinusMinus)))
            {
                return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan operator '++' nebo '--', radek {0}, sloupec {1}", cmd.TokenStartLine, cmd.TokenStartColumn)));
            }

            cmd.Left = var;

            return(cmd);
        }
Пример #13
0
        private bool ProceedPartCondition(OperatorAst op, long[][] mtx, List <string> vars)
        {
            bool isError = false;

            if (op != null)
            {
                if ((op.Token == TokenTypes.PlusPlus) || (op.Token == TokenTypes.MinusMinus))
                {
                    int  vu;
                    long c;
                    isError = !ProceedUnary(op, mtx, vars, out vu, out c);
                }
                if (!isError && (op.Left is OperatorAst))
                {
                    isError = !ProceedPartCondition(op.Left as OperatorAst, mtx, vars);
                }
                if (!isError && (op.Right is OperatorAst))
                {
                    isError = !ProceedPartCondition(op.Right as OperatorAst, mtx, vars);
                }
            }

            return(!isError);
        }
        private BaseAst GetAstNode(TokenModel token)
        {
            switch (token.Token)
            {
            case TokenTypes.FunctionRW:
                return(ConvertTo <FunctionAst>(token, AstNodeTypes.Function));

            case TokenTypes.IfRW:
                return(ConvertTo <IfAst>(token, AstNodeTypes.If));

            case TokenTypes.ForRW:
                return(ConvertTo <ForAst>(token, AstNodeTypes.For));

            case TokenTypes.WhileRW:
                return(ConvertTo <WhileAst>(token, AstNodeTypes.While));

            case TokenTypes.GotoRW:
                return(ConvertTo <GotoAst>(token, AstNodeTypes.Goto));

            case TokenTypes.ReturnRW:
                return(ConvertTo <BaseAst>(token, AstNodeTypes.Return));

            case TokenTypes.Number:
                NumberAst number = ConvertTo <NumberAst>(token, AstNodeTypes.Number);
                int       num;
                if (!TryParseNumber(number.TokenText, out num))
                {
                    return(BaseAst.GetErrorAstNode(string.Format("Nespravny format cisla, radek {0}, sloupec {1}", number.TokenStartLine, number.TokenStartColumn)));
                }
                number.Number = num;
                return(number);

            case TokenTypes.BraceLeft:
                return(ConvertTo <BlockAst>(token, AstNodeTypes.Block));

            case TokenTypes.Equals:
            case TokenTypes.Plus:
            case TokenTypes.Minus:
            case TokenTypes.Multi:
            case TokenTypes.PlusPlus:
            case TokenTypes.MinusMinus:
            case TokenTypes.EqualsEquals:
            case TokenTypes.Less:
            case TokenTypes.More:
            case TokenTypes.LessOrEquals:
            case TokenTypes.MoreOrEquals:
            case TokenTypes.NotEquals:
            case TokenTypes.Or:
            case TokenTypes.And:
            case TokenTypes.Neg:
                OperatorAst op = ConvertTo <OperatorAst>(token, AstNodeTypes.Operator);
                SetOperatorPriority(op);
                return(op);

            case TokenTypes.Error:
                return(ConvertTo <BaseAst>(token, AstNodeTypes.None));

            default:
                return(ConvertTo <BaseAst>(token, AstNodeTypes.Variable));
            }
        }
        private BaseAst GetSubExprAST(out BaseAst expr, int level, bool isCond)
        {
            expr = null;

            BaseAst        node  = null;
            List <BaseAst> nodes = new List <BaseAst>();

            // cislo, identifikator nebo leva zavorka
            if (!GetOperandNode(out node))
            {
                switch (node.Token)
                {
                case TokenTypes.Neg:
                    if (isCond)
                    {
                        OperatorAst nodeN = (OperatorAst)node;
                        GetOperandNode(out node);
                        if (node.Token != TokenTypes.ParenthesisLeft)
                        {
                            return(BaseAst.GetErrorAstNode(string.Format("Po operaci negace je ocekavana leva zavorka, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
                        }
                        BaseAst nodePRn = GetSubExprAST(out node, level + 1, isCond);
                        if (nodePRn.IsError)
                        {
                            return(nodePRn);
                        }
                        if (nodePRn.Token != TokenTypes.ParenthesisRight)
                        {
                            return(BaseAst.GetErrorAstNode(string.Format("Vyraz neni korektne ukoncen pravou zavorkou, radek {0}, sloupec {1}", nodePRn.TokenStartLine, nodePRn.TokenStartColumn)));
                        }
                        nodeN.Right = node;
                        node        = nodeN;
                    }
                    else
                    {
                        return(BaseAst.GetErrorAstNode(string.Format("Chybna operace negace, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
                    }
                    break;

                case TokenTypes.ParenthesisLeft:
                    BaseAst nodePR = GetSubExprAST(out node, level + 1, isCond);
                    if (nodePR.IsError)
                    {
                        return(nodePR);
                    }
                    if (nodePR.Token != TokenTypes.ParenthesisRight)
                    {
                        return(BaseAst.GetErrorAstNode(string.Format("Vyraz neni korektne ukoncen pravou zavorkou, radek {0}, sloupec {1}", nodePR.TokenStartLine, nodePR.TokenStartColumn)));
                    }
                    break;

                case TokenTypes.ParenthesisRight:
                    return(BaseAst.GetErrorAstNode(string.Format("Chybna prava zavorka, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));

                case TokenTypes.Error:
                    return(node);

                default:
                    return(BaseAst.GetErrorAstNode(string.Format("Prazdny vyraz, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
                }
            }

            nodes.Add(node);

            while (IsWantedToken(nextNode.Token, isCond))
            {
                if (!GetExprBinaryOperationNode(out node, isCond))
                {
                    switch (node.Token)
                    {
                    case TokenTypes.Identifier:
                    case TokenTypes.Number:
                    case TokenTypes.ParenthesisLeft:
                        return(BaseAst.GetErrorAstNode(string.Format("Nespravne formatovany vyraz, je ocekavan operator, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
                    }
                    if (node.Token == TokenTypes.ParenthesisRight)
                    {
                        if (level == 0)
                        {
                            return(BaseAst.GetErrorAstNode(string.Format("Chybna prava zavorka, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
                        }
                        break;
                    }
                    continue;
                }

                nodes.Add(node);

                if (!GetOperandNode(out node))
                {
                    switch (node.Token)
                    {
                    case TokenTypes.Neg:
                        if (isCond)
                        {
                            OperatorAst nodeN = (OperatorAst)node;
                            GetOperandNode(out node);
                            if (node.Token != TokenTypes.ParenthesisLeft)
                            {
                                return(BaseAst.GetErrorAstNode(string.Format("Po operaci negace je ocekavana leva zavorka, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
                            }
                            BaseAst nodePRn = GetSubExprAST(out node, level + 1, isCond);
                            if (nodePRn.IsError)
                            {
                                return(nodePRn);
                            }
                            if (nodePRn.Token != TokenTypes.ParenthesisRight)
                            {
                                return(BaseAst.GetErrorAstNode(string.Format("Vyraz neni korektne ukoncen pravou zavorkou, radek {0}, sloupec {1}", nodePRn.TokenStartLine, nodePRn.TokenStartColumn)));
                            }
                            nodeN.Right = node;
                            node        = nodeN;
                        }
                        else
                        {
                            return(BaseAst.GetErrorAstNode(string.Format("Chybna operace negace, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
                        }
                        break;

                    case TokenTypes.ParenthesisLeft:
                        BaseAst nodePR = GetSubExprAST(out node, level + 1, isCond);
                        if (nodePR.IsError)
                        {
                            return(nodePR);
                        }
                        if (nodePR.Token != TokenTypes.ParenthesisRight)
                        {
                            return(BaseAst.GetErrorAstNode(string.Format("Vyraz neni korektne ukoncen pravou zavorkou, radek {0}, sloupec {1}", nodePR.TokenStartLine, nodePR.TokenStartColumn)));
                        }
                        break;

                    case TokenTypes.Error:
                        return(node);

                    default:
                        return(BaseAst.GetErrorAstNode(string.Format("Nespravne formatovany vyraz, je ocekavan cislo, promenna nebo leva zavorka, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
                    }
                }
                nodes.Add(node);
            }

            if (nodes.Count == 0)
            {
                return(BaseAst.GetErrorAstNode(string.Format("Nespravne formatovany vyraz, je ocekavan cislo, promenna nebo leva zavorka, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn)));
            }

            int op = 10;

            while ((op < opMax) && (nodes.Count > 1))
            {
                int i = 1;
                while (i < nodes.Count)
                {
                    if (i >= (nodes.Count - 1))
                    {
                        return(BaseAst.GetErrorAstNode("Nespravne formatovany vyraz... chybny pocet operandu"));
                    }

                    OperatorAst oper = nodes[i] as OperatorAst;
                    if (oper == null)
                    {
                        return(BaseAst.GetErrorAstNode("Nespravne formatovany vyraz... uzel neni operace"));
                    }

                    if (oper.Priority == op)
                    {
                        oper.Left  = nodes[i - 1];
                        oper.Right = nodes[i + 1];
                        nodes.RemoveAt(i + 1);
                        nodes.RemoveAt(i - 1);
                    }
                    else
                    {
                        i += 2;
                    }
                }

                op += 10;
            }
            if (nodes.Count != 1)
            {
                return(BaseAst.GetErrorAstNode("Nespravne formatovany vyraz... nedobre utvoreny AST"));
            }

            expr = nodes[0];

            return(node);
        }
 private void WriteOperator(OperatorAst ast, List<string> vars, string p, bool writeLE)
 {
     file.WriteLine("{0}{1};", p, GetExpr(ast));
     if (writeLE)
         WriteLinearEquations(ast.Node, vars, p);
 }