コード例 #1
0
 public void Merge(ReportParser reportParser)
 {
     if (Compile != null)
     {
         if (reportParser.Compile != null)
         {
             if (Compile.Current == null)
             {
                 Compile = reportParser.Compile;
             }
             else if (reportParser.Compile.Current != null)
             {
                 Compile.Add(reportParser.Compile);
             }
             else
             {
                 Info.AddInfo($"Информацию компиляции пропущена при добавлении к информации: {Compile}");
             }
         }
         else
         {
             Info.AddInfo($"Не удалось добавить информацию компиляции к информации: {Compile}");
         }
     }
     else
     {
         Compile = reportParser.Compile;
     }
     Info.AddRange(reportParser.Info);
     if (IsSuccess)
     {
         CheckTreeOf_RuleOr_Error(Compile);
     }
 }
コード例 #2
0
        private ReportParser RuleOR(int deep, IList <Token> tokens, ref int begin, ref int end)
        {
            ParserToken        comp        = new ParserToken(this, OR, -1, FreeId++);
            ITreeNode <object> compileTree = new TreeNode <object>(comp);
            ReportParser       output      = new ReportParser(compileTree);

            foreach (object o in this)
            {
                comp.Helper++;
                if (o is Terminal)
                {
                    if (begin > end)
                    {
                        output.Info.Add(new ReportParserInfoLine(
                                            "Входные жетоны закончились", o, null, begin));
                    }
                    else if (!o.Equals(tokens[begin++].Type))
                    {
                        output.Info.Add(new ReportParserInfoLine(o, tokens[--begin], tokens, begin));
                    }
                    else
                    {
                        compileTree.Add(tokens[begin - 1]);
                        output.Info.Success(tokens[begin - 1].ToString());
                        return(output);
                    }
                }
                else if (o is Nonterminal nonterminal)
                {
                    ReportParser buffer = nonterminal.PCheckRule(deep, tokens, ref begin, ref end);
                    if (buffer.IsSuccess)
                    {
                        output.Merge(buffer);
                        output.Info.Success(o.ToString());
                        return(output); // Да, этот нетерминал нам подходит.
                    }
                    else
                    {
                        buffer.CompileCancel();
                        output.Merge(buffer);
                    }
                }
                else
                {
                    throw new Exception($"Unexpected type {o.GetType()} of {o} in list");
                }
            }
            if (begin < tokens.Count)
            {
                output.Info.Add(new ReportParserInfoLine("Для оператора OR не найдено ни одного истинного выражения.", this, tokens[begin], tokens, -1));
            }
            output.CompileCancel();
            return(output);
        }
コード例 #3
0
        private ReportParser RuleAND(int deep, IList <Token> tokens, ref int begin, ref int end)
        {
            ITreeNode <object> compileTree = new TreeNode <object>(new ParserToken(this, AND, Id: FreeId++));
            ReportParser       output      = new ReportParser(compileTree);
            int b = begin;
            int e = end;
            int i = -1;

            foreach (object o in this)
            {
                i++;
                if (o is Terminal)
                {
                    if (begin > end)
                    {
                        output.Info.Add(new ReportParserInfoLine(
                                            "Входные жетоны закончились", o, null, begin));
                    }
                    else if (!o.Equals(tokens[begin++].Type))
                    {
                        output.Info.Add(new ReportParserInfoLine(o, tokens[--begin], tokens, begin));
                    }
                    else
                    {
                        compileTree.Add(tokens[begin - 1]);
                        output.Info.Success(tokens[begin - 1].ToString());
                    }
                }
                else if (o is Nonterminal nonterminal)
                {
                    output.Merge(nonterminal.PCheckRule(deep, tokens, ref begin, ref end));
                    if (!output.IsSuccess)
                    {
                        output.Info.Add(new ReportParserInfoLine(o, null, tokens, begin));
                    }
                }
                if (!output.IsSuccess)
                {
                    begin = b;
                    end   = e;
                    output.CompileCancel();
                    return(output);
                }
            }
            if (!output.IsSuccess)
            {
                begin = b;
                end   = e;
                output.CompileCancel();
            }
            return(output);
        }
