CanonSharp/CanonSharp.Combinator/Extensions/ParserExtensions.cs
jackfiled cf19f8197e 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>
2024-08-18 12:01:27 +08:00

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
}