public bool TryCompile(Queue <Word> splittedWords) { // Коллекций номеров правил List <int> rulesFound = new List <int>(); // Коллекция элементов в магазине LinkedList <Word> stack = new LinkedList <Word>(); stack.AddLast(new Word(_lastWord)); OnCompileNextStep.Invoke(this, new CompileInfoEventArgs(splittedWords, stack, rulesFound)); while (splittedWords.Count > 0) { CompileActions action = CompileActions.Start; // Серем слово, для просмотра Word word = splittedWords.Peek(); // Проверяем, является ли последний символ символом конца цепочки if (word.Number == _lastWord.Number) { if (stack.Count == 2) { // Если последний символ в стеке - символ цепочки S, а первый - символ клнца цепочки // Тогда разбор окончен успешно if ((stack.Last.Value.Number == _firstRule.RuleWordNumber) && (stack.First.Value.Number == _lastWord.Number)) { CompiledText = stack.Last.Value.Temp; OnCompileDone.Invoke(this, new CompileInfoEventArgs(splittedWords, stack, rulesFound)); return(true); } } } int row = stack.Last.Value.Number; int col = word.Number; // Правило, для переноса if ((RuleTable[row, col] == 1 && action != CompileActions.Error) || (RuleTable[row, col] == 2 && action != CompileActions.Error)) { // Вытаскиваем слово из входной цепочки и заносим в стек Word tmpWord = splittedWords.Dequeue(); stack.AddLast(tmpWord); action = CompileActions.Next; } // Правило, для свертки if ((RuleTable[row, col] == 3) && action != CompileActions.Next && action != CompileActions.Error) { // Ищем количество слов, для свертки // Изначально, текуший символ не может иметь правило, для сдвига => cnt = 1 int cntWordsInStack = 1; // Начинаем поиск с конца цепочки LinkedListNode <Word> node = stack.Last; // Если правило не равняется сдвигу, то сдвигаем цепочку. Увеличиваем число найденных слов while (RuleTable[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) { List <Word> toCompileList = new List <Word>(); // Загружаем последний элемент стека srchNode = stack.Last; toCompileList.Add(srchNode.Value); // СмещаемЮ до первого элемента, в цепочке правил for (int i = 1; i < cntWordsInRule; i++) { srchNode = srchNode.Previous; toCompileList.Add(srchNode.Value); } // Присваиваем номер и символ правила, которое использовали int collapsedRuleNumber = Rules[ruleNumber].RuleWordNumber; // Производим покпиляцию по правилу node.Value.Temp = _compiler.Compil(ruleNumber, toCompileList.ToArray()); node.Value.Number = collapsedRuleNumber; node.Value.Value = Words[collapsedRuleNumber].Value; // Добаляем использованное правило в коллекцию правил rulesFound.Add(ruleNumber); // Очищаем ненужные элементы до конца списка while (node.Next != null) { stack.Remove(node.Next); } action = CompileActions.Next; break; } } } } if (action != CompileActions.Next) { OnCompileError.Invoke(this, new CompileErrorEventArgs(splittedWords, stack, rulesFound, RuleTable[row, col])); return(false); } OnCompileNextStep.Invoke(this, new CompileInfoEventArgs(splittedWords, stack, rulesFound)); } return(false); }
private void PythonProcess_OutputDataReceived(object sender, DataReceivedEventArgs e) { if (string.IsNullOrEmpty(e.Data)) { return; } if (e.Data.Contains("STDERR:")) { PythonProcess_ErrorDataReceived(sender, e); return; } Console.WriteLine("stdout[" + State + "]:" + e.Data); switch (State) { case STATE_RUNNING: { if (e.Data.Equals(END_RUN_CODE)) { State = STATE_WAITING; if (hasRunError) { OnRunError?.Invoke(); } } else if (e.Data.Contains(UPDATE_PROXY_VALUE)) { string[] split = e.Data.Split(new char[] { ':' }, 3); string name = split[1]; string value = split[2]; UpdateProxyProperty(name, value); } else if (e.Data.Contains(CALL_METHOD)) { string[] split = e.Data.Split(new char[] { ':' }, 3); string methodName = split[1]; JArray decoded = (JArray)JsonConvert.DeserializeObject(split[2]); object ans = CallProxyMethod(methodName, decoded); string jsonAns = ""; if (ans is Exception) { jsonAns = JsonConvert.SerializeObject(new Hashtable() { { "exception", ((Exception)ans).Message } }); } else { jsonAns = JsonConvert.SerializeObject(new Hashtable() { { "answer", ans } }); } pythonProcess.StandardInput.WriteLine(jsonAns); } else { OnStdOut?.Invoke(e.Data); OnDoneRunning?.Invoke(); } } break; case STATE_COMPILING: { if (e.Data.Equals(DONE_COMPILE_CODE)) { State = STATE_WAITING; OnDoneCompiling?.Invoke(); if (hasCompileError) { OnCompileError?.Invoke(); } } } break; } }