573 lines
24 KiB
C#
573 lines
24 KiB
C#
using System.Runtime.CompilerServices;
|
|
using CanonSharp.Combinator.Abstractions;
|
|
using CanonSharp.Combinator.Parsers.Bases;
|
|
using CanonSharp.Combinator.Parsers.Modifiers;
|
|
using static CanonSharp.Combinator.ParserBuilder;
|
|
|
|
namespace CanonSharp.Combinator.Extensions;
|
|
|
|
public static class ParserExtensions
|
|
{
|
|
#region BasesParser
|
|
|
|
/// <summary>
|
|
/// 选择组合子
|
|
/// </summary>
|
|
/// <param name="first"></param>
|
|
/// <param name="second"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, T> Alternative<TToken, T>(this IParser<TToken, T> first, IParser<TToken, T> second)
|
|
=> new AlternativeParser<TToken, T>(first, second);
|
|
|
|
/// <summary>
|
|
/// 选择组合子
|
|
/// 按照失败的解析结果选择第二个解析器
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="resume"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 单子解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="next">按照输出指定下一个解析器的函数</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 映射解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="map">按照输出指定结果的函数</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 映射解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="result">最后的输出结果</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, TResult> Map<TToken, T, TResult>(this IParser<TToken, T> parser, TResult result)
|
|
=> parser.Map(_ => result);
|
|
|
|
/// <summary>
|
|
/// 下一个解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="next">输入成功结果输出下一个解析器的函数</param>
|
|
/// <param name="failedNext">输入失败结果输出下一个解析器的函数</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 下一个解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="next">输入成功结果输出下一个解析器的函数</param>
|
|
/// <param name="failedHandler">输出失败结果输出后续结果的函数</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 下一个解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="next">输出成功结果输出下一个解析器的函数</param>
|
|
/// <param name="failedResult">如果失败之后返回该结果</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 下一个解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="nextResult">输入成功结果返回新的结果</param>
|
|
/// <param name="failedResume">输入失败结果返回下一个解析器的函数</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 下一个解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="nextResult">输入成功结果返回新的结果</param>
|
|
/// <param name="failedResult">输入失败结果返回新的结果</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 下一个解析器组合子
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="successfulHandler">输入成功结果返回新结果的函数</param>
|
|
/// <param name="failedResult">返回的失败结果</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TResult"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, TResult> Next<TToken, T, TResult>(this IParser<TToken, T> parser,
|
|
Func<T, TResult> successfulHandler, TResult failedResult)
|
|
=> parser.Next(successfulHandler, _ => failedResult);
|
|
|
|
#endregion
|
|
|
|
#region ModifiedParser
|
|
|
|
/// <summary>
|
|
/// 在解析结果上执行指定操作
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="successfulAction">成功结果上执行的操作</param>
|
|
/// <param name="failedAction">失败结果上执行的操作</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 在解析结果上执行指定的操作
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="successfulAction">成功结果上执行的操作</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, T> Do<TToken, T>(this IParser<TToken, T> parser, Action<T> successfulAction)
|
|
=> parser.Do(successfulAction, _ => { });
|
|
|
|
/// <summary>
|
|
/// 向前看解析器
|
|
/// 执行解析器的同时不消耗输入流
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, T> LookAhead<TToken, T>(this IParser<TToken, T> parser)
|
|
=> new LookAheadParser<TToken, T>(parser);
|
|
|
|
/// <summary>
|
|
/// 翻转上游解析器的输出结果
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="result">翻转之后的输出结果</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="TIgnore"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, T> Not<TToken, TIgnore, T>(this IParser<TToken, TIgnore> parser, T result)
|
|
=> new ReverseParser<TToken, TIgnore, T>(parser, result);
|
|
|
|
/// <summary>
|
|
/// 翻转上游解析器的输出结果
|
|
/// 输出结果默认为Unit
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="TIgnore"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, Unit> Not<TToken, TIgnore>(this IParser<TToken, TIgnore> parser)
|
|
=> parser.Not(Unit.Instance);
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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 IParser<TToken, T> Try<TToken, T>(this IParser<TToken, T> parser, T result)
|
|
=> parser.Try(_ => result);
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, bool> Try<TToken, T>(this IParser<TToken, T> parser)
|
|
=> parser.Next(_ => true, false).Try(false);
|
|
|
|
#endregion
|
|
|
|
#region Combinators
|
|
|
|
/// <summary>
|
|
/// 连接两个解析器,返回左边解析器的结果
|
|
/// </summary>
|
|
/// <param name="left"></param>
|
|
/// <param name="right"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="TLeft"></typeparam>
|
|
/// <typeparam name="TRight"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, TLeft> Left<TToken, TLeft, TRight>(this IParser<TToken, TLeft> left,
|
|
IParser<TToken, TRight> right)
|
|
=> left.Bind(right.Map);
|
|
|
|
/// <summary>
|
|
/// 连接两个解析器,返回右边解析器的结果
|
|
/// </summary>
|
|
/// <param name="left"></param>
|
|
/// <param name="right"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="TLeft"></typeparam>
|
|
/// <typeparam name="TRight"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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 IParser<TToken, IEnumerable<T>> ManyRecursively<TToken, T>(this IParser<TToken, T> parser,
|
|
IEnumerable<T> result)
|
|
=> parser.Next(x => parser.ManyRecursively(result.Append(x)), result);
|
|
|
|
/// <summary>
|
|
/// 将上游解析器运行零或若干次
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, IEnumerable<T>> Many<TToken, T>(this IParser<TToken, T> parser)
|
|
=> parser.ManyRecursively([]);
|
|
|
|
/// <summary>
|
|
/// 将上游解析器运行若干次
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, IEnumerable<T>> Many1<TToken, T>(this IParser<TToken, T> parser)
|
|
=> parser.Bind(x => parser.ManyRecursively([x]));
|
|
|
|
/// <summary>
|
|
/// 跳过执行上游解析器运行零或若干次
|
|
/// 跳过执行不是不执行
|
|
/// 而是不返回结果
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="TIgnore"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, Unit> SkipMany<TToken, TIgnore>(this IParser<TToken, TIgnore> parser)
|
|
=> Fix<TToken, Unit>(self => parser.Next(_ => self, Unit.Instance));
|
|
|
|
/// <summary>
|
|
/// 跳过执行上游解析器运行若干次
|
|
/// 跳过执行不是不执行
|
|
/// 而是不返回结果
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="TIgnore"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, Unit> SkipMany1<TToken, TIgnore>(this IParser<TToken, TIgnore> parser)
|
|
=> parser.Right(parser.SkipMany());
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 链式解析器组合子
|
|
/// 按照解析结果决定下一个解析器
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="chain"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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 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))));
|
|
|
|
/// <summary>
|
|
/// 执行指定解析器直到终结解析器执行成功的组合子
|
|
/// 指定解析器可以执行零次或者多次
|
|
/// </summary>
|
|
/// <param name="parser">指定重复执行的解析器</param>
|
|
/// <param name="terminator">判断是否终结的解析器</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TIgnore"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, IEnumerable<T>> ManyTill<TToken, T, TIgnore>(this IParser<TToken, T> parser,
|
|
IParser<TToken, TIgnore> terminator)
|
|
=> parser.ManyTillRecursively(terminator, []);
|
|
|
|
/// <summary>
|
|
/// 执行指定解析器直到终结解析器执行成功的组合子
|
|
/// 指定解析器至少执行一次
|
|
/// </summary>
|
|
/// <param name="parser">指定重复执行的解析器</param>
|
|
/// <param name="terminator">判断是否终结的解析器</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TIgnore"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 跳过指定解析器直到终结解析器执行成功的组合子
|
|
/// 指定解析器可以执行零次或者若干次
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="terminator"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="TIgnore"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 跳过指定解析器直到终结解析器执行成功的组合子
|
|
/// 指定解析器至少要执行一次
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="terminator"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="TIgnore"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, T> Skip1Till<TToken, TIgnore, T>(this IParser<TToken, TIgnore> parser,
|
|
IParser<TToken, T> terminator)
|
|
=> parser.Right(parser.SkipTill(terminator));
|
|
|
|
/// <summary>
|
|
/// 解析直到指定的解析器识别成功
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, T> Match<TToken, T>(this IParser<TToken, T> parser)
|
|
=> SkipTill(Any<TToken>(), parser);
|
|
|
|
/// <summary>
|
|
/// 在左右两个解析器指定的范围内进行解析
|
|
/// 解析类似于左右括号和左右引号类似的句式
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="left"></param>
|
|
/// <param name="right"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TLeft"></typeparam>
|
|
/// <typeparam name="TRight"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 在同一个解析器指定的范围内进行解析
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="quotedParser"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TQuote"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, IEnumerable<T>> Quote<TToken, T, TQuote>(this IParser<TToken, T> parser,
|
|
IParser<TToken, TQuote> quotedParser)
|
|
=> parser.Quote(quotedParser, quotedParser);
|
|
|
|
/// <summary>
|
|
/// 解析由分隔符解析器分割的多个符号
|
|
/// 例如a,b,c
|
|
/// 实际的解析器可以运行零次或者多次
|
|
/// </summary>
|
|
/// <param name="parser">实际的解析器</param>
|
|
/// <param name="separator">分隔符解析器</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TSeparator"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// 解析由分隔符解析器分割的多个符号
|
|
/// 例如a,b,c
|
|
/// 实际的解析器可以运行多次
|
|
/// </summary>
|
|
/// <param name="parser">实际的解析器</param>
|
|
/// <param name="separator">分隔符解析器</param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TSeparator"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, IEnumerable<T>> SeparatedBy<TToken, T, TSeparator>(this IParser<TToken, T> parser,
|
|
IParser<TToken, TSeparator> separator)
|
|
=> parser.SeparatedBy1(separator).Try([]);
|
|
|
|
/// <summary>
|
|
/// 解析直到使用分隔符解析器结束
|
|
/// 例如abc.
|
|
/// 实际的解析器可以运行零次或者多次
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="separator"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TSeparator"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, IEnumerable<T>> EndBy<TToken, T, TSeparator>(this IParser<TToken, T> parser,
|
|
IParser<TToken, TSeparator> separator)
|
|
=> parser.Many().Left(separator);
|
|
|
|
/// <summary>
|
|
/// 解析直到使用分隔符解析器结束
|
|
/// 例如abc.
|
|
/// 实际的解析器至少运行一次
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="separator"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TSeparator"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, IEnumerable<T>> EndBy1<TToken, T, TSeparator>(this IParser<TToken, T> parser,
|
|
IParser<TToken, TSeparator> separator)
|
|
=> parser.Many1().Left(separator);
|
|
|
|
/// <summary>
|
|
/// Separated和End的综合体
|
|
/// 形如a,b,c,
|
|
/// 实际的解析器至少运行一次
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="separator"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TSeparator"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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>
|
|
/// Separated和End的综合体
|
|
/// 形如a,b,c,
|
|
/// 实际的解析器可以运行零次或者多次
|
|
/// </summary>
|
|
/// <param name="parser"></param>
|
|
/// <param name="separator"></param>
|
|
/// <typeparam name="TToken"></typeparam>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <typeparam name="TSeparator"></typeparam>
|
|
/// <returns></returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static IParser<TToken, IEnumerable<T>> SeparatedOrEndBy<TToken, T, TSeparator>(this IParser<TToken, T> parser,
|
|
IParser<TToken, TSeparator> separator)
|
|
=> parser.SeparatedOrEndBy1(separator).Try([]);
|
|
|
|
#endregion
|
|
|
|
#region LINQ
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
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 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
|
|
}
|