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); }
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(); }
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; }
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()); }