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);
        }
        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);
        }
        private ReportParser RuleONE_AND_MORE(int deep, IList <Token> tokens, ref int begin, ref int end)
        {
            ParserToken  compile = new ParserToken(this, ONE_AND_MORE, -1, FreeId++);
            ReportParser output  = new ReportParser(compile);

            compile.Helper++;
            if (!RuleMORE(deep, tokens, output, ref begin, ref end))
            {
                output.CompileCancel();
                return(output);
            }
            compile.Helper++;
            do
            {
                RuleMORE(deep, tokens, output, ref begin, ref end);
                compile.Helper++;
            }while (output.IsSuccess);
            output.Info.Success($"Нетерминалы ZERO_AND_MORE всегда успешны. Текущий: {ToString()}");
            return(output);
        }