public static object Evaluate(Syntax current, bool fromDivsion) { if (current.Kind == TokenKind.Expression) { ExpressionSyntax expression = current as ExpressionSyntax; if (expression.AddOp != null) { AddOpSyntax add = expression.AddOp as AddOpSyntax; if (add.Operator.Kind == TokenKind.Plus) { return((int)Evaluate(expression.Term, false) + (int)Evaluate(expression.Expression, false)); } else { return((int)Evaluate(expression.Term, false) - (int)Evaluate(expression.Expression, false)); } } else if (expression.Term != null) { return(Evaluate(expression.Term, false)); } } else if (current.Kind == TokenKind.Term) { TermSyntax term = current as TermSyntax; if (term.Multiply != null) { MultiOpSyntax multi = term.Multiply as MultiOpSyntax; return((int)Evaluate(term.Factor, false) * (int)Evaluate(term.Term, false)); } else if (term.Factor != null) { return(Evaluate(term.Factor, false)); } } else if (current.Kind == TokenKind.Factor) { FactorSyntax factor = current as FactorSyntax; if (factor.Division != null) { MultiOpSyntax divide = factor.Division as MultiOpSyntax; int a = (int)Evaluate(factor.Unit, false); int b = (int)Evaluate(factor.Factor, true); if (fromDivsion) { return(a * b); } return(a / b); } else if (factor.Unit != null) { return(Evaluate(factor.Unit, false)); } } else if (current.Kind == TokenKind.Unit) { UnitSyntax unit = current as UnitSyntax; if (unit.Number != null) { return(Evaluate(unit.Number, false)); } else if (unit.LeftParenthesis != null) { return(Evaluate(unit.Expression, false)); } } else if (current.Kind == TokenKind.Number) { return(current.Value); } return(0); }
public static void PrintTree(Syntax root) { Stack <TreeState> tree = new Stack <TreeState>(); tree.Push(new TreeState(root, "", false)); PrintSection("Parse tree:"); while (tree.Count > 0) { var currentSyntax = tree.Pop(); var current = currentSyntax.Syntax; var indent = currentSyntax.Indent; var childIndent = currentSyntax.IsLast ? indent + " ":indent + "│ "; var marker = currentSyntax.IsLast ? "└──":"├──"; Console.Write($"{indent}{marker}"); Console.ForegroundColor = ConsoleColor.DarkCyan; Console.Write(current.Kind); if (current.Value != null) { Console.Write($" {current.Value}"); } Console.WriteLine(); Console.ResetColor(); switch (current.Kind) { // using stack cause we can write to console horizontally // when pushing to the stack // pushing inverse order of grammar // cause last item should be printed at last case TokenKind.Expression: { ExpressionSyntax expression = current as ExpressionSyntax; if (expression.AddOp != null) { tree.Push(new TreeState(expression.Expression, childIndent, true)); tree.Push(new TreeState(expression.AddOp, childIndent, false)); tree.Push(new TreeState(expression.Term, childIndent, false)); } else if (expression.Term != null) { tree.Push(new TreeState(expression.Term, childIndent, true)); } }; break; case TokenKind.Term: { TermSyntax term = current as TermSyntax; if (term.Multiply != null) { tree.Push(new TreeState(term.Term, childIndent, true)); tree.Push(new TreeState(term.Multiply, childIndent, false)); tree.Push(new TreeState(term.Factor, childIndent, false)); } else if (term.Factor != null) { tree.Push(new TreeState(term.Factor, childIndent, true)); } }; break; case TokenKind.Factor: { FactorSyntax factor = current as FactorSyntax; if (factor.Division != null) { tree.Push(new TreeState(factor.Factor, childIndent, true)); tree.Push(new TreeState(factor.Division, childIndent, false)); tree.Push(new TreeState(factor.Unit, childIndent, false)); } else if (factor.Unit != null) { tree.Push(new TreeState(factor.Unit, childIndent, true)); } }; break; case TokenKind.Unit: { UnitSyntax unit = current as UnitSyntax; if (unit.Number != null) { tree.Push(new TreeState(unit.Number, childIndent, true)); } else if (unit.LeftParenthesis != null) { tree.Push(new TreeState(unit.RightParenthesis, childIndent, true)); tree.Push(new TreeState(unit.Expression, childIndent, false)); tree.Push(new TreeState(unit.LeftParenthesis, childIndent, false)); } }; break; case TokenKind.Add_op: { AddOpSyntax add = current as AddOpSyntax; tree.Push(new TreeState(add.Operator, childIndent, true)); }; break; case TokenKind.Mult_op: { MultiOpSyntax multi = current as MultiOpSyntax; tree.Push(new TreeState(multi.Operator, childIndent, true)); }; break; case TokenKind.Division_op: { DivisionOpSyntax div = current as DivisionOpSyntax; tree.Push(new TreeState(div.Operator, childIndent, true)); }; break; default: break; } } }