feat: Grammar Parser (#3)

Reviewed-on: https://git.bupt-hpc.cn/jackfiled/CanonSharp/pulls/3
Co-authored-by: jackfiled <xcrenchangjun@outlook.com>
Co-committed-by: jackfiled <xcrenchangjun@outlook.com>
This commit is contained in:
2024-08-18 12:01:27 +08:00
committed by 任昌骏
parent 3ed8bf5d36
commit cf19f8197e
85 changed files with 2340 additions and 413 deletions

View File

@@ -11,7 +11,7 @@ namespace CanonSharp.Combinator.Text;
/// <param name="comparison">字符串比较模式</param>
public class StringParser(string except, StringComparison comparison) : PrimitiveParser<char, string>
{
protected override ParseResult<char, string> Run<TState>(TState state)
protected override IParseResult<char, string> Run<TState>(TState state)
{
TState[] states = state.AsEnumerable<char, TState>().Take(except.Length).ToArray();
string actual = new(states.Select(x => x.Current).ToArray());

View File

@@ -13,7 +13,7 @@ public static class TextParserBuilder
/// <param name="token">识别的单个字符</param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> Char(char token) => Satisfy<char>(x => x == token);
public static IParser<char, char> Char(char token) => Satisfy<char>(x => x == token);
/// <summary>
/// 忽略大小写识别单个字符
@@ -21,7 +21,7 @@ public static class TextParserBuilder
/// <param name="token"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> CharIgnoreCase(char token) =>
public static IParser<char, char> CharIgnoreCase(char token) =>
Satisfy<char>(x => char.ToUpperInvariant(x) == char.ToUpperInvariant(token));
/// <summary>
@@ -30,7 +30,7 @@ public static class TextParserBuilder
/// <param name="candidate"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> OneOf(string candidate) => Satisfy<char>(candidate.Contains);
public static IParser<char, char> OneOf(string candidate) => Satisfy<char>(candidate.Contains);
/// <summary>
/// 忽略大小写识别字符串中的一个字符
@@ -38,7 +38,7 @@ public static class TextParserBuilder
/// <param name="candidate"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> OneOfIgnoreCase(string candidate) =>
public static IParser<char, char> OneOfIgnoreCase(string candidate) =>
Satisfy<char>(x => candidate.Contains(x, StringComparison.OrdinalIgnoreCase));
/// <summary>
@@ -48,7 +48,7 @@ public static class TextParserBuilder
/// <param name="comparison">字符串比较方法</param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, string> String(string except, StringComparison comparison) =>
public static IParser<char, string> String(string except, StringComparison comparison) =>
new StringParser(except, comparison);
/// <summary>
@@ -57,7 +57,7 @@ public static class TextParserBuilder
/// <param name="except"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, string> String(string except) => String(except, StringComparison.Ordinal);
public static IParser<char, string> String(string except) => String(except, StringComparison.Ordinal);
/// <summary>
/// 忽略大小写识别一个字符串
@@ -65,7 +65,7 @@ public static class TextParserBuilder
/// <param name="except"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, string> StringIgnoreCase(string except) =>
public static IParser<char, string> StringIgnoreCase(string except) =>
String(except, StringComparison.OrdinalIgnoreCase);
/// <summary>
@@ -75,28 +75,28 @@ public static class TextParserBuilder
/// <param name="end">包括的终止字符</param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> Range(char start, char end) => Satisfy<char>(x => x >= start && x <= end);
public static IParser<char, char> Range(char start, char end) => Satisfy<char>(x => x >= start && x <= end);
/// <summary>
/// 识别Unicode字符类别的解析器
/// </summary>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> Letter() => Satisfy<char>(char.IsLetter);
public static IParser<char, char> Letter() => Satisfy<char>(char.IsLetter);
/// <summary>
/// 识别Unicode数字类别的解析器
/// </summary>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> Digit() => Satisfy<char>(char.IsDigit);
public static IParser<char, char> Digit() => Satisfy<char>(char.IsDigit);
/// <summary>
/// 识别ASCII字符类别的解析器
/// </summary>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> AsciiLetter() =>
public static IParser<char, char> AsciiLetter() =>
Satisfy<char>(x => x is >= 'a' and <= 'z' or >= 'A' and <= 'Z');
/// <summary>
@@ -104,20 +104,20 @@ public static class TextParserBuilder
/// </summary>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> AsciiDigit() => Satisfy<char>(x => x is >= '0' and <= '9');
public static IParser<char, char> AsciiDigit() => Satisfy<char>(x => x is >= '0' and <= '9');
/// <summary>
/// 识别Unicode空白类型的字符
/// </summary>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, char> Space() => Satisfy<char>(char.IsWhiteSpace);
public static IParser<char, char> Space() => Satisfy<char>(char.IsWhiteSpace);
/// <summary>
/// 识别所有的换行符
/// </summary>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<char, string> LineBreak() =>
public static IParser<char, string> LineBreak() =>
OneOf("\u000D\u000A\u0085\u2028\u2029\n").Map(x => x.ToString()) | String("\r\n");
}

View File

@@ -6,9 +6,9 @@ namespace CanonSharp.Combinator.Text;
public static class TextParserExtensions
{
public static Parser<char, T> SkipSpaces<T>(this Parser<char, T> parser)
public static IParser<char, T> SkipSpaces<T>(this IParser<char, T> parser)
=> Space().SkipTill(parser);
public static Parser<char, T> SkipSpaceAndLineBreak<T>(this Parser<char, T> parser)
public static IParser<char, T> SkipSpaceAndLineBreak<T>(this IParser<char, T> parser)
=> (Space().Map(x => x.ToString()) | LineBreak()).SkipTill(parser);
}