Пример #1
0
        public static List <Token> ConvertToTokensExpression(string inputString)
        {
            inputString = inputString.Replace(" ", "").ToLower(); // remove spaces

            List <Token> tokenExpression = new List <Token>();

            int i = 0;

            while (i < inputString.Length)
            {
                string tmp      = "";
                Token  newToken = new Token();

                if ((inputString[i] == '-' || inputString[i] == '+') &&
                    (i == 0 || inputString[i - 1] == '(' || OperationsManager.IsOperation(inputString[i - 1].ToString())))
                {
                    newToken.Type = TOKEN_TYPE.UNARY_OPERATION;
                }

                if (inputString[i] == '(')
                {
                    newToken.Type = TOKEN_TYPE.OPENING_BRACKET;
                    tmp           = inputString[i++].ToString();
                }
                else if (inputString[i] == ')')
                {
                    newToken.Type = TOKEN_TYPE.CLOSING_BRACKET;
                    tmp           = inputString[i++].ToString();
                }
                else if (char.IsDigit(inputString[i]))
                {
                    newToken.Type = TOKEN_TYPE.VARIABLE;
                    while (i != inputString.Length &&
                           (char.IsDigit(inputString[i]) || inputString[i] == '.' || inputString[i] == ','))
                    {
                        if (inputString[i] == '.')
                        {
                            tmp += ','; // for parsing to double in future
                            i++;
                        }
                        else
                        {
                            tmp += inputString[i++];
                        }
                    }
                }
                else if (char.IsLetter(inputString[i]))
                {
                    while (char.IsLetter(inputString[i]))
                    {
                        tmp += inputString[i++];
                        if (i == inputString.Length)
                        {
                            break;
                        }
                    }

                    if (OperationsManager.IsOperation(tmp))
                    {
                        newToken.Type = TOKEN_TYPE.BINARY_OPERATION;

                        try
                        {
                            if (OperationsManager.IsUnaryOperation(tmp))
                            {
                                newToken.Type = TOKEN_TYPE.UNARY_OPERATION;
                            }
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                    else if (ConstManager.IsConst(tmp))
                    {
                        newToken.Type = TOKEN_TYPE.CONST;
                    }
                    else
                    {
                        throw new Exception("Undefined operation or constant \"" + tmp + "\"");
                    }
                }
                else
                {
                    tmp = inputString[i++].ToString();
                    string checkOp = tmp;
                    if (i != inputString.Length)
                    {
                        checkOp += inputString[i];
                    }
                    if (OperationsManager.IsBitOperation(checkOp) ||
                        OperationsManager.IsLogicOperation(checkOp) ||
                        OperationsManager.IsCompareOperation(checkOp))
                    {
                        tmp = checkOp;
                        i++;
                    }

                    if (OperationsManager.IsUnaryOperation(tmp))
                    {
                        newToken.Type = TOKEN_TYPE.UNARY_OPERATION;
                    }
                }
                newToken.Value = tmp;
                tokenExpression.Add(newToken);
            }

            return(tokenExpression);
        }
Пример #2
0
        public static double CalculateExpression(List <Token> mathTokensExpression)
        {
            Stack <Token> postfixExpresion = ExpressionConverter.GetPostfixExpression(mathTokensExpression);
            Stack <Token> variablesStack   = new Stack <Token>();

            while (postfixExpresion.Count > 0)
            {
                Token token = postfixExpresion.Pop();
                switch (token.Type)
                {
                case TOKEN_TYPE.VARIABLE:
                {
                    variablesStack.Push(token);
                    break;
                }

                case TOKEN_TYPE.CONST:
                {
                    token.Value = ConstManager.GetConstByToken(token).Value.ToString();
                    variablesStack.Push(token);
                    break;
                }

                case TOKEN_TYPE.UNARY_OPERATION:
                {
                    Token  variable;
                    double var;
                    try
                    {
                        variable = variablesStack.Pop();
                        var      = double.Parse(variable.Value);
                    }
                    catch (Exception)
                    {
                        throw new Exception("Bad expression");
                    }

                    switch (token.Value)
                    {
                    case "-":
                    {
                        var *= -1;
                        break;
                    }

                    case "+":
                    {
                        break;
                    }

                    case "sqrt":
                    {
                        if (var < 0)
                        {
                            throw new Exception("Do not extract the sqrt of a negative number");
                        }
                        var = Math.Sqrt(var);

                        break;
                    }

                    case "not":
                    {
                        if (var != 0 && var != 1)
                        {
                            throw new Exception("Not boolean operand for \"" + token.Value + "\"");
                        }
                        var = var == 0 ? 1 : 0;

                        break;
                    }

                    case "!":
                    {
                        double n = var;
                        var = 1;

                        for (int i = 2; i <= n; i++)
                        {
                            var *= i;
                        }
                        break;
                    }

                    case "sin":
                    {
                        var = Math.Sin(var);
                        break;
                    }

                    case "cos":
                    {
                        var = Math.Cos(var);
                        break;
                    }

                    case "tg":
                    {
                        var = Math.Tan(var);
                        break;
                    }

                    case "ctg":
                    {
                        var = Math.Cos(var) / Math.Sin(var);
                        break;
                    }

                    case "log":
                    {
                        var = Math.Log(var);
                        break;
                    }

                    default:
                    {
                        throw new Exception("Undefined unary operator");
                    }
                    }

                    variable.Value = var.ToString();
                    variablesStack.Push(variable);
                    break;
                }

                case TOKEN_TYPE.BINARY_OPERATION:
                {
                    Token secondVar;
                    Token firstVar;

                    try
                    {
                        secondVar = variablesStack.Pop();
                        firstVar  = variablesStack.Pop();
                    }
                    catch (Exception)
                    {
                        throw new Exception("Bad expression");
                    }

                    double firstDouble, secondDouble;
                    try
                    {
                        firstDouble  = double.Parse(firstVar.Value);
                        secondDouble = double.Parse(secondVar.Value);
                    }
                    catch (Exception)
                    {
                        throw new Exception("Bad variable syntax");
                    }

                    Token newVar = new Token();
                    newVar.Type = TOKEN_TYPE.VARIABLE;

                    switch (token.Value)
                    {
                    case "+":
                    {
                        newVar.Value = (firstDouble + secondDouble).ToString();
                        break;
                    }

                    case "-":
                    {
                        newVar.Value = (firstDouble - secondDouble).ToString();
                        break;
                    }

                    case "*":
                    {
                        newVar.Value = (firstDouble * secondDouble).ToString();
                        break;
                    }

                    case "/":
                    {
                        if (secondDouble == 0)
                        {
                            throw new Exception("Сannot be divided by zero");
                        }
                        newVar.Value = (firstDouble / secondDouble).ToString();
                        break;
                    }

                    case "%":
                    {
                        newVar.Value = (firstDouble % secondDouble).ToString();
                        break;
                    }

                    case "^":
                    {
                        newVar.Value = Math.Pow(firstDouble, secondDouble).ToString();
                        break;
                    }

                    case "and":
                    {
                        newVar.Value = ((int)secondDouble & (int)firstDouble).ToString();
                        break;
                    }

                    case "or":
                    {
                        newVar.Value = ((int)secondDouble | (int)firstDouble).ToString();
                        break;
                    }

                    case "xor":
                    {
                        newVar.Value = ((int)secondDouble ^ (int)firstDouble).ToString();
                        break;
                    }

                    case ">>":
                    {
                        newVar.Value = ((int)firstDouble >> (int)secondDouble).ToString();
                        break;
                    }

                    case "<<":
                    {
                        newVar.Value = ((int)firstDouble << (int)secondDouble).ToString();
                        break;
                    }

                    case "||":
                    {
                        if ((firstDouble != 0 && firstDouble != 1) || (secondDouble != 0 && secondDouble != 1))
                        {
                            throw new Exception("Not boolean operands for \"||\"");
                        }
                        bool firstBool  = firstDouble == 0 ? false : true;
                        bool secondBool = secondDouble == 0 ? false : true;
                        newVar.Value = (firstBool || secondBool == true ? 1 : 0).ToString();
                        break;
                    }

                    case "&&":
                    {
                        if (firstDouble != 0 && firstDouble != 1 || secondDouble != 0 && secondDouble != 1)
                        {
                            throw new Exception("No boolean operands for \"" + token.Value + "\"");
                        }
                        bool firstBool  = firstDouble == 0 ? false : true;
                        bool secondBool = secondDouble == 0 ? false : true;
                        newVar.Value = (firstBool && secondBool == true ? 1 : 0).ToString();
                        break;
                    }

                    case ">":
                    {
                        newVar.Value = (firstDouble > secondDouble ? 1 : 0).ToString();
                        break;
                    }

                    case ">=":
                    {
                        newVar.Value = (firstDouble >= secondDouble ? 1 : 0).ToString();
                        break;
                    }

                    case "<":
                    {
                        newVar.Value = (firstDouble < secondDouble ? 1 : 0).ToString();
                        break;
                    }

                    case "<=":
                    {
                        newVar.Value = (firstDouble <= secondDouble ? 1 : 0).ToString();
                        break;
                    }

                    case "==":
                    {
                        newVar.Value = (firstDouble == secondDouble ? 1 : 0).ToString();
                        break;
                    }

                    case "!=":
                    {
                        newVar.Value = (firstDouble != secondDouble ? 1 : 0).ToString();
                        break;
                    }

                    default:
                    {
                        throw new Exception("Undefined binary operator");
                    }
                    }

                    variablesStack.Push(newVar);
                    break;
                }

                default:
                {
                    throw new Exception("Bad expression");
                }
                }
            }

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

            return(double.Parse(variablesStack.Pop().Value));
        }