예제 #1
0
        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);
        }
예제 #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;
                }
            }
        }