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; } }
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; } }
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; } }
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; } }
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)); }