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

@@ -1,49 +0,0 @@
namespace CanonSharp.Combinator.Abstractions;
/// <summary>
/// 失败解析结果基类
/// </summary>
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">解析结果类型</typeparam>
public abstract class FailedResult<TToken, T> : ParseResult<TToken, T>
{
public override T Value => throw Exception;
/// <summary>
/// 当前读取到的状态
/// </summary>
public abstract IReadState<TToken> State { get; }
/// <summary>
/// 解析失败的消息
/// </summary>
public abstract string Message { get; }
/// <summary>
/// 解析失败的异常
/// </summary>
public virtual ParseException Exception => new(ToString());
/// <summary>
/// 转换该失败结果的类型
/// </summary>
/// <typeparam name="TNext">转换之后的结果类型</typeparam>
/// <returns>转换之后的失败解析类型</returns>
public abstract FailedResult<TToken, TNext> Convert<TNext>();
internal override ParseResult<TToken, TResult> Next<TNext, TResult>(Func<T, Parser<TToken, TNext>> nextParser,
Func<ParseResult<TToken, TNext>, ParseResult<TToken, TResult>> continuation)
=> continuation(Convert<TNext>());
public override ParseResult<TToken, TResult> Map<TResult>(Func<T, TResult> map)
=> Convert<TResult>();
public override TResult CaseOf<TResult>(Func<SuccessfulResult<TToken, T>, TResult> successfulHandler,
Func<FailedResult<TToken, T>, TResult> failedHandler)
=> failedHandler(this);
public override string ToString()
{
return $"Parse Failed: {Message}.";
}
}

View File

@@ -0,0 +1,45 @@
namespace CanonSharp.Combinator.Abstractions;
/// <summary>
/// 失败解析结果基类
/// </summary>
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">解析结果类型</typeparam>
public interface IFailedResult<TToken, out T> : IParseResult<TToken, T>
{
T IParseResult<TToken, T>.Value => throw Exception;
/// <summary>
/// 当前读取到的状态
/// </summary>
public IReadState<TToken> State { get; }
/// <summary>
/// 解析失败的消息
/// </summary>
public string Message { get; }
/// <summary>
/// 解析失败的异常
/// </summary>
public ParseException Exception => new(Message);
/// <summary>
/// 转换该失败结果的类型
/// </summary>
/// <typeparam name="TNext">转换之后的结果类型</typeparam>
/// <returns>转换之后的失败解析类型</returns>
public IFailedResult<TToken, TNext> Convert<TNext>();
IParseResult<TToken, TResult> IParseResult<TToken, T>.Next<TNext, TResult>(
Func<T, IParser<TToken, TNext>> nextParser,
Func<IParseResult<TToken, TNext>, IParseResult<TToken, TResult>> continuation)
=> continuation(Convert<TNext>());
IParseResult<TToken, TResult> IParseResult<TToken, T>.Map<TResult>(Func<T, TResult> map)
=> Convert<TResult>();
TResult IParseResult<TToken, T>.CaseOf<TResult>(Func<ISuccessfulResult<TToken, T>, TResult> successfulHandler,
Func<IFailedResult<TToken, T>, TResult> failedHandler)
=> failedHandler(this);
}

View File

@@ -5,17 +5,12 @@ namespace CanonSharp.Combinator.Abstractions;
/// </summary>
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">实际结果类型</typeparam>
public abstract class ParseResult<TToken, T>
public interface IParseResult<TToken, out T>
{
/// <summary>
/// 实际结果对象
/// </summary>
public abstract T Value { get; }
protected ParseResult()
{
}
public T Value { get; }
/// <summary>
/// 在当前结果上应用下一个解析器
@@ -25,8 +20,8 @@ public abstract class ParseResult<TToken, T>
/// <typeparam name="TNext">下一个解析器函数返回的解析结果类型</typeparam>
/// <typeparam name="TResult">最终的解析结果类型</typeparam>
/// <returns></returns>
internal abstract ParseResult<TToken, TResult> Next<TNext, TResult>(Func<T, Parser<TToken, TNext>> nextParser,
Func<ParseResult<TToken, TNext>, ParseResult<TToken, TResult>> continuation);
internal IParseResult<TToken, TResult> Next<TNext, TResult>(Func<T, IParser<TToken, TNext>> nextParser,
Func<IParseResult<TToken, TNext>, IParseResult<TToken, TResult>> continuation);
/// <summary>
/// 映射结果
@@ -34,7 +29,7 @@ public abstract class ParseResult<TToken, T>
/// <param name="map">映射结果的函数</param>
/// <typeparam name="TResult">映射结果函数返回解析结果的类型</typeparam>
/// <returns>最终的解析结果</returns>
public abstract ParseResult<TToken, TResult> Map<TResult>(Func<T, TResult> map);
public IParseResult<TToken, TResult> Map<TResult>(Func<T, TResult> map);
/// <summary>
/// 在成功或者失败解析结果上应用不同的后继函数
@@ -43,6 +38,6 @@ public abstract class ParseResult<TToken, T>
/// <param name="failedHandler">在失败解析结构上应用的函数</param>
/// <typeparam name="TResult">最后返回解析结果的类型</typeparam>
/// <returns>最后的解析结果</returns>
public abstract TResult CaseOf<TResult>(Func<SuccessfulResult<TToken, T>, TResult> successfulHandler,
Func<FailedResult<TToken, T>, TResult> failedHandler);
public TResult CaseOf<TResult>(Func<ISuccessfulResult<TToken, T>, TResult> successfulHandler,
Func<IFailedResult<TToken, T>, TResult> failedHandler);
}

View File

@@ -7,7 +7,7 @@ namespace CanonSharp.Combinator.Abstractions;
/// </summary>
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">解析结果类型</typeparam>
public abstract class Parser<TToken, T>
public interface IParser<TToken, out T>
{
/// <summary>
/// 解析器运行函数
@@ -17,16 +17,16 @@ public abstract class Parser<TToken, T>
/// <typeparam name="TState">输入流状态类型</typeparam>
/// <typeparam name="TResult">后继函数运行之后的解析结果类型</typeparam>
/// <returns></returns>
internal abstract ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
internal IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>;
public ParseResult<TToken, T> Parse<TState>(TState state) where TState : IReadState<TToken, TState>
public IParseResult<TToken, T> Parse<TState>(TState state) where TState : IReadState<TToken, TState>
{
return Run(state);
}
private ParseResult<TToken, T> Run<TState>(TState state) where TState : IReadState<TToken, TState>
private IParseResult<TToken, T> Run<TState>(TState state) where TState : IReadState<TToken, TState>
{
try
{
@@ -38,6 +38,6 @@ public abstract class Parser<TToken, T>
}
}
public static Parser<TToken, T> operator |(Parser<TToken, T> a, Parser<TToken, T> b)
public static IParser<TToken, T> operator |(IParser<TToken, T> a, IParser<TToken, T> b)
=> a.Alternative(b);
}

View File

