Ошибка StackOverflowException в калькуляторе выражений

213
29 апреля 2018, 19:35

Делаю калькулятор выражений (по типу 2 + (2 * sin(2^2)))) При запуске и вводе даже банального выражения (2 + 2) выдает StackOverflowException. Я так понимаю проблема в том, что он не может выйти из рекурсии, но, вроде как, все возможные пути выхода у меня прописаны.

class Operation
{
    public double First;
    public string ParseFirst
    {
        get { return First.ToString(); }
        set { First = Convert.ToDouble(value); }
    }
    public double Second;
    public string ParseSecond
    {
        get { return Second.ToString(); }
        set { Second = Convert.ToDouble(value); }
    }
    public enum Operand
    {
        Sum,
        Subtraction,
        Multiplication,
        Division,
        Degree,
        Sqrt,
        Sin,
        Cos,
        Tg,
        Ln
    }
}
class Program
{
    static double Calculator(string Input)
    {
        double Result = 0;
        Operation.Operand operation = new Operation.Operand();
        Operation operand = new Operation();
        for (int i = 0; i < Input.Length | Input[i] != ')'; i++)
            {
                if (Input[i] == '(')
                {
                    operand.Second = Calculator(Input.Substring(0, i));
                }
                else
                {
                    if (Char.IsDigit(Input[i]))
                    {
                        string number = null;
                        while (!IsDelimeter(Input[i]) && !IsOperator(Input[i]))
                        {
                            number += Input[i];
                            i++;
                            if (i == Input.Length)
                            {
                                break;
                            }
                        }
                        i--;
                        operand.ParseFirst = number;
                    }
                    else
                    {
                        if (IsDelimeter(Input[i]))
                        {
                            continue;
                        }
                        else
                        {
                            if (IsOperator(Input[i]))
                            {
                                switch (Input[i])
                                {
                                    case '+':
                                        {
                                            operation = Operation.Operand.Sum;
                                            operand.Second = Calculator(Input.Substring(i));
                                            break;
                                        }
                                    case '-':
                                        {
                                            operation = Operation.Operand.Subtraction;
                                            operand.Second = Calculator(Input.Substring(i));
                                            break;
                                        }
                                    case '/':
                                        {
                                            operation = Operation.Operand.Division;
                                            operand.Second = Calculator(Input.Substring(i));
                                            break;
                                        }
                                    case '*':
                                        {
                                            operation = Operation.Operand.Multiplication;
                                            operand.Second = Calculator(Input.Substring(i));
                                            break;
                                        }
                                    case '^':
                                        {
                                            operation = Operation.Operand.Degree;
                                            operand.Second = Calculator(Input.Substring(i));
                                            break;
                                        }
                                    case 's':
                                        {
                                            if (Input[i + 1] == 'i' && Input[i + 2] == 'n' && Input[i + 3] == '(')
                                            {
                                                operation = Operation.Operand.Sin;
                                                operand.Second = Calculator(Input.Substring(i + 3));
                                                break;
                                            }
                                            else
                                            {
                                                if (Input[i + 1] == 'q' && Input[i + 2] == 'r' && Input[i + 3] == 't' && Input[i + 4] == '(')
                                                {
                                                    operation = Operation.Operand.Sqrt;
                                                    operand.Second = Calculator(Input.Substring(i + 4));
                                                    break;
                                                }
                                                else
                                                {
                                                    throw new ApplicationException("Ошибка ввода");
                                                }
                                            }
                                        }
                                    case 'c':
                                        {
                                            if (Input[i + 1] == 'o' && Input[i + 2] == 's' && Input[i + 3] == '(')
                                            {
                                                operation = Operation.Operand.Cos;
                                                operand.Second = Calculator(Input.Substring(i + 3));
                                                break;
                                            }
                                            else
                                            {
                                                throw new ApplicationException("Ошибка ввода");
                                            }
                                        }
                                    case 't':
                                        {
                                            if (Input[i + 1] == 'g' && Input[i + 2] == '(')
                                            {
                                                operation = Operation.Operand.Tg;
                                                operand.Second = Calculator(Input.Substring(i + 2));
                                                break;
                                            }
                                            else
                                            {
                                                throw new ApplicationException("Ошибка ввода");
                                            }
                                        }
                                    case 'l':
                                        {
                                            if (Input[i + 1] == 'n' && Input[i + 2] == '(')
                                            {
                                                operation = Operation.Operand.Ln;
                                                operand.Second = Calculator(Input.Substring(i + 2));
                                                break;
                                            }
                                            else
                                            {
                                                throw new ApplicationException("Ошибка ввода");
                                            }
                                        }
                                }
                                break;
                            }
                            else
                            {
                                throw new ApplicationException("Ошибка ввода");
                            }
                        }
                    }
                }
            }
        switch (operation)
        {
            case Operation.Operand.Sum:
                {
                    Result = operand.First + operand.Second;
                    break;
                }
            case Operation.Operand.Subtraction:
                {
                    Result = operand.First - operand.Second;
                    break;
                }
            case Operation.Operand.Multiplication:
                {
                    Result = operand.First * operand.Second;
                    break;
                }
            case Operation.Operand.Division:
                {
                    Result = operand.First / operand.Second;
                    break;
                }
            case Operation.Operand.Degree:
                {
                    Result = Math.Pow(operand.First, operand.Second);
                    break;
                }
            case Operation.Operand.Sqrt:
                {
                    Result = Math.Pow(operand.First, 2);
                    break;
                }
            case Operation.Operand.Sin:
                {
                    Result = Math.Sin(operand.First);
                    break;
                }
            case Operation.Operand.Cos:
                {
                    Result = Math.Cos(operand.First);
                    break;
                }
            case Operation.Operand.Tg:
                {
                    Result = Math.Tan(operand.First);
                    break;
                }
            case Operation.Operand.Ln:
                {
                    Result = Math.Log(operand.First);
                    break;
                }
            default:
                {
                    Result = operand.First;
                    break;
                }
        }
        return Result;
    }
    static private bool IsDelimeter(char c)
    {
        if ((" =".IndexOf(c) != -1))
        {
            return true;
        }
        return false;
    }

    static private bool IsOperator(char с)
    {
        if (("+-/*^()sctl".IndexOf(с) != -1))
        {
            return true;
        }
        return false;
    }

    static void Main(string[] args)
    {
        Console.Write("Введите выражение: ");
        Console.WriteLine(Calculator(Console.ReadLine()));
    }
}
READ ALSO
обновить БД на Azure Asp Core

обновить БД на Azure Asp Core

Я изменил модель MyModel добавив в нее новое свойство Myprop{get; set;}

168
Что выбрать лучше? [Клиент/Сервер]

Что выбрать лучше? [Клиент/Сервер]

Посоветуйте что лучше использовать под клиент/сервер TcpListener или Socket или TcpClient?

136
Как сократить код не используя цикл for

Как сократить код не используя цикл for

Есть массив ключ=значение string, значение имеет разделители , | послеSplit остаются начальные пробелы

145