예제 #1
0
        public static bool InfixToPostfix(Expression inputExpression, out Expression postfixExpression)
        {
            List<Token> postfixTokens = new List<Token>();
            Stack<Token> postfixStack = new Stack<Token>();

            //process all tokens in input-expression, one by one
            foreach (Token token in inputExpression.Tokens)
            {
                if (token.Type == TokenType.Constant) //handle constants
                {
                    postfixTokens.Add(token);
                }
                else if (token.Type == TokenType.Variable) //handle variables
                {
                    postfixTokens.Add(token);
                }
                else if (token.Type == TokenType.Operator) //handle operators
                {
                    if (CalcUtilities.IsOpenParenthesis(token)) //handle open-parenthesis
                    {
                        postfixStack.Push(token);
                    }
                    else if (CalcUtilities.IsCloseParenthesis(token)) //handle close-parenthesis
                    {
                        //pop all operators off the stack onto the output (until left parenthesis)
                        while (true)
                        {
                            if (postfixStack.Count == 0)
                            {
                                postfixExpression = null; //error: mismatched parenthesis
                                return (false);
                            }

                            Token top = postfixStack.Pop();
                            if (CalcUtilities.IsOpenParenthesis(top)) break;
                            else postfixTokens.Add(top);
                        }
                    }
                    else //handle arithmetic operators
                    {
                        Operator currentOperator = AllOperators.Find(token.LinearToken);

                        if (postfixStack.Count > 0)
                        {
                            Token top = postfixStack.Peek();
                            if (CalcUtilities.IsArithmeticOperator(top))
                            {
                                Operator stackOperator = AllOperators.Find(top.LinearToken);
                                if ((currentOperator.Associativity == OperatorAssociativity.LeftToRight &&
                                     currentOperator.PrecedenceLevel >= stackOperator.PrecedenceLevel) ||
                                    (currentOperator.Associativity == OperatorAssociativity.RightToLeft &&
                                     currentOperator.PrecedenceLevel > stackOperator.PrecedenceLevel)) //'>' operator implies less precedence
                                {
                                    postfixStack.Pop();
                                    postfixTokens.Add(top);
                                }
                            }
                        }

                        postfixStack.Push(token); //push operator to stack
                    }
                }
            }

            //after reading all tokens, pop entire stack to output
            while (postfixStack.Count > 0)
            {
                Token top = postfixStack.Pop();
                if (CalcUtilities.IsOpenParenthesis(top) || CalcUtilities.IsCloseParenthesis(top))
                {
                    postfixExpression = null; //error: mismatched parenthesis
                    return (false);
                }
                else
                {
                    postfixTokens.Add(top);
                }
            }

            postfixExpression = new Expression() { Tokens = postfixTokens };
            return (true);
        }