@@ -0,0 +1,29 @@
namespace CanonSharp.Combinator.Abstractions;
/// <summary>
/// 成功解析结果基类
/// </summary>
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">实际的解析结果类型</typeparam>
public interface ISuccessfulResult<TToken,out T> : IParseResult<TToken, T>
{
/// <summary>
/// 运行下一个解析器
/// </summary>
/// <param name="parser">下一个解析器</param>
/// <param name="continuation">处理解析结果的后继函数</param>
/// <typeparam name="TNext">下一个解析器返回的结果类型</typeparam>
/// <typeparam name="TResult">最终的结果类型</typeparam>
/// <returns>最终的结果</returns>
protected IParseResult<TToken, TResult> RunNext<TNext, TResult>(IParser<TToken, TNext> parser,
Func<IParseResult<TToken, TNext>, IParseResult<TToken, TResult>> continuation);
IParseResult<TToken, TResult> IParseResult<TToken, T>.Next<TNext, TResult>(
Func<T, IParser<TToken, TNext>> nextParser,
Func<IParseResult<TToken, TNext>, IParseResult<TToken, TResult>> continuation)
=> RunNext(nextParser(Value), continuation);
TResult IParseResult<TToken, T>.CaseOf<TResult>(Func<ISuccessfulResult<TToken, T>, TResult> successfulHandler,
Func<IFailedResult<TToken, T>, TResult> failedHandler)
=> successfulHandler(this);
}

View File

@@ -1,33 +0,0 @@
namespace CanonSharp.Combinator.Abstractions;
/// <summary>
/// 成功解析结果基类
/// </summary>
/// <param name="value">实际的解析结果</param>
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">实际的解析结果类型</typeparam>
public abstract class SuccessfulResult<TToken, T>(T value) : ParseResult<TToken, T>
{
public override T Value => value;
/// <summary>
/// 运行下一个解析器
/// </summary>
/// <param name="parser">下一个解析器</param>
/// <param name="continuation">处理解析结果的后继函数</param>
/// <typeparam name="TNext">下一个解析器返回的结果类型</typeparam>
/// <typeparam name="TResult">最终的结果类型</typeparam>
/// <returns>最终的结果</returns>
protected abstract ParseResult<TToken, TResult> RunNext<TNext, TResult>(Parser<TToken, TNext> parser,
Func<ParseResult<TToken, TNext>, ParseResult<TToken, TResult>> continuation);
internal override ParseResult<TToken, TResult> Next<TNext, TResult>(Func<T, Parser<TToken, TNext>> nextParser,
Func<ParseResult<TToken, TNext>, ParseResult<TToken, TResult>> continuation)
=> RunNext(nextParser(Value), continuation);
public override TResult CaseOf<TResult>(Func<SuccessfulResult<TToken, T>, TResult> successfulHandler,
Func<FailedResult<TToken, T>, TResult> failedHandler)
=> successfulHandler(this);
public override string ToString() => Value?.ToString() ?? string.Empty;
}

View File

