diff --git a/CanonSharp.Combinator/Abstractions/FailedResult.cs b/CanonSharp.Combinator/Abstractions/FailedResult.cs deleted file mode 100644 index 9fd8a42..0000000 --- a/CanonSharp.Combinator/Abstractions/FailedResult.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace CanonSharp.Combinator.Abstractions; - -/// -/// 失败解析结果基类 -/// -/// 输入流类型 -/// 解析结果类型 -public abstract class FailedResult : ParseResult -{ - public override T Value => throw Exception; - - /// - /// 当前读取到的状态 - /// - public abstract IReadState State { get; } - - /// - /// 解析失败的消息 - /// - public abstract string Message { get; } - - /// - /// 解析失败的异常 - /// - public virtual ParseException Exception => new(ToString()); - - /// - /// 转换该失败结果的类型 - /// - /// 转换之后的结果类型 - /// 转换之后的失败解析类型 - public abstract FailedResult Convert(); - - internal override ParseResult Next(Func> nextParser, - Func, ParseResult> continuation) - => continuation(Convert()); - - public override ParseResult Map(Func map) - => Convert(); - - public override TResult CaseOf(Func, TResult> successfulHandler, - Func, TResult> failedHandler) - => failedHandler(this); - - public override string ToString() - { - return $"Parse Failed: {Message}."; - } -} diff --git a/CanonSharp.Combinator/Abstractions/IFailedResult.cs b/CanonSharp.Combinator/Abstractions/IFailedResult.cs new file mode 100644 index 0000000..7f525cc --- /dev/null +++ b/CanonSharp.Combinator/Abstractions/IFailedResult.cs @@ -0,0 +1,47 @@ +namespace CanonSharp.Combinator.Abstractions; + +/// +/// 失败解析结果基类 +/// +/// 输入流类型 +/// 解析结果类型 +public interface IFailedResult : IParseResult +{ + T IParseResult.Value => throw Exception; + + /// + /// 当前读取到的状态 + /// + public IReadState State { get; } + + /// + /// 解析失败的消息 + /// + public string Message { get; } + + /// + /// 解析失败的异常 + /// + public ParseException Exception => new(ToString()); + + /// + /// 转换该失败结果的类型 + /// + /// 转换之后的结果类型 + /// 转换之后的失败解析类型 + public IFailedResult Convert(); + + IParseResult IParseResult.Next( + Func> nextParser, + Func, IParseResult> continuation) + => continuation(Convert()); + + IParseResult IParseResult.Map(Func map) + => Convert(); + + TResult IParseResult.CaseOf(Func, TResult> successfulHandler, + Func, TResult> failedHandler) + => failedHandler(this); + + string IParseResult.ToString() => $"Parse Failed: {Message}"; +} diff --git a/CanonSharp.Combinator/Abstractions/ParseResult.cs b/CanonSharp.Combinator/Abstractions/IParseResult.cs similarity index 71% rename from CanonSharp.Combinator/Abstractions/ParseResult.cs rename to CanonSharp.Combinator/Abstractions/IParseResult.cs index e38be41..569c198 100644 --- a/CanonSharp.Combinator/Abstractions/ParseResult.cs +++ b/CanonSharp.Combinator/Abstractions/IParseResult.cs @@ -5,12 +5,12 @@ namespace CanonSharp.Combinator.Abstractions; /// /// 输入流类型 /// 实际结果类型 -public abstract class ParseResult +public interface IParseResult { /// /// 实际结果对象 /// - public abstract T Value { get; } + public T Value { get; } /// /// 在当前结果上应用下一个解析器 @@ -20,8 +20,8 @@ public abstract class ParseResult /// 下一个解析器函数返回的解析结果类型 /// 最终的解析结果类型 /// - internal abstract ParseResult Next(Func> nextParser, - Func, ParseResult> continuation); + internal IParseResult Next(Func> nextParser, + Func, IParseResult> continuation); /// /// 映射结果 @@ -29,7 +29,7 @@ public abstract class ParseResult /// 映射结果的函数 /// 映射结果函数返回解析结果的类型 /// 最终的解析结果 - public abstract ParseResult Map(Func map); + public IParseResult Map(Func map); /// /// 在成功或者失败解析结果上应用不同的后继函数 @@ -38,6 +38,8 @@ public abstract class ParseResult /// 在失败解析结构上应用的函数 /// 最后返回解析结果的类型 /// 最后的解析结果 - public abstract TResult CaseOf(Func, TResult> successfulHandler, - Func, TResult> failedHandler); + public TResult CaseOf(Func, TResult> successfulHandler, + Func, TResult> failedHandler); + + public string ToString(); } diff --git a/CanonSharp.Combinator/Abstractions/Parser.cs b/CanonSharp.Combinator/Abstractions/IParser.cs similarity index 68% rename from CanonSharp.Combinator/Abstractions/Parser.cs rename to CanonSharp.Combinator/Abstractions/IParser.cs index 2159a95..edeb2e3 100644 --- a/CanonSharp.Combinator/Abstractions/Parser.cs +++ b/CanonSharp.Combinator/Abstractions/IParser.cs @@ -7,7 +7,7 @@ namespace CanonSharp.Combinator.Abstractions; /// /// 输入流类型 /// 解析结果类型 -public abstract class Parser +public interface IParser { /// /// 解析器运行函数 @@ -17,16 +17,16 @@ public abstract class Parser /// 输入流状态类型 /// 后继函数运行之后的解析结果类型 /// - internal abstract ParseResult Run(TState state, - Func, ParseResult> continuation) + internal IParseResult Run(TState state, + Func, IParseResult> continuation) where TState : IReadState; - public ParseResult Parse(TState state) where TState : IReadState + public IParseResult Parse(TState state) where TState : IReadState { return Run(state); } - private ParseResult Run(TState state) where TState : IReadState + private IParseResult Run(TState state) where TState : IReadState { try { @@ -38,6 +38,6 @@ public abstract class Parser } } - public static Parser operator |(Parser a, Parser b) + public static IParser operator |(IParser a, IParser b) => a.Alternative(b); } diff --git a/CanonSharp.Combinator/Abstractions/ISuccessfulResult.cs b/CanonSharp.Combinator/Abstractions/ISuccessfulResult.cs new file mode 100644 index 0000000..c8372eb --- /dev/null +++ b/CanonSharp.Combinator/Abstractions/ISuccessfulResult.cs @@ -0,0 +1,31 @@ +namespace CanonSharp.Combinator.Abstractions; + +/// +/// 成功解析结果基类 +/// +/// 输入流类型 +/// 实际的解析结果类型 +public interface ISuccessfulResult : IParseResult +{ + /// + /// 运行下一个解析器 + /// + /// 下一个解析器 + /// 处理解析结果的后继函数 + /// 下一个解析器返回的结果类型 + /// 最终的结果类型 + /// 最终的结果 + protected IParseResult RunNext(IParser parser, + Func, IParseResult> continuation); + + IParseResult IParseResult.Next( + Func> nextParser, + Func, IParseResult> continuation) + => RunNext(nextParser(Value), continuation); + + TResult IParseResult.CaseOf(Func, TResult> successfulHandler, + Func, TResult> failedHandler) + => successfulHandler(this); + + string IParseResult.ToString() => Value?.ToString() ?? string.Empty; +} diff --git a/CanonSharp.Combinator/Abstractions/SuccessfulResult.cs b/CanonSharp.Combinator/Abstractions/SuccessfulResult.cs deleted file mode 100644 index fc76084..0000000 --- a/CanonSharp.Combinator/Abstractions/SuccessfulResult.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace CanonSharp.Combinator.Abstractions; - -/// -/// 成功解析结果基类 -/// -/// 实际的解析结果 -/// 输入流类型 -/// 实际的解析结果类型 -public abstract class SuccessfulResult(T value) : ParseResult -{ - public override T Value => value; - - /// - /// 运行下一个解析器 - /// - /// 下一个解析器 - /// 处理解析结果的后继函数 - /// 下一个解析器返回的结果类型 - /// 最终的结果类型 - /// 最终的结果 - protected abstract ParseResult RunNext(Parser parser, - Func, ParseResult> continuation); - - internal override ParseResult Next(Func> nextParser, - Func, ParseResult> continuation) - => RunNext(nextParser(Value), continuation); - - public override TResult CaseOf(Func, TResult> successfulHandler, - Func, TResult> failedHandler) - => successfulHandler(this); - - public override string ToString() => Value?.ToString() ?? string.Empty; -} diff --git a/CanonSharp.Combinator/Extensions/ParserExtensions.cs b/CanonSharp.Combinator/Extensions/ParserExtensions.cs index 1493e2b..dc8c3dc 100644 --- a/CanonSharp.Combinator/Extensions/ParserExtensions.cs +++ b/CanonSharp.Combinator/Extensions/ParserExtensions.cs @@ -19,7 +19,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Alternative(this Parser first, Parser second) + public static IParser Alternative(this IParser first, IParser second) => new AlternativeParser(first, second); /// @@ -32,8 +32,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Alternative(this Parser parser, - Func, Parser> resume) + public static IParser Alternative(this IParser parser, + Func, IParser> resume) => new ResumeParser(parser, resume); /// @@ -46,8 +46,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Bind(this Parser parser, - Func> next) + public static IParser Bind(this IParser parser, + Func> next) => new BindParser(parser, next); /// @@ -60,7 +60,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Map(this Parser parser, Func map) + public static IParser Map(this IParser parser, Func map) => new MapParser(parser, map); /// @@ -73,7 +73,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Map(this Parser parser, TResult result) + public static IParser Map(this IParser parser, TResult result) => parser.Map(_ => result); /// @@ -87,9 +87,9 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Next(this Parser parser, - Func> next, - Func, Parser> failedNext) + public static IParser Next(this IParser parser, + Func> next, + Func, IParser> failedNext) => new NextParser(parser, next, failedNext); /// @@ -103,8 +103,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Next(this Parser parser, - Func> next, Func, TResult> failedHandler) + public static IParser Next(this IParser parser, + Func> next, Func, TResult> failedHandler) => parser.Next(next, failedResult => Pure(failedHandler(failedResult))); /// @@ -118,8 +118,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Next(this Parser parser, - Func> next, TResult failedResult) + public static IParser Next(this IParser parser, + Func> next, TResult failedResult) => parser.Next(next, _ => Pure(failedResult)); /// @@ -133,8 +133,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Next(this Parser parser, - Func nextResult, Func, Parser> failedResume) + public static IParser Next(this IParser parser, + Func nextResult, Func, IParser> failedResume) => parser.Next(x => Pure(nextResult(x)), failedResume); /// @@ -148,8 +148,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Next(this Parser parser, - Func nextResult, Func, TResult> failedResult) + public static IParser Next(this IParser parser, + Func nextResult, Func, TResult> failedResult) => new SuccessfulMapParser(parser, nextResult, failedResult); /// @@ -163,7 +163,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Next(this Parser parser, + public static IParser Next(this IParser parser, Func successfulHandler, TResult failedResult) => parser.Next(successfulHandler, _ => failedResult); @@ -181,8 +181,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Do(this Parser parser, Action successfulAction, - Action> failedAction) + public static IParser Do(this IParser parser, Action successfulAction, + Action> failedAction) => new DoParser(parser, successfulAction, failedAction); /// @@ -194,7 +194,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Do(this Parser parser, Action successfulAction) + public static IParser Do(this IParser parser, Action successfulAction) => parser.Do(successfulAction, _ => { }); /// @@ -206,7 +206,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser LookAhead(this Parser parser) + public static IParser LookAhead(this IParser parser) => new LookAheadParser(parser); /// @@ -219,7 +219,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Not(this Parser parser, T result) + public static IParser Not(this IParser parser, T result) => new ReverseParser(parser, result); /// @@ -231,21 +231,21 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Not(this Parser parser) + public static IParser Not(this IParser parser) => parser.Not(Unit.Instance); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Try(this Parser parser, - Func, T> resume) + public static IParser Try(this IParser parser, + Func, T> resume) => new TryParser(parser, resume); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Try(this Parser parser, T result) + public static IParser Try(this IParser parser, T result) => parser.Try(_ => result); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Try(this Parser parser) + public static IParser Try(this IParser parser) => parser.Next(_ => true, false).Try(false); #endregion @@ -262,8 +262,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Left(this Parser left, - Parser right) + public static IParser Left(this IParser left, + IParser right) => left.Bind(right.Map); /// @@ -276,12 +276,12 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Right(this Parser left, - Parser right) + public static IParser Right(this IParser left, + IParser right) => left.Bind(_ => right); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Parser> ManyRecursively(this Parser parser, + private static IParser> ManyRecursively(this IParser parser, IEnumerable result) => parser.Next(x => parser.ManyRecursively(result.Append(x)), result); @@ -293,7 +293,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Many(this Parser parser) + public static IParser> Many(this IParser parser) => parser.ManyRecursively([]); /// @@ -304,7 +304,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Many1(this Parser parser) + public static IParser> Many1(this IParser parser) => parser.Bind(x => parser.ManyRecursively([x])); /// @@ -317,7 +317,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser SkipMany(this Parser parser) + public static IParser SkipMany(this IParser parser) => Fix(self => parser.Next(_ => self, Unit.Instance)); /// @@ -330,11 +330,11 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser SkipMany1(this Parser parser) + public static IParser SkipMany1(this IParser parser) => parser.Right(parser.SkipMany()); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Parser ChainRecursively(Func> chain, T value) + private static IParser ChainRecursively(Func> chain, T value) => chain(value).Next(x => ChainRecursively(chain, x), value); /// @@ -347,12 +347,12 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Chain(this Parser parser, Func> chain) + public static IParser Chain(this IParser parser, Func> chain) => parser.Bind(x => ChainRecursively(chain, x)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Parser> ManyTillRecursively(this Parser parser, - Parser terminator, IEnumerable result) + private static IParser> ManyTillRecursively(this IParser parser, + IParser terminator, IEnumerable result) => terminator.Next(_ => Pure>(result), _ => parser.Bind(x => parser.ManyTillRecursively(terminator, result.Append(x)))); @@ -367,8 +367,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> ManyTill(this Parser parser, - Parser terminator) + public static IParser> ManyTill(this IParser parser, + IParser terminator) => parser.ManyTillRecursively(terminator, []); /// @@ -382,8 +382,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Many1Till(this Parser parser, - Parser terminator) + public static IParser> Many1Till(this IParser parser, + IParser terminator) => parser.Bind(x => parser.ManyTillRecursively(terminator, [x])); /// @@ -397,8 +397,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser SkipTill(this Parser parser, - Parser terminator) + public static IParser SkipTill(this IParser parser, + IParser terminator) => Fix(self => terminator | parser.Right(self)); /// @@ -412,8 +412,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Skip1Till(this Parser parser, - Parser terminator) + public static IParser Skip1Till(this IParser parser, + IParser terminator) => parser.Right(parser.SkipTill(terminator)); /// @@ -424,7 +424,7 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Match(this Parser parser) + public static IParser Match(this IParser parser) => SkipTill(Any(), parser); /// @@ -440,8 +440,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Quote(this Parser parser, - Parser left, Parser right) + public static IParser> Quote(this IParser parser, + IParser left, IParser right) => left.Right(parser.ManyTill(right)); /// @@ -454,8 +454,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Quote(this Parser parser, - Parser quotedParser) + public static IParser> Quote(this IParser parser, + IParser quotedParser) => parser.Quote(quotedParser, quotedParser); /// @@ -470,8 +470,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> SeparatedBy1(this Parser parser, - Parser separator) + public static IParser> SeparatedBy1(this IParser parser, + IParser separator) => parser.Bind(x => separator.Right(parser).ManyRecursively([x])); /// @@ -486,8 +486,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> SeparatedBy(this Parser parser, - Parser separator) + public static IParser> SeparatedBy(this IParser parser, + IParser separator) => parser.SeparatedBy1(separator).Try([]); /// @@ -502,8 +502,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> EndBy(this Parser parser, - Parser separator) + public static IParser> EndBy(this IParser parser, + IParser separator) => parser.Many().Left(separator); /// @@ -518,8 +518,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> EndBy1(this Parser parser, - Parser separator) + public static IParser> EndBy1(this IParser parser, + IParser separator) => parser.Many1().Left(separator); /// @@ -534,8 +534,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> SeparatedOrEndBy1(this Parser parser, - Parser separator) + public static IParser> SeparatedOrEndBy1(this IParser parser, + IParser separator) => parser.SeparatedBy1(separator).Left(separator.Try()); /// @@ -550,8 +550,8 @@ public static class ParserExtensions /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> SeparatedOrEndBy(this Parser parser, - Parser separator) + public static IParser> SeparatedOrEndBy(this IParser parser, + IParser separator) => parser.SeparatedOrEndBy1(separator).Try([]); #endregion @@ -559,13 +559,13 @@ public static class ParserExtensions #region LINQ [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Select(this Parser parser, + public static IParser Select(this IParser parser, Func selector) => parser.Map(selector); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser SelectMany(this Parser parser, - Func> selector, Func projector) + public static IParser SelectMany(this IParser parser, + Func> selector, Func projector) => parser.Bind(x => selector(x).Map(y => projector(x, y))); #endregion diff --git a/CanonSharp.Combinator/ParseResultBuilder.cs b/CanonSharp.Combinator/ParseResultBuilder.cs index 3f09e0b..b6c616c 100644 --- a/CanonSharp.Combinator/ParseResultBuilder.cs +++ b/CanonSharp.Combinator/ParseResultBuilder.cs @@ -19,7 +19,7 @@ public static class ParseResultBuilder /// 解析成功的对象类型 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ParseResult Succeed(T value, TState state) + public static IParseResult Succeed(T value, TState state) where TState : IReadState => new InternalSuccessfulResult(value, state); @@ -32,7 +32,7 @@ public static class ParseResultBuilder /// 解析成功的对象类型 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ParseResult Fail(TState state) + public static IParseResult Fail(TState state) where TState : IReadState => new FailedResultWithError(state); @@ -47,7 +47,7 @@ public static class ParseResultBuilder /// 解析成功的对象类型 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ParseResult Fail(string message, TState state) + public static IParseResult Fail(string message, TState state) where TState : IReadState => new FailedResultWithMessage(message, state); @@ -61,7 +61,7 @@ public static class ParseResultBuilder /// 解析成功的对象类型 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static ParseResult Fail(Exception exception, TState state) + public static IParseResult Fail(Exception exception, TState state) where TState : IReadState => new FailedResultWithException(exception, state); } diff --git a/CanonSharp.Combinator/ParserBuilder.cs b/CanonSharp.Combinator/ParserBuilder.cs index b4bde54..f2ce356 100644 --- a/CanonSharp.Combinator/ParserBuilder.cs +++ b/CanonSharp.Combinator/ParserBuilder.cs @@ -20,7 +20,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Pure(T value) + public static IParser Pure(T value) => new PureParser(value); /// @@ -31,7 +31,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Pure(Func, T> valueFunc) + public static IParser Pure(Func, T> valueFunc) => new DelayedPureParser(valueFunc); /// @@ -40,7 +40,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Null() => Pure(Unit.Instance); + public static IParser Null() => Pure(Unit.Instance); /// /// 失败的解析器 @@ -49,7 +49,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Fail() => new FailedParser(); + public static IParser Fail() => new FailedParser(); /// /// 失败的解析器 @@ -59,7 +59,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Fail(string message) => new FailedParserWithMessage(message); + public static IParser Fail(string message) => new FailedParserWithMessage(message); /// /// 失败的解析器 @@ -69,7 +69,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Fail(Func, string> messageFunc) => + public static IParser Fail(Func, string> messageFunc) => new FailedParserWithDelayedMessage(messageFunc); /// @@ -80,7 +80,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Fail(Exception exception) => + public static IParser Fail(Exception exception) => new FailedParserWithException(exception); /// @@ -90,7 +90,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Satisfy(Func predicate) + public static IParser Satisfy(Func predicate) => new SatisfyParser(predicate); /// @@ -99,7 +99,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Any() => Satisfy(_ => true); + public static IParser Any() => Satisfy(_ => true); /// /// 识别指定输入元素的解析器 @@ -108,7 +108,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Token(TToken token) + public static IParser Token(TToken token) => Satisfy(t => EqualityComparer.Default.Equals(t, token)); /// @@ -118,7 +118,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Skip(int count) => new SkipParser(count); + public static IParser Skip(int count) => new SkipParser(count); /// /// 识别指定数量输入元素的解析器 @@ -127,7 +127,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Take(int count) => new TakeParser(count); + public static IParser> Take(int count) => new TakeParser(count); #endregion @@ -141,7 +141,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Fix(Func, Parser> parserFix) + public static IParser Fix(Func, IParser> parserFix) => new FixParser(parserFix); #endregion @@ -156,7 +156,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Choice(IEnumerable> parsers) + public static IParser Choice(IEnumerable> parsers) => parsers.Aggregate((result, parser) => result.Alternative(parser)); /// @@ -167,7 +167,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Choice(params Parser[] parsers) + public static IParser Choice(params IParser[] parsers) => Choice(parsers.AsEnumerable()); /// @@ -178,7 +178,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Sequence(IEnumerable> parsers) + public static IParser> Sequence(IEnumerable> parsers) => parsers.Reverse().Aggregate(Pure>([]), (next, parser) => parser.Bind( x => next.Map(result => result.Prepend(x)))); @@ -191,7 +191,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Sequence(params Parser[] parsers) + public static IParser> Sequence(params IParser[] parsers) => Sequence(parsers.AsEnumerable()); /// @@ -203,7 +203,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> TakeTill(Parser terminator) + public static IParser> TakeTill(IParser terminator) => Any().ManyTill(terminator); /// @@ -215,7 +215,7 @@ public static class ParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser> Take1Till(Parser termintor) + public static IParser> Take1Till(IParser termintor) => Any().Many1Till(termintor); #endregion diff --git a/CanonSharp.Combinator/Parsers/Bases/AlternativeParser.cs b/CanonSharp.Combinator/Parsers/Bases/AlternativeParser.cs index af68952..f4cfe1c 100644 --- a/CanonSharp.Combinator/Parsers/Bases/AlternativeParser.cs +++ b/CanonSharp.Combinator/Parsers/Bases/AlternativeParser.cs @@ -10,11 +10,12 @@ namespace CanonSharp.Combinator.Parsers.Bases; /// 第二个解析器 /// 输入流类型 /// 解析器结果类型 -internal sealed class AlternativeParser(Parser first, Parser second) - : Parser +internal sealed class AlternativeParser(IParser first, IParser second) + : IParser { - internal override ParseResult Run(TState state, - Func, ParseResult> continuation) + public IParseResult Run(TState state, + Func, IParseResult> continuation) + where TState : IReadState { return first.Run(state, result => result.CaseOf(continuation, _ => second.Run(state, continuation))); } diff --git a/CanonSharp.Combinator/Parsers/Bases/BindParser.cs b/CanonSharp.Combinator/Parsers/Bases/BindParser.cs index 10be255..e6b42a1 100644 --- a/CanonSharp.Combinator/Parsers/Bases/BindParser.cs +++ b/CanonSharp.Combinator/Parsers/Bases/BindParser.cs @@ -11,10 +11,11 @@ namespace CanonSharp.Combinator.Parsers.Bases; /// 上游解析器结果类型 /// 下游解析器结果类型 internal sealed class BindParser( - Parser parser, - Func> next) : Parser + IParser parser, + Func> next) : IParser { - internal override ParseResult Run(TState state, - Func, ParseResult> continuation) + public IParseResult Run(TState state, + Func, IParseResult> continuation) + where TState : IReadState => parser.Run(state, result => result.Next(next, continuation)); } diff --git a/CanonSharp.Combinator/Parsers/Bases/FixParser.cs b/CanonSharp.Combinator/Parsers/Bases/FixParser.cs index 81b9bab..4edbc05 100644 --- a/CanonSharp.Combinator/Parsers/Bases/FixParser.cs +++ b/CanonSharp.Combinator/Parsers/Bases/FixParser.cs @@ -9,16 +9,17 @@ namespace CanonSharp.Combinator.Parsers.Bases; /// /// /// -internal sealed class FixParser : Parser +internal sealed class FixParser : IParser { - private readonly Parser _parser; + private readonly IParser _parser; - public FixParser(Func, Parser> func) + public FixParser(Func, IParser> func) { _parser = func(this); } - internal override ParseResult Run(TState state, - Func, ParseResult> continuation) + public IParseResult Run(TState state, + Func, IParseResult> continuation) + where TState : IReadState => _parser.Run(state, continuation); } diff --git a/CanonSharp.Combinator/Parsers/Bases/MapParser.cs b/CanonSharp.Combinator/Parsers/Bases/MapParser.cs index 0a94072..81ac998 100644 --- a/CanonSharp.Combinator/Parsers/Bases/MapParser.cs +++ b/CanonSharp.Combinator/Parsers/Bases/MapParser.cs @@ -12,10 +12,11 @@ namespace CanonSharp.Combinator.Parsers.Bases; /// /// internal sealed class MapParser( - Parser parser, - Func func) : Parser + IParser parser, + Func func) : IParser { - internal override ParseResult Run(TState state, - Func, ParseResult> continuation) + public IParseResult Run(TState state, + Func, IParseResult> continuation) + where TState : IReadState => parser.Run(state, result => continuation(result.Map(func))); } diff --git a/CanonSharp.Combinator/Parsers/Bases/NextParser.cs b/CanonSharp.Combinator/Parsers/Bases/NextParser.cs index 67b4242..687a134 100644 --- a/CanonSharp.Combinator/Parsers/Bases/NextParser.cs +++ b/CanonSharp.Combinator/Parsers/Bases/NextParser.cs @@ -12,12 +12,13 @@ namespace CanonSharp.Combinator.Parsers.Bases; /// 上游解析器结果类型 /// 最终解析结果类型 internal sealed class NextParser( - Parser parser, - Func> successfulParser, - Func, Parser> failedParser) : Parser + IParser parser, + Func> successfulParser, + Func, IParser> failedParser) : IParser { - internal override ParseResult Run(TState state, - Func, ParseResult> continuation) + public IParseResult Run(TState state, + Func, IParseResult> continuation) + where TState : IReadState { return parser.Run(state, result => result.CaseOf( successfulResult => successfulResult.Next(successfulParser, continuation), diff --git a/CanonSharp.Combinator/Parsers/Bases/ResumeParser.cs b/CanonSharp.Combinator/Parsers/Bases/ResumeParser.cs index 9cf4d76..f9c8c75 100644 --- a/CanonSharp.Combinator/Parsers/Bases/ResumeParser.cs +++ b/CanonSharp.Combinator/Parsers/Bases/ResumeParser.cs @@ -11,11 +11,12 @@ namespace CanonSharp.Combinator.Parsers.Bases; /// 输入令牌类型 /// 解析结果类型 internal sealed class ResumeParser( - Parser parser, - Func, Parser> failedHandler) : Parser + IParser parser, + Func, IParser> failedHandler) : IParser { - internal override ParseResult Run(TState state, - Func, ParseResult> continuation) + public IParseResult Run(TState state, + Func, IParseResult> continuation) + where TState : IReadState { return parser.Run(state, result => result.CaseOf(continuation, diff --git a/CanonSharp.Combinator/Parsers/ModifiedParser.cs b/CanonSharp.Combinator/Parsers/ModifiedParser.cs index 6a70c79..7b5e4fb 100644 --- a/CanonSharp.Combinator/Parsers/ModifiedParser.cs +++ b/CanonSharp.Combinator/Parsers/ModifiedParser.cs @@ -9,18 +9,20 @@ namespace CanonSharp.Combinator.Parsers; /// 输入流类型 /// 需要修改结果的解析器 /// 最终返回的解析结果 -public abstract class ModifiedParser(Parser parser) : Parser +public abstract class ModifiedParser(IParser parser) + : IParser { - protected abstract ParseResult Fail(TState state, - FailedResult failedResult) + protected abstract IParseResult Fail(TState state, + IFailedResult failedResult) where TState : IReadState; - protected abstract ParseResult Succeed(TState state, - SuccessfulResult successfulResult) + protected abstract IParseResult Succeed(TState state, + ISuccessfulResult successfulResult) where TState : IReadState; - internal override ParseResult Run(TState state, - Func, ParseResult> continuation) + public IParseResult Run(TState state, + Func, IParseResult> continuation) + where TState : IReadState => parser.Run(state, result => result.CaseOf( success => continuation(Succeed(state, success)), failure => continuation(Fail(state, failure)))); diff --git a/CanonSharp.Combinator/Parsers/Modifiers/DoParser.cs b/CanonSharp.Combinator/Parsers/Modifiers/DoParser.cs index 332bb87..0af8683 100644 --- a/CanonSharp.Combinator/Parsers/Modifiers/DoParser.cs +++ b/CanonSharp.Combinator/Parsers/Modifiers/DoParser.cs @@ -11,18 +11,18 @@ namespace CanonSharp.Combinator.Parsers.Modifiers; /// 输入流类型 /// 解析结果类型 internal sealed class DoParser( - Parser parser, + IParser parser, Action succeed, - Action> fail) : ModifiedParser(parser) + Action> fail) : ModifiedParser(parser) { - protected override ParseResult Succeed(TState state, - SuccessfulResult successfulResult) + protected override IParseResult Succeed(TState state, + ISuccessfulResult successfulResult) { succeed(successfulResult.Value); return successfulResult; } - protected override ParseResult Fail(TState state, FailedResult failedResult) + protected override IParseResult Fail(TState state, IFailedResult failedResult) { fail(failedResult); return failedResult; diff --git a/CanonSharp.Combinator/Parsers/Modifiers/LookAheadParser.cs b/CanonSharp.Combinator/Parsers/Modifiers/LookAheadParser.cs index 7210a6c..5ee592c 100644 --- a/CanonSharp.Combinator/Parsers/Modifiers/LookAheadParser.cs +++ b/CanonSharp.Combinator/Parsers/Modifiers/LookAheadParser.cs @@ -10,12 +10,12 @@ namespace CanonSharp.Combinator.Parsers.Modifiers; /// 需要向前看的解析器 /// 输入流令牌 /// 返回的解析结果类型 -internal sealed class LookAheadParser(Parser parser) : ModifiedParser(parser) +internal sealed class LookAheadParser(IParser parser) : ModifiedParser(parser) { - protected override ParseResult Succeed(TState state, - SuccessfulResult successfulResult) + protected override IParseResult Succeed(TState state, + ISuccessfulResult successfulResult) => ParseResultBuilder.Succeed(successfulResult.Value, state); - protected override ParseResult Fail(TState state, FailedResult failedResult) + protected override IParseResult Fail(TState state, IFailedResult failedResult) => ParseResultBuilder.Fail($"Failed when looking ahead: {failedResult}", state); } diff --git a/CanonSharp.Combinator/Parsers/Modifiers/ReverseParser.cs b/CanonSharp.Combinator/Parsers/Modifiers/ReverseParser.cs index 14655f5..c6518bc 100644 --- a/CanonSharp.Combinator/Parsers/Modifiers/ReverseParser.cs +++ b/CanonSharp.Combinator/Parsers/Modifiers/ReverseParser.cs @@ -12,15 +12,15 @@ namespace CanonSharp.Combinator.Parsers.Modifiers; /// 输入流的类型 /// 上游解析器结果类型 /// 最终的返回结果 -internal sealed class ReverseParser(Parser parser, T result) +internal sealed class ReverseParser(IParser parser, T result) : ModifiedParser(parser) { - protected override ParseResult Succeed(TState state, - SuccessfulResult successfulResult) + protected override IParseResult Succeed(TState state, + ISuccessfulResult successfulResult) => ParseResultBuilder.Fail($"Unexpected successful result: {successfulResult.Value}", state); - protected override ParseResult Fail(TState state, - FailedResult failedResult) + protected override IParseResult Fail(TState state, + IFailedResult failedResult) => ParseResultBuilder.Succeed(result, state); } diff --git a/CanonSharp.Combinator/Parsers/Modifiers/SuccessfulMapParser.cs b/CanonSharp.Combinator/Parsers/Modifiers/SuccessfulMapParser.cs index cfb4e0c..eb38a4d 100644 --- a/CanonSharp.Combinator/Parsers/Modifiers/SuccessfulMapParser.cs +++ b/CanonSharp.Combinator/Parsers/Modifiers/SuccessfulMapParser.cs @@ -12,15 +12,15 @@ namespace CanonSharp.Combinator.Parsers.Modifiers; /// 上游解析器解析结果类型 /// 最终的解析结果类型 internal sealed class SuccessfulMapParser( - Parser parser, + IParser parser, Func successfulHandler, - Func, T> failedHandler) : ModifiedParser(parser) + Func, T> failedHandler) : ModifiedParser(parser) { - protected override ParseResult Succeed(TState state, - SuccessfulResult successfulResult) + protected override IParseResult Succeed(TState state, + ISuccessfulResult successfulResult) => successfulResult.Map(successfulHandler); - protected override ParseResult Fail(TState state, - FailedResult failedResult) + protected override IParseResult Fail(TState state, + IFailedResult failedResult) => ParseResultBuilder.Succeed(failedHandler(failedResult), state); } diff --git a/CanonSharp.Combinator/Parsers/Modifiers/TryParser.cs b/CanonSharp.Combinator/Parsers/Modifiers/TryParser.cs index 88c0ab6..cc87e13 100644 --- a/CanonSharp.Combinator/Parsers/Modifiers/TryParser.cs +++ b/CanonSharp.Combinator/Parsers/Modifiers/TryParser.cs @@ -11,13 +11,13 @@ namespace CanonSharp.Combinator.Parsers.Modifiers; /// 处理失败结果的恢复函数 /// 输入流令牌 /// 解析器返回结果类型 -internal sealed class TryParser(Parser parser, Func, T> resume) +internal sealed class TryParser(IParser parser, Func, T> resume) : ModifiedParser(parser) { - protected override ParseResult Succeed(TState state, - SuccessfulResult successfulResult) + protected override IParseResult Succeed(TState state, + ISuccessfulResult successfulResult) => successfulResult; - protected override ParseResult Fail(TState state, FailedResult failedResult) + protected override IParseResult Fail(TState state, IFailedResult failedResult) => ParseResultBuilder.Succeed(resume(failedResult), state); } diff --git a/CanonSharp.Combinator/Parsers/PrimitiveParser.cs b/CanonSharp.Combinator/Parsers/PrimitiveParser.cs index c53fb82..10c5b1c 100644 --- a/CanonSharp.Combinator/Parsers/PrimitiveParser.cs +++ b/CanonSharp.Combinator/Parsers/PrimitiveParser.cs @@ -8,7 +8,7 @@ namespace CanonSharp.Combinator.Parsers; /// /// 输入流类型 /// 解析结果的类型 -public abstract class PrimitiveParser : Parser +public abstract class PrimitiveParser : IParser { /// /// 运行解析器 返回解析结果 @@ -16,10 +16,11 @@ public abstract class PrimitiveParser : Parser /// 当前输入流的状态 /// 输入流状态的类型 /// 解析结果 - protected abstract ParseResult Run(TState state) + protected abstract IParseResult Run(TState state) where TState : IReadState; - internal sealed override ParseResult Run(TState state, - Func, ParseResult> continuation) + public IParseResult Run(TState state, + Func, IParseResult> continuation) + where TState : IReadState => continuation(Run(state)); } diff --git a/CanonSharp.Combinator/Parsers/Primitives/FailedParser.cs b/CanonSharp.Combinator/Parsers/Primitives/FailedParser.cs index 4477e9c..7f746c1 100644 --- a/CanonSharp.Combinator/Parsers/Primitives/FailedParser.cs +++ b/CanonSharp.Combinator/Parsers/Primitives/FailedParser.cs @@ -9,7 +9,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives; /// 解析结果的类型 internal sealed class FailedParser : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) => ParseResultBuilder.Fail(state); } @@ -21,7 +21,7 @@ internal sealed class FailedParser : PrimitiveParser /// 解析结果的类型 internal sealed class FailedParserWithMessage(string message) : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) => ParseResultBuilder.Fail(message, state); } @@ -34,7 +34,7 @@ internal sealed class FailedParserWithMessage(string message) : Primi internal sealed class FailedParserWithDelayedMessage(Func, string> messageFunc) : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) => ParseResultBuilder.Fail(messageFunc(state), state); } @@ -46,6 +46,6 @@ internal sealed class FailedParserWithDelayedMessage(Func解析结果的类型 internal sealed class FailedParserWithException(Exception e) : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) => ParseResultBuilder.Fail(e, state); } diff --git a/CanonSharp.Combinator/Parsers/Primitives/PureParser.cs b/CanonSharp.Combinator/Parsers/Primitives/PureParser.cs index 6ded706..dcead7a 100644 --- a/CanonSharp.Combinator/Parsers/Primitives/PureParser.cs +++ b/CanonSharp.Combinator/Parsers/Primitives/PureParser.cs @@ -10,7 +10,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives; /// 解析成功返回值的类型 internal sealed class PureParser(T value) : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) => ParseResultBuilder.Succeed(value, state); } @@ -22,6 +22,6 @@ internal sealed class PureParser(T value) : PrimitiveParser解析成功返回值的类型 internal sealed class DelayedPureParser(Func, T> valueFunc) : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) => ParseResultBuilder.Succeed(valueFunc(state), state); } diff --git a/CanonSharp.Combinator/Parsers/Primitives/SatisfyParser.cs b/CanonSharp.Combinator/Parsers/Primitives/SatisfyParser.cs index 25ec82c..37805f6 100644 --- a/CanonSharp.Combinator/Parsers/Primitives/SatisfyParser.cs +++ b/CanonSharp.Combinator/Parsers/Primitives/SatisfyParser.cs @@ -9,7 +9,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives; /// 输入流类型 internal sealed class SatisfyParser(Func predicate) : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) { return state.HasValue && predicate(state.Current) ? ParseResultBuilder.Succeed(state.Current, state.Next) diff --git a/CanonSharp.Combinator/Parsers/Primitives/SkipParser.cs b/CanonSharp.Combinator/Parsers/Primitives/SkipParser.cs index ffa1061..bb82c81 100644 --- a/CanonSharp.Combinator/Parsers/Primitives/SkipParser.cs +++ b/CanonSharp.Combinator/Parsers/Primitives/SkipParser.cs @@ -10,7 +10,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives; /// 输入流类型 internal sealed class SkipParser(int count) : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) { List result = state.AsEnumerable().Take(count).ToList(); diff --git a/CanonSharp.Combinator/Parsers/Primitives/TakeParser.cs b/CanonSharp.Combinator/Parsers/Primitives/TakeParser.cs index 670c7c0..fe876d0 100644 --- a/CanonSharp.Combinator/Parsers/Primitives/TakeParser.cs +++ b/CanonSharp.Combinator/Parsers/Primitives/TakeParser.cs @@ -10,7 +10,7 @@ namespace CanonSharp.Combinator.Parsers.Primitives; /// 输入流类型 internal sealed class TakeParser(int count) : PrimitiveParser> { - protected override ParseResult> Run(TState state) + protected override IParseResult> Run(TState state) { List result = state.AsEnumerable().Take(count).ToList(); diff --git a/CanonSharp.Combinator/Results/FailedResultWithError.cs b/CanonSharp.Combinator/Results/FailedResultWithError.cs index 14efb87..fb5bbec 100644 --- a/CanonSharp.Combinator/Results/FailedResultWithError.cs +++ b/CanonSharp.Combinator/Results/FailedResultWithError.cs @@ -8,14 +8,14 @@ namespace CanonSharp.Combinator.Results; /// 输入流的类型 /// 输入流的读取类型 /// 实际的结果类型 -internal sealed class FailedResultWithError(TState state) : FailedResult +internal sealed class FailedResultWithError(TState state) : IFailedResult where TState : IReadState { - public override IReadState State => state; + public IReadState State => state; - public override string Message => $"Unexpected state: {state}."; + public string Message => $"Unexpected state: {state}."; - public override FailedResult Convert() + public IFailedResult Convert() { return new FailedResultWithError(state); } diff --git a/CanonSharp.Combinator/Results/FailedResultWithException.cs b/CanonSharp.Combinator/Results/FailedResultWithException.cs index 85005c5..39bb609 100644 --- a/CanonSharp.Combinator/Results/FailedResultWithException.cs +++ b/CanonSharp.Combinator/Results/FailedResultWithException.cs @@ -10,15 +10,15 @@ namespace CanonSharp.Combinator.Results; /// 输入流类型 /// 当前输入流状态的类型 /// 解析结果的类型 -public class FailedResultWithException(Exception exception, TState state) : FailedResult +public class FailedResultWithException(Exception exception, TState state) : IFailedResult where TState : IReadState { - public override IReadState State => state; + public IReadState State => state; - public override ParseException Exception => new(ToString(), exception); + public ParseException Exception => new(ToString(), exception); - public override string Message => $"Exception occured: {exception}."; + public string Message => $"Exception occured: {exception}."; - public override FailedResult Convert() + public IFailedResult Convert() => new FailedResultWithException(exception, state); } diff --git a/CanonSharp.Combinator/Results/FailedResultWithMessage.cs b/CanonSharp.Combinator/Results/FailedResultWithMessage.cs index d28bc2f..c870244 100644 --- a/CanonSharp.Combinator/Results/FailedResultWithMessage.cs +++ b/CanonSharp.Combinator/Results/FailedResultWithMessage.cs @@ -10,14 +10,14 @@ namespace CanonSharp.Combinator.Results; /// 输入流的类型 /// 读取状态类型 /// 解析结果的类型 -internal sealed class FailedResultWithMessage(string message, TState state) : FailedResult +internal sealed class FailedResultWithMessage(string message, TState state) : IFailedResult where TState : IReadState { - public override IReadState State => state; + public IReadState State => state; - public override string Message => message; + public string Message => message; - public override FailedResult Convert() + public IFailedResult Convert() { return new FailedResultWithMessage(message, state); } diff --git a/CanonSharp.Combinator/Results/InternalSuccessfulResult.cs b/CanonSharp.Combinator/Results/InternalSuccessfulResult.cs index 3934453..3658d1c 100644 --- a/CanonSharp.Combinator/Results/InternalSuccessfulResult.cs +++ b/CanonSharp.Combinator/Results/InternalSuccessfulResult.cs @@ -11,13 +11,15 @@ namespace CanonSharp.Combinator.Results; /// 输入流的状态类型 /// 解析结果的类型 internal sealed class InternalSuccessfulResult(T result, TState state) - : SuccessfulResult(result) + : ISuccessfulResult where TState : IReadState { - protected override ParseResult RunNext(Parser parser, - Func, ParseResult> continuation) + public T Value => result; + + public IParseResult RunNext(IParser parser, + Func, IParseResult> continuation) => parser.Run(state, continuation); - public override ParseResult Map(Func map) + public IParseResult Map(Func map) => new InternalSuccessfulResult(map(Value), state); } diff --git a/CanonSharp.Combinator/Text/StringParser.cs b/CanonSharp.Combinator/Text/StringParser.cs index 1d20dd8..9d67174 100644 --- a/CanonSharp.Combinator/Text/StringParser.cs +++ b/CanonSharp.Combinator/Text/StringParser.cs @@ -11,7 +11,7 @@ namespace CanonSharp.Combinator.Text; /// 字符串比较模式 public class StringParser(string except, StringComparison comparison) : PrimitiveParser { - protected override ParseResult Run(TState state) + protected override IParseResult Run(TState state) { TState[] states = state.AsEnumerable().Take(except.Length).ToArray(); string actual = new(states.Select(x => x.Current).ToArray()); diff --git a/CanonSharp.Combinator/Text/TextParserBuilder.cs b/CanonSharp.Combinator/Text/TextParserBuilder.cs index 2ca83db..921df85 100644 --- a/CanonSharp.Combinator/Text/TextParserBuilder.cs +++ b/CanonSharp.Combinator/Text/TextParserBuilder.cs @@ -13,7 +13,7 @@ public static class TextParserBuilder /// 识别的单个字符 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Char(char token) => Satisfy(x => x == token); + public static IParser Char(char token) => Satisfy(x => x == token); /// /// 忽略大小写识别单个字符 @@ -21,7 +21,7 @@ public static class TextParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser CharIgnoreCase(char token) => + public static IParser CharIgnoreCase(char token) => Satisfy(x => char.ToUpperInvariant(x) == char.ToUpperInvariant(token)); /// @@ -30,7 +30,7 @@ public static class TextParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser OneOf(string candidate) => Satisfy(candidate.Contains); + public static IParser OneOf(string candidate) => Satisfy(candidate.Contains); /// /// 忽略大小写识别字符串中的一个字符 @@ -38,7 +38,7 @@ public static class TextParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser OneOfIgnoreCase(string candidate) => + public static IParser OneOfIgnoreCase(string candidate) => Satisfy(x => candidate.Contains(x, StringComparison.OrdinalIgnoreCase)); /// @@ -48,7 +48,7 @@ public static class TextParserBuilder /// 字符串比较方法 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser String(string except, StringComparison comparison) => + public static IParser String(string except, StringComparison comparison) => new StringParser(except, comparison); /// @@ -57,7 +57,7 @@ public static class TextParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser String(string except) => String(except, StringComparison.Ordinal); + public static IParser String(string except) => String(except, StringComparison.Ordinal); /// /// 忽略大小写识别一个字符串 @@ -65,7 +65,7 @@ public static class TextParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser StringIgnoreCase(string except) => + public static IParser StringIgnoreCase(string except) => String(except, StringComparison.OrdinalIgnoreCase); /// @@ -75,28 +75,28 @@ public static class TextParserBuilder /// 包括的终止字符 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Range(char start, char end) => Satisfy(x => x >= start && x <= end); + public static IParser Range(char start, char end) => Satisfy(x => x >= start && x <= end); /// /// 识别Unicode字符类别的解析器 /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Letter() => Satisfy(char.IsLetter); + public static IParser Letter() => Satisfy(char.IsLetter); /// /// 识别Unicode数字类别的解析器 /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Digit() => Satisfy(char.IsDigit); + public static IParser Digit() => Satisfy(char.IsDigit); /// /// 识别ASCII字符类别的解析器 /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser AsciiLetter() => + public static IParser AsciiLetter() => Satisfy(x => x is >= 'a' and <= 'z' or >= 'A' and <= 'Z'); /// @@ -104,20 +104,20 @@ public static class TextParserBuilder /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser AsciiDigit() => Satisfy(x => x is >= '0' and <= '9'); + public static IParser AsciiDigit() => Satisfy(x => x is >= '0' and <= '9'); /// /// 识别Unicode空白类型的字符 /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser Space() => Satisfy(char.IsWhiteSpace); + public static IParser Space() => Satisfy(char.IsWhiteSpace); /// /// 识别所有的换行符 /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Parser LineBreak() => + public static IParser LineBreak() => OneOf("\u000D\u000A\u0085\u2028\u2029\n").Map(x => x.ToString()) | String("\r\n"); } diff --git a/CanonSharp.Combinator/Text/TextParserExtensions.cs b/CanonSharp.Combinator/Text/TextParserExtensions.cs index 77df384..09516aa 100644 --- a/CanonSharp.Combinator/Text/TextParserExtensions.cs +++ b/CanonSharp.Combinator/Text/TextParserExtensions.cs @@ -6,9 +6,9 @@ namespace CanonSharp.Combinator.Text; public static class TextParserExtensions { - public static Parser SkipSpaces(this Parser parser) + public static IParser SkipSpaces(this IParser parser) => Space().SkipTill(parser); - public static Parser SkipSpaceAndLineBreak(this Parser parser) + public static IParser SkipSpaceAndLineBreak(this IParser parser) => (Space().Map(x => x.ToString()) | LineBreak()).SkipTill(parser); } diff --git a/CanonSharp.Common/CanonSharp.Common.csproj b/CanonSharp.Pascal/CanonSharp.Pascal.csproj similarity index 86% rename from CanonSharp.Common/CanonSharp.Common.csproj rename to CanonSharp.Pascal/CanonSharp.Pascal.csproj index 4359b8a..f2b8c9f 100644 --- a/CanonSharp.Common/CanonSharp.Common.csproj +++ b/CanonSharp.Pascal/CanonSharp.Pascal.csproj @@ -4,6 +4,7 @@ net8.0 enable enable + CanonSharp.Common @@ -15,8 +16,4 @@ - - - - diff --git a/CanonSharp.Common/Scanner/LexicalScanner.cs b/CanonSharp.Pascal/Scanner/LexicalScanner.cs similarity index 78% rename from CanonSharp.Common/Scanner/LexicalScanner.cs rename to CanonSharp.Pascal/Scanner/LexicalScanner.cs index 4ad4c1e..e84b7c8 100644 --- a/CanonSharp.Common/Scanner/LexicalScanner.cs +++ b/CanonSharp.Pascal/Scanner/LexicalScanner.cs @@ -4,11 +4,11 @@ using CanonSharp.Combinator.Extensions; using static CanonSharp.Combinator.Text.TextParserBuilder; using static CanonSharp.Combinator.ParserBuilder; -namespace CanonSharp.Common.Scanner; +namespace CanonSharp.Pascal.Scanner; public sealed class LexicalScanner { - private readonly Parser> _parser = PascalParser(); + private readonly IParser> _parser = PascalParser(); public IEnumerable Tokenize(TState state) where TState : IReadState @@ -16,7 +16,7 @@ public sealed class LexicalScanner return _parser.Parse(state).Value; } - public static Parser KeywordParser() + public static IParser KeywordParser() { return from value in Choice(StringIgnoreCase("program"), StringIgnoreCase("const"), @@ -49,16 +49,16 @@ public sealed class LexicalScanner select new LexicalToken(LexicalTokenType.Keyword, value); } - public static Parser DelimiterParser() + public static IParser DelimiterParser() { - Parser semicolonParser = from token in Char(':') + IParser semicolonParser = from token in Char(':') from _ in Char('=').LookAhead().Not() select new LexicalToken(LexicalTokenType.Delimiter, token.ToString()); - Parser periodParser = from token in Char('.') + IParser periodParser = from token in Char('.') from _ in Char('.').LookAhead().Not() select new LexicalToken(LexicalTokenType.Delimiter, "."); - Parser singleCharTokenParser = from token in Choice( + IParser singleCharTokenParser = from token in Choice( String(","), String(";"), String("("), @@ -71,17 +71,17 @@ public sealed class LexicalScanner return singleCharTokenParser | semicolonParser | periodParser; } - public static Parser OperatorParser() + public static IParser OperatorParser() { - Parser lessParser = from token in Char('<') + IParser lessParser = from token in Char('<') from _ in Char('=').LookAhead().Not() select new LexicalToken(LexicalTokenType.Operator, "<"); - Parser greaterParser = from token in Char('>') + IParser greaterParser = from token in Char('>') from _ in Char('=').LookAhead().Not() select new LexicalToken(LexicalTokenType.Operator, ">"); - Parser otherParsers = from token in Choice( + IParser otherParsers = from token in Choice( String("="), String("!="), String("<="), @@ -96,14 +96,14 @@ public sealed class LexicalScanner return otherParsers | lessParser | greaterParser; } - public static Parser ConstIntegerParser() + public static IParser ConstIntegerParser() { return from nums in AsciiDigit().Many1() from _ in Char('.').LookAhead().Not() select new LexicalToken(LexicalTokenType.ConstInteger, new string(nums.ToArray())); } - public static Parser ConstFloatParser() + public static IParser ConstFloatParser() { return from integer in AsciiDigit().Many1() from _ in Char('.') @@ -112,24 +112,24 @@ public sealed class LexicalScanner new string(integer.ToArray()) + '.' + new string(fraction.ToArray())); } - public static Parser IdentifierParser() + public static IParser IdentifierParser() { return from first in AsciiLetter() | Char('_') from second in (AsciiLetter() | AsciiDigit() | Char('_')).Many() select new LexicalToken(LexicalTokenType.Identifier, first + new string(second.ToArray())); } - public static Parser CommentParser() + public static IParser CommentParser() { return Any().Quote(Char('{'), Char('}')).Map(_ => Unit.Instance); } - public static Parser JunkParser() + public static IParser JunkParser() { return Space().Map(_ => Unit.Instance) | LineBreak().Map(_ => Unit.Instance) | CommentParser(); } - public static Parser CharParser() + public static IParser CharParser() { return from str in Any().Quote(Char('\'')).Map(x => new string(x.ToArray())) select str.Length <= 1 @@ -137,7 +137,7 @@ public sealed class LexicalScanner : new LexicalToken(LexicalTokenType.String, str); } - public static Parser> PascalParser() + public static IParser> PascalParser() { return JunkParser().SkipTill(Choice(KeywordParser(), DelimiterParser(), diff --git a/CanonSharp.Common/Scanner/LexicalToken.cs b/CanonSharp.Pascal/Scanner/LexicalToken.cs similarity index 95% rename from CanonSharp.Common/Scanner/LexicalToken.cs rename to CanonSharp.Pascal/Scanner/LexicalToken.cs index 1733ade..28e9f6c 100644 --- a/CanonSharp.Common/Scanner/LexicalToken.cs +++ b/CanonSharp.Pascal/Scanner/LexicalToken.cs @@ -1,4 +1,4 @@ -namespace CanonSharp.Common.Scanner; +namespace CanonSharp.Pascal.Scanner; public enum LexicalTokenType { diff --git a/CanonSharp.Common/Scanner/StringReadState.cs b/CanonSharp.Pascal/Scanner/StringReadState.cs similarity index 97% rename from CanonSharp.Common/Scanner/StringReadState.cs rename to CanonSharp.Pascal/Scanner/StringReadState.cs index 15ce837..0475996 100644 --- a/CanonSharp.Common/Scanner/StringReadState.cs +++ b/CanonSharp.Pascal/Scanner/StringReadState.cs @@ -1,6 +1,6 @@ using CanonSharp.Combinator.Abstractions; -namespace CanonSharp.Common.Scanner; +namespace CanonSharp.Pascal.Scanner; /// /// 字符串输入流状态 diff --git a/CanonSharp.Tests/CanonSharp.Tests.csproj b/CanonSharp.Tests/CanonSharp.Tests.csproj index d5d6a25..19c1429 100644 --- a/CanonSharp.Tests/CanonSharp.Tests.csproj +++ b/CanonSharp.Tests/CanonSharp.Tests.csproj @@ -23,7 +23,7 @@ - + diff --git a/CanonSharp.Tests/CombinatorsTests/BasicParsersTests.cs b/CanonSharp.Tests/CombinatorsTests/BasicParsersTests.cs index 8abb6e7..fe4d3b9 100644 --- a/CanonSharp.Tests/CombinatorsTests/BasicParsersTests.cs +++ b/CanonSharp.Tests/CombinatorsTests/BasicParsersTests.cs @@ -11,7 +11,7 @@ public class BasicParsersTests : ParserTestsBase [Fact] public void AlternativeTest() { - Parser parser = Token('a') | Token('b'); + IParser parser = Token('a') | Token('b'); ValidateSuccessfulResult(parser, 'a', "abc"); ValidateSuccessfulResult(parser, 'b', "bcd"); @@ -26,7 +26,7 @@ public class BasicParsersTests : ParserTestsBase [Fact] public void BindTest() { - Parser parser = Token('a').Bind(_ => Token('b')).Bind(_ => Token('c')); + IParser parser = Token('a').Bind(_ => Token('b')).Bind(_ => Token('c')); ValidateSuccessfulResult(parser, 'c', "abc"); ValidateFailedResult(parser, "acd"); @@ -36,7 +36,7 @@ public class BasicParsersTests : ParserTestsBase [Fact] public void MapTest() { - Parser parser = Token('a').Map(c => $"{c}"); + IParser parser = Token('a').Map(c => $"{c}"); ValidateSuccessfulResult(parser, "a", "abc"); parser = Token('a').Map("test"); @@ -46,7 +46,7 @@ public class BasicParsersTests : ParserTestsBase [Fact] public void NextTest() { - Parser parser = Token('a').Next(_ => Token('a'), _ => Token('b')); + IParser parser = Token('a').Next(_ => Token('a'), _ => Token('b')); ValidateSuccessfulResult(parser, 'a', "aaa"); ValidateSuccessfulResult(parser, 'b', "bbb"); @@ -61,7 +61,7 @@ public class BasicParsersTests : ParserTestsBase [Fact] public void NextTest2() { - Parser parser = Token('a').Next(_ => "123", _ => Pure("456")); + IParser parser = Token('a').Next(_ => "123", _ => Pure("456")); ValidateSuccessfulResult(parser, "123", "aaa"); ValidateSuccessfulResult(parser, "456", "bbb"); @@ -77,7 +77,7 @@ public class BasicParsersTests : ParserTestsBase [Fact] public void FixTest() { - Parser parser = Fix(self => Token('a').Next(_ => self, Unit.Instance)) + IParser parser = Fix(self => Token('a').Next(_ => self, Unit.Instance)) .Bind(_ => Token('b')); ValidateSuccessfulResult(parser, 'b', "aaaaab"); } diff --git a/CanonSharp.Tests/CombinatorsTests/CombinatorParserTests.cs b/CanonSharp.Tests/CombinatorsTests/CombinatorParserTests.cs index b70d3be..247f980 100644 --- a/CanonSharp.Tests/CombinatorsTests/CombinatorParserTests.cs +++ b/CanonSharp.Tests/CombinatorsTests/CombinatorParserTests.cs @@ -11,7 +11,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void ChoiceTest() { - Parser parser = Choice(Token('a'), Token('b'), Token('c')); + IParser parser = Choice(Token('a'), Token('b'), Token('c')); ValidateSuccessfulResult(parser, 'a', "abc"); ValidateSuccessfulResult(parser, 'b', "bcd"); ValidateSuccessfulResult(parser, 'c', "cde"); @@ -25,10 +25,10 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void SequenceTest() { - Parser> parser = Sequence(Token('a'), Token('b'), Token('c')); + IParser> parser = Sequence(Token('a'), Token('b'), Token('c')); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "abc"); - IEnumerable> parsers = [Token('a'), Token('b'), Token('c')]; + IEnumerable> parsers = [Token('a'), Token('b'), Token('c')]; parser = Sequence(parsers); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "abc"); } @@ -36,7 +36,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void LeftRightTest() { - Parser parser = Token('a').Left(Token('b')); + IParser parser = Token('a').Left(Token('b')); ValidateSuccessfulResult(parser, 'a', "ab"); parser = Token('a').Right(Token('b')); @@ -46,7 +46,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void ManyTest() { - Parser> parser = Token('a').Many(); + IParser> parser = Token('a').Many(); ValidateSuccessfulResult(parser, [], "bbb"); ValidateSuccessfulResult(parser, ['a', 'a', 'a'], "aaa"); @@ -58,7 +58,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void SkipManyTest() { - Parser parser = Token('a').SkipMany().Right(Token('b')); + IParser parser = Token('a').SkipMany().Right(Token('b')); ValidateSuccessfulResult(parser, 'b', "aaaab"); ValidateSuccessfulResult(parser, 'b', "bbbb"); @@ -72,7 +72,7 @@ public class CombinatorParserTests : ParserTestsBase { // 等效于Many1 // 但是不返回中间结果 - Parser parser = Token('a').Chain(Token); + IParser parser = Token('a').Chain(Token); ValidateSuccessfulResult(parser, 'a', "aa"); ValidateFailedResult(parser, "bb"); @@ -84,7 +84,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void ManyTillTest() { - Parser> parser = Token('a').ManyTill(Token('b').LookAhead()); + IParser> parser = Token('a').ManyTill(Token('b').LookAhead()); ValidateSuccessfulResult(parser, ['a', 'a', 'a'], "aaab"); ValidateSuccessfulResult(parser, [], "b"); @@ -96,7 +96,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void SkipTillTest() { - Parser parser = Token('a').SkipTill(Token('b')); + IParser parser = Token('a').SkipTill(Token('b')); ValidateSuccessfulResult(parser, 'b', "aaab"); ValidateSuccessfulResult(parser, 'b', "b"); @@ -108,7 +108,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void TakeTillTest() { - Parser> parser = TakeTill(Token('b').LookAhead()); + IParser> parser = TakeTill(Token('b').LookAhead()); ValidateSuccessfulResult(parser, ['a', 'a'], "aab"); ValidateSuccessfulResult(parser, [], "b"); @@ -120,7 +120,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void MatchTest() { - Parser parser = Token('b').Match(); + IParser parser = Token('b').Match(); ValidateSuccessfulResult(parser, 'b', "asdfasdfasdfasdfb"); ValidateSuccessfulResult(parser, 'b', "b"); } @@ -128,7 +128,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void QuoteTest() { - Parser> parser = Any().Quote(Token('['), Token(']')); + IParser> parser = Any().Quote(Token('['), Token(']')); ValidateSuccessfulResult(parser, ['1', '2', '3'], "[123]"); parser = Any().Quote(Token('\'')); @@ -138,7 +138,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void SeparatedByTest() { - Parser> parser = Token('a').SeparatedBy(Token(',')); + IParser> parser = Token('a').SeparatedBy(Token(',')); ValidateSuccessfulResult(parser, ['a', 'a', 'a'], "a,a,a"); ValidateSuccessfulResult(parser, ['a'], "a"); ValidateSuccessfulResult(parser, [], ""); @@ -152,7 +152,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void EndByTest() { - Parser> parser = Satisfy(char.IsLetter).EndBy(Token('.')); + IParser> parser = Satisfy(char.IsLetter).EndBy(Token('.')); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "abc."); ValidateSuccessfulResult(parser, [], "."); @@ -164,7 +164,7 @@ public class CombinatorParserTests : ParserTestsBase [Fact] public void SeparatedOrEndByTest() { - Parser> parser = Satisfy(char.IsLetter).SeparatedOrEndBy1(Token(',')); + IParser> parser = Satisfy(char.IsLetter).SeparatedOrEndBy1(Token(',')); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "a,b,c,"); ValidateSuccessfulResult(parser, ['a', 'b', 'c'], "a,b,c"); ValidateFailedResult(parser, ""); diff --git a/CanonSharp.Tests/CombinatorsTests/LinqTests.cs b/CanonSharp.Tests/CombinatorsTests/LinqTests.cs index 8aaffa0..d6fde40 100644 --- a/CanonSharp.Tests/CombinatorsTests/LinqTests.cs +++ b/CanonSharp.Tests/CombinatorsTests/LinqTests.cs @@ -10,7 +10,7 @@ public class LinqTests : ParserTestsBase [Fact] public void SelectTest1() { - Parser parser = from token in Char('a') + IParser parser = from token in Char('a') select token.ToString(); ValidateSuccessfulResult(parser, "a", "a"); ValidateFailedResult(parser, "b"); @@ -19,7 +19,7 @@ public class LinqTests : ParserTestsBase [Fact] public void SelectManyTest1() { - Parser parser = from _1 in Char('a') + IParser parser = from _1 in Char('a') from _2 in Char('b') from _3 in Char('c') select 123; diff --git a/CanonSharp.Tests/CombinatorsTests/ModifierParserTests.cs b/CanonSharp.Tests/CombinatorsTests/ModifierParserTests.cs index 498fcda..1f47bc7 100644 --- a/CanonSharp.Tests/CombinatorsTests/ModifierParserTests.cs +++ b/CanonSharp.Tests/CombinatorsTests/ModifierParserTests.cs @@ -12,7 +12,7 @@ public class ModifierParserTests : ParserTestsBase [Fact] public void DoTest() { - Parser parser = Token('a').Do(x => Assert.Equal('a', x)).Do(x => Assert.Equal('a', x), + IParser parser = Token('a').Do(x => Assert.Equal('a', x)).Do(x => Assert.Equal('a', x), failedResult => Assert.ThrowsAny(() => failedResult.Value)); ValidateSuccessfulResult(parser, 'a', "abc"); @@ -22,7 +22,7 @@ public class ModifierParserTests : ParserTestsBase [Fact] public void LookAheadTest() { - Parser parser = Token('a').LookAhead().Next(_ => Token('a'), _ => Token('b')); + IParser parser = Token('a').LookAhead().Next(_ => Token('a'), _ => Token('b')); ValidateSuccessfulResult(parser, 'a', "abc"); ValidateSuccessfulResult(parser, 'b', "bcd"); } @@ -30,7 +30,7 @@ public class ModifierParserTests : ParserTestsBase [Fact] public void NotTest() { - Parser parser = Token('a').Not('b'); + IParser parser = Token('a').Not('b'); ValidateSuccessfulResult(parser, 'b', "bcd"); parser = Token('a').Not().Bind(_ => Token('b')); @@ -40,7 +40,7 @@ public class ModifierParserTests : ParserTestsBase [Fact] public void TryTest() { - Parser parser = String("abc").Try("cde"); + IParser parser = String("abc").Try("cde"); ValidateSuccessfulResult(parser, "abc", "abc"); ValidateSuccessfulResult(parser, "cde", "cde"); diff --git a/CanonSharp.Tests/CombinatorsTests/PrimitiveParserTests.cs b/CanonSharp.Tests/CombinatorsTests/PrimitiveParserTests.cs index 39d1825..6702458 100644 --- a/CanonSharp.Tests/CombinatorsTests/PrimitiveParserTests.cs +++ b/CanonSharp.Tests/CombinatorsTests/PrimitiveParserTests.cs @@ -11,7 +11,7 @@ public class PrimitiveParserTests : ParserTestsBase [Fact] public void PureTest() { - Parser parser = Pure('a'); + IParser parser = Pure('a'); ValidateSuccessfulResult(parser, 'a', "abc"); parser = Pure(_ => 'a'); @@ -21,18 +21,18 @@ public class PrimitiveParserTests : ParserTestsBase [Fact] public void NullTest() { - Parser parser = Null(); + IParser parser = Null(); ValidateSuccessfulResult(parser, Unit.Instance, "abc"); } [Fact] public void FailTest() { - Parser parser = Fail(); + IParser parser = Fail(); ValidateFailedResult(parser, "abc"); parser = Fail("Failed message"); - FailedResult result = ValidateFailedResult(parser, "abc"); + IFailedResult result = ValidateFailedResult(parser, "abc"); Assert.Equal("Failed message", result.Message); parser = Fail(x => $"{x}"); @@ -47,7 +47,7 @@ public class PrimitiveParserTests : ParserTestsBase [Fact] public void SatisfyTest() { - Parser parser = Satisfy(char.IsLetter); + IParser parser = Satisfy(char.IsLetter); ValidateSuccessfulResult(parser, 'a', "abc"); ValidateFailedResult(parser, "123"); } @@ -55,28 +55,28 @@ public class PrimitiveParserTests : ParserTestsBase [Fact] public void SatisfyFailedTest() { - Parser parser = Satisfy(char.IsLetter); + IParser parser = Satisfy(char.IsLetter); ValidateFailedResult(parser, ""); } [Fact] public void AnyTest() { - Parser parser = Any(); + IParser parser = Any(); ValidateSuccessfulResult(parser, '1', "123"); } [Fact] public void TokenTest() { - Parser parser = Token('a'); + IParser parser = Token('a'); ValidateSuccessfulResult(parser, 'a', "abc"); } [Fact] public void TakeTest() { - Parser> parser = Take(5); + IParser> parser = Take(5); ValidateSuccessfulResult(parser, ['h', 'e', 'l', 'l', 'o'], "hello"); ValidateFailedResult(parser, "abc"); } @@ -84,7 +84,7 @@ public class PrimitiveParserTests : ParserTestsBase [Fact] public void SkipTest() { - Parser parser = Skip(5).Bind(_ => Token(',')); + IParser parser = Skip(5).Bind(_ => Token(',')); ValidateSuccessfulResult(parser, ',', "hello,world."); ValidateFailedResult(parser, "abc"); } diff --git a/CanonSharp.Tests/ReaderTests/StringReadStateTests.cs b/CanonSharp.Tests/ReaderTests/StringReadStateTests.cs index 4aeeb8d..2f0a426 100644 --- a/CanonSharp.Tests/ReaderTests/StringReadStateTests.cs +++ b/CanonSharp.Tests/ReaderTests/StringReadStateTests.cs @@ -1,5 +1,5 @@ using CanonSharp.Combinator.Extensions; -using CanonSharp.Common.Scanner; +using CanonSharp.Pascal.Scanner; namespace CanonSharp.Tests.LexicalAnalyzerTests; diff --git a/CanonSharp.Tests/ScannerTest/LexicalParserTests.cs b/CanonSharp.Tests/ScannerTest/LexicalParserTests.cs index 4bd0d84..bddc9cf 100644 --- a/CanonSharp.Tests/ScannerTest/LexicalParserTests.cs +++ b/CanonSharp.Tests/ScannerTest/LexicalParserTests.cs @@ -1,4 +1,4 @@ -using CanonSharp.Common.Scanner; +using CanonSharp.Pascal.Scanner; using CanonSharp.Tests.Utils; namespace CanonSharp.Tests.ScannerTest; diff --git a/CanonSharp.Tests/ScannerTest/LexicalTokenParserTest.cs b/CanonSharp.Tests/ScannerTest/LexicalTokenParserTest.cs index 9f939d2..7665088 100644 --- a/CanonSharp.Tests/ScannerTest/LexicalTokenParserTest.cs +++ b/CanonSharp.Tests/ScannerTest/LexicalTokenParserTest.cs @@ -1,7 +1,7 @@ using CanonSharp.Combinator; using CanonSharp.Combinator.Abstractions; using CanonSharp.Combinator.Extensions; -using CanonSharp.Common.Scanner; +using CanonSharp.Pascal.Scanner; using CanonSharp.Tests.Utils; namespace CanonSharp.Tests.ScannerTest; @@ -29,7 +29,7 @@ public class LexicalTokenParserTest : LexicalTestBase [InlineData("while")] public void KeywordParserTest(string literalValue) { - Parser keyword = LexicalScanner.KeywordParser(); + IParser keyword = LexicalScanner.KeywordParser(); ValidateSuccessfulParser(keyword, LexicalTokenType.Keyword, literalValue, literalValue); } @@ -39,7 +39,7 @@ public class LexicalTokenParserTest : LexicalTestBase [InlineData("todo")] public void FailedKeywordParserTest(string input) { - Parser keyword = LexicalScanner.KeywordParser(); + IParser keyword = LexicalScanner.KeywordParser(); ValidateFailedParser(keyword, input); } @@ -55,7 +55,7 @@ public class LexicalTokenParserTest : LexicalTestBase [InlineData("..")] public void DelimiterParserTest(string literalValue) { - Parser delimiter = LexicalScanner.DelimiterParser(); + IParser delimiter = LexicalScanner.DelimiterParser(); ValidateSuccessfulParser(delimiter, LexicalTokenType.Delimiter, literalValue, literalValue); } @@ -63,7 +63,7 @@ public class LexicalTokenParserTest : LexicalTestBase [InlineData(":=")] public void FailedDelimiterParserTest(string input) { - Parser delimiter = LexicalScanner.DelimiterParser(); + IParser delimiter = LexicalScanner.DelimiterParser(); ValidateFailedParser(delimiter, input); } @@ -81,7 +81,7 @@ public class LexicalTokenParserTest : LexicalTestBase [InlineData(":=")] public void OperatorParserTest(string literalValue) { - Parser operatorParser = LexicalScanner.OperatorParser(); + IParser operatorParser = LexicalScanner.OperatorParser(); ValidateSuccessfulParser(operatorParser, LexicalTokenType.Operator, literalValue, literalValue); } @@ -94,7 +94,7 @@ public class LexicalTokenParserTest : LexicalTestBase [InlineData("andand")] public void IdentifierParserTest(string literalValue) { - Parser identifier = LexicalScanner.IdentifierParser(); + IParser identifier = LexicalScanner.IdentifierParser(); ValidateSuccessfulParser(identifier, LexicalTokenType.Identifier, literalValue, literalValue); } @@ -105,7 +105,7 @@ public class LexicalTokenParserTest : LexicalTestBase public void ConstIntegerTest(int value, string input) { StringReadState state = new(input); - ParseResult result = LexicalScanner.ConstIntegerParser().Parse(state); + IParseResult result = LexicalScanner.ConstIntegerParser().Parse(state); Assert.Equal(LexicalTokenType.ConstInteger, result.Value.TokenType); Assert.Equal(value, int.Parse(result.Value.LiteralValue)); @@ -117,7 +117,7 @@ public class LexicalTokenParserTest : LexicalTestBase public void ConstFloatTest(double value, string input) { StringReadState state = new(input); - ParseResult result = LexicalScanner.ConstFloatParser().Parse(state); + IParseResult result = LexicalScanner.ConstFloatParser().Parse(state); Assert.Equal(LexicalTokenType.ConstFloat, result.Value.TokenType); Assert.Equal(value, double.Parse(result.Value.LiteralValue)); @@ -129,7 +129,7 @@ public class LexicalTokenParserTest : LexicalTestBase public void CharTest(char value, string input) { StringReadState state = new(input); - ParseResult result = LexicalScanner.CharParser().Parse(state); + IParseResult result = LexicalScanner.CharParser().Parse(state); Assert.Equal(LexicalTokenType.Character, result.Value.TokenType); Assert.Equal(value, char.Parse(result.Value.LiteralValue)); @@ -140,7 +140,7 @@ public class LexicalTokenParserTest : LexicalTestBase public void StringTest(string value, string input) { StringReadState state = new(input); - ParseResult result = LexicalScanner.CharParser().Parse(state); + IParseResult result = LexicalScanner.CharParser().Parse(state); Assert.Equal(LexicalTokenType.String, result.Value.TokenType); Assert.Equal(value, result.Value.LiteralValue); @@ -152,7 +152,7 @@ public class LexicalTokenParserTest : LexicalTestBase public void CommentTest(string input) { StringReadState state = new(input); - ParseResult result = LexicalScanner.CommentParser().Parse(state); + IParseResult result = LexicalScanner.CommentParser().Parse(state); Assert.Equal(Unit.Instance, result.Value); } @@ -168,8 +168,8 @@ public class LexicalTokenParserTest : LexicalTestBase public void JunkTest(string input) { StringReadState state = new(input); - Parser parser = LexicalScanner.JunkParser().SkipTill(LexicalScanner.KeywordParser()); - ParseResult result = parser.Parse(state); + IParser parser = LexicalScanner.JunkParser().SkipTill(LexicalScanner.KeywordParser()); + IParseResult result = parser.Parse(state); Assert.Equal(LexicalTokenType.Keyword, result.Value.TokenType); Assert.Equal("program", result.Value.LiteralValue); diff --git a/CanonSharp.Tests/TextTests/TextParserTests.cs b/CanonSharp.Tests/TextTests/TextParserTests.cs index d39f5d7..00bb448 100644 --- a/CanonSharp.Tests/TextTests/TextParserTests.cs +++ b/CanonSharp.Tests/TextTests/TextParserTests.cs @@ -1,7 +1,7 @@ using CanonSharp.Combinator.Abstractions; using CanonSharp.Combinator.Extensions; using CanonSharp.Combinator.Text; -using CanonSharp.Common.Scanner; +using CanonSharp.Pascal.Scanner; using CanonSharp.Tests.Utils; using static CanonSharp.Combinator.Text.TextParserBuilder; @@ -24,7 +24,7 @@ public class TextParserTests : ParserTestsBase [InlineData('d', "d")] public void OneOfTest(char except, string input) { - Parser parser = OneOf("abcd"); + IParser parser = OneOf("abcd"); ValidateSuccessfulResult(parser, except, input); } @@ -39,7 +39,7 @@ public class TextParserTests : ParserTestsBase [InlineData('D', "D")] public void OneOfIgnoreCaseTest(char except, string input) { - Parser parser = OneOfIgnoreCase("abcd"); + IParser parser = OneOfIgnoreCase("abcd"); ValidateSuccessfulResult(parser, except, input); } @@ -50,7 +50,7 @@ public class TextParserTests : ParserTestsBase [InlineData("Hello,World.")] public void StringIgnoreCaseTest(string literalValue) { - Parser parser = StringIgnoreCase("hello,world."); + IParser parser = StringIgnoreCase("hello,world."); ValidateSuccessfulResult(parser, literalValue, literalValue); } @@ -60,7 +60,7 @@ public class TextParserTests : ParserTestsBase [InlineData('9')] public void RangeTest(char except) { - Parser parser = Range('0', '9'); + IParser parser = Range('0', '9'); ValidateSuccessfulResult(parser, except, except.ToString()); ValidateFailedResult(parser, "abc"); @@ -161,8 +161,8 @@ public class TextParserTests : ParserTestsBase test """); - Parser> parser = StringIgnoreCase("test").SkipSpaceAndLineBreak().Many(); - ParseResult> result = parser.Parse(state); + IParser> parser = StringIgnoreCase("test").SkipSpaceAndLineBreak().Many(); + IParseResult> result = parser.Parse(state); Assert.All(result.Value, x => Assert.Equal("test", x.ToLower())); } diff --git a/CanonSharp.Tests/Utils/LexicalTestBase.cs b/CanonSharp.Tests/Utils/LexicalTestBase.cs index fdb9657..ac521a8 100644 --- a/CanonSharp.Tests/Utils/LexicalTestBase.cs +++ b/CanonSharp.Tests/Utils/LexicalTestBase.cs @@ -1,33 +1,33 @@ using CanonSharp.Combinator; using CanonSharp.Combinator.Abstractions; -using CanonSharp.Common.Scanner; +using CanonSharp.Pascal.Scanner; namespace CanonSharp.Tests.Utils; public abstract class LexicalTestBase { - protected static void ValidateSuccessfulParser(Parser parser, LexicalTokenType exceptedType, + protected static void ValidateSuccessfulParser(IParser parser, LexicalTokenType exceptedType, string literalValue, string input) { StringReadState state = new(input); - ParseResult result = parser.Parse(state); + IParseResult result = parser.Parse(state); Assert.Equal(exceptedType, result.Value.TokenType); Assert.Equal(literalValue, result.Value.LiteralValue); } - protected static void ValidateFailedParser(Parser parser, string input) + protected static void ValidateFailedParser(IParser parser, string input) { StringReadState state = new(input); - ParseResult result = parser.Parse(state); + IParseResult result = parser.Parse(state); Assert.ThrowsAny(() => result.Value); } - protected static void ValidateLexicalTokens(Parser> parser, string input, + protected static void ValidateLexicalTokens(IParser> parser, string input, IEnumerable<(LexicalTokenType, string)> exceptedResult) { StringReadState state = new(input); - ParseResult> result = parser.Parse(state); + IParseResult> result = parser.Parse(state); foreach (((LexicalTokenType exceptedType, string exceptedValue), LexicalToken token) in exceptedResult.Zip( result.Value)) diff --git a/CanonSharp.Tests/Utils/ParserTestsBase.cs b/CanonSharp.Tests/Utils/ParserTestsBase.cs index 49949ff..31f8e14 100644 --- a/CanonSharp.Tests/Utils/ParserTestsBase.cs +++ b/CanonSharp.Tests/Utils/ParserTestsBase.cs @@ -1,26 +1,26 @@ using CanonSharp.Combinator; using CanonSharp.Combinator.Abstractions; -using CanonSharp.Common.Scanner; +using CanonSharp.Pascal.Scanner; namespace CanonSharp.Tests.Utils; public abstract class ParserTestsBase { - protected static void ValidateSuccessfulResult(Parser parser, T value, string source) + protected static void ValidateSuccessfulResult(IParser parser, T value, string source) { StringReadState state = new(source); - ParseResult result = parser.Parse(state); + IParseResult result = parser.Parse(state); Assert.Equal(value, result.Value); } protected static void ValidateSuccessfulResult( - Parser> parser, + IParser> parser, IEnumerable values, string source) { StringReadState state = new(source); - ParseResult> result = parser.Parse(state); + IParseResult> result = parser.Parse(state); foreach ((T actual, T except) in result.Value.Zip(values)) { @@ -28,16 +28,16 @@ public abstract class ParserTestsBase } } - protected static FailedResult ValidateFailedResult(Parser parser, string source) + protected static IFailedResult ValidateFailedResult(IParser parser, string source) { StringReadState state = new(source); - ParseResult result = parser.Parse(state); + IParseResult result = parser.Parse(state); Assert.ThrowsAny(() => { _ = result.Value; }); - return (FailedResult)result; + return (IFailedResult)result; } } diff --git a/CanonSharp.sln b/CanonSharp.sln index fea8a09..592439b 100644 --- a/CanonSharp.sln +++ b/CanonSharp.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CanonSharp.Tests", "CanonSharp.Tests\CanonSharp.Tests.csproj", "{5A28EF92-805F-44E9-8E13-EA9A5BB623BB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CanonSharp.Common", "CanonSharp.Common\CanonSharp.Common.csproj", "{288943FE-E3E6-49E2-8C6F-9B5B9242266C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CanonSharp.Pascal", "CanonSharp.Pascal\CanonSharp.Pascal.csproj", "{288943FE-E3E6-49E2-8C6F-9B5B9242266C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".gitea", ".gitea", "{B97A35A0-4616-4B3F-8F73-A66827BC98BA}" EndProject