예제 #1
0
        public Expression Parse(string input)
        {
            if (string.IsNullOrWhiteSpace(input))
            {
                return(null);
            }

            ExpressionTokenizer tokenizer = new ExpressionTokenizer(input);

            while (tokenizer.HasToken())
            {
                Token     token      = tokenizer.NextToken();
                TokenType tokenType  = token.Type;
                string    tokenValue = token.Value;
                if (tokenType == TokenType.Operator)
                {
                    switch (tokenValue)
                    {
                    case "(":
                        if (operatorStack.Contains(")"))
                        {
                            throw new Exception("Illigal expression");
                        }
                        operatorStack.Push(tokenValue);
                        break;

                    case ")":
                        if (!operatorStack.Contains("("))
                        {
                            throw new Exception("Illigal expression");
                        }
                        while (operatorStack.Count > 0)
                        {
                            string op = operatorStack.Pop();
                            if (op == "(")
                            {
                                break;
                            }
                            Expression right = operandStack.Pop();
                            Expression left  = operandStack.Pop();
                            operandStack.Push(ParseBinaryExpression(op, left, right));
                        }
                        break;

                    case "+":
                    case "-":
                        if (operatorStack.Count == 0)
                        {
                            operatorStack.Push(tokenValue);
                        }
                        else
                        {
                            if (operatorStack.Peek() != "(")
                            {
                                string     op    = operatorStack.Pop();
                                Expression right = operandStack.Pop();
                                Expression left  = operandStack.Pop();
                                operandStack.Push(ParseBinaryExpression(op, left, right));
                            }
                            operatorStack.Push(tokenValue);
                        }
                        break;

                    case "*":
                    case "/":
                        if (operatorStack.Count == 0)
                        {
                            operatorStack.Push(tokenValue);
                        }
                        else
                        {
                            var _op = operatorStack.Peek();
                            if (_op != "+" && _op != "-" && _op != "(")
                            {
                                string     op    = operatorStack.Pop();
                                Expression right = operandStack.Pop();
                                Expression left  = operandStack.Pop();
                                operandStack.Push(ParseBinaryExpression(op, left, right));
                            }
                            operatorStack.Push(tokenValue);
                        }
                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    if (tokenType == TokenType.Literal)
                    {
                        operandStack.Push(new Literal(tokenValue));
                    }
                    else
                    {
                        operandStack.Push(new Variable(tokenValue));
                    }
                }
            }

            while (operatorStack.Count > 0)
            {
                string     op    = operatorStack.Pop();
                Expression right = operandStack.Pop();
                Expression left  = operandStack.Pop();
                operandStack.Push(ParseBinaryExpression(op, left, right));
            }

            if (operandStack.Count != 1)
            {
                throw new Exception("Invalid expression");
            }

            return(operandStack.Pop());
        }