@@ -19,7 +19,7 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Alternative<TToken, T>(this Parser<TToken, T> first, Parser<TToken, T> second)
public static IParser<TToken, T> Alternative<TToken, T>(this IParser<TToken, T> first, IParser<TToken, T> second)
=> new AlternativeParser<TToken, T>(first, second);
/// <summary>
@@ -32,8 +32,8 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Alternative<TToken, T>(this Parser<TToken, T> parser,
Func<FailedResult<TToken, T>, Parser<TToken, T>> resume)
public static IParser<TToken, T> Alternative<TToken, T>(this IParser<TToken, T> parser,
Func<IFailedResult<TToken, T>, IParser<TToken, T>> resume)
=> new ResumeParser<TToken, T>(parser, resume);
/// <summary>
@@ -46,8 +46,8 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Bind<TToken, T, TResult>(this Parser<TToken, T> parser,
Func<T, Parser<TToken, TResult>> next)
public static IParser<TToken, TResult> Bind<TToken, T, TResult>(this IParser<TToken, T> parser,
Func<T, IParser<TToken, TResult>> next)
=> new BindParser<TToken, T, TResult>(parser, next);
/// <summary>
@@ -60,7 +60,7 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Map<TToken, T, TResult>(this Parser<TToken, T> parser, Func<T, TResult> map)
public static IParser<TToken, TResult> Map<TToken, T, TResult>(this IParser<TToken, T> parser, Func<T, TResult> map)
=> new MapParser<TToken, T, TResult>(parser, map);
/// <summary>
@@ -73,7 +73,7 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Map<TToken, T, TResult>(this Parser<TToken, T> parser, TResult result)
public static IParser<TToken, TResult> Map<TToken, T, TResult>(this IParser<TToken, T> parser, TResult result)
=> parser.Map(_ => result);
/// <summary>
@@ -87,9 +87,9 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Next<TToken, T, TResult>(this Parser<TToken, T> parser,
Func<T, Parser<TToken, TResult>> next,
Func<FailedResult<TToken, T>, Parser<TToken, TResult>> failedNext)
public static IParser<TToken, TResult> Next<TToken, T, TResult>(this IParser<TToken, T> parser,
Func<T, IParser<TToken, TResult>> next,
Func<IFailedResult<TToken, T>, IParser<TToken, TResult>> failedNext)
=> new NextParser<TToken, T, TResult>(parser, next, failedNext);
/// <summary>
@@ -103,8 +103,8 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Next<TToken, T, TResult>(this Parser<TToken, T> parser,
Func<T, Parser<TToken, TResult>> next, Func<FailedResult<TToken, T>, TResult> failedHandler)
public static IParser<TToken, TResult> Next<TToken, T, TResult>(this IParser<TToken, T> parser,
Func<T, IParser<TToken, TResult>> next, Func<IFailedResult<TToken, T>, TResult> failedHandler)
=> parser.Next(next, failedResult => Pure<TToken, TResult>(failedHandler(failedResult)));
/// <summary>
@@ -118,8 +118,8 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Next<TToken, T, TResult>(this Parser<TToken, T> parser,
Func<T, Parser<TToken, TResult>> next, TResult failedResult)
public static IParser<TToken, TResult> Next<TToken, T, TResult>(this IParser<TToken, T> parser,
Func<T, IParser<TToken, TResult>> next, TResult failedResult)
=> parser.Next(next, _ => Pure<TToken, TResult>(failedResult));
/// <summary>
@@ -133,8 +133,8 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Next<TToken, T, TResult>(this Parser<TToken, T> parser,
Func<T, TResult> nextResult, Func<FailedResult<TToken, T>, Parser<TToken, TResult>> failedResume)
public static IParser<TToken, TResult> Next<TToken, T, TResult>(this IParser<TToken, T> parser,
Func<T, TResult> nextResult, Func<IFailedResult<TToken, T>, IParser<TToken, TResult>> failedResume)
=> parser.Next(x => Pure<TToken, TResult>(nextResult(x)), failedResume);
/// <summary>
@@ -148,8 +148,8 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Next<TToken, T, TResult>(this Parser<TToken, T> parser,
Func<T, TResult> nextResult, Func<FailedResult<TToken, T>, TResult> failedResult)
public static IParser<TToken, TResult> Next<TToken, T, TResult>(this IParser<TToken, T> parser,
Func<T, TResult> nextResult, Func<IFailedResult<TToken, T>, TResult> failedResult)
=> new SuccessfulMapParser<TToken, T, TResult>(parser, nextResult, failedResult);
/// <summary>
@@ -163,7 +163,7 @@ public static class ParserExtensions
/// <typeparam name="TResult"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Next<TToken, T, TResult>(this Parser<TToken, T> parser,
public static IParser<TToken, TResult> Next<TToken, T, TResult>(this IParser<TToken, T> parser,
Func<T, TResult> successfulHandler, TResult failedResult)
=> parser.Next(successfulHandler, _ => failedResult);
@@ -181,8 +181,8 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Do<TToken, T>(this Parser<TToken, T> parser, Action<T> successfulAction,
Action<FailedResult<TToken, T>> failedAction)
public static IParser<TToken, T> Do<TToken, T>(this IParser<TToken, T> parser, Action<T> successfulAction,
Action<IFailedResult<TToken, T>> failedAction)
=> new DoParser<TToken, T>(parser, successfulAction, failedAction);
/// <summary>
@@ -194,7 +194,7 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Do<TToken, T>(this Parser<TToken, T> parser, Action<T> successfulAction)
public static IParser<TToken, T> Do<TToken, T>(this IParser<TToken, T> parser, Action<T> successfulAction)
=> parser.Do(successfulAction, _ => { });
/// <summary>
@@ -206,7 +206,7 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> LookAhead<TToken, T>(this Parser<TToken, T> parser)
public static IParser<TToken, T> LookAhead<TToken, T>(this IParser<TToken, T> parser)
=> new LookAheadParser<TToken, T>(parser);
/// <summary>
@@ -219,7 +219,7 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Not<TToken, TIgnore, T>(this Parser<TToken, TIgnore> parser, T result)
public static IParser<TToken, T> Not<TToken, TIgnore, T>(this IParser<TToken, TIgnore> parser, T result)
=> new ReverseParser<TToken, TIgnore, T>(parser, result);
/// <summary>
@@ -231,21 +231,21 @@ public static class ParserExtensions
/// <typeparam name="TIgnore"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, Unit> Not<TToken, TIgnore>(this Parser<TToken, TIgnore> parser)
public static IParser<TToken, Unit> Not<TToken, TIgnore>(this IParser<TToken, TIgnore> parser)
=> parser.Not(Unit.Instance);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Try<TToken, T>(this Parser<TToken, T> parser,
Func<FailedResult<TToken, T>, T> resume)
public static IParser<TToken, T> Try<TToken, T>(this IParser<TToken, T> parser,
Func<IFailedResult<TToken, T>, T> resume)
=> new TryParser<TToken, T>(parser, resume);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Try<TToken, T>(this Parser<TToken, T> parser, T result)
public static IParser<TToken, T> Try<TToken, T>(this IParser<TToken, T> parser, T result)
=> parser.Try(_ => result);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, bool> Try<TToken, T>(this Parser<TToken, T> parser)
public static IParser<TToken, bool> Try<TToken, T>(this IParser<TToken, T> parser)
=> parser.Next(_ => true, false).Try(false);
#endregion
@@ -262,8 +262,8 @@ public static class ParserExtensions
/// <typeparam name="TRight"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TLeft> Left<TToken, TLeft, TRight>(this Parser<TToken, TLeft> left,
Parser<TToken, TRight> right)
public static IParser<TToken, TLeft> Left<TToken, TLeft, TRight>(this IParser<TToken, TLeft> left,
IParser<TToken, TRight> right)
=> left.Bind(right.Map);
/// <summary>
@@ -276,12 +276,12 @@ public static class ParserExtensions
/// <typeparam name="TRight"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TRight> Right<TToken, TLeft, TRight>(this Parser<TToken, TLeft> left,
Parser<TToken, TRight> right)
public static IParser<TToken, TRight> Right<TToken, TLeft, TRight>(this IParser<TToken, TLeft> left,
IParser<TToken, TRight> right)
=> left.Bind(_ => right);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Parser<TToken, IEnumerable<T>> ManyRecursively<TToken, T>(this Parser<TToken, T> parser,
private static IParser<TToken, IEnumerable<T>> ManyRecursively<TToken, T>(this IParser<TToken, T> parser,
IEnumerable<T> result)
=> parser.Next(x => parser.ManyRecursively(result.Append(x)), result);
@@ -293,7 +293,7 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> Many<TToken, T>(this Parser<TToken, T> parser)
public static IParser<TToken, IEnumerable<T>> Many<TToken, T>(this IParser<TToken, T> parser)
=> parser.ManyRecursively([]);
/// <summary>
@@ -304,7 +304,7 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> Many1<TToken, T>(this Parser<TToken, T> parser)
public static IParser<TToken, IEnumerable<T>> Many1<TToken, T>(this IParser<TToken, T> parser)
=> parser.Bind(x => parser.ManyRecursively([x]));
/// <summary>
@@ -317,7 +317,7 @@ public static class ParserExtensions
/// <typeparam name="TIgnore"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, Unit> SkipMany<TToken, TIgnore>(this Parser<TToken, TIgnore> parser)
public static IParser<TToken, Unit> SkipMany<TToken, TIgnore>(this IParser<TToken, TIgnore> parser)
=> Fix<TToken, Unit>(self => parser.Next(_ => self, Unit.Instance));
/// <summary>
@@ -330,11 +330,11 @@ public static class ParserExtensions
/// <typeparam name="TIgnore"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, Unit> SkipMany1<TToken, TIgnore>(this Parser<TToken, TIgnore> parser)
public static IParser<TToken, Unit> SkipMany1<TToken, TIgnore>(this IParser<TToken, TIgnore> parser)
=> parser.Right(parser.SkipMany());
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Parser<TToken, T> ChainRecursively<TToken, T>(Func<T, Parser<TToken, T>> chain, T value)
private static IParser<TToken, T> ChainRecursively<TToken, T>(Func<T, IParser<TToken, T>> chain, T value)
=> chain(value).Next(x => ChainRecursively(chain, x), value);
/// <summary>
@@ -347,12 +347,12 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Chain<TToken, T>(this Parser<TToken, T> parser, Func<T, Parser<TToken, T>> chain)
public static IParser<TToken, T> Chain<TToken, T>(this IParser<TToken, T> parser, Func<T, IParser<TToken, T>> chain)
=> parser.Bind(x => ChainRecursively(chain, x));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Parser<TToken, IEnumerable<T>> ManyTillRecursively<TToken, T, TIgnore>(this Parser<TToken, T> parser,
Parser<TToken, TIgnore> terminator, IEnumerable<T> result)
private static IParser<TToken, IEnumerable<T>> ManyTillRecursively<TToken, T, TIgnore>(this IParser<TToken, T> parser,
IParser<TToken, TIgnore> terminator, IEnumerable<T> result)
=> terminator.Next(_ => Pure<TToken, IEnumerable<T>>(result),
_ => parser.Bind(x => parser.ManyTillRecursively(terminator, result.Append(x))));
@@ -367,8 +367,8 @@ public static class ParserExtensions
/// <typeparam name="TIgnore"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> ManyTill<TToken, T, TIgnore>(this Parser<TToken, T> parser,
Parser<TToken, TIgnore> terminator)
public static IParser<TToken, IEnumerable<T>> ManyTill<TToken, T, TIgnore>(this IParser<TToken, T> parser,
IParser<TToken, TIgnore> terminator)
=> parser.ManyTillRecursively(terminator, []);
/// <summary>
@@ -382,8 +382,8 @@ public static class ParserExtensions
/// <typeparam name="TIgnore"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> Many1Till<TToken, T, TIgnore>(this Parser<TToken, T> parser,
Parser<TToken, TIgnore> terminator)
public static IParser<TToken, IEnumerable<T>> Many1Till<TToken, T, TIgnore>(this IParser<TToken, T> parser,
IParser<TToken, TIgnore> terminator)
=> parser.Bind(x => parser.ManyTillRecursively(terminator, [x]));
/// <summary>
@@ -397,8 +397,8 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> SkipTill<TToken, TIgnore, T>(this Parser<TToken, TIgnore> parser,
Parser<TToken, T> terminator)
public static IParser<TToken, T> SkipTill<TToken, TIgnore, T>(this IParser<TToken, TIgnore> parser,
IParser<TToken, T> terminator)
=> Fix<TToken, T>(self => terminator | parser.Right(self));
/// <summary>
@@ -412,8 +412,8 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Skip1Till<TToken, TIgnore, T>(this Parser<TToken, TIgnore> parser,
Parser<TToken, T> terminator)
public static IParser<TToken, T> Skip1Till<TToken, TIgnore, T>(this IParser<TToken, TIgnore> parser,
IParser<TToken, T> terminator)
=> parser.Right(parser.SkipTill(terminator));
/// <summary>
@@ -424,7 +424,7 @@ public static class ParserExtensions
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Match<TToken, T>(this Parser<TToken, T> parser)
public static IParser<TToken, T> Match<TToken, T>(this IParser<TToken, T> parser)
=> SkipTill(Any<TToken>(), parser);
/// <summary>
@@ -440,8 +440,8 @@ public static class ParserExtensions
/// <typeparam name="TRight"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> Quote<TToken, T, TLeft, TRight>(this Parser<TToken, T> parser,
Parser<TToken, TLeft> left, Parser<TToken, TRight> right)
public static IParser<TToken, IEnumerable<T>> Quote<TToken, T, TLeft, TRight>(this IParser<TToken, T> parser,
IParser<TToken, TLeft> left, IParser<TToken, TRight> right)
=> left.Right(parser.ManyTill(right));
/// <summary>
@@ -454,8 +454,8 @@ public static class ParserExtensions
/// <typeparam name="TQuote"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> Quote<TToken, T, TQuote>(this Parser<TToken, T> parser,
Parser<TToken, TQuote> quotedParser)
public static IParser<TToken, IEnumerable<T>> Quote<TToken, T, TQuote>(this IParser<TToken, T> parser,
IParser<TToken, TQuote> quotedParser)
=> parser.Quote(quotedParser, quotedParser);
/// <summary>
@@ -470,8 +470,8 @@ public static class ParserExtensions
/// <typeparam name="TSeparator"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> SeparatedBy1<TToken, T, TSeparator>(this Parser<TToken, T> parser,
Parser<TToken, TSeparator> separator)
public static IParser<TToken, IEnumerable<T>> SeparatedBy1<TToken, T, TSeparator>(this IParser<TToken, T> parser,
IParser<TToken, TSeparator> separator)
=> parser.Bind(x => separator.Right(parser).ManyRecursively([x]));
/// <summary>
@@ -486,8 +486,8 @@ public static class ParserExtensions
/// <typeparam name="TSeparator"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> SeparatedBy<TToken, T, TSeparator>(this Parser<TToken, T> parser,
Parser<TToken, TSeparator> separator)
public static IParser<TToken, IEnumerable<T>> SeparatedBy<TToken, T, TSeparator>(this IParser<TToken, T> parser,
IParser<TToken, TSeparator> separator)
=> parser.SeparatedBy1(separator).Try([]);
/// <summary>
@@ -502,8 +502,8 @@ public static class ParserExtensions
/// <typeparam name="TSeparator"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> EndBy<TToken, T, TSeparator>(this Parser<TToken, T> parser,
Parser<TToken, TSeparator> separator)
public static IParser<TToken, IEnumerable<T>> EndBy<TToken, T, TSeparator>(this IParser<TToken, T> parser,
IParser<TToken, TSeparator> separator)
=> parser.Many().Left(separator);
/// <summary>
@@ -518,8 +518,8 @@ public static class ParserExtensions
/// <typeparam name="TSeparator"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> EndBy1<TToken, T, TSeparator>(this Parser<TToken, T> parser,
Parser<TToken, TSeparator> separator)
public static IParser<TToken, IEnumerable<T>> EndBy1<TToken, T, TSeparator>(this IParser<TToken, T> parser,
IParser<TToken, TSeparator> separator)
=> parser.Many1().Left(separator);
/// <summary>
@@ -534,8 +534,8 @@ public static class ParserExtensions
/// <typeparam name="TSeparator"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> SeparatedOrEndBy1<TToken, T, TSeparator>(this Parser<TToken, T> parser,
Parser<TToken, TSeparator> separator)
public static IParser<TToken, IEnumerable<T>> SeparatedOrEndBy1<TToken, T, TSeparator>(this IParser<TToken, T> parser,
IParser<TToken, TSeparator> separator)
=> parser.SeparatedBy1(separator).Left(separator.Try());
/// <summary>
@@ -550,8 +550,8 @@ public static class ParserExtensions
/// <typeparam name="TSeparator"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> SeparatedOrEndBy<TToken, T, TSeparator>(this Parser<TToken, T> parser,
Parser<TToken, TSeparator> separator)
public static IParser<TToken, IEnumerable<T>> SeparatedOrEndBy<TToken, T, TSeparator>(this IParser<TToken, T> parser,
IParser<TToken, TSeparator> separator)
=> parser.SeparatedOrEndBy1(separator).Try([]);
#endregion
@@ -559,13 +559,13 @@ public static class ParserExtensions
#region LINQ
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> Select<TToken, T, TResult>(this Parser<TToken, T> parser,
public static IParser<TToken, TResult> Select<TToken, T, TResult>(this IParser<TToken, T> parser,
Func<T, TResult> selector)
=> parser.Map(selector);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TResult> SelectMany<TToken, T, TIntermediate, TResult>(this Parser<TToken, T> parser,
Func<T, Parser<TToken, TIntermediate>> selector, Func<T, TIntermediate, TResult> projector)
public static IParser<TToken, TResult> SelectMany<TToken, T, TIntermediate, TResult>(this IParser<TToken, T> parser,
Func<T, IParser<TToken, TIntermediate>> selector, Func<T, TIntermediate, TResult> projector)
=> parser.Bind(x => selector(x).Map(y => projector(x, y)));
#endregion

View File

@@ -19,7 +19,7 @@ public static class ParseResultBuilder
/// <typeparam name="T">解析成功的对象类型</typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ParseResult<TToken, T> Succeed<TToken, TState, T>(T value, TState state)
public static IParseResult<TToken, T> Succeed<TToken, TState, T>(T value, TState state)
where TState : IReadState<TToken, TState>
=> new InternalSuccessfulResult<TToken, TState, T>(value, state);
@@ -32,7 +32,7 @@ public static class ParseResultBuilder
/// <typeparam name="T">解析成功的对象类型</typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ParseResult<TToken, T> Fail<TToken, TState, T>(TState state)
public static IParseResult<TToken, T> Fail<TToken, TState, T>(TState state)
where TState : IReadState<TToken, TState>
=> new FailedResultWithError<TToken, TState, T>(state);
@@ -47,7 +47,7 @@ public static class ParseResultBuilder
/// <typeparam name="T">解析成功的对象类型</typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ParseResult<TToken, T> Fail<TToken, TState, T>(string message, TState state)
public static IParseResult<TToken, T> Fail<TToken, TState, T>(string message, TState state)
where TState : IReadState<TToken, TState>
=> new FailedResultWithMessage<TToken, TState, T>(message, state);
@@ -61,7 +61,7 @@ public static class ParseResultBuilder
/// <typeparam name="T">解析成功的对象类型</typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ParseResult<TToken, T> Fail<TToken, TState, T>(Exception exception, TState state)
public static IParseResult<TToken, T> Fail<TToken, TState, T>(Exception exception, TState state)
where TState : IReadState<TToken, TState>
=> new FailedResultWithException<TToken, TState, T>(exception, state);
}

