Beispiel #1
0
        private void CreateLinearEquations(ProgramAst prg)
        {
            Queue <IaNode> q = new Queue <IaNode>();

            q.Enqueue(prg.VarGraph);
            foreach (IaNode node in prg.Graph.Values)
            {
                q.Enqueue(node);
            }

            while (q.Count > 0)
            {
                IaNode n = q.Dequeue();
                if ((n.GeneratorSet != null) && (n.LinearEquations == null))
                {
                    n.LinearEquations = new LinearEquations(n, bg, printLE);
                    n.LinearEquations.CalculateLE();

                    foreach (IaEdge edge in n.Edges)
                    {
                        if (edge.To.LinearEquations == null)
                        {
                            q.Enqueue(edge.To);
                        }
                    }
                }
            }
        }
Beispiel #2
0
        private void CreateTransitionMatrixes(ProgramAst prg)
        {
            Queue <IaNode> q = new Queue <IaNode>();

            q.Enqueue(prg.VarGraph);
            foreach (string name in prg.OrigFncs.Keys)
            {
                q.Enqueue(prg.Graph[name]);
            }

            while (q.Count > 0)
            {
                IaNode n = q.Dequeue();
                if (n != null)
                {
                    foreach (IaEdge edge in n.Edges)
                    {
                        if (edge.MatrixSet == null)
                        {
                            var mtx = new TransitionMatrixSet(edge, bg);
                            mtx.GetMatrix(prg.Vars);
                            edge.MatrixSet = mtx;

                            if (printM)
                            {
                                mtx.Print();
                            }

                            q.Enqueue(edge.To);
                        }
                    }
                }
            }
        }
 private void PrintVarsDecl(ProgramAst program)
 {
     foreach (string varName in program.VarsDecl.Keys)
     {
         PrintSAVarDecl(varName, program.VarsDecl[varName]);
     }
 }
Beispiel #4
0
 public void Analyze(ProgramAst prg)
 {
     CreateTransitionMatrixes(prg);
     CreateFunctionMatrixes(prg);
     CreateGeneratorSets(prg);
     CreateLinearEquations(prg);
 }
        private void WriteVariables(ProgramAst prg)
        {
            string varStr = string.Empty;

            foreach (string var in prg.Vars)
            {
                if (prg.VarsDecl[var] == null)
                {
                    if (string.IsNullOrEmpty(varStr))
                        varStr = "var " + var;
                    else
                        varStr += ", " + var;
                }
                else
                {
                    if (!string.IsNullOrEmpty(varStr))
                        file.WriteLine(varStr + ";");
                    varStr = string.Empty;

                    BaseAst varAst = prg.VarsDecl[var];
                    file.WriteLine("var {0};", GetExpr(varAst));
                    WriteLinearEquations(varAst.Node, prg.Vars, "");
                }
            }

            if (!string.IsNullOrEmpty(varStr))
                file.WriteLine(varStr + ";");
        }
