Exemple #1
0
        private static void DoStart(ref RangeParserContext context)
        {
            switch (context.Character)
            {
            case '(':
                context.Reset(State.Minimum, Flags.Parenthesis);
                break;

            case '*':
            case '?':
                context.Reset(State.MinimumFinal);
                break;

            case '~':
                context.Reset(State.Separator);
                break;

            default:
                if (!context.IsWhitespace)
                {
                    context.Accept(State.Minimum);
                }
                break;
            }
        }
Exemple #2
0
        private static void DoMaximum(ref RangeParserContext context, out ReadOnlySpan <char> value)
        {
            switch (context.Character)
            {
            case '*':
            case '?':
                context.Reset(State.MaximumFinal, out value);
                break;

            case ')':
                context.Reset(State.Final, out value);
                break;

            default:
                context.Accept(State.Maximum);
                value = ReadOnlySpan <char> .Empty;
                break;
            }
        }
Exemple #3
0
        private static void DoMinimunFinal(ref RangeParserContext context)
        {
            switch (context.Character)
            {
            case '~':
                context.Reset(State.Separator);
                break;

            case ')':
                context.Reset(State.Final);
                break;

            default:
                if (!context.IsWhitespace)
                {
                    context.Error($"The invalid character is at {context.Index + 1} character.");
                }
                break;
            }
        }
Exemple #4
0
        private static void DoSeparator(ref RangeParserContext context)
        {
            switch (context.Character)
            {
            case '*':
            case '?':
                context.Reset(State.MaximumFinal);
                break;

            default:
                if (!context.IsWhitespace)
                {
                    context.Accept(State.Maximum);
                }
                break;
            }
        }
Exemple #5
0
        public static RangeParserResult Parse <T>(ReadOnlySpan <char> span, int start = 0) where T : struct
        {
            var minimum = ReadOnlySpan <char> .Empty;
            var maximum = ReadOnlySpan <char> .Empty;
            var context = new RangeParserContext(span);

            for (int i = start; i < span.Length; i++)
            {
                context.Move(i);

                switch (context.State)
                {
                case State.Error:
                    return(new RangeParserResult(context.ErrorMessage));

                case State.Start:
                    DoStart(ref context);
                    break;

                case State.Final:
                    DoFinal(ref context);
                    break;

                case State.Minimum:
                    DoMinimum(ref context, out minimum);
                    break;

                case State.MinimumFinal:
                    DoMinimunFinal(ref context);
                    break;

                case State.Maximum:
                    DoMaximum(ref context, out maximum);
                    break;

                case State.MaximumFinal:
                    DoMaximumFinal(ref context);
                    break;

                case State.Separator:
                    DoSeparator(ref context);
                    break;
                }
            }

            if (context.State != State.Final)
            {
                //未正常关闭圆括号
                if (context.HasFlags(Flags.Parenthesis))
                {
                    return(new RangeParserResult("Missing the closing parenthesis."));
                }

                //必须移动指针到最后,以便Reset正确计算内容值
                context.Move(-1);

                switch (context.State)
                {
                case State.Minimum:
                case State.MinimumFinal:
                case State.Separator:
                    context.Reset(out minimum);
                    break;

                default:
                    context.Reset(out maximum);
                    break;
                }
            }

            if (maximum.IsEmpty && (context.State == State.Minimum || context.State == State.MinimumFinal))
            {
                maximum = minimum;
            }

            return(new RangeParserResult(minimum, maximum));
        }