View File

@@ -20,7 +20,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Pure<TToken, T>(T value)
public static IParser<TToken, T> Pure<TToken, T>(T value)
=> new PureParser<TToken, T>(value);
/// <summary>
@@ -31,7 +31,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Pure<TToken, T>(Func<IReadState<TToken>, T> valueFunc)
public static IParser<TToken, T> Pure<TToken, T>(Func<IReadState<TToken>, T> valueFunc)
=> new DelayedPureParser<TToken, T>(valueFunc);
/// <summary>
@@ -40,7 +40,7 @@ public static class ParserBuilder
/// <typeparam name="TToken"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, Unit> Null<TToken>() => Pure<TToken, Unit>(Unit.Instance);
public static IParser<TToken, Unit> Null<TToken>() => Pure<TToken, Unit>(Unit.Instance);
/// <summary>
/// 失败的解析器
@@ -49,7 +49,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Fail<TToken, T>() => new FailedParser<TToken, T>();
public static IParser<TToken, T> Fail<TToken, T>() => new FailedParser<TToken, T>();
/// <summary>
/// 失败的解析器
@@ -59,7 +59,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Fail<TToken, T>(string message) => new FailedParserWithMessage<TToken, T>(message);
public static IParser<TToken, T> Fail<TToken, T>(string message) => new FailedParserWithMessage<TToken, T>(message);
/// <summary>
/// 失败的解析器
@@ -69,7 +69,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Fail<TToken, T>(Func<IReadState<TToken>, string> messageFunc) =>
public static IParser<TToken, T> Fail<TToken, T>(Func<IReadState<TToken>, string> messageFunc) =>
new FailedParserWithDelayedMessage<TToken, T>(messageFunc);
/// <summary>
@@ -80,7 +80,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Fail<TToken, T>(Exception exception) =>
public static IParser<TToken, T> Fail<TToken, T>(Exception exception) =>
new FailedParserWithException<TToken, T>(exception);
/// <summary>
@@ -90,7 +90,7 @@ public static class ParserBuilder
/// <typeparam name="TToken"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TToken> Satisfy<TToken>(Func<TToken, bool> predicate)
public static IParser<TToken, TToken> Satisfy<TToken>(Func<TToken, bool> predicate)
=> new SatisfyParser<TToken>(predicate);
/// <summary>
@@ -99,7 +99,7 @@ public static class ParserBuilder
/// <typeparam name="TToken"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TToken> Any<TToken>() => Satisfy<TToken>(_ => true);
public static IParser<TToken, TToken> Any<TToken>() => Satisfy<TToken>(_ => true);
/// <summary>
/// 识别指定输入元素的解析器
@@ -108,7 +108,7 @@ public static class ParserBuilder
/// <typeparam name="TToken"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, TToken> Token<TToken>(TToken token)
public static IParser<TToken, TToken> Token<TToken>(TToken token)
=> Satisfy<TToken>(t => EqualityComparer<TToken>.Default.Equals(t, token));
/// <summary>
@@ -118,7 +118,7 @@ public static class ParserBuilder
/// <typeparam name="TToken"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, Unit> Skip<TToken>(int count) => new SkipParser<TToken>(count);
public static IParser<TToken, Unit> Skip<TToken>(int count) => new SkipParser<TToken>(count);
/// <summary>
/// 识别指定数量输入元素的解析器
@@ -127,7 +127,7 @@ public static class ParserBuilder
/// <typeparam name="TToken"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<TToken>> Take<TToken>(int count) => new TakeParser<TToken>(count);
public static IParser<TToken, IEnumerable<TToken>> Take<TToken>(int count) => new TakeParser<TToken>(count);
#endregion
@@ -141,7 +141,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Fix<TToken, T>(Func<Parser<TToken, T>, Parser<TToken, T>> parserFix)
public static IParser<TToken, T> Fix<TToken, T>(Func<IParser<TToken, T>, IParser<TToken, T>> parserFix)
=> new FixParser<TToken, T>(parserFix);
#endregion
@@ -156,8 +156,8 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Choice<TToken, T>(IEnumerable<Parser<TToken, T>> parsers)
=> parsers.Reverse().Aggregate((next, parser) => parser.Alternative(next));
public static IParser<TToken, T> Choice<TToken, T>(IEnumerable<IParser<TToken, T>> parsers)
=> parsers.Aggregate((result, parser) => result.Alternative(parser));
/// <summary>
/// 按照给定的解析器组依次尝试
@@ -167,7 +167,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, T> Choice<TToken, T>(params Parser<TToken, T>[] parsers)
public static IParser<TToken, T> Choice<TToken, T>(params IParser<TToken, T>[] parsers)
=> Choice(parsers.AsEnumerable());
/// <summary>
@@ -178,7 +178,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> Sequence<TToken, T>(IEnumerable<Parser<TToken, T>> parsers)
public static IParser<TToken, IEnumerable<T>> Sequence<TToken, T>(IEnumerable<IParser<TToken, T>> parsers)
=> parsers.Reverse().Aggregate(Pure<TToken, IEnumerable<T>>([]),
(next, parser) => parser.Bind(
x => next.Map(result => result.Prepend(x))));
@@ -191,7 +191,7 @@ public static class ParserBuilder
/// <typeparam name="T"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<T>> Sequence<TToken, T>(params Parser<TToken, T>[] parsers)
public static IParser<TToken, IEnumerable<T>> Sequence<TToken, T>(params IParser<TToken, T>[] parsers)
=> Sequence(parsers.AsEnumerable());
/// <summary>
@@ -203,7 +203,7 @@ public static class ParserBuilder
/// <typeparam name="TIgnore"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<TToken>> TakeTill<TToken, TIgnore>(Parser<TToken, TIgnore> terminator)
public static IParser<TToken, IEnumerable<TToken>> TakeTill<TToken, TIgnore>(IParser<TToken, TIgnore> terminator)
=> Any<TToken>().ManyTill(terminator);
/// <summary>
@@ -215,9 +215,8 @@ public static class ParserBuilder
/// <typeparam name="TIgnore"></typeparam>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Parser<TToken, IEnumerable<TToken>> Take1Till<TToken, TIgnore>(Parser<TToken, TIgnore> termintor)
public static IParser<TToken, IEnumerable<TToken>> Take1Till<TToken, TIgnore>(IParser<TToken, TIgnore> termintor)
=> Any<TToken>().Many1Till(termintor);
#endregion
}