Beispiel #6
0
        private void CreateEmptyFunctionG(ProgramAst prg, List <IaEdge> fncCallEdges)
        {
            foreach (IaNode node in prg.Graph.Values)
            {
                Queue <IaNode> q = new Queue <IaNode>();
                q.Enqueue(node);
                while (q.Count > 0)
                {
                    IaNode n = q.Dequeue();
                    if (n.FunctionGSet == null)
                    {
                        n.FunctionGSet = new GeneratorSet(n, bfm);
                        foreach (IaEdge edge in n.Edges)
                        {
                            if ((edge.Ast != null) && (edge.Ast.AstType == AstNodeTypes.FunctionCall))
                            {
                                fncCallEdges.Add(edge);
                            }

                            if (edge.To.FunctionGSet == null)
                            {
                                q.Enqueue(edge.To);
                            }
                        }
                    }
                }
            }
        }
 private void WriteFunctions(ProgramAst prg)
 {
     foreach (string name in prg.OrigFncs.Keys)
     {
         WriteFunction(name, prg.OrigFncs[name], prg.Vars);
     }
 }
        private BaseAst CheckFunctionCallsInIfAST(ProgramAst program, IfAst cmd)
        {
            BaseAst err = CheckFunctionCallsInStatementAST(program, cmd.IfBody);

            if ((err != null) && (err.Token != TokenTypes.End) && (err.IsError))
            {
                return(err);
            }
            return(CheckFunctionCallsInStatementAST(program, cmd.ElseBody));
        }
 private BaseAst CheckFunctionCallsInBlockAST(ProgramAst program, BlockAst block)
 {
     foreach (BaseAst node in block.Statements)
     {
         BaseAst err = CheckFunctionCallsInStatementAST(program, node);
         if ((err != null) && (err.Token != TokenTypes.End) && (err.IsError))
         {
             return(err);
         }
     }
     return(BaseAst.GetEndAstNode());
 }
        public bool CreateGraph(ProgramAst program)
        {
            if (!CreateVariableGraph(program))
            {
                return(false);
            }

            if (!CreateFunctionGraphs(program))
            {
                return(false);
            }

            return(true);
        }
        public void Write(ProgramAst prg, string originProgramFile)
        {
            string programFile = GetProgramFile(originProgramFile);

            using (file = new StreamWriter(programFile, false))
            {
                WriteVariables(prg);

                WriteFunctions(prg);

                file.Flush();
                file.Close();
            }
        }
 public bool CheckAST(ProgramAst program)
 {
     foreach (string fncName in program.OrigFncs.Keys)
     {
         FunctionAst fnc = program.OrigFncs[fncName];
         BaseAst     err = CheckFunctionAST(program, fnc);
         if ((err.Token != TokenTypes.End) && (err.IsError))
         {
             Console.WriteLine("Error: '{0}'", err.ErrorMessage);
             return(false);
         }
     }
     return(true);
 }
        private BaseAst CheckFunctionCallsInForAST(ProgramAst program, ForAst cmd)
        {
            BaseAst err = CheckFunctionCallsInStatementAST(program, cmd.Init);

            if ((err != null) && (err.Token != TokenTypes.End) && (err.IsError))
            {
                return(err);
            }
            err = CheckFunctionCallsInStatementAST(program, cmd.Close);
            if ((err != null) && (err.Token != TokenTypes.End) && (err.IsError))
            {
                return(err);
            }
            return(CheckFunctionCallsInStatementAST(program, cmd.ForBody));
        }
        public bool GetAST(out ProgramAst prg)
        {
            program = new ProgramAst();
            prg     = program;

            BaseAst node = BaseAst.GetInitLoopAstNode();

            while ((node.Token != TokenTypes.End) && (!node.IsError))
            {
                ReadNextAst();
                node = actualNode;

                switch (actualNode.Token)
                {
                case TokenTypes.VarRW:     // deklarace globalni promenne
                    node = GetVariables();
                    break;


                case TokenTypes.FunctionRW:     // deklarace funkce
                    node = GetFunctionAST(node as FunctionAst);
                    break;


                case TokenTypes.End:     // konec programu
                    break;


                default:
                    node = BaseAst.GetErrorAstNode(string.Format("Je ocekavano klicove slovo 'var' nebo 'function', radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn));
                    break;
                }
            }

            if (node.IsError)
            {
                Console.WriteLine("Error: '{0}'", node.ErrorMessage);
                return(false);
            }
            return(true);
        }
        public bool ConvertToIfGoto(ProgramAst program)
        {
            if (isPrint)
            {
                PrintVarsDecl(program);
            }

            foreach (string fncName in program.OrigFncs.Keys)
            {
                FunctionAst fnc = program.OrigFncs[fncName];
                FunctionAst cf  = ConvertTo <FunctionAst>(fnc, AstNodeTypes.Function);
                cf.Body = ConvertFncBodyAST(fnc.Body);

                if (isPrint)
                {
                    PrintSAFncDecl(fncName, cf.Body);
                }

                program.ConvFncs.Add(fncName, cf);
            }
            return(true);
        }
        private BaseAst CheckFunctionCallsInStatementAST(ProgramAst program, BaseAst st)
        {
            if ((st != null) && (st.AstType == AstNodeTypes.FunctionCall))
            {
                if (!program.OrigFncs.Keys.Contains(st.TokenText))
                {
                    return(BaseAst.GetErrorAstNode(string.Format("Funkce '{0}' doposud nebyla deklarovana, radek {1}, sloupec {2}", st.TokenText, st.TokenStartLine, st.TokenStartColumn)));
                }
            }

            BaseAst inner = null;

            if (st is BlockAst)
            {
                inner = CheckFunctionCallsInBlockAST(program, st as BlockAst);
            }
            if (st is IfAst)
            {
                inner = CheckFunctionCallsInIfAST(program, st as IfAst);
            }
            if (st is WhileAst)
            {
                inner = CheckFunctionCallsInWhileAST(program, st as WhileAst);
            }
            if (st is ForAst)
            {
                inner = CheckFunctionCallsInForAST(program, st as ForAst);
            }

            if ((inner != null) && (inner.Token != TokenTypes.End) && (inner.IsError))
            {
                return(inner);
            }

            return(BaseAst.GetEndAstNode());
        }
        private bool CreateVariableGraph(ProgramAst program)
        {
            IaNode node = new IaNode {
                FncName = "var_decl", Name = "var_decl_begin"
            };

            program.VarGraph = node;
            foreach (string varName in program.Vars)
            {
                BaseAst ast = program.VarsDecl[varName];
                if (ast != null)
                {
                    IaNode to = new IaNode {
                        FncName = "var_decl", Name = "var_decl_after_" + varName
                    };
                    ast.Node  = to;
                    node.Next = new IaEdge {
                        Name = "var_decl_expr_line#" + ast.TokenStartLine, Ast = ast, From = node, To = to
                    };
                    node = to;
                }
            }
            return(true);
        }
Beispiel #18
0
        private void CreateGeneratorSets(ProgramAst prg)
        {
            Queue <NodeVector> w_queue = VariableGeneratorSets(prg);

            while (w_queue.Count > 0)
            {
                NodeVector pair = w_queue.Dequeue();

                IaNode from = pair.Node;
                foreach (IaEdge edge in from.Edges)
                {
                    IaNode to = edge.To;

                    if ((edge.Ast != null) && (edge.Ast.AstType == AstNodeTypes.FunctionCall))
                    {
                        IaNode fncBegin = prg.Graph[edge.Ast.TokenText];
                        if (fncBegin.GeneratorSet == null)
                        {
                            fncBegin.GeneratorSet = new GeneratorSet(fncBegin, bg);
                        }

                        if (fncBegin.GeneratorSet.AddVector(pair.Vector))
                        {
                            if (printG)
                            {
                                fncBegin.GeneratorSet.Print();
                            }

                            w_queue.Enqueue(new NodeVector {
                                Node = fncBegin, Vector = pair.Vector
                            });
                        }
                    }

                    foreach (long[][] a_mtx in edge.MatrixSet.TMatrixes)
                    {
                        long[]     xi = bg.MatrixMultiVector(a_mtx, pair.Vector.Vr, bg.var_m);
                        LeadVector x  = new LeadVector(xi);
                        if (x.Lidx >= 0)
                        {
                            if (to.GeneratorSet == null)
                            {
                                to.GeneratorSet = new GeneratorSet(to, bg);
                            }

                            if (to.GeneratorSet.AddVector(x))
                            {
                                if (printG)
                                {
                                    to.GeneratorSet.Print();
                                }

                                w_queue.Enqueue(new NodeVector {
                                    Node = to, Vector = x
                                });
                            }
                        }
                    }
                }
            }
        }
        private BaseAst CheckFunctionAST(ProgramAst program, FunctionAst fnc)
        {
            BaseAst err = CheckFunctionCallsInBlockAST(program, fnc.Body);

            return(err);
        }
        private bool CreateFunctionGraphs(ProgramAst program)
        {
            foreach (string fncName in program.ConvFncs.Keys)
            {
                FunctionAst fnc = program.ConvFncs[fncName] as FunctionAst;
                if (fnc != null)
                {
                    if ((fnc.Body != null) && (fnc.Body.Statements != null) && (fnc.Body.Statements.Count > 0))
                    {
                        bool isAnyCmd = false;
                        foreach (BaseAst st in fnc.Body.Statements)
                        {
                            if ((st is OperatorAst) || (st is ConditionAst) || (st.AstType == AstNodeTypes.FunctionCall) || (st.AstType == AstNodeTypes.Return))
                            {
                                isAnyCmd = true;
                                break;
                            }
                        }
                        if (isAnyCmd)
                        {
                            Dictionary <string, IaNode> lbls = new Dictionary <string, IaNode>();
                            List <Tuple <string, IaNode, string, int> > gts = new List <Tuple <string, IaNode, string, int> >();

                            IaNode node = new IaNode {
                                FncName = fncName, Name = fncName + "_fnc_begin"
                            };
                            program.OrigFncs[fncName].Node = node;
                            program.Graph.Add(fncName, node);
                            int i = 0;
                            while (i < fnc.Body.Statements.Count)
                            {
                                BaseAst st = fnc.Body.Statements[i];
                                if (st is OperatorAst)
                                {
                                    IaNode next = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_expr_line#" + st.TokenStartLine
                                    };
                                    st.Node   = next;
                                    node.Next = new IaEdge {
                                        Name = fncName + "_expr_line#" + st.TokenStartLine, Ast = st, From = node, To = next
                                    };
                                    node = next;
                                    i++;
                                    continue;
                                }
                                if (st.AstType == AstNodeTypes.FunctionCall)
                                {
                                    IaNode next = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_fnccall_line#" + st.TokenStartLine
                                    };
                                    st.Node   = next;
                                    node.Next = new IaEdge {
                                        Name = fncName + "_fnccall_line#" + st.TokenStartLine, Ast = st, From = node, To = next
                                    };
                                    node = next;
                                    i++;
                                    continue;
                                }
                                if (st is ConditionAst)
                                {
                                    IaNode next = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_condition_line#" + st.TokenStartLine
                                    };
                                    st.Node   = next;
                                    node.Next = new IaEdge {
                                        Name = fncName + "_condition_line#" + st.TokenStartLine, Ast = st, From = node, To = next
                                    };
                                    node = next;
                                    i++;

                                    BaseAst gt = fnc.Body.Statements[i];
                                    node.ReverseAst = gt;
                                    gts.Add(new Tuple <string, IaNode, string, int>("IsTrue", node, (gt as GotoAst).Label, st.TokenStartLine));
                                    next = new IaNode {
                                        FncName = fncName, Name = fncName + "_condition_false_line#" + st.TokenStartLine
                                    };
                                    node.IsFalse = new IaEdge {
                                        Name = fncName + "_condition_false_line#" + st.TokenStartLine, From = node, To = next
                                    };
                                    node = next;
                                    i++;
                                    continue;
                                }
                                if (st.AstType == AstNodeTypes.Label)
                                {
                                    node.Name = fncName + "_label_" + st.TokenText;
                                    lbls.Add(st.TokenText, node);
                                    i++;
                                    continue;
                                }
                                if (st is GotoAst)
                                {
                                    node.ReverseAst = st;
                                    gts.Add(new Tuple <string, IaNode, string, int>("Next", node, (st as GotoAst).Label, st.TokenStartLine));
                                    node = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_goto_line#" + (st as GotoAst).Label
                                    };                                                                                                     // po goto musi byt novy node (nova vetev)
                                    i++;
                                    continue;
                                }
                                if (st.AstType == AstNodeTypes.Return)
                                {
                                    node.ReverseAst = st;
                                    gts.Add(new Tuple <string, IaNode, string, int>("End", node, "$End$", st.TokenStartLine));
                                    node = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_return_line#" + st.TokenStartLine
                                    };                                                                                                   // aktualni node je konec funkce, novy node pro pokracovani, jinak se zahodi
                                    i++;
                                    continue;
                                }
                            }

                            program.LastNode.Add(fncName, node);
                            lbls.Add("$End$", node);

                            foreach (Tuple <string, IaNode, string, int> gt in gts)
                            {
                                IaNode to = lbls[gt.Item3];
                                if (to == null)
                                {
                                    Console.WriteLine("Neznamy label {0} pri vytvareni grafu.", gt.Item3);
                                    return(false);
                                }
                                if (gt.Item1 == "Next")
                                {
                                    gt.Item2.Next = new IaEdge {
                                        Name = fncName + "_goto_line#" + gt.Item4, From = gt.Item2, To = to
                                    }
                                }
                                ;
                                else if (gt.Item1 == "IsTrue")
                                {
                                    gt.Item2.IsTrue = new IaEdge {
                                        Name = fncName + "_condition_true_line#" + gt.Item4, From = gt.Item2, To = to
                                    }
                                }
                                ;
                                else if (gt.Item1 == "End")
                                {
                                    gt.Item2.Next = new IaEdge {
                                        Name = fncName + "_return#" + gt.Item4, From = gt.Item2, To = to
                                    }
                                }
                                ;

                                if (gt.Item2.ReverseAst != null)
                                {
                                    gt.Item2.ReverseAst.Node = to;
                                }
                            }
                        }
                    }
                }
            }
            return(true);
        }
 private BaseAst CheckFunctionCallsInWhileAST(ProgramAst program, WhileAst cmd)
 {
     return(CheckFunctionCallsInStatementAST(program, cmd.WhileBody));
 }
