diff --git a/src/Superpower/ParserExtensions.cs b/src/Superpower/ParserExtensions.cs index 2f25f3e..baf242b 100644 --- a/src/Superpower/ParserExtensions.cs +++ b/src/Superpower/ParserExtensions.cs @@ -115,5 +115,63 @@ public static bool IsMatch(this TextParser parser, TextSpan input) var result = parser(input); return result.HasValue && result.Remainder.IsAtEnd; } + + /// + /// Attempts the parser and invokes the exceptionHandler if the parser throws . + /// + /// The type of tokens consumed by the parser. + /// The type of the result. + /// The parser. + /// A function that handles and returns a . + /// A parser that calls the first parser and handles by calling the exception handler. + /// Thrown if either the parser or the exceptionHandler is null. + public static TokenListParser Catch(this TokenListParser parser, Func> exceptionHandler) + { + if (parser == null) throw new ArgumentNullException(nameof(parser)); + if (exceptionHandler == null) throw new ArgumentNullException(nameof(exceptionHandler)); + + return input => + { + try + { + return parser(input); + } + catch (ParseException ex) + { + return exceptionHandler(ex); + } + }; + } + + /// + /// Attempts the parser and invokes the exceptionHandler if the parser throws TException. + /// + /// The type of tokens consumed by the parser. + /// The type of the result. + /// The type of exception caught and handled by + /// The parser. + /// A function that handles TException and returns a . + /// A parser that calls the first parser and handles TException by calling the exception handler. + /// Thrown if either the parser or the exceptionHandler is null. + public static TokenListParser Catch( + this TokenListParser parser, + Func> exceptionHandler) + where TException : Exception + { + if (parser == null) throw new ArgumentNullException(nameof(parser)); + if (exceptionHandler == null) throw new ArgumentNullException(nameof(exceptionHandler)); + + return input => + { + try + { + return parser(input); + } + catch (TException ex) + { + return exceptionHandler(ex); + } + }; + } } }