예제 #1
0
        public static double evaluate(string s, ArgTable argTable)
        {
            try
            {
                Split(s);
            }
            catch (Exception E)
            {
                Console.WriteLine("Ошибка разбиения: " + E.Message);
                Console.Read();
            }
            Console.WriteLine();
            double Result = 0.0;

            try
            {
                Result = Evaluate(argTable);
            }
            catch (Exception E)
            {
                Console.Write("ОШИБКА ВЫЧИСЛЕНИЯ: " + E.Message);
                Console.Read();
            }
            return(Result);
        }
예제 #2
0
        public static double Evaluate(ArgTable argTable)
        {
            ArgStack = new Stack<double>();
            OpStack = new Stack<Operation>();
            int depth = 0;
            bool needValue = true;
            int n = 0;

            Identifiers = new List<Identifier>();
            Identifier ID;
            ID.IdentifierString = "";
            ID.Value = 0;
            bool IsNew = true;

            //Console.WriteLine("Семантический анализ: ");
            foreach (Part CurrentPart in Parts)
            {
                n++;
                switch (CurrentPart.Type)
                {
                    case PartType.Number:
                        if (!needValue)
                            throw new Exception("Неуместное число: (" + CurrentPart.Value.ToString() + "): позиция "
                                                                      + CurrentPart.Position.ToString());
                        ArgStack.Push(double.Parse(CurrentPart.Value));
                        needValue = false;
                        break;
                    case PartType.Parenthesis:
                        if (CurrentPart.Value[0] == '(')
                            if (!needValue)
                                throw new Exception("Неуместная открывающая скобка: позиция " + CurrentPart.Position.ToString());
                            else
                                depth++;
                        else
                            if (depth == 0 || needValue)
                            throw new Exception("Неуместная закрывающая скобка: позиция " + CurrentPart.Position.ToString());
                        else
                            depth--;
                        break;
                    case PartType.Sign:
                        Operation CurrentOperation;
                        if (needValue)
                            if (CurrentPart.Value[0] == '-')
                            {
                                CurrentOperation.Sign = '~';
                                CurrentOperation.Precedence = depth * 10 + 1;
                                OpStack.Push(CurrentOperation);
                            }
                            else
                                throw new Exception("Неуместный знак: (" + CurrentPart.Value.ToString() + "): позиция "
                                                                               + CurrentPart.Position.ToString());
                        else
                        {
                            CurrentOperation.Sign = CurrentPart.Value[0];
                            CurrentOperation.Precedence = 0;
                            switch (CurrentPart.Value[0])
                            {
                                case '+':
                                    CurrentOperation.Precedence = depth * 10 + 1;
                                    break;
                                case '-':
                                    CurrentOperation.Precedence = depth * 10 + 1;
                                    break;
                                case '*':
                                    CurrentOperation.Precedence = depth * 10 + 2;
                                    break;
                                case '/':
                                    CurrentOperation.Precedence = depth * 10 + 2;
                                    break;
                                case '^':
                                    CurrentOperation.Precedence = depth * 10 + 3;
                                    break;
                            }
                            Reduce(CurrentOperation.Precedence);
                            OpStack.Push(CurrentOperation);
                            needValue = true;
                        }

                        break;
                    case PartType.Identifier:
                        if (!needValue)
                            throw new Exception("Неуместный идиентификатор: (" + CurrentPart.Value.ToString() +
                                "): позиция " + CurrentPart.Position.ToString());
                        foreach (Identifier CurrentIdentifier in Identifiers)
                        {
                            if ((CurrentPart.Value).ToLower() == (CurrentIdentifier.IdentifierString).ToLower())
                            {
                                ArgStack.Push(CurrentIdentifier.Value);
                                IsNew = false;
                            }
                            else
                                IsNew = true;
                            if (IsNew == false)
                                break;
                        }

                        if (IsNew == true)
                        {
                            ID.IdentifierString = CurrentPart.Value;
                            for (int i = 0; i < argTable.args.Count; i++)
                            {
                                if (ID.IdentifierString == argTable.args[i])
                                    ID.Value = argTable.values[i];
                            }
                            ArgStack.Push(ID.Value);
                            Identifiers.Add(ID);
                        }
                        needValue = false;
                        break;
                }
                // Вывод списка лексем с текущими состояниями стеков аргументов и операций
                //Console.WriteLine("__________________");
                //Console.WriteLine("Обработка лексемы № {0:d}", n);
                //Console.WriteLine("Стек аргументов: ");
                //foreach (double Arg in ArgStack)
                //    Console.WriteLine("{0:g}", Arg.ToString());
                //Console.WriteLine("Стек операций:");
                //foreach (Operation Op in OpStack)
                //    Console.WriteLine("{0:g} ({1:d})", Op.Sign.ToString(), Op.Precedence.ToString());
            }
            Reduce(0);
            if (depth > 0)
            {
                throw new Exception("Не закрыты скобки в конце строки");
            }
            return ArgStack.FirstOrDefault();
        }