View File

@@ -10,11 +10,12 @@ namespace CanonSharp.Combinator.Parsers.Bases;
/// <param name="second">第二个解析器</param>
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">解析器结果类型</typeparam>
internal sealed class AlternativeParser<TToken, T>(Parser<TToken, T> first, Parser<TToken, T> second)
: Parser<TToken, T>
internal sealed class AlternativeParser<TToken, T>(IParser<TToken, T> first, IParser<TToken, T> second)
: IParser<TToken, T>
{
internal override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
public IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>
{
return first.Run(state, result => result.CaseOf(continuation, _ => second.Run(state, continuation)));
}

View File

@@ -11,10 +11,11 @@ namespace CanonSharp.Combinator.Parsers.Bases;
/// <typeparam name="TIntermediate">上游解析器结果类型</typeparam>
/// <typeparam name="T">下游解析器结果类型</typeparam>
internal sealed class BindParser<TToken, TIntermediate, T>(
Parser<TToken, TIntermediate> parser,
Func<TIntermediate, Parser<TToken, T>> next) : Parser<TToken, T>
IParser<TToken, TIntermediate> parser,
Func<TIntermediate, IParser<TToken, T>> next) : IParser<TToken, T>
{
internal override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
public IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>
=> parser.Run(state, result => result.Next(next, continuation));
}

