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