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(); }
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 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 void WriteStatement(BaseAst ast, List<string> vars, string p, bool writeLE) { if (ast is OperatorAst) WriteOperator(ast as OperatorAst, vars, p, writeLE); else if (ast is IfAst) WriteIf(ast as IfAst, vars, p, writeLE); else if (ast is WhileAst) WriteWhile(ast as WhileAst, vars, p, writeLE); else if (ast is ForAst) WriteFor(ast as ForAst, vars, p, writeLE); else if (ast is BlockAst) WriteBlock(ast as BlockAst, vars, p, writeLE); else if (ast is GotoAst) WriteGoto(ast as GotoAst, vars, p, writeLE); else { if (ast.AstType == AstNodeTypes.FunctionCall) WriteFunctionCall(ast, vars, p, writeLE); else if (ast.AstType == AstNodeTypes.Label) WriteLabel(ast); else if (ast.AstType == AstNodeTypes.Return) WriteReturn(ast, vars, p, writeLE); else throw new ApplicationException(); } }
private bool ProceedNode(BaseAst node, int sign, long[][] mtx, int vi, List <string> vars) { int vii; long c; bool isError = false; if ((node.AstType == AstNodeTypes.Number) || (node.AstType == AstNodeTypes.Variable) || ((node.AstType == AstNodeTypes.Operator) && (node.Token == TokenTypes.Multi))) { if (!(isError = !GetConst(node, sign, vars, out vii, out c))) { mtx[vii][vi] = (mtx[vii][vi] + c) % var_m; } } else if ((node.AstType == AstNodeTypes.Operator) && ((node.Token == TokenTypes.PlusPlus) || (node.Token == TokenTypes.MinusMinus))) { isError = !ProceedUnary(node as OperatorAst, sign, mtx, vi, vars); } else { isError = true; } return(!isError); }
private BaseAst GetWhileAST(WhileAst cmd) { if (cmd == null) { return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetWhileAST(WhileAst cmd)', parametr 'cmd' je null")); } BaseAst cond; BaseAst tmp = GetCondAST(out cond); if (tmp.IsError) { return(tmp); } cmd.Condition = cond; BaseAst st = StatementOrBlock(); if (st.IsError) { return(st); } cmd.WhileBody = st; return(cmd); }
private bool GetExprBinaryOperationNode(out BaseAst node, bool isCond) { ReadNextAst(); node = actualNode; switch (node.Token) { case TokenTypes.End: node = BaseAst.GetErrorAstNode(string.Format("Konec programu, vyraz neni korektne ukoncen, radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn)); return(false); case TokenTypes.Plus: case TokenTypes.Minus: case TokenTypes.Multi: return(true); case TokenTypes.EqualsEquals: case TokenTypes.Less: case TokenTypes.More: case TokenTypes.LessOrEquals: case TokenTypes.MoreOrEquals: case TokenTypes.NotEquals: case TokenTypes.Or: case TokenTypes.And: return(isCond); default: return(false); } }
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 IEnumerable <BaseAst> ConvertStatement(BaseAst node) { if (node is BlockAst) { List <BaseAst> block = new List <BaseAst>(); foreach (BaseAst st in (node as BlockAst).Statements) { block.AddRange(ConvertStatement(st)); } return(block); } if (node is IfAst) { return(ConvertIf(node as IfAst)); } if (node is WhileAst) { return(ConvertWhile(node as WhileAst)); } if (node is ForAst) { return(ConvertFor(node as ForAst)); } return(new List <BaseAst>() { node }); }
private bool ProceedExpr(BaseAst top, long[][] mtx, int vi, List <string> vars) { BaseAst node = top; int sign = 1; bool isError = false; while ((node != null) && (!isError)) { if ((node.AstType == AstNodeTypes.Number) || (node.AstType == AstNodeTypes.Variable) || ((node.AstType == AstNodeTypes.Operator) && ((node.Token == TokenTypes.Multi) || (node.Token == TokenTypes.PlusPlus)) || (node.Token == TokenTypes.MinusMinus))) { isError = !ProceedNode(node, sign, mtx, vi, vars); node = null; } else if ((node.AstType == AstNodeTypes.Operator) && (node is OperatorAst) && ((node.Token == TokenTypes.Plus) || (node.Token == TokenTypes.Minus))) { BaseAst left = (node as OperatorAst).Left; BaseAst right = (node as OperatorAst).Right; sign = 1; if (node.Token == TokenTypes.Minus) { sign = -1; } if ((right.AstType == AstNodeTypes.Operator) && ((right.Token == TokenTypes.Plus) || (right.Token == TokenTypes.Minus))) { BaseAst tmp = left; left = right; right = tmp; } if ((right.AstType == AstNodeTypes.Number) || (right.AstType == AstNodeTypes.Variable) || ((right.AstType == AstNodeTypes.Operator) && ((right.Token == TokenTypes.Multi) || (right.Token == TokenTypes.PlusPlus)) || (right.Token == TokenTypes.MinusMinus))) { if (isError = !ProceedNode(right, sign, mtx, vi, vars)) { break; } } else { isError = true; break; } sign = 1; node = left; } else { isError = true; break; } } return(!isError); }
private void WriteFunctionBody(BaseAst ast, List<string> vars, string prefix, bool writeLE) { file.WriteLine("{0}{{", prefix); WriteStatement(ast, vars, prefix + " ", writeLE); file.WriteLine("{0}}}", prefix); }
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 NegateCondition(BaseAst cond) { if ((cond is OperatorAst) && ((cond as OperatorAst).Token == TokenTypes.Neg)) { return((cond as OperatorAst).Right); } return(new OperatorAst { Token = TokenTypes.Neg, AstType = AstNodeTypes.Operator, TokenText = "!", Right = cond }); }
private bool GetConst(BaseAst node, int sign, List <string> vars, out int vii, out long c) { vii = 0; c = 0; if ((node.AstType == AstNodeTypes.Number) && (node is NumberAst)) { c = ((sign * (node as NumberAst).Number + var_m) % var_m + var_m) % var_m; } else if (node.AstType == AstNodeTypes.Variable) { vii = vars.IndexOf(node.TokenText) + 1; c = 1; if (sign < 0) { c = var_m - 1; } } else if ((node.AstType == AstNodeTypes.Operator) && (node is OperatorAst) && (node.Token == TokenTypes.Multi)) { BaseAst num = (node as OperatorAst).Left; BaseAst var = (node as OperatorAst).Right; if (var is NumberAst) { BaseAst tmp = num; num = var; var = tmp; } if ((num.AstType == AstNodeTypes.Number) && (num is NumberAst)) { c = ((sign * (num as NumberAst).Number + var_m) % var_m + var_m) % var_m; } else { return(false); } if (var.AstType == AstNodeTypes.Variable) { vii = vars.IndexOf(var.TokenText) + 1; } else { return(false); } } else { return(false); } return(true); }
private BaseAst GetReturnAST(BaseAst cmd) { if ((cmd == null) || (cmd.AstType != AstNodeTypes.Return)) { return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetReturnAST(BaseAst cmd)', parametr 'cmd' je null")); } cmd.AstType = AstNodeTypes.Return; return(cmd); }
private void PrintSAVarDecl(string varName, BaseAst var) { if (var != null) { Console.WriteLine("var {0} = {1};", varName, PrintSAExpr(var)); } else { Console.WriteLine("var {0};", varName); } }
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()); }
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); }
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)); }
private BaseAst StatementOrBlock() { if (nextNode.Token == TokenTypes.BraceLeft) { ReadNextAst(); BaseAst st = actualNode; BaseAst tmp = GetBlockAST(st as BlockAst); if (tmp.IsError) { return(tmp); } return(st); } return(GetStatementAST()); }
private BaseAst GetFunctionAST(FunctionAst fnc) { if (fnc == null) { return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetFunctionNode(FunctionAst fnc)', parametr 'fnc' je null")); } ReadNextAst(); if (actualNode.Token != TokenTypes.Identifier) { return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan identifikator funkce, radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); } if (program.OrigFncs.Keys.Contains(actualNode.TokenText)) { return(BaseAst.GetErrorAstNode(string.Format("Funkce '{0}' j*z byla deklarovana, radek {1}, sloupec {2}", actualNode.TokenText, actualNode.TokenStartLine, actualNode.TokenStartColumn))); } program.OrigFncs.Add(actualNode.TokenText, fnc); ReadNextAst(); if (actualNode.Token != TokenTypes.ParenthesisLeft) { return(BaseAst.GetErrorAstNode(string.Format("Je ocekavana leva zavorka '(', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); } ReadNextAst(); if (actualNode.Token != TokenTypes.ParenthesisRight) { return(BaseAst.GetErrorAstNode(string.Format("Je ocekavana prava zavorka ')', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); } ReadNextAst(); if ((actualNode.Token != TokenTypes.BraceLeft) && !(actualNode is BlockAst)) { return(BaseAst.GetErrorAstNode(string.Format("Je ocekavana leva slozena zavorka '{{', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); } BaseAst node = GetFncBodyAST(actualNode as BlockAst); if (node.IsError) { return(node); } fnc.Body = node as BlockAst; return(fnc); }
private BaseAst GetLabelAST(BaseAst label) { if ((label == null) || (label.AstType != AstNodeTypes.Variable)) { return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetLabelAST(BaseAst label)', parametr 'label' je null")); } label.AstType = AstNodeTypes.Label; ReadNextAst(); if (actualNode.Token != TokenTypes.Colon) { return(BaseAst.GetErrorAstNode(string.Format("Je ocekavana ':', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); } return(label); }
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 BaseAst AssignmentOrUnaryOrFnc() { ReadNextAst(); BaseAst node = actualNode; switch (actualNode.Token) { case TokenTypes.End: return(BaseAst.GetErrorAstNode(string.Format("Konec programu, blok neni korektne ukoncen, radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); case TokenTypes.Identifier: switch (nextNode.Token) { case TokenTypes.ParenthesisLeft: node = GetFunctionCallAST(node); break; case TokenTypes.Equals: node = GetAssignmentAST(node); break; case TokenTypes.PlusPlus: case TokenTypes.MinusMinus: node = GetUnaryOpAST(node); break; default: return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan znak prirazeni '=', radek {0}, sloupec {1}", nextNode.TokenStartLine, nextNode.TokenStartColumn))); } break; case TokenTypes.PlusPlus: case TokenTypes.MinusMinus: node = GetUnaryOpAST(node as OperatorAst); break; default: return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan prikaz, radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); } return(node); }
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); }
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); }
private BaseAst GetBlockAST(BlockAst block) { if (block == null) { return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetBlockAST(BlockAst block)', parametr 'block' je null")); } BaseAst node = BaseAst.GetInitLoopAstNode(); while ((node.Token != TokenTypes.BraceRight) && !(node.IsError)) { node = GetStatementAST(); switch (node.Token) { case TokenTypes.End: return(BaseAst.GetErrorAstNode(string.Format("Konec programu, blok neni korektne ukoncen, radek {0}, sloupec {1}", node.TokenStartLine, node.TokenStartColumn))); case TokenTypes.BraceLeft: node = GetBlockAST(node as BlockAst); break; } if (node.IsError) { return(node); } if (node.Token == TokenTypes.BraceRight) { break; } block.Statements.Add(node); } return(block); }
private BaseAst GetFunctionCallAST(BaseAst cmd) { if ((cmd == null) || (cmd.AstType != AstNodeTypes.Variable)) { return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetFunctionCallAST(BaseAst cmd)', parametr 'cmd' je null")); } cmd.AstType = AstNodeTypes.FunctionCall; ReadNextAst(); if (actualNode.Token != TokenTypes.ParenthesisLeft) { return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan '(', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); } ReadNextAst(); if (actualNode.Token != TokenTypes.ParenthesisRight) { return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan ')', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn))); } return(cmd); }
private BaseAst GetIfAST(IfAst cmd) { if (cmd == null) { return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetIfAST(IfAst cmd)', parametr 'cmd' je null")); } BaseAst cond; BaseAst tmp = GetCondAST(out cond); if (tmp.IsError) { return(tmp); } cmd.Condition = cond; BaseAst block = StatementOrBlock(); if (block.IsError) { return(block); } cmd.IfBody = block; if (nextNode.Token == TokenTypes.ElseRW) { ReadNextAst(); block = StatementOrBlock(); if (block.IsError) { return(block); } cmd.ElseBody = block; } return(cmd); }