public void PrintInfo(LinkedList <Word> arrS, List <int> rulesFounded, Queue <Word> splittedWords) { string s1 = ""; foreach (var word in splittedWords) { s1 += Words[word.Number].Value + " "; } PrintCompileInfo.Invoke(@"Строка:" + s1 + '\n'); string s2 = ""; foreach (var arrVal in arrS) { s2 += $"{arrVal.Value} "; } PrintCompileInfo.Invoke(@"Магазин:" + s2 + '\n'); string s3 = ""; foreach (var rule in rulesFounded) { s3 = s3 + (rule + 1) + " "; } PrintCompileInfo.Invoke(@"Правила:" + s3 + '\n'); PrintCompileInfo.Invoke(@" " + '\n'); }
public void Algorithm(Queue <Word> splittedWords) { // Коллекций номеров правил List <int> rulesFound = new List <int>(); //TODO: XML док LinkedList <Word> stack = new LinkedList <Word>(); //TODO: Избавиться от зависимости последнего символа stack.AddLast(Words.Last()); PrintInfo(stack, rulesFound, splittedWords); while (splittedWords.Count > 0) { CompileActions action = CompileActions.Start; // Серем слово, для просмотра Word word = splittedWords.Peek(); // Проверяем, является ли последний символ символом конца цепочки if (word.Number == Words.Last().Number) { if (stack.Count == 2) { // Если последний символ в стеке - символ цепочки S, а первый - символ клнца цепочки // Тогда разбор окончен успешно // TODO: Убрать первый сивол, заменить if ((stack.Last.Value.Number == Words.First().Number) && (stack.First.Value.Number == Words.Last().Number)) { PrintCompileResult.Invoke(stack.Last.Value.Temp); return; } } } int row = stack.Last.Value.Number; int col = word.Number; // Правило, для переноса if ((RuleRuleTable[row, col] == 1 && action != CompileActions.Error) || (RuleRuleTable[row, col] == 2 && action != CompileActions.Error)) { // Вытаскиваем слово из входной цепочки и заносим в стек Word tmpWord = splittedWords.Dequeue(); stack.AddLast(tmpWord); action = CompileActions.Next; } // Правило, для свертки if ((RuleRuleTable[row, col] == 3) && action != CompileActions.Next && action != CompileActions.Error) { // Ищем количество слов, для свертки // Изначально, текуший символ не может иметь правило, для сдвига => cnt = 1 int cntWordsInStack = 1; // Начинаем поиск с конца цепочки LinkedListNode <Word> node = stack.Last; // Если правило не равняется сдвигу, то сдвигаем цепочку. Увеличиваем число найденных слов while (RuleRuleTable[node.Previous.Value.Number, node.Value.Number] != 1) { node = node.Previous; cntWordsInStack++; } // Ищем подходящее правило for (var ruleNumber = 0; ruleNumber < Rules.Length; ruleNumber++) { // Ищем подходящие по длене правило из списка правил if (Rules[ruleNumber].CountOfWords == cntWordsInStack) { // Количество символов, которые последовательно совпадают в цепочке и правиле int cntWordsInRule = 0; // Присваиваем начальный символ цепочки, для свертки LinkedListNode <Word> srchNode = node; // Можно изменить способ сверки for (var i = 0; i < cntWordsInStack; i++) { // Сверяет последовательность слов в выбранном правиле с цепочкой правил в стеке if (Rules[ruleNumber].RuleList[i] == srchNode.Value.Number) { cntWordsInRule++; srchNode = srchNode.Next; } else { break; } } // Если количество сошлось, то это то правило if (cntWordsInRule == cntWordsInStack) { // Загружаем последний элемент стека srchNode = stack.Last; // СмещаемЮ до первого элемента, в цепочке правил for (int i = 1; i < cntWordsInRule; i++) { srchNode = srchNode.Previous; } // Производим покпиляцию по правилу MyCompil(ruleNumber, srchNode); // Присваиваем номер и символ правила, которое использовали int collapsedRuleNumber = Rules[ruleNumber].RuleNumber; node.Value.Number = collapsedRuleNumber; node.Value.Value = Words[collapsedRuleNumber].Value; // Добаляем использованное правило в коллекцию правил rulesFound.Add(ruleNumber); // Очищаем ненужные элементы до конца списка while (node.Next != null) { stack.Remove(node.Next); } action = CompileActions.Next; //PrintCompileResult.Invoke($"Value: {node.Value.Value} \nRule: {node.Value.Number} \nTemp: {node.Value.Temp}"); PrintCompileResult.Invoke(string.Format("Value: {0} \nRule: {1} \nTemp: {2}", node.Value.Value, node.Value.Number, node.Value.Temp)); break; } } } } if (action != CompileActions.Next) { PrintCompileInfo.Invoke(@"Ошибка при выполнении восходящего разбора!"); PrintCompileResult.Invoke(""); return; } PrintInfo(stack, rulesFound, splittedWords); } }