Beispiel #22
0
        private void CreateFunctionMatrixes(ProgramAst prg)
        {
            List <IaEdge> fncCallEdges = new List <IaEdge>();

            CreateEmptyFunctionG(prg, fncCallEdges);

            Queue <NodeMatrix> w_queue = new Queue <NodeMatrix>();

            foreach (string name in prg.OrigFncs.Keys)
            {
                w_queue.Enqueue(new NodeMatrix {
                    Node = prg.Graph[name], Matrix = bfm.GetIdentity(bg.var_n)
                });
            }

            while (w_queue.Count > 0)
            {
                NodeMatrix pair = w_queue.Dequeue();

                IaNode from = pair.Node;
                if ((from.Next != null) || (from.IsTrue != null) || (from.IsFalse != null))
                {
                    foreach (IaEdge edge in from.Edges)
                    {
                        if ((edge.Ast == null) || (edge.Ast.AstType != AstNodeTypes.FunctionCall))
                        {
                            IaNode to = edge.To;

                            // pruchod hranou s maticemi
                            foreach (long[][] a_mtx in edge.MatrixSet.TMatrixes)
                            {
                                long[][]   mtx = bg.MatrixMultiMatrix(a_mtx, pair.Matrix, bfm.var_m);
                                long[]     xi  = bg.MatrixToVector(mtx);
                                LeadVector x   = new LeadVector(xi);
                                if (x.Lidx >= 0)
                                {
                                    if (to.FunctionGSet.AddVector(x))
                                    {
                                        if (printG)
                                        {
                                            to.FunctionGSet.Print();
                                        }

                                        w_queue.Enqueue(new NodeMatrix {
                                            Node = to, Matrix = mtx
                                        });
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    // pokud se jedna o konecny uzel funkce
                    foreach (IaEdge edge in fncCallEdges)
                    {
                        if ((edge.Ast == null) || (edge.Ast.AstType != AstNodeTypes.FunctionCall))
                        {
                            throw new ApplicationException();
                        }

                        if (edge.Ast.TokenText == from.FncName)
                        {
                            IaNode to = edge.To;

                            int i = 0;
                            while (edge.From.FunctionGSet.GArr[i] != null)
                            {
                                LeadVector vector = edge.From.FunctionGSet.GArr[i];
                                long[][]   matrix = bfm.VectorToMatrix(vector.Vr, bg.var_n);

                                long[][]   mtx = bg.MatrixMultiMatrix(pair.Matrix, matrix, bfm.var_m);
                                long[]     xi  = bg.MatrixToVector(mtx);
                                LeadVector x   = new LeadVector(xi);
                                if (x.Lidx >= 0)
                                {
                                    if (to.FunctionGSet.AddVector(x))
                                    {
                                        if (printG)
                                        {
                                            to.FunctionGSet.Print();
                                        }

                                        w_queue.Enqueue(new NodeMatrix {
                                            Node = to, Matrix = mtx
                                        });
                                    }
                                }
                                i++;
                            }
                        }
                    }
                }
            }
            // distribuce mnozin zmenovych matic z vystupnich uzlu na hrany volajici funkce
            foreach (string fncName in prg.LastNode.Keys)
            {
                IaNode last = prg.LastNode[fncName];

                List <long[][]> mtxs = new List <long[][]>();
                int             i    = 0;
                while (last.FunctionGSet.GArr[i] != null)
                {
                    mtxs.Add(bfm.VectorToMatrix(last.FunctionGSet.GArr[i].Vr, bg.var_n));
                    i++;
                }
                if (mtxs.Count > 0)
                {
                    foreach (IaEdge edge in fncCallEdges)
                    {
                        if ((edge.Ast == null) || (edge.Ast.AstType != AstNodeTypes.FunctionCall))
                        {
                            throw new ApplicationException();
                        }

                        if (edge.Ast.TokenText == last.FncName)
                        {
                            edge.MatrixSet.TMatrixes.Clear();
                            edge.MatrixSet.TMatrixes.AddRange(mtxs);
                        }
                    }
                }
            }
        }
Beispiel #23
0
        private Queue <NodeVector> VariableGeneratorSets(ProgramAst prg)
        {
            Queue <NodeVector> w_queue = new Queue <NodeVector>();
            IaNode             main    = prg.Graph["main"];

            main.GeneratorSet = new GeneratorSet(main, bg);

            Queue <NodeVector> vq = new Queue <NodeVector>();

            prg.VarGraph.GeneratorSet = new GeneratorSet(prg.VarGraph, bg);
            AddIdentityVectors(vq, prg.VarGraph);

            while (vq.Count > 0)
            {
                NodeVector pair = vq.Dequeue();

                IaNode from = pair.Node;
                if (from.Edges.Count() > 0)
                {
                    foreach (IaEdge edge in from.Edges)
                    {
                        IaNode to = edge.To;

                        foreach (long[][] a_mtx in edge.MatrixSet.TMatrixes)
                        {
                            long[]     xi = bg.MatrixMultiVector(a_mtx, pair.Vector.Vr, bg.var_m);
                            LeadVector x  = new LeadVector(xi);
                            if (x.Lidx >= 0)
                            {
                                if (to.GeneratorSet == null)
                                {
                                    to.GeneratorSet = new GeneratorSet(to, bg);
                                }

                                if (to.GeneratorSet.AddVector(x))
                                {
                                    if (printG)
                                    {
                                        to.GeneratorSet.Print();
                                    }

                                    vq.Enqueue(new NodeVector {
                                        Node = to, Vector = x
                                    });
                                }
                            }
                        }
                    }
                }
                else
                {
                    // konec definice promennych
                    main.GeneratorSet.AddVector(pair.Vector);
                    w_queue.Enqueue(new NodeVector {
                        Node = main, Vector = pair.Vector
                    });
                }
            }

            return(w_queue);
        }