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); } } } } }
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]); } }
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 + ";"); }
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); }
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)); }
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); } } } } }
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); }