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); }
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(); }
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); }
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); }
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); }