예제 #1
0
        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;
            }
        }