예제 #2
0
        public static void Validate(Expression expression, ref List<Token> postfixTokens, out bool isError, out int errorTokenIndex, out string errorMessage)
        {
            //initialize index of each token
            int tokenIndex = 0;
            foreach (Token token in expression.Tokens)
            {
                token.Index = tokenIndex;
                tokenIndex += 1;
            }

            Stack<Token> postfixStack = new Stack<Token>();
            foreach (Token token in expression.Tokens)
            {
                if (token.Type == TokenType.Constant) //handle constants
                {
                    postfixTokens.Add(token);
                }
                else if (token.Type == TokenType.Variable) //handle variables
                {
                    postfixTokens.Add(token);
                }
                else if (token.Type == TokenType.Operator) //handle operators
                {
                    if (CalcUtilities.IsOpenParenthesis(token)) //handle open-parenthesis
                    {
                        postfixStack.Push(token);
                    }
                    else if (CalcUtilities.IsCloseParenthesis(token)) //handle close-parenthesis
                    {
                        //pop all operators off the stack onto the output (until left parenthesis)
                        while (true)
                        {
                            if (postfixStack.Count == 0)
                            {
                                isError = true;
                                errorTokenIndex = token.Index;
                                errorMessage = "Mismatched parenthesis.";
                                return;
                            }

                            Token top = postfixStack.Pop();

                            if (CalcUtilities.IsOpenParenthesis(top))
                            {
                                break;
                            }
                            else
                            {
                                postfixTokens.Add(top);
                            }
                        }
                    }
                    else //handle other operators (usually arithmetic)
                    {
                        Operator operator1 = AllOperators.Find(token.LinearToken);

                        while (true)
                        {
                            if (postfixStack.Count == 0)
                            {
                                break;
                            }

                            Token top = postfixStack.Peek();
                            if (CalcUtilities.IsArithmeticOperator(top))
                            {
                                bool readyToPopOperator2 = false;
                                Operator operator2 = AllOperators.Find(top.LinearToken);
                                if (operator1.Associativity == OperatorAssociativity.LeftToRight && operator1.PrecedenceLevel >= operator2.PrecedenceLevel) //'>' operator implies less precedence
                                {
                                    readyToPopOperator2 = true;
                                }
                                else if (operator1.Associativity == OperatorAssociativity.RightToLeft && operator1.PrecedenceLevel > operator2.PrecedenceLevel)
                                {
                                    readyToPopOperator2 = true;
                                }

                                if (readyToPopOperator2)
                                {
                                    postfixStack.Pop();
                                    postfixTokens.Add(top);
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }

                        postfixStack.Push(token);
                    }
                }
            }

            //pop entire stack to output
            while (postfixStack.Count > 0)
            {
                Token top = postfixStack.Pop();

                if (CalcUtilities.IsOpenParenthesis(top) || CalcUtilities.IsCloseParenthesis(top))
                {
                    isError = true;
                    errorTokenIndex = top.Index;
                    errorMessage = "Mismatched Parenthesis.";
                    return;
                }
                else
                {
                    postfixTokens.Add(top);
                }
            }

            Stack<Token> evaluateStack = new Stack<Token>();
            foreach (Token token in postfixTokens)
            {
                if (token.Type == TokenType.Constant)
                {
                    evaluateStack.Push(token);
                }
                else if (token.Type == TokenType.Variable)
                {
                    evaluateStack.Push(token);
                }
                else if (token.Type == TokenType.Operator)
                {
                    Token top;
                    switch (((Operator)token.TokenObject).OperandCount)
                    {
                        case 1:
                            if (evaluateStack.Count >= 1)
                            {
                                top = evaluateStack.Pop();

                                //add a dummy constant as result of arithmetic evaluation
                                Token dummyConstantToken = CalcUtilities.CreateNumberConstantToken("1");
                                evaluateStack.Push(dummyConstantToken);
                            }
                            else
                            {
                                isError = true;
                                errorTokenIndex = token.Index;
                                errorMessage = "Missing Operand for Operator '" + token.LinearToken + "'.";
                                return;
                            }
                            break;
                        case 2:
                            if (evaluateStack.Count >= 2)
                            {
                                Token temp = evaluateStack.Pop();
                                top = evaluateStack.Pop();

                                //add a dummy constant as result of arithmetic evaluation
                                Token dummyConstantToken = CalcUtilities.CreateNumberConstantToken("1");
                                evaluateStack.Push(dummyConstantToken);
                            }
                            else
                            {
                                isError = true;
                                errorTokenIndex = token.Index;
                                errorMessage = "Missing Operand for Operator '" + token.LinearToken + "'.";
                                return;
                            }
                            break;
                    }
                }
            }

            if (evaluateStack.Count == 1) //there should be exactly one token left in evaluate-stack
            {
                //leave the last token intact (as we are not evaluating to find the result)
                isError = false;
                errorTokenIndex = -1;
                errorMessage = string.Empty;
            }
            else
            {
                isError = true;
                errorTokenIndex = expression.Tokens.Count - 1;
                errorMessage = "Incomplete Expression.";
            }
        }
예제 #3
0
        //checks whether the input expression contains only number-constants and operators.
        public static bool IsArithmeticExpression(Expression expression)
        {
            foreach (Token token in expression.Tokens)
            {
                if (!(token.Type == TokenType.Constant || token.Type == TokenType.Operator))
                {
                    return (false);
                }
            }

            return (true);
        }