View File

@@ -9,25 +9,17 @@ namespace CanonSharp.Combinator.Parsers.Bases;
/// </summary>
/// <typeparam name="TToken"></typeparam>
/// <typeparam name="T"></typeparam>
internal sealed class FixParser<TToken, T> : Parser<TToken, T>
internal sealed class FixParser<TToken, T> : IParser<TToken, T>
{
private readonly Parser<TToken, T> _parser;
private readonly IParser<TToken, T> _parser;
public FixParser(Func<Parser<TToken, T>, Parser<TToken, T>> func)
public FixParser(Func<IParser<TToken, T>, IParser<TToken, T>> func)
{
_parser = func(this);
}
internal override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
public IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>
=> _parser.Run(state, continuation);
}
internal sealed class FixParser<TToken, TParameter, T>(
Func<Func<TParameter, Parser<TToken, T>>, TParameter, Parser<TToken, T>> func,
TParameter parameter) : Parser<TToken, T>
{
internal override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
=> func(p => new FixParser<TToken, TParameter, T>(func, p), parameter).Run(state, continuation);
}

View File

@@ -12,10 +12,11 @@ namespace CanonSharp.Combinator.Parsers.Bases;
/// <typeparam name="TIntermediate"></typeparam>
/// <typeparam name="T"></typeparam>
internal sealed class MapParser<TToken, TIntermediate, T>(
Parser<TToken, TIntermediate> parser,
Func<TIntermediate, T> func) : Parser<TToken, T>
IParser<TToken, TIntermediate> parser,
Func<TIntermediate, T> func) : IParser<TToken, T>
{
internal override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
public IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>
=> parser.Run(state, result => continuation(result.Map(func)));
}

View File

