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