private static void TestArithmetic() { do { Console.Clear(); Console.Write("Введите арифметическое выражение: "); string expression = Console.ReadLine(); string convertedExpression = PolishArithmetic.GetPolishNotation(expression); Console.WriteLine("\nВыражение в обратной польской нотации: {0}", convertedExpression); string result = PolishArithmetic.CalculatePolishExpression(convertedExpression); Console.Write("\nРезультат вычисления: "); if (!Char.IsLetter(result[0])) { Console.Write(result); } Console.WriteLine(); PolishArithmetic.SetVars(); foreach (KeyValuePair <string, string> p in PolishArithmetic.Vars) { Console.WriteLine(p.Key + " = " + p.Value); } PolishArithmetic.Vars.Clear(); Console.WriteLine("\n(Нажмите ESC, чтобы выйти)"); }while (Console.ReadKey().Key != ConsoleKey.Escape); }
// Возвращает выражение, переведенное в обратную польскую запись public static List <string> GetPolishNote(string expression) { List <string> polishExpression = new List <string>(); expression = expression.Replace(" ", ""); if (expression[0] == 'w') // while (a > 0) t += 2 { string modifiedExpression = "if "; int index = expression.IndexOf('(') + 1; int bracketCounter = 1; while (bracketCounter != 0) { modifiedExpression += expression[index++]; if (expression[index] == '(') { bracketCounter++; } else if (expression[index] == ')') { bracketCounter--; } } modifiedExpression += " then "; modifiedExpression += expression.Substring(index + 1); polishExpression = PolishCondition.GetPolishNote(modifiedExpression); polishExpression.Remove("$"); polishExpression.Add("0"); polishExpression.Add("!"); polishExpression.Add("$"); polishExpression[polishExpression.IndexOf("!F") - 1] = (Convert.ToInt32(polishExpression[polishExpression.IndexOf("!F") - 1]) + 2).ToString(); } else if (expression[0] == 'd') // do t += 2 while (a > 0) { // do b = 2 while (a > 0) // b 2 = a 0 > 0 !T $ expression = expression.Substring(2); string action = expression.Substring(0, expression.IndexOf("while")); polishExpression.AddRange(PolishArithmetic.GetPolishNotation(action).Split(' ')); expression = expression.Substring(expression.IndexOf("while")); expression = expression.Substring(expression.IndexOf("(") + 1); string condition = expression.Substring(0, expression.LastIndexOf(")")); int compOpIndex = 0; for (int j = 0; j < condition.Length; j++) { if (condition[j] == '>' || condition[j] == '<' || condition[j] == '~' || condition[j] == '}' || condition[j] == '{') { compOpIndex = j; break; } } string logicLeftPart = condition.Substring(0, compOpIndex); string logicRightPart = condition.Substring(compOpIndex + 1); condition = PolishArithmetic.GetPolishNotation(logicLeftPart) + " " + PolishArithmetic.GetPolishNotation(logicRightPart) + " " + condition[compOpIndex]; polishExpression.AddRange(condition.Split(' ')); polishExpression.Add("0"); polishExpression.Add("!T"); polishExpression.Add("$"); } else if (expression[0] == 'f') // for (i = 0; i < a; i += 1) t += 2 { // for (i = 0; i < a; i += 1) t += 2 // i 0 = i a < 24 !F 17 !! i i 1 + = 3 !! t t 2 + = 10 !! $ string[] parts = expression.Split(';'); // [for(i=0][i<a][i+=1)t+=2] parts[0] = parts[0].Substring(parts[0].IndexOf("(") + 1); polishExpression.AddRange(PolishArithmetic.GetPolishNotation(parts[0]).Split(' ')); int Bindex = polishExpression.Count; string condition = parts[1]; int compOpIndex = 0; for (int j = 0; j < condition.Length; j++) { if (condition[j] == '>' || condition[j] == '<' || condition[j] == '~' || condition[j] == '}' || condition[j] == '{') { compOpIndex = j; break; } } string logicLeftPart = condition.Substring(0, compOpIndex); string logicRightPart = condition.Substring(compOpIndex + 1); condition = PolishArithmetic.GetPolishNotation(logicLeftPart) + " " + PolishArithmetic.GetPolishNotation(logicRightPart) + " " + condition[compOpIndex]; polishExpression.AddRange(condition.Split(' ')); polishExpression.Add("#"); polishExpression.Add("!F"); polishExpression.Add("#"); polishExpression.Add("!!"); int Cindex = polishExpression.Count; string counter = parts[2].Substring(0, parts[2].IndexOf(")")); polishExpression.AddRange(PolishArithmetic.GetPolishNotation(counter).Split(' ')); polishExpression.Add(Bindex.ToString()); polishExpression.Add("!!"); int Aindex = polishExpression.Count(); string action = parts[2].Substring(parts[2].IndexOf(")") + 1); polishExpression.AddRange(PolishArithmetic.GetPolishNotation(action).Split(' ')); polishExpression.Add(Cindex.ToString()); polishExpression.Add("!!"); polishExpression.Add("$"); polishExpression[polishExpression.IndexOf("#")] = (polishExpression.Count - 1).ToString(); polishExpression[polishExpression.IndexOf("#")] = Aindex.ToString(); } return(polishExpression); }
// Возвращает выражение, переведенное в обратную польскую запись public static List <string> GetPolishNote(string expression) { List <string> polishExpression = new List <string>(); // if a > 0 then a = ~a else if b > 2 then a = ~b else a = b + 1 // a 0 > t1 !F a a ~ = t0 !! (t1) b 2 > t2 !F a b ~ = t0 !! (t2) a b 1 + = (t0)$ string expressionBuffer = ""; expression += "$"; for (int i = 0; i < expression.Length; i++) { if (expression[i] == '$') { // конвертируем выражение expressionBuffer = PolishArithmetic.GetPolishNotation(expressionBuffer).Replace(" ", " "); polishExpression.AddRange(expressionBuffer.Split(' ')); polishExpression.Add("$"); continue; } else if (i != expression.Length - 1 && expression[i] == 'i' && expression[i + 1] == 'f') { // очищаем буфер i++; expressionBuffer = ""; continue; } else if (i != expression.Length - 1 && expression[i] == 't' && expression[i + 1] == 'h') { // конвертируем условием, добавляем метки, очищаем буфер // a > 0 //индекс оператора сравнения int compOpIndex = 0; for (int j = 0; j < expressionBuffer.Length; j++) { if (expressionBuffer[j] == '>' || expressionBuffer[j] == '<' || expressionBuffer[j] == '~' || expressionBuffer[j] == '}' || expressionBuffer[j] == '{') { compOpIndex = j; break; } } string logicLeftPart = expressionBuffer.Substring(0, compOpIndex); string logicRightPart = expressionBuffer.Substring(compOpIndex + 1); expressionBuffer = PolishArithmetic.GetPolishNotation(logicLeftPart) + " " + PolishArithmetic.GetPolishNotation(logicRightPart) + " " + expressionBuffer[compOpIndex]; polishExpression.AddRange(expressionBuffer.Split(' ')); polishExpression.Add("#"); polishExpression.Add("!F"); i += 3; expressionBuffer = ""; continue; } else if (i != expression.Length - 1 && expression[i] == 'e' && expression[i + 1] == 'l') { // конвертируем выражение, добавляем метки, очищаем буфер expressionBuffer = PolishArithmetic.GetPolishNotation(expressionBuffer).Replace(" ", " "); polishExpression.AddRange(expressionBuffer.Split(' ')); polishExpression.Add("#"); polishExpression.Add("!!"); i += 3; expressionBuffer = ""; continue; } else { // запись очередного элемента expressionBuffer += expression[i]; } } // if a > 0 then if b > 0 then a = 1 else b = 1 // a 0 > # !F b 0 > # !F a 1 = # !! b 1 = $ // a 0 > # !F b 0 > # !F a 1 = n !! b 1 = $ // // if a > 0 then a = 1 // a 0 > # !F a 1 = $ // // if a > 0 then a = 1 else a = 2 // a 0 > # !F a 1 = # !! a 2 = $ // // if a > 0 then a = 1 else if b > 2 then a = 2 else a = 3 // a 0 > # !F a 1 = # !! a 2 ~ # !F a 2 = # !! a 3 = $ // a 0 > # !F a 1 = n !! a 2 ~ # !F a 2 = n !! a 3 = $ // // if a > 0 then if b > 0 then a = 1 else if b < 0 then a = 42 else b = 1 else a = 14 // a 0 > 30 !F b 0 > 15 !F a 1 = 33 !! b 0 < 25 !F a 42 = 33 !! b 1 = 33 !! a 14 = $ for (int i = 0; i < polishExpression.Count; i++) { if (polishExpression[i] == "!!") { polishExpression[i - 1] = (polishExpression.Count - 1).ToString(); } } for (int i = polishExpression.Count - 1; i >= 0; i--) { if (polishExpression[i] == "!F") { int index = polishExpression.IndexOf("!!", i); if (index != -1) { polishExpression[i - 1] = (index + 1).ToString(); polishExpression[index] = "!!!"; } else { polishExpression[i - 1] = (polishExpression.Count - 1).ToString(); } } } for (int i = 0; i < polishExpression.Count; i++) { if (polishExpression[i] == "!!!") { polishExpression[i] = "!!"; } } return(polishExpression); }