feat: Parser Combinator库和词法分析器 (#2)
All checks were successful
Run unit test / Unit-Test (push) Successful in 41s
All checks were successful
Run unit test / Unit-Test (push) Successful in 41s
Reviewed-on: https://git.bupt-hpc.cn/jackfiled/CanonSharp/pulls/2 Co-authored-by: jackfiled <xcrenchangjun@outlook.com> Co-committed-by: jackfiled <xcrenchangjun@outlook.com>
This commit is contained in:
49
CanonSharp.Combinator/Abstractions/FailedResult.cs
Normal file
49
CanonSharp.Combinator/Abstractions/FailedResult.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
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}.";
|
||||
}
|
||||
}
|
26
CanonSharp.Combinator/Abstractions/IReadState.cs
Normal file
26
CanonSharp.Combinator/Abstractions/IReadState.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace CanonSharp.Combinator.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// 输入流的读取状态
|
||||
/// </summary>
|
||||
/// <typeparam name="TToken">输入流元素类型</typeparam>
|
||||
public interface IReadState<out TToken>
|
||||
{
|
||||
public TToken Current { get; }
|
||||
|
||||
public bool HasValue { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输入流的读取状态
|
||||
/// </summary>
|
||||
/// <typeparam name="TToken">输入流元素类型</typeparam>
|
||||
/// <typeparam name="TState">下一个读取状态的类型</typeparam>
|
||||
public interface IReadState<out TToken, TState> : IReadState<TToken>, IEquatable<TState>
|
||||
where TState : IReadState<TToken, TState>
|
||||
{
|
||||
/// <summary>
|
||||
/// 下一个读取状态
|
||||
/// </summary>
|
||||
TState Next { get; }
|
||||
}
|
48
CanonSharp.Combinator/Abstractions/ParseResult.cs
Normal file
48
CanonSharp.Combinator/Abstractions/ParseResult.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
namespace CanonSharp.Combinator.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// 解析器结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TToken">输入流类型</typeparam>
|
||||
/// <typeparam name="T">实际结果类型</typeparam>
|
||||
public abstract class ParseResult<TToken, T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 实际结果对象
|
||||
/// </summary>
|
||||
public abstract T Value { get; }
|
||||
|
||||
protected ParseResult()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在当前结果上应用下一个解析器
|
||||
/// </summary>
|
||||
/// <param name="nextParser">下一个解析器的函数</param>
|
||||
/// <param name="continuation">处理解析结果的后继函数</param>
|
||||
/// <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);
|
||||
|
||||
/// <summary>
|
||||
/// 映射结果
|
||||
/// </summary>
|
||||
/// <param name="map">映射结果的函数</param>
|
||||
/// <typeparam name="TResult">映射结果函数返回解析结果的类型</typeparam>
|
||||
/// <returns>最终的解析结果</returns>
|
||||
public abstract ParseResult<TToken, TResult> Map<TResult>(Func<T, TResult> map);
|
||||
|
||||
/// <summary>
|
||||
/// 在成功或者失败解析结果上应用不同的后继函数
|
||||
/// </summary>
|
||||
/// <param name="successfulHandler">在成功解析结果上应用的函数</param>
|
||||
/// <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);
|
||||
}
|
43
CanonSharp.Combinator/Abstractions/Parser.cs
Normal file
43
CanonSharp.Combinator/Abstractions/Parser.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using CanonSharp.Combinator.Extensions;
|
||||
|
||||
namespace CanonSharp.Combinator.Abstractions;
|
||||
|
||||
/// <summary>
|
||||
/// 解析器抽象基类
|
||||
/// </summary>
|
||||
/// <typeparam name="TToken">输入流类型</typeparam>
|
||||
/// <typeparam name="T">解析结果类型</typeparam>
|
||||
public abstract class Parser<TToken, T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 解析器运行函数
|
||||
/// </summary>
|
||||
/// <param name="state">解析的输入流状态</param>
|
||||
/// <param name="continuation">运行之后的后继函数</param>
|
||||
/// <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)
|
||||
where TState : IReadState<TToken, TState>;
|
||||
|
||||
public ParseResult<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>
|
||||
{
|
||||
try
|
||||
{
|
||||
return Run(state, result => result);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return ParseResultBuilder.Fail<TToken, TState, T>(e, state);
|
||||
}
|
||||
}
|
||||
|
||||
public static Parser<TToken, T> operator |(Parser<TToken, T> a, Parser<TToken, T> b)
|
||||
=> a.Alternative(b);
|
||||
}
|
33
CanonSharp.Combinator/Abstractions/SuccessfulResult.cs
Normal file
33
CanonSharp.Combinator/Abstractions/SuccessfulResult.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
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;
|
||||
}
|
Reference in New Issue
Block a user