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