private static double ParseSimpleStatement()
        {
            // Get a token
            Token token = ExpressionParser.ParseToken();

            switch (token.tokenType)
            {
            case TokenType.START_BRACKET:
                double val = ParseStatement();
                ParseToken(")");
                return(val);

            case TokenType.IDENTIFIER:
                return(ParseIdentifier(token));

            case TokenType.OPERATOR:
                switch (token.sval)
                {
                case "-":
                    return(-ParseSimpleStatement());

                case "!":
                    return(ParseSimpleStatement() == 0.0 ? 1.0 : 0.0);

                default:
                    throw new ArgumentException("Unexpected operator: " + token.sval);
                }

            case TokenType.VALUE:
                return(token.dval);

            default:
                throw new ArgumentException("Unexpected value: " + token.sval);
            }
        }
        private static double ParseStatement()
        {
            double lval = ParseSimpleStatement();

            // End of statement
            if (expression.Length == 0)
            {
                return(lval);
            }

            // Get next token
            Token token = ExpressionParser.ParseToken();

            while (token != null)
            {
                switch (token.tokenType)
                {
                case TokenType.START_BRACKET:
                    throw new ArgumentException("Unexpected value: " + token.sval);

                case TokenType.END_BRACKET:
                    expression = ")" + expression;
                    return(lval);

                case TokenType.IDENTIFIER:
                case TokenType.VALUE:
                    throw new ArgumentException("Unexpected value: " + token.sval);

                case TokenType.OPERATOR:
                    lval = ParseOperation(lval, token.sval);
                    break;

                default:
                    throw new ArgumentException("Unexpected value: " + token.sval);
                }

                // Get next token
                token = ExpressionParser.ParseToken();
            }

            return(lval);
        }
        private static double ParseOperation(double lval, string op)
        {
            double rval = ParseSimpleStatement();

            // Get a token
            Token token = ExpressionParser.ParseToken();

            while (token != null)
            {
                switch (token.tokenType)
                {
                case TokenType.START_BRACKET:
                case TokenType.IDENTIFIER:
                case TokenType.VALUE:
                    throw new ArgumentException("Unexpected value: " + token.sval);

                case TokenType.END_BRACKET:
                    expression = token.sval + expression;
                    return(ApplyOperator(lval, op, rval));

                case TokenType.OPERATOR:
                    if (precedence[op] >= precedence[token.sval])
                    {
                        expression = token.sval + expression;
                        return(ApplyOperator(lval, op, rval));
                    }
                    else
                    {
                        rval  = ParseOperation(rval, token.sval);
                        token = ExpressionParser.ParseToken();
                    }
                    break;

                default:
                    throw new ArgumentException("Unexpected value: " + token.sval);
                }
            }

            return(ApplyOperator(lval, op, rval));
        }