コード例 #4
0
        private ReportParser RuleZERO_AND_MORE(int deep, IList <Token> tokens, ref int begin, ref int end)
        {
            ParserToken  compile = new ParserToken(this, ZERO_AND_MORE, -1, FreeId++);
            ReportParser output  = new ReportParser(compile);

            do
            {
                RuleMORE(deep, tokens, output, ref begin, ref end);
                compile.Helper++;
            }while (output.IsSuccess);
            output.Info.Success($"Нетерминалы ZERO_AND_MORE всегда успешны. Текущий: {ToString()}");
            return(output);
        }
コード例 #5
0
        private bool RuleMORE(int deep, IList <Token> tokens, ReportParser output, ref int begin, ref int end)
        {
            int b = begin;
            int e = end;

            if (Count != 1)
            {
                throw new NotSupportedException($"Правило {rule} поддерживает только один элемент в нетерминале.");
            }
            foreach (object o in this)
            {
                if (o is Terminal)
                {
                    if (begin > end)
                    {
                        output.Info.Add(new ReportParserInfoLine(
                                            "Входные жетоны закончились", o, null, begin));
                    }
                    else if (!o.Equals(tokens[begin++].Type))
                    {
                        output.Info.Add(new ReportParserInfoLine(o, tokens[--begin], tokens, begin));
                    }
                    else
                    {
                        output.Compile.Add(tokens[begin - 1]);
                    }
                }
                else if (o is Nonterminal nonterminal)
                {
                    output.Merge(nonterminal.PCheckRule(deep, tokens, ref begin, ref end));
                    if (!output.IsSuccess)
                    {
                        output.Info.Add(new ReportParserInfoLine(o, null, tokens, begin));
                    }
                }
                if (!output.IsSuccess)
                {
                    begin = b;
                    end   = e;
                    return(output.IsSuccess);
                }
            }
            if (!output.IsSuccess)
            {
                begin = b;
                end   = e;
            }
            return(output.IsSuccess);
        }
コード例 #6
0
        /// <summary>
        /// Проверяет, чтобы заданные жетоны соответствовали нетерминалу.
        /// </summary>
        /// <param name="tokens">Список жетонов, которые надо проверить.</param>
        /// <param name="begin">Первый доступный индекс в листе tokens.</param>
        /// <param name="end">Последний доступный индекс в листе tokens.</param>
        /// <returns>Отчёт анализа кода.</returns>
        private ReportParser PCheckRule(int deep, IList <Token> tokens, ref int begin, ref int end)
        {
            if (tokens == null)
            {
                throw new ArgumentNullException("Список жетонов должен был инициализирован.");
            }
            ReportParser output        = new ReportParser();
            ulong        currentFreeId = FreeId;

            output.Info.AddInfo($"Зашёл в нетерминал: {ToString()}, FreeId: RPC{currentFreeId}");
            if (--deep <= 0)
            {
                output.Info.Add(new ReportParserInfoLine("Обнаружена бесконечная рекурсия. Выход..."));
            }
            else
            {
                switch (rule)
                {
                case AND:
                    output.Merge(RuleAND(deep, tokens, ref begin, ref end));
                    break;

                case ONE_AND_MORE:
                    output.Merge(RuleONE_AND_MORE(deep, tokens, ref begin, ref end));
                    break;

                case OR:
                    output.Merge(RuleOR(deep, tokens, ref begin, ref end));
                    break;

                case ZERO_AND_MORE:
                    output.Merge(RuleZERO_AND_MORE(deep, tokens, ref begin, ref end));
                    break;

                case NONE:
                    output.Info.Add(new ReportParserInfoLine("Игнорирую."));
                    break;

                default:
                    throw new NotImplementedException($"Оператор {Enum.GetName(typeof(RuleOperator), rule)} не реализован.");
                }
            }
            output.Info.AddInfo($"Состояние отчёта: {output.IsSuccess}, выхожу из нетерминала: {ToString()} RPC{currentFreeId}");
            return(output);
        }