Beispiel #1
0
        /// <summary>
        /// Ищет в контейнере последний терминальный символ, у которого нет дочерних элементов.
        /// </summary>
        /// <param name="container"></param>
        /// <returns></returns>
        private int lastIndexOfVnWithoutChilds(List <OutputTreeCell> container)
        {
            if (container.Count == 0)
            {
                //Logger.Info("-- OutputTree is empty");
                return(-1);
            }
            if (container.Count == 1 & container[0].Value.Equals(SpecialSymbs.NOT_TERMINAL_SYMB))
            {
                return(0);
            }
            if (container[container.Count - 1].Equals(SpecialSymbs.NOT_TERMINAL_SYMB))
            {
                return(container.Count - 1);
            }

            for (int i = container.Count - 2; i >= 0; i--)
            {
                OutputTreeCell pre  = container[i];
                OutputTreeCell post = container[i + 1];

                if (!pre.Value.Equals(SpecialSymbs.NOT_TERMINAL_SYMB))
                {
                    continue;
                }
                if (pre.Level < post.Level)
                {
                    continue;
                }
                return(i);
            }

            //Logger.Info("-- All VN with child elems");
            return(-1);
        }
Beispiel #2
0
        /// <summary>
        /// Метод, используя матрицу правил и последовательность использованных правил, строит Дерево Вывода.
        /// </summary>
        /// <param name="rulesMatrix"></param>
        /// <param name="usedRulesList"></param>
        /// <returns></returns>
        public List <OutputTreeCell> GetOutputTree(RulesMatrix rulesMatrix, List <int> usedRulesList)
        {
            List <OutputTreeCell> treeContainer = new List <OutputTreeCell>();

            OutputTreeCell root = new OutputTreeCell(0, SpecialSymbs.NOT_TERMINAL_SYMB);

            treeContainer.Add(root);

            //Logger.Info("Iteration 0, tree: {0}", string.Join(" || ", treeContainer.ToArray()));

            for (int ruleIdx = usedRulesList.Count - 1; ruleIdx >= 0; ruleIdx--)
            {
                int iteration = usedRulesList.Count - ruleIdx;
                //Logger.Info("Iteration: {0} || Rule #{1} || size of tree: {2}", iteration, usedRulesList[ruleIdx], treeContainer.Count);
                //Logger.Info("- Tree at start: {0}", string.Join(" ", treeContainer.ToArray()));

                string[] ruleSymbs = rulesMatrix.GetRuleByNumber(usedRulesList[ruleIdx]);

                int insertIdx = lastIndexOfVnWithoutChilds(treeContainer) + 1;
                if ((insertIdx - 1) < 0)
                {
                    break;
                }

                //Logger.Info("-- Last index of VN without childs: {0}", insertIdx - 1);
                int childsLevel = treeContainer[insertIdx - 1].Level + 1;

                // Закидывание символов из текущего правила рядом с нетерминалом, который они раскрывают
                foreach (string symb in Reverse(ruleSymbs))
                {
                    treeContainer.Insert(insertIdx, new OutputTreeCell(childsLevel, symb));
                }

                //Logger.Info("- Tree at end: {0}", string.Join(" ", treeContainer.ToArray()));
            }

            // Logger.Info("\nFull tree: {0}\n", string.Join(" || ", treeContainer.ToArray()));

            return(treeContainer);
        }
        /// <summary>
        /// Метод, выполняющий красивую отрисвоку Дерева вывода в консоль.
        /// </summary>
        public void DrawToConsole()
        {
            if (OutputTree.Count == 0)
            {
                throw new System.Exception("Пустое дерево - нечего рисовать!");
            }
            if (OutputTree.Count == 1)
            {
                MakeDrawing(new StringBuilder(OutputTree[0].Value));
            }

            StringBuilder treeD = new StringBuilder();
            List <int>    currentChildsAtLevels = new List <int>();

            for (int i = 0; i <= GetMaxLevel(); i++)
            {
                currentChildsAtLevels.Add(0);
            }

            treeD.Append(OutputTree[0].Value).Append('\n');

            //Logger.Info("GetMaxLevel = {0}, Len of OutputTree = {1}", GetMaxLevel(), OutputTree.Count);

            int lastNodeLvl = OutputTree[0].Level;

            for (int i = 1; i < OutputTree.Count; i++)
            {
                OutputTreeCell currentNode = OutputTree[i];
                int            currentLvl  = currentNode.Level;
                if (lastNodeLvl < currentLvl)
                {
                    currentChildsAtLevels[lastNodeLvl] = FindAmountOfDirectChilds(i - 1);
                }

                //Logger.Info("Now symb: [ {0} -> {1} ], currLvl={2}, lastLvl={3} array of direct childs: {4}",
                //currentLvl, currentNode.Value, currentLvl, lastNodeLvl, string.Join(" ", currentChildsAtLevels.ToArray()));

                for (int j = 0; j < currentLvl; j++)
                {
                    if (currentChildsAtLevels[j] > 0)
                    {
                        treeD.Append('|');
                    }
                    else
                    {
                        treeD.Append(' ');
                    }

                    if (currentLvl - j > 1)
                    {
                        SpamSymbol(treeD, AmountOfSlashesBeforeSymbol + AmountOfSpacesBeforeSymbol, ' ');
                    }

                    if (currentNode.Level - 1 == j)
                    {
                        ReduceChildsAmountBy1(currentChildsAtLevels, currentNode.Level);
                    }
                }

                SpamSymbol(treeD, AmountOfSlashesBeforeSymbol, '-');
                SpamSymbol(treeD, AmountOfSpacesBeforeSymbol, ' ');
                treeD.Append(currentNode.Value);
                treeD.Append('\n');

                lastNodeLvl = currentLvl;
            }

            MakeDrawing(treeD);
        }