public TreeState(Syntax syntax, string indent, bool isLast) { Syntax = syntax; Indent = indent; IsLast = isLast; }
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; } } }