Example #1
0
        private static Token EvaluateArithmetic(Token token1, Token token2, Token operatorToken)
        {
            //check if both tokens are numeric constants
            double number1      = double.NaN;
            double number2      = double.NaN;
            bool   validNumber1 = (token1.Type == TokenType.Constant) && double.TryParse(token1.LinearToken, out number1);
            bool   validNumber2 = (token2.Type == TokenType.Constant) && double.TryParse(token2.LinearToken, out number2);

            if (validNumber1 && validNumber2)
            {
                Operator op          = AllOperators.Find(operatorToken.LinearToken);
                double   returnValue = double.NaN;

                returnValue = op.Execute(number1, number2);

                returnValue = Math.Round(returnValue, 4);
                Constant returnValueConstant = new Constant()
                {
                    Value = returnValue.ToString()
                };
                return(new Token(TokenType.Constant, returnValueConstant));
            }
            else
            {
                return(CalcUtilities.CreateNumberConstantToken("1"));
            }
        }
Example #2
0
        public static Token Resolve(string text)
        {
            //check if a number-constant
            double numberValue;

            if (double.TryParse(text, out numberValue))
            {
                Constant constant = new Constant()
                {
                    Value = text
                };
                return(new Token(TokenType.Constant, constant));
            }

            //check if operator
            Operator op = AllOperators.Find(text);

            if (op != null)
            {
                return(new Token(TokenType.Operator, op));
            }

            //this token must be a variable
            Variable variable = new Variable()
            {
                Name = text
            };

            return(new Token(TokenType.Variable, variable));
        }
Example #3
0
        public static Expression Split(string expressionString)
        {
            List <Token> tokens = new List <Token>();

            //read the input-expression letter-by-letter and build tokens
            string alphaNumericString = string.Empty;

            Token lastOp = CalcUtilities.CreateOperatorToken('X');

            for (int index = 0; index < expressionString.Length; index++)
            {
                char currentChar = expressionString[index];

                if (AllOperators.Find("" + currentChar) != null) //if operator
                {
                    if (alphaNumericString.Length > 0)
                    {
                        tokens.Add(Token.Resolve(alphaNumericString));
                        alphaNumericString = string.Empty;
                    }

                    if (lastOp != null && (((Operator)lastOp.TokenObject).PrecedenceLevel < 1 || ((Operator)lastOp.TokenObject).SymbolText != ")"))
                    {
                        if (currentChar == '-')
                        {
                            currentChar = '_';
                        }
                    }

                    Token op = CalcUtilities.CreateOperatorToken(currentChar);
                    lastOp = op;
                    tokens.Add(op);
                }
                else if (Char.IsLetterOrDigit(currentChar) || currentChar == '.') //if alphabet or digit or dot
                {
                    alphaNumericString += currentChar;
                    lastOp              = null;
                }
            }

            //check if any token at last
            if (alphaNumericString.Length > 0)
            {
                tokens.Add(Token.Resolve(alphaNumericString));
            }

            return(new Expression()
            {
                Tokens = tokens
            });
        }
Example #4
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.";
            }
        }
Example #5
0
        public static Token CreateOperatorToken(char op)
        {
            Operator operatorObject = AllOperators.Find("" + op);

            return(new Token(TokenType.Operator, operatorObject));
        }
Example #6
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);
        }
Example #7
0
 public static bool IsCloseParenthesis(Token token)
 {
     return(token.Type == TokenType.Operator && token.LinearToken.Equals(AllOperators.Find(")").SymbolText));
 }