예제 #3
0
 public static double evaluate(string s, ArgTable argTable)
 {
     try
     {
         Split(s);
     }
     catch (Exception E)
     {
         Console.WriteLine("Ошибка разбиения: " + E.Message);
         Console.Read();
     }
     Console.WriteLine();
     double Result = 0.0;
     try
     {
         Result = Evaluate(argTable);
     }
     catch (Exception E)
     {
         Console.Write("ОШИБКА ВЫЧИСЛЕНИЯ: " + E.Message);
         Console.Read();
     }
     return Result;
 }
예제 #4
0
        public static double Evaluate(ArgTable argTable)
        {
            ArgStack = new Stack <double>();
            OpStack  = new Stack <Operation>();
            int  depth     = 0;
            bool needValue = true;
            int  n         = 0;

            Identifiers = new List <Identifier>();
            Identifier ID;

            ID.IdentifierString = "";
            ID.Value            = 0;
            bool IsNew = true;

            //Console.WriteLine("Семантический анализ: ");
            foreach (Part CurrentPart in Parts)
            {
                n++;
                switch (CurrentPart.Type)
                {
                case PartType.Number:
                    if (!needValue)
                    {
                        throw new Exception("Неуместное число: (" + CurrentPart.Value.ToString() + "): позиция "
                                            + CurrentPart.Position.ToString());
                    }
                    ArgStack.Push(double.Parse(CurrentPart.Value));
                    needValue = false;
                    break;

                case PartType.Parenthesis:
                    if (CurrentPart.Value[0] == '(')
                    {
                        if (!needValue)
                        {
                            throw new Exception("Неуместная открывающая скобка: позиция " + CurrentPart.Position.ToString());
                        }
                        else
                        {
                            depth++;
                        }
                    }
                    else
                    if (depth == 0 || needValue)
                    {
                        throw new Exception("Неуместная закрывающая скобка: позиция " + CurrentPart.Position.ToString());
                    }
                    else
                    {
                        depth--;
                    }
                    break;

                case PartType.Sign:
                    Operation CurrentOperation;
                    if (needValue)
                    {
                        if (CurrentPart.Value[0] == '-')
                        {
                            CurrentOperation.Sign       = '~';
                            CurrentOperation.Precedence = depth * 10 + 1;
                            OpStack.Push(CurrentOperation);
                        }
                        else
                        {
                            throw new Exception("Неуместный знак: (" + CurrentPart.Value.ToString() + "): позиция "
                                                + CurrentPart.Position.ToString());
                        }
                    }
                    else
                    {
                        CurrentOperation.Sign       = CurrentPart.Value[0];
                        CurrentOperation.Precedence = 0;
                        switch (CurrentPart.Value[0])
                        {
                        case '+':
                            CurrentOperation.Precedence = depth * 10 + 1;
                            break;

                        case '-':
                            CurrentOperation.Precedence = depth * 10 + 1;
                            break;

                        case '*':
                            CurrentOperation.Precedence = depth * 10 + 2;
                            break;

                        case '/':
                            CurrentOperation.Precedence = depth * 10 + 2;
                            break;

                        case '^':
                            CurrentOperation.Precedence = depth * 10 + 3;
                            break;
                        }
                        Reduce(CurrentOperation.Precedence);
                        OpStack.Push(CurrentOperation);
                        needValue = true;
                    }

                    break;

                case PartType.Identifier:
                    if (!needValue)
                    {
                        throw new Exception("Неуместный идиентификатор: (" + CurrentPart.Value.ToString() +
                                            "): позиция " + CurrentPart.Position.ToString());
                    }
                    foreach (Identifier CurrentIdentifier in Identifiers)
                    {
                        if ((CurrentPart.Value).ToLower() == (CurrentIdentifier.IdentifierString).ToLower())
                        {
                            ArgStack.Push(CurrentIdentifier.Value);
                            IsNew = false;
                        }
                        else
                        {
                            IsNew = true;
                        }
                        if (IsNew == false)
                        {
                            break;
                        }
                    }

                    if (IsNew == true)
                    {
                        ID.IdentifierString = CurrentPart.Value;
                        for (int i = 0; i < argTable.args.Count; i++)
                        {
                            if (ID.IdentifierString == argTable.args[i])
                            {
                                ID.Value = argTable.values[i];
                            }
                        }
                        ArgStack.Push(ID.Value);
                        Identifiers.Add(ID);
                    }
                    needValue = false;
                    break;
                }
                // Вывод списка лексем с текущими состояниями стеков аргументов и операций
                //Console.WriteLine("__________________");
                //Console.WriteLine("Обработка лексемы № {0:d}", n);
                //Console.WriteLine("Стек аргументов: ");
                //foreach (double Arg in ArgStack)
                //    Console.WriteLine("{0:g}", Arg.ToString());
                //Console.WriteLine("Стек операций:");
                //foreach (Operation Op in OpStack)
                //    Console.WriteLine("{0:g} ({1:d})", Op.Sign.ToString(), Op.Precedence.ToString());
            }
            Reduce(0);
            if (depth > 0)
            {
                throw new Exception("Не закрыты скобки в конце строки");
            }
            return(ArgStack.FirstOrDefault());
        }