@@ -12,12 +12,13 @@ namespace CanonSharp.Combinator.Parsers.Bases;
/// <typeparam name="TIntermediate">上游解析器结果类型</typeparam>
/// <typeparam name="T">最终解析结果类型</typeparam>
internal sealed class NextParser<TToken, TIntermediate, T>(
Parser<TToken, TIntermediate> parser,
Func<TIntermediate, Parser<TToken, T>> successfulParser,
Func<FailedResult<TToken, TIntermediate>, Parser<TToken, T>> failedParser) : Parser<TToken, T>
IParser<TToken, TIntermediate> parser,
Func<TIntermediate, IParser<TToken, T>> successfulParser,
Func<IFailedResult<TToken, TIntermediate>, IParser<TToken, T>> failedParser) : IParser<TToken, T>
{
internal override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
public IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>
{
return parser.Run(state, result => result.CaseOf(
successfulResult => successfulResult.Next(successfulParser, continuation),

View File

@@ -11,11 +11,12 @@ namespace CanonSharp.Combinator.Parsers.Bases;
/// <typeparam name="TToken">输入令牌类型</typeparam>
/// <typeparam name="T">解析结果类型</typeparam>
internal sealed class ResumeParser<TToken, T>(
Parser<TToken, T> parser,
Func<FailedResult<TToken, T>, Parser<TToken, T>> failedHandler) : Parser<TToken, T>
IParser<TToken, T> parser,
Func<IFailedResult<TToken, T>, IParser<TToken, T>> failedHandler) : IParser<TToken, T>
{
internal override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
public IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>
{
return parser.Run(state,
result => result.CaseOf(continuation,

View File

@@ -9,18 +9,20 @@ namespace CanonSharp.Combinator.Parsers;
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="TIntermediate">需要修改结果的解析器</typeparam>
/// <typeparam name="T">最终返回的解析结果</typeparam>
public abstract class ModifiedParser<TToken, TIntermediate, T>(Parser<TToken, TIntermediate> parser) : Parser<TToken, T>
public abstract class ModifiedParser<TToken, TIntermediate, T>(IParser<TToken, TIntermediate> parser)
: IParser<TToken, T>
{
protected abstract ParseResult<TToken, T> Fail<TState>(TState state,
FailedResult<TToken, TIntermediate> failedResult)
protected abstract IParseResult<TToken, T> Fail<TState>(TState state,
IFailedResult<TToken, TIntermediate> failedResult)
where TState : IReadState<TToken, TState>;
protected abstract ParseResult<TToken, T> Succeed<TState>(TState state,
SuccessfulResult<TToken, TIntermediate> successfulResult)
protected abstract IParseResult<TToken, T> Succeed<TState>(TState state,
ISuccessfulResult<TToken, TIntermediate> successfulResult)
where TState : IReadState<TToken, TState>;
internal override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
public IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>
=> parser.Run(state, result => result.CaseOf(
success => continuation(Succeed(state, success)),
failure => continuation(Fail(state, failure))));

View File

@@ -11,18 +11,18 @@ namespace CanonSharp.Combinator.Parsers.Modifiers;
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">解析结果类型</typeparam>
internal sealed class DoParser<TToken, T>(
Parser<TToken, T> parser,
IParser<TToken, T> parser,
Action<T> succeed,
Action<FailedResult<TToken, T>> fail) : ModifiedParser<TToken, T, T>(parser)
Action<IFailedResult<TToken, T>> fail) : ModifiedParser<TToken, T, T>(parser)
{
protected override ParseResult<TToken, T> Succeed<TState>(TState state,
SuccessfulResult<TToken, T> successfulResult)
protected override IParseResult<TToken, T> Succeed<TState>(TState state,
ISuccessfulResult<TToken, T> successfulResult)
{
succeed(successfulResult.Value);
return successfulResult;
}
protected override ParseResult<TToken, T> Fail<TState>(TState state, FailedResult<TToken, T> failedResult)
protected override IParseResult<TToken, T> Fail<TState>(TState state, IFailedResult<TToken, T> failedResult)
{
fail(failedResult);
return failedResult;

View File

@@ -10,12 +10,12 @@ namespace CanonSharp.Combinator.Parsers.Modifiers;
/// <param name="parser">需要向前看的解析器</param>
/// <typeparam name="TToken">输入流令牌</typeparam>
/// <typeparam name="T">返回的解析结果类型</typeparam>
internal sealed class LookAheadParser<TToken, T>(Parser<TToken, T> parser) : ModifiedParser<TToken, T, T>(parser)
internal sealed class LookAheadParser<TToken, T>(IParser<TToken, T> parser) : ModifiedParser<TToken, T, T>(parser)
{
protected override ParseResult<TToken, T> Succeed<TState>(TState state,
SuccessfulResult<TToken, T> successfulResult)
protected override IParseResult<TToken, T> Succeed<TState>(TState state,
ISuccessfulResult<TToken, T> successfulResult)
=> ParseResultBuilder.Succeed<TToken, TState, T>(successfulResult.Value, state);
protected override ParseResult<TToken, T> Fail<TState>(TState state, FailedResult<TToken, T> failedResult)
protected override IParseResult<TToken, T> Fail<TState>(TState state, IFailedResult<TToken, T> failedResult)
=> ParseResultBuilder.Fail<TToken, TState, T>($"Failed when looking ahead: {failedResult}", state);
}

View File

@@ -12,15 +12,15 @@ namespace CanonSharp.Combinator.Parsers.Modifiers;
/// <typeparam name="TToken">输入流的类型</typeparam>
/// <typeparam name="TIntermediate">上游解析器结果类型</typeparam>
/// <typeparam name="T">最终的返回结果</typeparam>
internal sealed class ReverseParser<TToken, TIntermediate, T>(Parser<TToken, TIntermediate> parser, T result)
internal sealed class ReverseParser<TToken, TIntermediate, T>(IParser<TToken, TIntermediate> parser, T result)
: ModifiedParser<TToken, TIntermediate, T>(parser)
{
protected override ParseResult<TToken, T> Succeed<TState>(TState state,
SuccessfulResult<TToken, TIntermediate> successfulResult)
protected override IParseResult<TToken, T> Succeed<TState>(TState state,
ISuccessfulResult<TToken, TIntermediate> successfulResult)
=> ParseResultBuilder.Fail<TToken, TState, T>($"Unexpected successful result: {successfulResult.Value}",
state);
protected override ParseResult<TToken, T> Fail<TState>(TState state,
FailedResult<TToken, TIntermediate> failedResult)
protected override IParseResult<TToken, T> Fail<TState>(TState state,
IFailedResult<TToken, TIntermediate> failedResult)
=> ParseResultBuilder.Succeed<TToken, TState, T>(result, state);
}

View File

@@ -12,15 +12,15 @@ namespace CanonSharp.Combinator.Parsers.Modifiers;
/// <typeparam name="TIntermediate">上游解析器解析结果类型</typeparam>
/// <typeparam name="T">最终的解析结果类型</typeparam>
internal sealed class SuccessfulMapParser<TToken, TIntermediate, T>(
Parser<TToken, TIntermediate> parser,
IParser<TToken, TIntermediate> parser,
Func<TIntermediate, T> successfulHandler,
Func<FailedResult<TToken, TIntermediate>, T> failedHandler) : ModifiedParser<TToken, TIntermediate, T>(parser)
Func<IFailedResult<TToken, TIntermediate>, T> failedHandler) : ModifiedParser<TToken, TIntermediate, T>(parser)
{
protected override ParseResult<TToken, T> Succeed<TState>(TState state,
SuccessfulResult<TToken, TIntermediate> successfulResult)
protected override IParseResult<TToken, T> Succeed<TState>(TState state,
ISuccessfulResult<TToken, TIntermediate> successfulResult)
=> successfulResult.Map(successfulHandler);
protected override ParseResult<TToken, T> Fail<TState>(TState state,
FailedResult<TToken, TIntermediate> failedResult)
protected override IParseResult<TToken, T> Fail<TState>(TState state,
IFailedResult<TToken, TIntermediate> failedResult)
=> ParseResultBuilder.Succeed<TToken, TState, T>(failedHandler(failedResult), state);
}

View File

@@ -11,13 +11,13 @@ namespace CanonSharp.Combinator.Parsers.Modifiers;
/// <param name="resume">处理失败结果的恢复函数</param>
/// <typeparam name="TToken">输入流令牌</typeparam>
/// <typeparam name="T">解析器返回结果类型</typeparam>
internal sealed class TryParser<TToken, T>(Parser<TToken, T> parser, Func<FailedResult<TToken, T>, T> resume)
internal sealed class TryParser<TToken, T>(IParser<TToken, T> parser, Func<IFailedResult<TToken, T>, T> resume)
: ModifiedParser<TToken, T, T>(parser)
{
protected override ParseResult<TToken, T> Succeed<TState>(TState state,
SuccessfulResult<TToken, T> successfulResult)
protected override IParseResult<TToken, T> Succeed<TState>(TState state,
ISuccessfulResult<TToken, T> successfulResult)
=> successfulResult;
protected override ParseResult<TToken, T> Fail<TState>(TState state, FailedResult<TToken, T> failedResult)
protected override IParseResult<TToken, T> Fail<TState>(TState state, IFailedResult<TToken, T> failedResult)
=> ParseResultBuilder.Succeed<TToken, TState, T>(resume(failedResult), state);
}

View File

@@ -8,7 +8,7 @@ namespace CanonSharp.Combinator.Parsers;
/// </summary>
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="T">解析结果的类型</typeparam>
public abstract class PrimitiveParser<TToken, T> : Parser<TToken, T>
public abstract class PrimitiveParser<TToken, T> : IParser<TToken, T>
{
/// <summary>
/// 运行解析器 返回解析结果
@@ -16,10 +16,11 @@ public abstract class PrimitiveParser<TToken, T> : Parser<TToken, T>
/// <param name="state">当前输入流的状态</param>
/// <typeparam name="TState">输入流状态的类型</typeparam>
/// <returns>解析结果</returns>
protected abstract ParseResult<TToken, T> Run<TState>(TState state)
protected abstract IParseResult<TToken, T> Run<TState>(TState state)
where TState : IReadState<TToken, TState>;
internal sealed override ParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<ParseResult<TToken, T>, ParseResult<TToken, TResult>> continuation)
public IParseResult<TToken, TResult> Run<TState, TResult>(TState state,
Func<IParseResult<TToken, T>, IParseResult<TToken, TResult>> continuation)
where TState : IReadState<TToken, TState>
=> continuation(Run(state));
}

View File

@@ -9,7 +9,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives;
/// <typeparam name="T">解析结果的类型</typeparam>
internal sealed class FailedParser<TToken, T> : PrimitiveParser<TToken, T>
{
protected override ParseResult<TToken, T> Run<TState>(TState state)
protected override IParseResult<TToken, T> Run<TState>(TState state)
=> ParseResultBuilder.Fail<TToken, TState, T>(state);
}
@@ -21,7 +21,7 @@ internal sealed class FailedParser<TToken, T> : PrimitiveParser<TToken, T>
/// <typeparam name="T">解析结果的类型</typeparam>
internal sealed class FailedParserWithMessage<TToken, T>(string message) : PrimitiveParser<TToken, T>
{
protected override ParseResult<TToken, T> Run<TState>(TState state)
protected override IParseResult<TToken, T> Run<TState>(TState state)
=> ParseResultBuilder.Fail<TToken, TState, T>(message, state);
}
@@ -34,7 +34,7 @@ internal sealed class FailedParserWithMessage<TToken, T>(string message) : Primi
internal sealed class FailedParserWithDelayedMessage<TToken, T>(Func<IReadState<TToken>, string> messageFunc)
: PrimitiveParser<TToken, T>
{
protected override ParseResult<TToken, T> Run<TState>(TState state)
protected override IParseResult<TToken, T> Run<TState>(TState state)
=> ParseResultBuilder.Fail<TToken, TState, T>(messageFunc(state), state);
}
@@ -46,6 +46,6 @@ internal sealed class FailedParserWithDelayedMessage<TToken, T>(Func<IReadState<
/// <typeparam name="T">解析结果的类型</typeparam>
internal sealed class FailedParserWithException<TToken, T>(Exception e) : PrimitiveParser<TToken, T>
{
protected override ParseResult<TToken, T> Run<TState>(TState state)
protected override IParseResult<TToken, T> Run<TState>(TState state)
=> ParseResultBuilder.Fail<TToken, TState, T>(e, state);
}

View File

@@ -10,7 +10,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives;
/// <typeparam name="T">解析成功返回值的类型</typeparam>
internal sealed class PureParser<TToken, T>(T value) : PrimitiveParser<TToken, T>
{
protected override ParseResult<TToken, T> Run<TState>(TState state)
protected override IParseResult<TToken, T> Run<TState>(TState state)
=> ParseResultBuilder.Succeed<TToken, TState, T>(value, state);
}
@@ -22,6 +22,6 @@ internal sealed class PureParser<TToken, T>(T value) : PrimitiveParser<TToken, T
/// <typeparam name="T">解析成功返回值的类型</typeparam>
internal sealed class DelayedPureParser<TToken, T>(Func<IReadState<TToken>, T> valueFunc) : PrimitiveParser<TToken, T>
{
protected override ParseResult<TToken, T> Run<TState>(TState state)
protected override IParseResult<TToken, T> Run<TState>(TState state)
=> ParseResultBuilder.Succeed<TToken, TState, T>(valueFunc(state), state);
}

View File

@@ -9,7 +9,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives;
/// <typeparam name="TToken">输入流类型</typeparam>
internal sealed class SatisfyParser<TToken>(Func<TToken, bool> predicate) : PrimitiveParser<TToken, TToken>
{
protected override ParseResult<TToken, TToken> Run<TState>(TState state)
protected override IParseResult<TToken, TToken> Run<TState>(TState state)
{
return state.HasValue && predicate(state.Current)
? ParseResultBuilder.Succeed<TToken, TState, TToken>(state.Current, state.Next)

View File

@@ -10,7 +10,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives;
/// <typeparam name="TToken">输入流类型</typeparam>
internal sealed class SkipParser<TToken>(int count) : PrimitiveParser<TToken, Unit>
{
protected override ParseResult<TToken, Unit> Run<TState>(TState state)
protected override IParseResult<TToken, Unit> Run<TState>(TState state)
{
List<TState> result = state.AsEnumerable<TToken, TState>().Take(count).ToList();

View File

@@ -10,7 +10,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives;
/// <typeparam name="TToken">输入流类型</typeparam>
internal sealed class TakeParser<TToken>(int count) : PrimitiveParser<TToken, IEnumerable<TToken>>
{
protected override ParseResult<TToken, IEnumerable<TToken>> Run<TState>(TState state)
protected override IParseResult<TToken, IEnumerable<TToken>> Run<TState>(TState state)
{
List<TState> result = state.AsEnumerable<TToken, TState>().Take(count).ToList();

View File

@@ -8,15 +8,17 @@ namespace CanonSharp.Combinator.Results;
/// <typeparam name="TToken">输入流的类型</typeparam>
/// <typeparam name="TState">输入流的读取类型</typeparam>
/// <typeparam name="T">实际的结果类型</typeparam>
internal sealed class FailedResultWithError<TToken, TState, T>(TState state) : FailedResult<TToken, T>
internal sealed class FailedResultWithError<TToken, TState, T>(TState state) : IFailedResult<TToken, T>
where TState : IReadState<TToken, TState>
{
public override IReadState<TToken> State => state;
public IReadState<TToken> State => state;
public override string Message => $"Unexpected state: {state}.";
public string Message => $"Unexpected state: {state}.";
public override FailedResult<TToken, TNext> Convert<TNext>()
public IFailedResult<TToken, TNext> Convert<TNext>()
{
return new FailedResultWithError<TToken, TState, TNext>(state);
}
public override string ToString() => $"Parse failed: {Message}.";
}

View File

@@ -10,15 +10,18 @@ namespace CanonSharp.Combinator.Results;
/// <typeparam name="TToken">输入流类型</typeparam>
/// <typeparam name="TState">当前输入流状态的类型</typeparam>
/// <typeparam name="T">解析结果的类型</typeparam>
public class FailedResultWithException<TToken, TState, T>(Exception exception, TState state) : FailedResult<TToken, T>
internal sealed class FailedResultWithException<TToken, TState, T>(Exception exception, TState state)
: IFailedResult<TToken, T>
where TState : IReadState<TToken, TState>
{
public override IReadState<TToken> State => state;
public IReadState<TToken> State => state;
public override ParseException Exception => new(ToString(), exception);
public ParseException Exception => new(Message, exception);
public override string Message => $"Exception occured: {exception}.";
public string Message => $"Exception occured: {exception}.";
public override FailedResult<TToken, TNext> Convert<TNext>()
public IFailedResult<TToken, TNext> Convert<TNext>()
=> new FailedResultWithException<TToken, TState, TNext>(exception, state);
public override string ToString() => $"Parse failed: {Message}.";
}

View File

@@ -10,15 +10,18 @@ namespace CanonSharp.Combinator.Results;
/// <typeparam name="TToken">输入流的类型</typeparam>
/// <typeparam name="TState">读取状态类型</typeparam>
/// <typeparam name="T">解析结果的类型</typeparam>
internal sealed class FailedResultWithMessage<TToken, TState, T>(string message, TState state) : FailedResult<TToken, T>
internal sealed class FailedResultWithMessage<TToken, TState, T>(string message, TState state)
: IFailedResult<TToken, T>
where TState : IReadState<TToken, TState>
{
public override IReadState<TToken> State => state;
public IReadState<TToken> State => state;
public override string Message => message;
public string Message => message;
public override FailedResult<TToken, TNext> Convert<TNext>()
public IFailedResult<TToken, TNext> Convert<TNext>()
{
return new FailedResultWithMessage<TToken, TState, TNext>(message, state);
}
public override string ToString() => $"Parse failed: {Message}.";
}

View File

@@ -11,13 +11,17 @@ namespace CanonSharp.Combinator.Results;
/// <typeparam name="TState">输入流的状态类型</typeparam>
/// <typeparam name="T">解析结果的类型</typeparam>
internal sealed class InternalSuccessfulResult<TToken, TState, T>(T result, TState state)
: SuccessfulResult<TToken, T>(result)
: ISuccessfulResult<TToken, T>
where TState : IReadState<TToken, TState>
{
protected override ParseResult<TToken, TResult> RunNext<TNext, TResult>(Parser<TToken, TNext> parser,
Func<ParseResult<TToken, TNext>, ParseResult<TToken, TResult>> continuation)
public T Value => result;
public IParseResult<TToken, TResult> RunNext<TNext, TResult>(IParser<TToken, TNext> parser,
Func<IParseResult<TToken, TNext>, IParseResult<TToken, TResult>> continuation)
=> parser.Run(state, continuation);
public override ParseResult<TToken, TResult> Map<TResult>(Func<T, TResult> map)
public IParseResult<TToken, TResult> Map<TResult>(Func<T, TResult> map)
=> new InternalSuccessfulResult<TToken, TState, TResult>(map(Value), state);
public override string ToString() => Value?.ToString() ?? string.Empty;
}

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