Make RegexParseException and RegexParseError public, rename enum fields (#40902)
authorAbel Braaksma <abel.online@xs4all.nl>
Mon, 17 Aug 2020 22:25:22 +0000 (00:25 +0200)
committerGitHub <noreply@github.com>
Mon, 17 Aug 2020 22:25:22 +0000 (15:25 -0700)
* RegexParseException, RegexParseError public, rename enum fields

* Add Unknown field to RegexParseError

* Add definitions to ref file

* Satisfy NET48 tests

* Some nits to resolve review comments

* Add default message and Unknown message

* Added doc comments

* Fix nit in auto-layout change of csproj file

* Simplify message for RegexParseException ctor overload

* Remove PlatformDetection.IsNetFramework in RegexParserTests.cs

* Rename resource names to match the enum names

* Use partial class and methods to separate netfx and core

* Add offset tests

* Apply suggestions from code review

Nits

* Add remaining test offsets. Verify all offsets.

* Nit and TFM

* Update src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
* Update src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
* Update src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs

Co-authored-by: Stephen Toub <stoub@microsoft.com>
* Code review: properly test for deserialized type of exn

* Code review: fix doc comments

* Code review: fix doc comments

* Code review: offset gt zero

* Code review: add some tests, remove redundant whiteline

* Code review: add doc comment as suggested

* Code review: fix doc comments

* ref edits with tool

* Code review: some nits

* Remove using

* Rename unknown

* Incorrect edit in AssertExtensions

* Cherry-pick #d4090296

* Fix naming, ref file, resource strings

Co-authored-by: Dan Moseley <danmose@microsoft.com>
Co-authored-by: Prashanth Govindarajan <prgovi@microsoft.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs
src/libraries/System.Text.RegularExpressions/ref/System.Text.RegularExpressions.cs
src/libraries/System.Text.RegularExpressions/src/Resources/Strings.resx
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexCharClass.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParseError.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParseException.cs
src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexParser.cs
src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.cs
src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs [new file with mode: 0644]
src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs [new file with mode: 0644]
src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Tests.csproj

index dea97ee..ec648c7 100644 (file)
@@ -209,7 +209,7 @@ namespace System
                 if (exceptionTypes.Any(t => t.Equals(exceptionType)))
                     return;
 
-                throw new XunitException($"Expected one of: ({string.Join<Type>(", ", exceptionTypes)}) -> Actual: ({e.GetType()})");
+                throw new XunitException($"Expected one of: ({string.Join<Type>(", ", exceptionTypes)}) -> Actual: ({exceptionType})");
             }
 
             throw new XunitException($"Expected one of: ({string.Join<Type>(", ", exceptionTypes)}) -> Actual: No exception thrown");
index d25af2a..e048a2e 100644 (file)
@@ -241,6 +241,48 @@ namespace System.Text.RegularExpressions
         ECMAScript = 256,
         CultureInvariant = 512,
     }
+    public enum RegexParseError
+    {
+        Unknown = 0,
+        AlternationHasTooManyConditions = 1,
+        AlternationHasMalformedCondition = 2,
+        InvalidUnicodePropertyEscape = 3,
+        MalformedUnicodePropertyEscape = 4,
+        UnrecognizedEscape = 5,
+        UnrecognizedControlCharacter = 6,
+        MissingControlCharacter = 7,
+        InsufficientOrInvalidHexDigits = 8,
+        QuantifierOrCaptureGroupOutOfRange = 9,
+        UndefinedNamedReference = 10,
+        UndefinedNumberedReference = 11,
+        MalformedNamedReference = 12,
+        UnescapedEndingBackslash = 13,
+        UnterminatedComment = 14,
+        InvalidGroupingConstruct = 15,
+        AlternationHasNamedCapture = 16,
+        AlternationHasComment = 17,
+        AlternationHasMalformedReference = 18,
+        AlternationHasUndefinedReference = 19,
+        CaptureGroupNameInvalid = 20,
+        CaptureGroupOfZero = 21,
+        UnterminatedBracket = 22,
+        ExclusionGroupNotLast = 23,
+        ReversedCharacterRange = 24,
+        ShorthandClassInCharacterRange = 25,
+        InsufficientClosingParentheses = 26,
+        ReversedQuantifierRange = 27,
+        NestedQuantifiersNotParenthesized = 28,
+        QuantifierAfterNothing = 29,
+        InsufficientOpeningParentheses = 30,
+        UnrecognizedUnicodeProperty = 31,
+    }
+    public sealed partial class RegexParseException : System.ArgumentException
+    {
+        private RegexParseException() { }
+        public System.Text.RegularExpressions.RegexParseError Error { get { throw null; } }
+        public int Offset { get { throw null; } }
+        public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
+    }
     public abstract partial class RegexRunner
     {
         protected internal int[]? runcrawl;
index 06943ac..ef01f52 100644 (file)
   <resheader name="writer">
     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <data name="AlternationCantCapture" xml:space="preserve">
+  <data name="Generic" xml:space="preserve">
+    <value>Regular expression parser error '{0}' at offset {1}.</value>
+  </data>
+  <data name="AlternationHasNamedCapture" xml:space="preserve">
     <value>Alternation conditions do not capture and cannot be named.</value>
   </data>
-  <data name="AlternationCantHaveComment" xml:space="preserve">
+  <data name="AlternationHasComment" xml:space="preserve">
     <value>Alternation conditions cannot be comments.</value>
   </data>
   <data name="Arg_ArrayPlusOffTooSmall" xml:space="preserve">
   <data name="ArgumentNull_ArrayWithNullElements" xml:space="preserve">
     <value>The array cannot contain null elements.</value>
   </data>
-  <data name="BadClassInCharRange" xml:space="preserve">
+  <data name="ShorthandClassInCharacterRange" xml:space="preserve">
     <value>Cannot include class \\{0} in character range.</value>
   </data>
+  <data name="ShorthandClassInCharacterRangeNoPlaceholder" xml:space="preserve">
+    <value>Cannot include class in character range.</value>
+  </data>
   <data name="BeginIndexNotNegative" xml:space="preserve">
     <value>Start index cannot be less than 0 or greater than input length.</value>
   </data>
-  <data name="CaptureGroupOutOfRange" xml:space="preserve">
+  <data name="QuantifierOrCaptureGroupOutOfRange" xml:space="preserve">
     <value>Capture group numbers must be less than or equal to Int32.MaxValue.</value>
   </data>
-  <data name="CapnumNotZero" xml:space="preserve">
+  <data name="CaptureGroupOfZero" xml:space="preserve">
     <value>Capture number cannot be zero.</value>
   </data>
   <data name="CountTooSmall" xml:space="preserve">
   <data name="EnumNotStarted" xml:space="preserve">
     <value>Enumeration has either not started or has already finished.</value>
   </data>
-  <data name="IllegalCondition" xml:space="preserve">
+  <data name="AlternationHasMalformedCondition" xml:space="preserve">
     <value>Illegal conditional (?(...)) expression.</value>
   </data>
   <data name="IllegalDefaultRegexMatchTimeoutInAppDomain" xml:space="preserve">
     <value>AppDomain data '{0}' contains the invalid value or object '{1}' for specifying a default matching timeout for System.Text.RegularExpressions.Regex.</value>
   </data>
-  <data name="IllegalEndEscape" xml:space="preserve">
+  <data name="UnescapedEndingBackslash" xml:space="preserve">
     <value>Illegal \\ at end of pattern.</value>
   </data>
-  <data name="IllegalRange" xml:space="preserve">
+  <data name="ReversedQuantifierRange" xml:space="preserve">
     <value>Illegal {x,y} with x &gt; y.</value>
   </data>
-  <data name="IncompleteSlashP" xml:space="preserve">
+  <data name="InvalidUnicodePropertyEscape" xml:space="preserve">
     <value>Incomplete \\p{X} character escape.</value>
   </data>
   <data name="InternalError_ScanRegex" xml:space="preserve">
     <value>Internal error in ScanRegex.</value>
   </data>
-  <data name="InvalidGroupName" xml:space="preserve">
+  <data name="CaptureGroupNameInvalid" xml:space="preserve">
     <value>Invalid group name: Group names must begin with a word character.</value>
   </data>
   <data name="InvalidEmptyArgument" xml:space="preserve">
   <data name="LengthNotNegative" xml:space="preserve">
     <value>Length cannot be less than 0 or exceed input length.</value>
   </data>
-  <data name="MalformedNameRef" xml:space="preserve">
+  <data name="MalformedNamedReference" xml:space="preserve">
     <value>Malformed \\k&lt;...&gt; named back reference.</value>
   </data>
-  <data name="MalformedReference" xml:space="preserve">
+  <data name="AlternationHasMalformedReference" xml:space="preserve">
     <value>(?({0}) ) malformed.</value>
   </data>
-  <data name="MalformedSlashP" xml:space="preserve">
+  <data name="AlternationHasMalformedReferenceNoPlaceholder" xml:space="preserve">
+    <value>Alternation has malformed reference.</value>
+  </data>
+  <data name="MalformedUnicodePropertyEscape" xml:space="preserve">
     <value>Malformed \\p{X} character escape.</value>
   </data>
   <data name="MakeException" xml:space="preserve">
     <value>Invalid pattern '{0}' at offset {1}. {2}</value>
   </data>
-  <data name="MissingControl" xml:space="preserve">
+  <data name="MissingControlCharacter" xml:space="preserve">
     <value>Missing control character.</value>
   </data>
-  <data name="NestedQuantify" xml:space="preserve">
+  <data name="NestedQuantifiersNotParenthesized" xml:space="preserve">
     <value>Nested quantifier '{0}'.</value>
   </data>
+  <data name="NestedQuantifiersNotParenthesizedNoPlaceholder" xml:space="preserve">
+    <value>Nested quantifier no parenthesized.</value>
+  </data>
   <data name="NoResultOnFailed" xml:space="preserve">
     <value>Result cannot be called on a failed Match.</value>
   </data>
-  <data name="NotEnoughParens" xml:space="preserve">
+  <data name="InsufficientClosingParentheses" xml:space="preserve">
     <value>Not enough )'s.</value>
   </data>
   <data name="NotSupported_ReadOnlyCollection" xml:space="preserve">
   <data name="PlatformNotSupported_CompileToAssembly" xml:space="preserve">
     <value>This platform does not support writing compiled regular expressions to an assembly.</value>
   </data>
-  <data name="QuantifyAfterNothing" xml:space="preserve">
+  <data name="QuantifierAfterNothing" xml:space="preserve">
     <value>Quantifier {x,y} following nothing.</value>
   </data>
   <data name="RegexMatchTimeoutException_Occurred" xml:space="preserve">
   <data name="ReplacementError" xml:space="preserve">
     <value>Replacement pattern error.</value>
   </data>
-  <data name="ReversedCharRange" xml:space="preserve">
+  <data name="ReversedCharacterRange" xml:space="preserve">
     <value>[x-y] range in reverse order.</value>
   </data>
-  <data name="SubtractionMustBeLast" xml:space="preserve">
+  <data name="ExclusionGroupNotLast" xml:space="preserve">
     <value>A subtraction must be the last element in a character class.</value>
   </data>
-  <data name="TooFewHex" xml:space="preserve">
+  <data name="InsufficientOrInvalidHexDigits" xml:space="preserve">
     <value>Insufficient hexadecimal digits.</value>
   </data>
-  <data name="TooManyAlternates" xml:space="preserve">
+  <data name="AlternationHasTooManyConditions" xml:space="preserve">
     <value>Too many | in (?()|).</value>
   </data>
-  <data name="TooManyParens" xml:space="preserve">
+  <data name="InsufficientOpeningParentheses" xml:space="preserve">
     <value>Too many )'s.</value>
   </data>
-  <data name="UndefinedBackref" xml:space="preserve">
+  <data name="UndefinedNumberedReference" xml:space="preserve">
     <value>Reference to undefined group number {0}.</value>
   </data>
-  <data name="UndefinedNameRef" xml:space="preserve">
+  <data name="UndefinedNumberedReferenceNoPlaceholder" xml:space="preserve">
+    <value>Reference to undefined group number.</value>
+  </data>
+  <data name="UndefinedNamedReference" xml:space="preserve">
     <value>Reference to undefined group name '{0}'.</value>
   </data>
-  <data name="UndefinedReference" xml:space="preserve">
+  <data name="UndefinedNamedReferenceNoPlaceholder" xml:space="preserve">
+    <value>Reference to undefined group name.</value>
+  </data>
+  <data name="AlternationHasUndefinedReference" xml:space="preserve">
     <value>(?({0}) ) reference to undefined group.</value>
   </data>
+  <data name="AlternationHasUndefinedReferenceNoPlaceholder" xml:space="preserve">
+    <value>Alternation has a reference to undefined group.</value>
+  </data>
   <data name="UnexpectedOpcode" xml:space="preserve">
     <value>Unexpected opcode in regular expression generation: {0}.</value>
   </data>
-  <data name="UnknownProperty" xml:space="preserve">
+  <data name="UnrecognizedUnicodeProperty" xml:space="preserve">
     <value>Unknown property '{0}'.</value>
   </data>
-  <data name="UnrecognizedControl" xml:space="preserve">
+  <data name="UnrecognizedUnicodePropertyNoPlaceholder" xml:space="preserve">
+    <value>Unknown property Unicode property.</value>
+  </data>
+  <data name="UnrecognizedControlCharacter" xml:space="preserve">
     <value>Unrecognized control character.</value>
   </data>
   <data name="UnrecognizedEscape" xml:space="preserve">
     <value>Unrecognized escape sequence \\{0}.</value>
   </data>
-  <data name="UnrecognizedGrouping" xml:space="preserve">
+  <data name="InvalidGroupingConstruct" xml:space="preserve">
     <value>Unrecognized grouping construct.</value>
   </data>
   <data name="UnterminatedBracket" xml:space="preserve">
index 840f895..d4022f6 100644 (file)
@@ -1515,8 +1515,8 @@ namespace System.Text.RegularExpressions
                 }
             }
 
-            throw new RegexParseException(RegexParseError.UnknownUnicodeProperty, currentPos,
-                SR.Format(SR.MakeException, pattern, currentPos, SR.Format(SR.UnknownProperty, capname)));
+            throw new RegexParseException(RegexParseError.UnrecognizedUnicodeProperty, currentPos,
+                SR.Format(SR.MakeException, pattern, currentPos, SR.Format(SR.UnrecognizedUnicodeProperty, capname)));
         }
 
 #if DEBUG
index 6f930e6..108d1cb 100644 (file)
 
 namespace System.Text.RegularExpressions
 {
-    internal enum RegexParseError
+    /// <summary>
+    /// Specifies the detailed underlying reason why a <see cref="RegexParseException"/> is thrown when a
+    /// regular expression contains a parsing error.
+    /// </summary>
+    /// <remarks>
+    /// This information is made available through <see cref="RegexParseException.Error"/>.
+    /// </remarks>
+    public enum RegexParseError
     {
-        TooManyAlternates,
-        IllegalCondition,
-        IncompleteSlashP,
-        MalformedSlashP,
+        /// <summary>
+        /// An unknown regular expression parse error.
+        /// </summary>
+        Unknown,
+        /// <summary>
+        /// An alternation in a regular expression has too many conditions.
+        /// </summary>
+        AlternationHasTooManyConditions,
+        /// <summary>
+        /// An alternation in a regular expression has a malformed condition.
+        /// </summary>
+        AlternationHasMalformedCondition,
+        /// <summary>
+        /// A Unicode property escape in a regular expression is invalid or unknown.
+        /// </summary>
+        InvalidUnicodePropertyEscape,
+        /// <summary>
+        /// A Unicode property escape is malformed.
+        /// </summary>
+        MalformedUnicodePropertyEscape,
+        /// <summary>
+        /// An escape character or sequence in a regular expression is invalid.
+        /// </summary>
         UnrecognizedEscape,
-        UnrecognizedControl,
-        MissingControl,
-        TooFewHex,
-        CaptureGroupOutOfRange,
-        UndefinedNameRef,
-        UndefinedBackref,
-        MalformedNameRef,
-        IllegalEndEscape,
+        /// <summary>
+        /// A control character in a regular expression is not recognized.
+        /// </summary>
+        UnrecognizedControlCharacter,
+        /// <summary>
+        /// A control character in a regular expression is missing.
+        /// </summary>
+        MissingControlCharacter,
+        /// <summary>
+        /// A hexadecimal escape sequence in a regular expression does not have enough digits, or contains invalid digits.
+        /// </summary>
+        InsufficientOrInvalidHexDigits,
+        /// <summary>
+        /// A captured group or a quantifier in a regular expression is not within range, that is, it is larger than <see cref="int.MaxValue"/>.
+        /// </summary>
+        QuantifierOrCaptureGroupOutOfRange,
+        /// <summary>
+        /// A used named reference in a regular expression is not defined.
+        /// </summary>
+        UndefinedNamedReference,
+        /// <summary>
+        /// A used numbered reference in a regular expression is not defined.
+        /// </summary>
+        UndefinedNumberedReference,
+        /// <summary>
+        /// A named reference in a regular expression is malformed.
+        /// </summary>
+        MalformedNamedReference,
+        /// <summary>
+        /// A regular expression ends with a non-escaped ending backslash.
+        /// </summary>
+        UnescapedEndingBackslash,
+        /// <summary>
+        /// A comment in a regular expression is not terminated.
+        /// </summary>
         UnterminatedComment,
-        UnrecognizedGrouping,
-        AlternationCantCapture,
-        AlternationCantHaveComment,
-        MalformedReference,
-        UndefinedReference,
-        InvalidGroupName,
-        CapnumNotZero,
+        /// <summary>
+        /// A grouping construct in a regular expression is invalid or malformed.
+        /// </summary>
+        InvalidGroupingConstruct,
+        /// <summary>
+        /// An alternation construct in a regular expression uses a named capture.
+        /// </summary>
+        AlternationHasNamedCapture,
+        /// <summary>
+        /// An alternation construct in a regular expression contains a comment.
+        /// </summary>
+        AlternationHasComment,
+        /// <summary>
+        /// An alternation construct in a regular expression contains a malformed reference.
+        /// </summary>
+        AlternationHasMalformedReference,
+        /// <summary>
+        /// An alternation construct in a regular expression contains an undefined reference.
+        /// </summary>
+        AlternationHasUndefinedReference,
+        /// <summary>
+        /// The group name of a captured group in a regular expression is invalid.
+        /// </summary>
+        CaptureGroupNameInvalid,
+        /// <summary>
+        /// A regular expression defines a numbered subexpression named zero.
+        /// </summary>
+        CaptureGroupOfZero,
+        /// <summary>
+        /// A regular expression has a non-escaped left square bracket, or misses a closing right square bracket.
+        /// </summary>
         UnterminatedBracket,
-        SubtractionMustBeLast,
-        ReversedCharRange,
-        BadClassInCharRange,
-        NotEnoughParentheses,
-        IllegalRange,
-        NestedQuantify,
-        QuantifyAfterNothing,
-        TooManyParentheses,
-        UnknownUnicodeProperty
+        /// <summary>
+        /// A character class in a regular expression with an exclusion group is not the last part of the character class.
+        /// </summary>
+        ExclusionGroupNotLast,
+        /// <summary>
+        /// A character class in a regular expression contains an inverse character range, like z-a instead of a-z.
+        /// </summary>
+        ReversedCharacterRange,
+        /// <summary>
+        /// A character-class in a regular expression contains a short-hand class that is not allowed inside a character class.
+        /// </summary>
+        ShorthandClassInCharacterRange,
+        /// <summary>
+        /// A regular expression has a non-escaped left parenthesis, or misses a closing right parenthesis.
+        /// </summary>
+        InsufficientClosingParentheses,
+        /// <summary>
+        /// A quantifier range in a regular expression is inverse, like <code>{10,1}</code> instead of <code>(1,10}</code>.
+        /// </summary>
+        ReversedQuantifierRange,
+        /// <summary>
+        /// Repeated quantifiers on another quantifier inside a regular expression are not grouped in parentheses.
+        /// </summary>
+        NestedQuantifiersNotParenthesized,
+        /// <summary>
+        /// A quantifier in a regular expression is in a position where it cannot quantify anything, like at the beginning of a regular expression or in a group.
+        /// </summary>
+        QuantifierAfterNothing,
+        /// <summary>
+        /// A regular expression has a non-escaped right parenthesis, or misses an opening left parenthesis.
+        /// </summary>
+        InsufficientOpeningParentheses,
+        /// <summary>
+        /// A unicode property in a regular expression is not recognized, or invalid.
+        /// </summary>
+        UnrecognizedUnicodeProperty
     }
 }
index 3682911..a013805 100644 (file)
@@ -5,23 +5,152 @@ using System.Runtime.Serialization;
 
 namespace System.Text.RegularExpressions
 {
+    /// <summary>
+    /// An exception as a result of a parse error in a regular expression <see cref="RegularExpressions"/>, with
+    /// detailed information in the <see cref="Error"/> and <see cref="Offset"/> properties.
+    /// </summary>
     [Serializable]
-    internal sealed class RegexParseException : ArgumentException
+    public sealed class RegexParseException : ArgumentException
     {
-        private readonly RegexParseError _error; // tests access this via private reflection
-
         /// <summary>Gets the error that happened during parsing.</summary>
-        public RegexParseError Error => _error;
+        public RegexParseError Error { get; }
 
-        /// <summary>Gets the offset in the supplied pattern.</summary>
+        /// <summary>Gets the zero-based character offset in the regular expression pattern where the parse error occurs.</summary>
         public int Offset { get; }
 
-        public RegexParseException(RegexParseError error, int offset, string message) : base(message)
+        internal RegexParseException(RegexParseError error, int offset, string message) : base(message)
+        {
+            Error = error;
+            Offset = offset;
+        }
+
+        internal RegexParseException(string pattern, RegexParseError error, int offset) : base(MakeMessage(pattern, error, offset))
         {
-            _error = error;
+            Error = error;
             Offset = offset;
         }
 
+        /// <summary>
+        /// Construct a <see cref="RegexParseException"/> that creates a default message based on the given <see cref="RegexParseError"/> value.
+        /// </summary>
+        /// <param name="pattern">The pattern of the regular expression.</param>
+        /// <param name="error">The <see cref="RegexParseError"/> value detailing the type of parse error.</param>
+        /// <param name="offset">The zero-based offset in the regular expression where the parse error occurs.</param>
+        private static string MakeMessage(string pattern, RegexParseError error, int offset)
+        {
+            string message;
+            switch (error)
+            {
+                case RegexParseError.Unknown:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.Generic);
+                    break;
+                case RegexParseError.AlternationHasTooManyConditions:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.AlternationHasTooManyConditions);
+                    break;
+                case RegexParseError.AlternationHasMalformedCondition:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.AlternationHasMalformedCondition);
+                    break;
+                case RegexParseError.InvalidUnicodePropertyEscape:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.InvalidUnicodePropertyEscape);
+                    break;
+                case RegexParseError.MalformedUnicodePropertyEscape:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.MalformedUnicodePropertyEscape);
+                    break;
+                case RegexParseError.UnrecognizedEscape:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.UnrecognizedEscape);
+                    break;
+                case RegexParseError.UnrecognizedControlCharacter:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.UnrecognizedControlCharacter);
+                    break;
+                case RegexParseError.MissingControlCharacter:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.MissingControlCharacter);
+                    break;
+                case RegexParseError.InsufficientOrInvalidHexDigits:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.InsufficientOrInvalidHexDigits);
+                    break;
+                case RegexParseError.QuantifierOrCaptureGroupOutOfRange:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.QuantifierOrCaptureGroupOutOfRange);
+                    break;
+                case RegexParseError.UndefinedNamedReference:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.UndefinedNamedReferenceNoPlaceholder);
+                    break;
+                case RegexParseError.UndefinedNumberedReference:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.UndefinedNumberedReferenceNoPlaceholder);
+                    break;
+                case RegexParseError.MalformedNamedReference:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.MalformedNamedReference);
+                    break;
+                case RegexParseError.UnescapedEndingBackslash:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.UnescapedEndingBackslash);
+                    break;
+                case RegexParseError.UnterminatedComment:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.UnterminatedComment);
+                    break;
+                case RegexParseError.InvalidGroupingConstruct:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.InvalidGroupingConstruct);
+                    break;
+                case RegexParseError.AlternationHasNamedCapture:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.AlternationHasNamedCapture);
+                    break;
+                case RegexParseError.AlternationHasComment:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.AlternationHasComment);
+                    break;
+                case RegexParseError.AlternationHasMalformedReference:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.AlternationHasMalformedReferenceNoPlaceholder);
+                    break;
+                case RegexParseError.AlternationHasUndefinedReference:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.AlternationHasUndefinedReferenceNoPlaceholder);
+                    break;
+                case RegexParseError.CaptureGroupNameInvalid:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.CaptureGroupNameInvalid);
+                    break;
+                case RegexParseError.CaptureGroupOfZero:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.CaptureGroupOfZero);
+                    break;
+                case RegexParseError.UnterminatedBracket:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.UnterminatedBracket);
+                    break;
+                case RegexParseError.ExclusionGroupNotLast:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.ExclusionGroupNotLast);
+                    break;
+                case RegexParseError.ReversedCharacterRange:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.ReversedCharacterRange);
+                    break;
+                case RegexParseError.ShorthandClassInCharacterRange:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.ShorthandClassInCharacterRangeNoPlaceholder);
+                    break;
+                case RegexParseError.InsufficientClosingParentheses:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.InsufficientClosingParentheses);
+                    break;
+                case RegexParseError.ReversedQuantifierRange:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.ReversedQuantifierRange);
+                    break;
+                case RegexParseError.NestedQuantifiersNotParenthesized:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.NestedQuantifiersNotParenthesizedNoPlaceholder);
+                    break;
+                case RegexParseError.QuantifierAfterNothing:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.QuantifierAfterNothing);
+                    break;
+                case RegexParseError.InsufficientOpeningParentheses:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.InsufficientOpeningParentheses);
+                    break;
+                case RegexParseError.UnrecognizedUnicodeProperty:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.UnrecognizedUnicodePropertyNoPlaceholder);
+                    break;
+                default:
+                    message = SR.Format(SR.MakeException, pattern, offset, SR.Generic);
+                    break;
+            }
+
+            return message;
+        }
+
+        private RegexParseException(SerializationInfo info, StreamingContext context)
+        {
+            // It means someone modified the payload.
+            throw new NotImplementedException();
+        }
+
         public override void GetObjectData(SerializationInfo info, StreamingContext context)
         {
             base.GetObjectData(info, context);
index cb051da..fae6d58 100644 (file)
@@ -350,7 +350,7 @@ namespace System.Text.RegularExpressions
                     case ')':
                         if (EmptyStack())
                         {
-                            throw MakeException(RegexParseError.TooManyParentheses, SR.TooManyParens);
+                            throw MakeException(RegexParseError.InsufficientOpeningParentheses, SR.InsufficientOpeningParentheses);
                         }
 
                         AddGroup();
@@ -366,7 +366,7 @@ namespace System.Text.RegularExpressions
                     case '\\':
                         if (CharsRight() == 0)
                         {
-                            throw MakeException(RegexParseError.IllegalEndEscape, SR.IllegalEndEscape);
+                            throw MakeException(RegexParseError.UnescapedEndingBackslash, SR.UnescapedEndingBackslash);
                         }
 
                         AddUnitNode(ScanBackslash(scanOnly: false)!);
@@ -398,8 +398,8 @@ namespace System.Text.RegularExpressions
                         if (Unit() == null)
                         {
                             throw wasPrevQuantifier ?
-                                MakeException(RegexParseError.NestedQuantify, SR.Format(SR.NestedQuantify, ch)) :
-                                MakeException(RegexParseError.QuantifyAfterNothing, SR.QuantifyAfterNothing);
+                                MakeException(RegexParseError.NestedQuantifiersNotParenthesized, SR.Format(SR.NestedQuantifiersNotParenthesized, ch)) :
+                                MakeException(RegexParseError.QuantifierAfterNothing, SR.QuantifierAfterNothing);
                         }
                         MoveLeft();
                         break;
@@ -482,7 +482,7 @@ namespace System.Text.RegularExpressions
 
                     if (min > max)
                     {
-                        throw MakeException(RegexParseError.IllegalRange, SR.IllegalRange);
+                        throw MakeException(RegexParseError.ReversedQuantifierRange, SR.ReversedQuantifierRange);
                     }
 
                     AddConcatenate(lazy, min, max);
@@ -497,7 +497,7 @@ namespace System.Text.RegularExpressions
 
             if (!EmptyStack())
             {
-                throw MakeException(RegexParseError.NotEnoughParentheses, SR.NotEnoughParens);
+                throw MakeException(RegexParseError.InsufficientClosingParentheses, SR.InsufficientClosingParentheses);
             }
 
             AddGroup();
@@ -593,7 +593,7 @@ namespace System.Text.RegularExpressions
                             {
                                 if (inRange)
                                 {
-                                    throw MakeException(RegexParseError.BadClassInCharRange, SR.Format(SR.BadClassInCharRange, ch));
+                                    throw MakeException(RegexParseError.ShorthandClassInCharacterRange, SR.Format(SR.ShorthandClassInCharacterRange, ch));
                                 }
                                 charClass!.AddDigit(UseOptionE(), ch == 'D', _pattern, _currentPos);
                             }
@@ -605,7 +605,7 @@ namespace System.Text.RegularExpressions
                             {
                                 if (inRange)
                                 {
-                                    throw MakeException(RegexParseError.BadClassInCharRange, SR.Format(SR.BadClassInCharRange, ch));
+                                    throw MakeException(RegexParseError.ShorthandClassInCharacterRange, SR.Format(SR.ShorthandClassInCharacterRange, ch));
                                 }
                                 charClass!.AddSpace(UseOptionE(), ch == 'S');
                             }
@@ -617,7 +617,7 @@ namespace System.Text.RegularExpressions
                             {
                                 if (inRange)
                                 {
-                                    throw MakeException(RegexParseError.BadClassInCharRange, SR.Format(SR.BadClassInCharRange, ch));
+                                    throw MakeException(RegexParseError.ShorthandClassInCharacterRange, SR.Format(SR.ShorthandClassInCharacterRange, ch));
                                 }
 
                                 charClass!.AddWord(UseOptionE(), ch == 'W');
@@ -630,7 +630,7 @@ namespace System.Text.RegularExpressions
                             {
                                 if (inRange)
                                 {
-                                    throw MakeException(RegexParseError.BadClassInCharRange, SR.Format(SR.BadClassInCharRange, ch));
+                                    throw MakeException(RegexParseError.ShorthandClassInCharacterRange, SR.Format(SR.ShorthandClassInCharacterRange, ch));
                                 }
 
                                 charClass!.AddCategoryFromName(ParseProperty(), ch != 'p', caseInsensitive, _pattern, _currentPos);
@@ -648,7 +648,7 @@ namespace System.Text.RegularExpressions
                                 {
                                     if (chPrev > ch)
                                     {
-                                        throw MakeException(RegexParseError.ReversedCharRange, SR.ReversedCharRange);
+                                        throw MakeException(RegexParseError.ReversedCharacterRange, SR.ReversedCharacterRange);
                                     }
 
                                     charClass!.AddRange(chPrev, ch);
@@ -700,7 +700,7 @@ namespace System.Text.RegularExpressions
 
                             if (CharsRight() > 0 && RightChar() != ']')
                             {
-                                throw MakeException(RegexParseError.SubtractionMustBeLast, SR.SubtractionMustBeLast);
+                                throw MakeException(RegexParseError.ExclusionGroupNotLast, SR.ExclusionGroupNotLast);
                             }
                         }
                         else
@@ -708,7 +708,7 @@ namespace System.Text.RegularExpressions
                             // a regular range, like a-z
                             if (chPrev > ch)
                             {
-                                throw MakeException(RegexParseError.ReversedCharRange, SR.ReversedCharRange);
+                                throw MakeException(RegexParseError.ReversedCharacterRange, SR.ReversedCharacterRange);
                             }
                             charClass!.AddRange(chPrev, ch);
                         }
@@ -732,7 +732,7 @@ namespace System.Text.RegularExpressions
 
                         if (CharsRight() > 0 && RightChar() != ']')
                         {
-                            throw MakeException(RegexParseError.SubtractionMustBeLast, SR.SubtractionMustBeLast);
+                            throw MakeException(RegexParseError.ExclusionGroupNotLast, SR.ExclusionGroupNotLast);
                         }
                     }
                     else
@@ -877,12 +877,12 @@ namespace System.Text.RegularExpressions
                                     // check if we have bogus characters after the number
                                     if (CharsRight() > 0 && !(RightChar() == close || RightChar() == '-'))
                                     {
-                                        throw MakeException(RegexParseError.InvalidGroupName, SR.InvalidGroupName);
+                                        throw MakeException(RegexParseError.CaptureGroupNameInvalid, SR.CaptureGroupNameInvalid);
                                     }
 
                                     if (capnum == 0)
                                     {
-                                        throw MakeException(RegexParseError.CapnumNotZero, SR.CapnumNotZero);
+                                        throw MakeException(RegexParseError.CaptureGroupOfZero, SR.CaptureGroupOfZero);
                                     }
                                 }
                                 else if (RegexCharClass.IsWordChar(ch))
@@ -897,7 +897,7 @@ namespace System.Text.RegularExpressions
                                     // check if we have bogus character after the name
                                     if (CharsRight() > 0 && !(RightChar() == close || RightChar() == '-'))
                                     {
-                                        throw MakeException(RegexParseError.InvalidGroupName, SR.InvalidGroupName);
+                                        throw MakeException(RegexParseError.CaptureGroupNameInvalid, SR.CaptureGroupNameInvalid);
                                     }
                                 }
                                 else if (ch == '-')
@@ -907,7 +907,7 @@ namespace System.Text.RegularExpressions
                                 else
                                 {
                                     // bad group name - starts with something other than a word character and isn't a number
-                                    throw MakeException(RegexParseError.InvalidGroupName, SR.InvalidGroupName);
+                                    throw MakeException(RegexParseError.CaptureGroupNameInvalid, SR.CaptureGroupNameInvalid);
                                 }
 
                                 // grab part after - if any
@@ -923,13 +923,13 @@ namespace System.Text.RegularExpressions
 
                                         if (!IsCaptureSlot(uncapnum))
                                         {
-                                            throw MakeException(RegexParseError.UndefinedBackref, SR.Format(SR.UndefinedBackref, uncapnum));
+                                            throw MakeException(RegexParseError.UndefinedNumberedReference, SR.Format(SR.UndefinedNumberedReference, uncapnum));
                                         }
 
                                         // check if we have bogus characters after the number
                                         if (CharsRight() > 0 && RightChar() != close)
                                         {
-                                            throw MakeException(RegexParseError.InvalidGroupName, SR.InvalidGroupName);
+                                            throw MakeException(RegexParseError.CaptureGroupNameInvalid, SR.CaptureGroupNameInvalid);
                                         }
                                     }
                                     else if (RegexCharClass.IsWordChar(ch))
@@ -942,19 +942,19 @@ namespace System.Text.RegularExpressions
                                         }
                                         else
                                         {
-                                            throw MakeException(RegexParseError.UndefinedNameRef, SR.Format(SR.UndefinedNameRef, uncapname));
+                                            throw MakeException(RegexParseError.UndefinedNamedReference, SR.Format(SR.UndefinedNamedReference, uncapname));
                                         }
 
                                         // check if we have bogus character after the name
                                         if (CharsRight() > 0 && RightChar() != close)
                                         {
-                                            throw MakeException(RegexParseError.InvalidGroupName, SR.InvalidGroupName);
+                                            throw MakeException(RegexParseError.CaptureGroupNameInvalid, SR.CaptureGroupNameInvalid);
                                         }
                                     }
                                     else
                                     {
                                         // bad group name - starts with something other than a word character and isn't a number
-                                        throw MakeException(RegexParseError.InvalidGroupName, SR.InvalidGroupName);
+                                        throw MakeException(RegexParseError.CaptureGroupNameInvalid, SR.CaptureGroupNameInvalid);
                                     }
                                 }
 
@@ -987,10 +987,10 @@ namespace System.Text.RegularExpressions
                                         return new RegexNode(RegexNode.Testref, _options, capnum);
                                     }
 
-                                    throw MakeException(RegexParseError.UndefinedReference, SR.Format(SR.UndefinedReference, capnum.ToString()));
+                                    throw MakeException(RegexParseError.AlternationHasUndefinedReference, SR.Format(SR.AlternationHasUndefinedReference, capnum.ToString()));
                                 }
 
-                                throw MakeException(RegexParseError.MalformedReference, SR.Format(SR.MalformedReference, capnum.ToString()));
+                                throw MakeException(RegexParseError.AlternationHasMalformedReference, SR.Format(SR.AlternationHasMalformedReference, capnum.ToString()));
                             }
                             else if (RegexCharClass.IsWordChar(ch))
                             {
@@ -1015,18 +1015,18 @@ namespace System.Text.RegularExpressions
                             // disallow comments in the condition
                             if (rightchar2 == '#')
                             {
-                                throw MakeException(RegexParseError.AlternationCantHaveComment, SR.AlternationCantHaveComment);
+                                throw MakeException(RegexParseError.AlternationHasComment, SR.AlternationHasComment);
                             }
 
                             // disallow named capture group (?<..>..) in the condition
                             if (rightchar2 == '\'')
                             {
-                                throw MakeException(RegexParseError.AlternationCantCapture, SR.AlternationCantCapture);
+                                throw MakeException(RegexParseError.AlternationHasNamedCapture, SR.AlternationHasNamedCapture);
                             }
 
                             if (charsRight >= 4 && rightchar2 == '<' && RightChar(3) != '!' && RightChar(3) != '=')
                             {
-                                throw MakeException(RegexParseError.AlternationCantCapture, SR.AlternationCantCapture);
+                                throw MakeException(RegexParseError.AlternationHasNamedCapture, SR.AlternationHasNamedCapture);
                             }
                         }
 
@@ -1066,7 +1066,7 @@ namespace System.Text.RegularExpressions
             ;
             // break Recognize comes here
 
-            throw MakeException(RegexParseError.UnrecognizedGrouping, SR.UnrecognizedGrouping);
+            throw MakeException(RegexParseError.InvalidGroupingConstruct, SR.InvalidGroupingConstruct);
         }
 
         /*
@@ -1218,7 +1218,7 @@ namespace System.Text.RegularExpressions
         {
             if (CharsRight() == 0)
             {
-                throw MakeException(RegexParseError.IllegalEndEscape, SR.IllegalEndEscape);
+                throw MakeException(RegexParseError.UnescapedEndingBackslash, SR.UnescapedEndingBackslash);
             }
 
             int backpos = Textpos();
@@ -1243,7 +1243,7 @@ namespace System.Text.RegularExpressions
 
                 if (!angled || CharsRight() <= 0)
                 {
-                    throw MakeException(RegexParseError.MalformedNameRef, SR.MalformedNameRef);
+                    throw MakeException(RegexParseError.MalformedNamedReference, SR.MalformedNamedReference);
                 }
 
                 ch = RightChar();
@@ -1270,7 +1270,7 @@ namespace System.Text.RegularExpressions
                     return
                         scanOnly ? null :
                         IsCaptureSlot(capnum) ? new RegexNode(RegexNode.Ref, _options, capnum) :
-                        throw MakeException(RegexParseError.UndefinedBackref, SR.Format(SR.UndefinedBackref, capnum.ToString()));
+                        throw MakeException(RegexParseError.UndefinedNumberedReference, SR.Format(SR.UndefinedNumberedReference, capnum.ToString()));
                 }
             }
 
@@ -1320,7 +1320,7 @@ namespace System.Text.RegularExpressions
 
                     if (capnum <= 9)
                     {
-                        throw MakeException(RegexParseError.UndefinedBackref, SR.Format(SR.UndefinedBackref, capnum.ToString()));
+                        throw MakeException(RegexParseError.UndefinedNumberedReference, SR.Format(SR.UndefinedNumberedReference, capnum.ToString()));
                     }
                 }
             }
@@ -1336,7 +1336,7 @@ namespace System.Text.RegularExpressions
                     return
                         scanOnly ? null :
                         IsCaptureName(capname) ? new RegexNode(RegexNode.Ref, _options, CaptureSlotFromName(capname)) :
-                        throw MakeException(RegexParseError.UndefinedNameRef, SR.Format(SR.UndefinedNameRef, capname));
+                        throw MakeException(RegexParseError.UndefinedNamedReference, SR.Format(SR.UndefinedNamedReference, capname));
                 }
             }
 
@@ -1401,7 +1401,7 @@ namespace System.Text.RegularExpressions
                         int digit = ch - '0';
                         if (newcapnum > MaxValueDiv10 || (newcapnum == MaxValueDiv10 && digit > MaxValueMod10))
                         {
-                            throw MakeException(RegexParseError.CaptureGroupOutOfRange, SR.CaptureGroupOutOfRange);
+                            throw MakeException(RegexParseError.QuantifierOrCaptureGroupOutOfRange, SR.QuantifierOrCaptureGroupOutOfRange);
                         }
 
                         newcapnum = newcapnum * 10 + digit;
@@ -1548,7 +1548,7 @@ namespace System.Text.RegularExpressions
 
                 if (i > MaxValueDiv10 || (i == MaxValueDiv10 && d > MaxValueMod10))
                 {
-                    throw MakeException(RegexParseError.CaptureGroupOutOfRange, SR.CaptureGroupOutOfRange);
+                    throw MakeException(RegexParseError.QuantifierOrCaptureGroupOutOfRange, SR.QuantifierOrCaptureGroupOutOfRange);
                 }
 
                 i = (i * 10) + d;
@@ -1575,7 +1575,7 @@ namespace System.Text.RegularExpressions
 
             if (c > 0)
             {
-                throw MakeException(RegexParseError.TooFewHex, SR.TooFewHex);
+                throw MakeException(RegexParseError.InsufficientOrInvalidHexDigits, SR.InsufficientOrInvalidHexDigits);
             }
 
             return (char)i;
@@ -1607,7 +1607,7 @@ namespace System.Text.RegularExpressions
         {
             if (CharsRight() == 0)
             {
-                throw MakeException(RegexParseError.MissingControl, SR.MissingControl);
+                throw MakeException(RegexParseError.MissingControlCharacter, SR.MissingControlCharacter);
             }
 
             char ch = RightCharMoveRight();
@@ -1624,7 +1624,7 @@ namespace System.Text.RegularExpressions
                 return ch;
             }
 
-            throw MakeException(RegexParseError.UnrecognizedControl, SR.UnrecognizedControl);
+            throw MakeException(RegexParseError.UnrecognizedControlCharacter, SR.UnrecognizedControlCharacter);
         }
 
         /// <summary>Returns true for options allowed only at the top level</summary>
@@ -1717,13 +1717,13 @@ namespace System.Text.RegularExpressions
         {
             if (CharsRight() < 3)
             {
-                throw MakeException(RegexParseError.IncompleteSlashP, SR.IncompleteSlashP);
+                throw MakeException(RegexParseError.InvalidUnicodePropertyEscape, SR.InvalidUnicodePropertyEscape);
             }
 
             char ch = RightCharMoveRight();
             if (ch != '{')
             {
-                throw MakeException(RegexParseError.MalformedSlashP, SR.MalformedSlashP);
+                throw MakeException(RegexParseError.MalformedUnicodePropertyEscape, SR.MalformedUnicodePropertyEscape);
             }
 
             int startpos = Textpos();
@@ -1741,7 +1741,7 @@ namespace System.Text.RegularExpressions
 
             if (CharsRight() == 0 || RightCharMoveRight() != '}')
             {
-                throw MakeException(RegexParseError.IncompleteSlashP, SR.IncompleteSlashP);
+                throw MakeException(RegexParseError.InvalidUnicodePropertyEscape, SR.InvalidUnicodePropertyEscape);
             }
 
             return capname;
@@ -2176,7 +2176,7 @@ namespace System.Text.RegularExpressions
             {
                 if (_unit == null)
                 {
-                    throw MakeException(RegexParseError.IllegalCondition, SR.IllegalCondition);
+                    throw MakeException(RegexParseError.AlternationHasMalformedCondition, SR.AlternationHasMalformedCondition);
                 }
 
                 _group.AddChild(_unit);
@@ -2280,7 +2280,7 @@ namespace System.Text.RegularExpressions
 
                 if (_group.Type == RegexNode.Testref && _group.ChildCount() > 2 || _group.ChildCount() > 3)
                 {
-                    throw MakeException(RegexParseError.TooManyAlternates, SR.TooManyAlternates);
+                    throw MakeException(RegexParseError.AlternationHasTooManyConditions, SR.AlternationHasTooManyConditions);
                 }
             }
             else
index 849afb7..e4f555b 100644 (file)
@@ -2,27 +2,14 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.IO;
-using System.Reflection;
 using System.Runtime.Serialization.Formatters.Binary;
 using Xunit;
 using Xunit.Sdk;
 
 namespace System.Text.RegularExpressions.Tests
 {
-    public class RegexParserTests
+    public partial class RegexParserTests
     {
-        private static readonly Type s_parseExceptionType;
-        private static readonly FieldInfo s_parseErrorField;
-
-        static RegexParserTests()
-        {
-            if (!PlatformDetection.IsNetFramework)
-            {
-                s_parseExceptionType = typeof(Regex).Assembly.GetType("System.Text.RegularExpressions.RegexParseException", true);
-                s_parseErrorField = s_parseExceptionType.GetField("_error", BindingFlags.NonPublic | BindingFlags.Instance);
-            }
-        }
-
         [Theory]
         // Basic
         [InlineData("", RegexOptions.None, null)]
@@ -30,8 +17,8 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData("  ", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?#)", RegexOptions.None, null)]
         [InlineData("(?# )", RegexOptions.None, null)]
-        [InlineData("(?#", RegexOptions.None, RegexParseError.UnterminatedComment)]
-        [InlineData("(?# ", RegexOptions.None, RegexParseError.UnterminatedComment)]
+        [InlineData("(?#", RegexOptions.None, RegexParseError.UnterminatedComment, 3)]
+        [InlineData("(?# ", RegexOptions.None, RegexParseError.UnterminatedComment, 4)]
         [InlineData("(?#)(?#)", RegexOptions.None, null)]
         [InlineData("(?#)(?#)", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?#) (?#)", RegexOptions.None, null)]
@@ -42,10 +29,10 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(@"[a\x00(?#)b]", RegexOptions.None, null)]
         [InlineData(@"[a\u0000(?#)b]", RegexOptions.None, null)]
         [InlineData(@"[a\](?#)b]", RegexOptions.None, null)]
-        [InlineData("(?", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(? ", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(? ", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
+        [InlineData("(?", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 2)]
+        [InlineData("(?", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 2)]
+        [InlineData("(? ", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData("(? ", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 3)]
         [InlineData("(?i)", RegexOptions.None, null)]
         [InlineData("(?im)", RegexOptions.None, null)]
         [InlineData("(?im-x)", RegexOptions.None, null)]
@@ -58,12 +45,12 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(" (?-x:) ", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData(" (?-x: ) ", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData(" (?-x: (?+x: ) ) ", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?-x", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?-x ", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?-x :", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?-x )", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?-x :)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(")", RegexOptions.None, RegexParseError.TooManyParentheses)]
+        [InlineData("(?-x", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 4)]
+        [InlineData("(?-x ", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData("(?-x :", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData("(?-x )", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData("(?-x :)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(")", RegexOptions.None, RegexParseError.InsufficientOpeningParentheses, 1)]
         [InlineData("a", RegexOptions.None, null)]
         [InlineData("ab", RegexOptions.None, null)]
         [InlineData("a*", RegexOptions.None, null)]
@@ -74,8 +61,8 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData("a??", RegexOptions.None, null)]
         [InlineData("()", RegexOptions.None, null)]
         [InlineData("(a)", RegexOptions.None, null)]
-        [InlineData("(", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(a", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
+        [InlineData("(", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 1)]
+        [InlineData("(a", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 2)]
         [InlineData("|", RegexOptions.None, null)]
         [InlineData(" |", RegexOptions.None, null)]
         [InlineData("| ", RegexOptions.None, null)]
@@ -89,7 +76,7 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData("a{0}", RegexOptions.None, null)]
         [InlineData("a{0,}", RegexOptions.None, null)]
         [InlineData("a{0,1}", RegexOptions.None, null)]
-        [InlineData("a{1,0}", RegexOptions.None, RegexParseError.IllegalRange)]
+        [InlineData("a{1,0}", RegexOptions.None, RegexParseError.ReversedQuantifierRange, 6)]
         [InlineData("a{0}?", RegexOptions.None, null)]
         [InlineData("a{0,}?", RegexOptions.None, null)]
         [InlineData("a{0,1}?", RegexOptions.None, null)]
@@ -105,43 +92,43 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData("a{0,1 }", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("a* ?", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("a* ?", RegexOptions.None, null)]
-        [InlineData("*", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData("(*)", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData("a**", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData("+", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData("(+)", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData("a*+", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData("?", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData("(?)", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData("a*??", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData("{0}", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData("({0})", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData("a*{0}", RegexOptions.None, RegexParseError.NestedQuantify)]
+        [InlineData("*", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData("(*)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 2)]
+        [InlineData("a**", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 3)]
+        [InlineData("+", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData("(+)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 2)]
+        [InlineData("a*+", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 3)]
+        [InlineData("?", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData("(?)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 2)]
+        [InlineData("a*??", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 4)]
+        [InlineData("{0}", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData("({0})", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 2)]
+        [InlineData("a*{0}", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 3)]
         [InlineData("{0", RegexOptions.None, null)]
         [InlineData("({0)", RegexOptions.None, null)]
         [InlineData("a*{0", RegexOptions.None, null)]
         [InlineData(@"\w", RegexOptions.None, null)]
         [InlineData(@"\b\B\A\G\Z\z\w\W\s\W\s\S\d\D", RegexOptions.None, null)]
-        [InlineData(@"\c", RegexOptions.None, RegexParseError.MissingControl)]
-        [InlineData(@"\c<", RegexOptions.None, RegexParseError.UnrecognizedControl)]
+        [InlineData(@"\c", RegexOptions.None, RegexParseError.MissingControlCharacter, 2)]
+        [InlineData(@"\c<", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 3)]
         [InlineData(@"\ca", RegexOptions.None, null)]
         [InlineData(@"\cA", RegexOptions.None, null)]
-        [InlineData(@"\c A", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"\c(a)", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"\c>", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"\c?", RegexOptions.None, RegexParseError.UnrecognizedControl)]
+        [InlineData(@"\c A", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 3)]
+        [InlineData(@"\c(a)", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 3)]
+        [InlineData(@"\c>", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 3)]
+        [InlineData(@"\c?", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 3)]
         [InlineData(@"\c@", RegexOptions.None, null)]
         [InlineData(@"\c^", RegexOptions.None, null)]
         [InlineData(@"\c_", RegexOptions.None, null)]
-        [InlineData(@"\c`", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"\c{", RegexOptions.None, RegexParseError.UnrecognizedControl)]
+        [InlineData(@"\c`", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 3)]
+        [InlineData(@"\c{", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 3)]
         [InlineData(@"\cz", RegexOptions.None, null)]
         [InlineData(@"\cZ", RegexOptions.None, null)]
-        [InlineData(@"\m", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\x", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\x ", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\x0", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\x0 ", RegexOptions.None, RegexParseError.TooFewHex)]
+        [InlineData(@"\m", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\x", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"\x ", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"\x0", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"\x0 ", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 4)]
         [InlineData(@"\x00", RegexOptions.None, null)]
         [InlineData(@"\x00 ", RegexOptions.None, null)]
         [InlineData(@"\x000", RegexOptions.None, null)]
@@ -149,17 +136,17 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(@"\xFF", RegexOptions.None, null)]
         [InlineData(@"\xfF", RegexOptions.None, null)]
         [InlineData(@"\xfff", RegexOptions.None, null)]
-        [InlineData(@"\xgg", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\m ", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\u", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\u0", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\u00", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\u000", RegexOptions.None, RegexParseError.TooFewHex)]
+        [InlineData(@"\xgg", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 3)]
+        [InlineData(@"\m ", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\u", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"\u0", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"\u00", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"\u000", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
         [InlineData(@"\u0000", RegexOptions.None, null)]
         [InlineData(@"\u0000 ", RegexOptions.None, null)]
-        [InlineData(@"\u ", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\u0 ", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"\ugggg", RegexOptions.None, RegexParseError.TooFewHex)]
+        [InlineData(@"\u ", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"\u0 ", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"\ugggg", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 3)]
         [InlineData(@"\0", RegexOptions.None, null)]
         [InlineData(@"\0 ", RegexOptions.None, null)]
         [InlineData(@"\00", RegexOptions.None, null)]
@@ -168,45 +155,45 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(@"\000 ", RegexOptions.None, null)]
         [InlineData(@"\0000", RegexOptions.None, null)]
         [InlineData(@"\0000 ", RegexOptions.None, null)]
-        [InlineData(@"\7", RegexOptions.None, RegexParseError.UndefinedBackref)]
+        [InlineData(@"\7", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 2)]
         [InlineData(@"\78", RegexOptions.None, null)]
-        [InlineData(@"\8", RegexOptions.None, RegexParseError.UndefinedBackref)]
+        [InlineData(@"\8", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 2)]
         [InlineData(@"\40", RegexOptions.ECMAScript, null)]
         [InlineData(@"\401", RegexOptions.ECMAScript, null)]
         [InlineData(@"\37", RegexOptions.ECMAScript, null)]
         [InlineData(@"\371", RegexOptions.ECMAScript, null)]
         [InlineData(@"\0000", RegexOptions.ECMAScript, null)]
-        [InlineData(@"\k", RegexOptions.None, RegexParseError.MalformedNameRef)]
-        [InlineData(@"\k ", RegexOptions.None, RegexParseError.MalformedNameRef)]
-        [InlineData(@"\k<", RegexOptions.None, RegexParseError.MalformedNameRef)]
-        [InlineData(@"\k< ", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\k<0", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\k<0 ", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
+        [InlineData(@"\k", RegexOptions.None, RegexParseError.MalformedNamedReference, 1)]
+        [InlineData(@"\k ", RegexOptions.None, RegexParseError.MalformedNamedReference, 3)]
+        [InlineData(@"\k<", RegexOptions.None, RegexParseError.MalformedNamedReference, 3)]
+        [InlineData(@"\k< ", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\k<0", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\k<0 ", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
         [InlineData(@"\k<0>", RegexOptions.None, null)]
         [InlineData(@"\k<0> ", RegexOptions.None, null)]
         [InlineData(@"\k<00> ", RegexOptions.None, null)]
-        [InlineData(@"\k<a> ", RegexOptions.None, RegexParseError.UndefinedNameRef)]
+        [InlineData(@"\k<a> ", RegexOptions.None, RegexParseError.UndefinedNamedReference, 5)]
         [InlineData(@"(?<a>)\k<a> ", RegexOptions.None, null)]
-        [InlineData(@"\k", RegexOptions.ECMAScript, RegexParseError.MalformedNameRef)]
-        [InlineData(@"\k ", RegexOptions.ECMAScript, RegexParseError.MalformedNameRef)]
-        [InlineData(@"\k<", RegexOptions.ECMAScript, RegexParseError.MalformedNameRef)]
+        [InlineData(@"\k", RegexOptions.ECMAScript, RegexParseError.MalformedNamedReference, 1)]
+        [InlineData(@"\k ", RegexOptions.ECMAScript, RegexParseError.MalformedNamedReference, 3)]
+        [InlineData(@"\k<", RegexOptions.ECMAScript, RegexParseError.MalformedNamedReference, 3)]
         [InlineData(@"\k< ", RegexOptions.ECMAScript, null)]
         [InlineData(@"\k<0", RegexOptions.ECMAScript, null)]
         [InlineData(@"\k<0 ", RegexOptions.ECMAScript, null)]
         [InlineData(@"\k<0>", RegexOptions.ECMAScript, null)]
         [InlineData(@"\k<0> ", RegexOptions.ECMAScript, null)]
-        [InlineData(@"\k'", RegexOptions.None, RegexParseError.MalformedNameRef)]
-        [InlineData(@"\k' ", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\k'0", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\k'0 ", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
+        [InlineData(@"\k'", RegexOptions.None, RegexParseError.MalformedNamedReference, 3)]
+        [InlineData(@"\k' ", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\k'0", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\k'0 ", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
         [InlineData(@"\k'0'", RegexOptions.None, null)]
         [InlineData(@"\k'0' ", RegexOptions.None, null)]
         [InlineData(@"\k'00' ", RegexOptions.None, null)]
-        [InlineData(@"\k'a' ", RegexOptions.None, RegexParseError.UndefinedNameRef)]
+        [InlineData(@"\k'a' ", RegexOptions.None, RegexParseError.UndefinedNamedReference, 5)]
         [InlineData(@"(?<a>)\k'a' ", RegexOptions.None, null)]
-        [InlineData(@"\k<0' ", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\k'0> ", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\", RegexOptions.None, RegexParseError.IllegalEndEscape)]
+        [InlineData(@"\k<0' ", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\k'0> ", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\", RegexOptions.None, RegexParseError.UnescapedEndingBackslash, 1)]
         [InlineData(@"\ ", RegexOptions.None, null)]
         [InlineData(@"\<", RegexOptions.None, null)]
         [InlineData(@"\< ", RegexOptions.None, null)]
@@ -215,9 +202,9 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(@"\<0>", RegexOptions.None, null)]
         [InlineData(@"\<0> ", RegexOptions.None, null)]
         [InlineData(@"\<00> ", RegexOptions.None, null)]
-        [InlineData(@"\<a> ", RegexOptions.None, RegexParseError.UndefinedNameRef)]
+        [InlineData(@"\<a> ", RegexOptions.None, RegexParseError.UndefinedNamedReference, 4)]
         [InlineData(@"(?<a>)\<a> ", RegexOptions.None, null)]
-        [InlineData(@"\", RegexOptions.ECMAScript, RegexParseError.IllegalEndEscape)]
+        [InlineData(@"\", RegexOptions.ECMAScript, RegexParseError.UnescapedEndingBackslash, 1)]
         [InlineData(@"\ ", RegexOptions.ECMAScript, null)]
         [InlineData(@"\<", RegexOptions.ECMAScript, null)]
         [InlineData(@"\< ", RegexOptions.ECMAScript, null)]
@@ -232,77 +219,77 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(@"\'0'", RegexOptions.None, null)]
         [InlineData(@"\'0' ", RegexOptions.None, null)]
         [InlineData(@"\'00' ", RegexOptions.None, null)]
-        [InlineData(@"\'a' ", RegexOptions.None, RegexParseError.UndefinedNameRef)]
+        [InlineData(@"\'a' ", RegexOptions.None, RegexParseError.UndefinedNamedReference, 4)]
         [InlineData(@"(?<a>)\'a' ", RegexOptions.None, null)]
         [InlineData(@"\<0' ", RegexOptions.None, null)]
         [InlineData(@"\'0> ", RegexOptions.None, null)]
         [InlineData("\\p{Cc}", RegexOptions.None, null)]
-        [InlineData("\\p{ Cc }", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData("\\p{ Cc }", RegexOptions.IgnorePatternWhitespace, RegexParseError.IncompleteSlashP)]
-        [InlineData("\\p {Cc}", RegexOptions.IgnorePatternWhitespace, RegexParseError.MalformedSlashP)]
-        [InlineData("\\p{xxx}", RegexOptions.None, RegexParseError.UnknownUnicodeProperty)]
-        [InlineData("\\p", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData("\\p{", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData("\\p{}", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData("\\p{} ", RegexOptions.None, RegexParseError.UnknownUnicodeProperty)]
-        [InlineData("\\p {} ", RegexOptions.None, RegexParseError.MalformedSlashP)]
-        [InlineData("\\p{Cc ", RegexOptions.None, RegexParseError.IncompleteSlashP)]
+        [InlineData("\\p{ Cc }", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 4)]
+        [InlineData("\\p{ Cc }", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidUnicodePropertyEscape, 4)]
+        [InlineData("\\p {Cc}", RegexOptions.IgnorePatternWhitespace, RegexParseError.MalformedUnicodePropertyEscape, 3)]
+        [InlineData("\\p{xxx}", RegexOptions.None, RegexParseError.UnrecognizedUnicodeProperty, 7)]
+        [InlineData("\\p", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 2)]
+        [InlineData("\\p{", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 2)]
+        [InlineData("\\p{}", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 2)]
+        [InlineData("\\p{} ", RegexOptions.None, RegexParseError.UnrecognizedUnicodeProperty, 4)]
+        [InlineData("\\p {} ", RegexOptions.None, RegexParseError.MalformedUnicodePropertyEscape, 3)]
+        [InlineData("\\p{Cc ", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 6)]
         [InlineData("\\p{IsArabicPresentationForms-A}", RegexOptions.None, null)]
         [InlineData("(?:)", RegexOptions.None, null)]
         [InlineData("(?:a)", RegexOptions.None, null)]
-        [InlineData("(?:", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?: ", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
+        [InlineData("(?:", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 3)]
+        [InlineData("(?: ", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 4)]
         [InlineData("(?=)", RegexOptions.None, null)]
         [InlineData("(?=a)", RegexOptions.None, null)]
-        [InlineData("(?=", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?= ", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
+        [InlineData("(?=", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 3)]
+        [InlineData("(?= ", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 4)]
         [InlineData("(?!)", RegexOptions.None, null)]
         [InlineData("(?!a)", RegexOptions.None, null)]
-        [InlineData("(?!", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?! ", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
+        [InlineData("(?!", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 3)]
+        [InlineData("(?! ", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 4)]
         [InlineData("(?>)", RegexOptions.None, null)]
         [InlineData("(?>a)", RegexOptions.None, null)]
-        [InlineData("(?>", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?> ", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
+        [InlineData("(?>", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 3)]
+        [InlineData("(?> ", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 4)]
         [InlineData("(?<=)", RegexOptions.None, null)]
         [InlineData("(?<=a)", RegexOptions.None, null)]
-        [InlineData("(?<=", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?<= ", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
+        [InlineData("(?<=", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 4)]
+        [InlineData("(?<= ", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 5)]
         [InlineData("(?<!)", RegexOptions.None, null)]
         [InlineData("(?<!a)", RegexOptions.None, null)]
-        [InlineData("(?<!", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?<! ", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?<", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?<>", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<a", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?<a>", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?<a>a", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
+        [InlineData("(?<!", RegexOptions.None, RegexParseError.InsufficientClosingParentheses,4)]
+        [InlineData("(?<! ", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 5)]
+        [InlineData("(?<", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData("(?<>", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 3)]
+        [InlineData("(?<a", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 4)]
+        [InlineData("(?<a>", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 5)]
+        [InlineData("(?<a>a", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 6)]
         [InlineData("(?<a>a)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<a >a)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<a >a)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?< a>a)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData("(?< a>a)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?< a >a)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData("(?< a >a)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
+        [InlineData("(?<a >a)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 4)]
+        [InlineData("(?<a >a)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 4)]
+        [InlineData("(?< a>a)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 3)]
+        [InlineData("(?< a>a)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 3)]
+        [InlineData("(?< a >a)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 3)]
+        [InlineData("(?< a >a)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 3)]
         [InlineData("(?<ab>a)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<0>a)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CapnumNotZero)]
+        [InlineData("(?<0>a)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupOfZero, 4)]
         [InlineData("(?<1>a)", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?<10>a)", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?<1>)", RegexOptions.None, null)]
         [InlineData("(?<1> )", RegexOptions.None, null)]
         [InlineData("(?<1> )", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?'a')", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?(", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?(0", RegexOptions.IgnorePatternWhitespace, RegexParseError.MalformedReference)]
-        [InlineData("(?(0)", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
+        [InlineData("(?(", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 3)]
+        [InlineData("(?(0", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasMalformedReference, 4)]
+        [InlineData("(?(0)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 5)]
         [InlineData("(?(0))", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?(0)a)", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?(0)a|)", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?(0)a|b)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?(0)a|b|)", RegexOptions.IgnorePatternWhitespace, RegexParseError.TooManyAlternates)]
-        [InlineData("(?(0)a|b|c)", RegexOptions.IgnorePatternWhitespace, RegexParseError.TooManyAlternates)]
-        [InlineData("(?(0 )", RegexOptions.IgnorePatternWhitespace, RegexParseError.MalformedReference)]
-        [InlineData("(?(1))", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedReference)]
+        [InlineData("(?(0)a|b|)", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasTooManyConditions, 10)]
+        [InlineData("(?(0)a|b|c)", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasTooManyConditions, 11)]
+        [InlineData("(?(0 )", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasMalformedReference, 5)]
+        [InlineData("(?(1))", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasUndefinedReference, 5)]
         [InlineData("(?(00))", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?(a))", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?<a>)(?(a))", RegexOptions.IgnorePatternWhitespace, null)]
@@ -310,20 +297,20 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData("(?<a>)(?( a))", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?(()a()))", RegexOptions.None, null)]
         [InlineData("(?((?<x>)a(?<y>)))", RegexOptions.None, null)]
-        [InlineData("(?(?'", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationCantCapture)]
-        [InlineData("(?(?'x'))", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationCantCapture)]
-        [InlineData("(?(?#", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnterminatedComment)]
-        [InlineData("(?(?#)", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationCantHaveComment)]
-        [InlineData("(?(?#))", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationCantHaveComment)]
-        [InlineData("(?(?<", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?(?<a", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationCantCapture)]
-        [InlineData("(?(?<a>", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationCantCapture)]
-        [InlineData("(?(?<a>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationCantCapture)]
-        [InlineData("(?(?<a>))", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationCantCapture)]
+        [InlineData("(?(?'", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasNamedCapture, 2)]
+        [InlineData("(?(?'x'))", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasNamedCapture, 2)]
+        [InlineData("(?(?#", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnterminatedComment, 5)]
+        [InlineData("(?(?#)", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasComment, 2)]
+        [InlineData("(?(?#))", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasComment, 2)]
+        [InlineData("(?(?<", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData("(?(?<a", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasNamedCapture, 2)]
+        [InlineData("(?(?<a>", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasNamedCapture, 2)]
+        [InlineData("(?(?<a>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasNamedCapture, 2)]
+        [InlineData("(?(?<a>))", RegexOptions.IgnorePatternWhitespace, RegexParseError.AlternationHasNamedCapture, 2)]
         [InlineData("(?(?<=))", RegexOptions.IgnorePatternWhitespace, null)]
         [InlineData("(?(?<!))", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData(@"\1", RegexOptions.None, RegexParseError.UndefinedBackref)]
-        [InlineData(@"\1 ", RegexOptions.None, RegexParseError.UndefinedBackref)]
+        [InlineData(@"\1", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 2)]
+        [InlineData(@"\1 ", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 2)]
         [InlineData(@"()\1", RegexOptions.None, null)]
         [InlineData(@"()\1 ", RegexOptions.None, null)]
         [InlineData(@"()\10 ", RegexOptions.None, null)]
@@ -333,131 +320,131 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(@"()\1 ", RegexOptions.ECMAScript, null)]
         [InlineData(@"()\10 ", RegexOptions.ECMAScript, null)]
         [InlineData(@"()()()()()()()()()()\10 ", RegexOptions.ECMAScript, null)]
-        [InlineData(@"[", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[ ", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[]", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[] ", RegexOptions.None, RegexParseError.UnterminatedBracket)]
+        [InlineData(@"[", RegexOptions.None, RegexParseError.UnterminatedBracket, 1)]
+        [InlineData(@"[ ", RegexOptions.None, RegexParseError.UnterminatedBracket, 2)]
+        [InlineData(@"[]", RegexOptions.None, RegexParseError.UnterminatedBracket, 2)]
+        [InlineData(@"[] ", RegexOptions.None, RegexParseError.UnterminatedBracket, 3)]
         [InlineData(@"[a]", RegexOptions.None, null)]
         [InlineData(@"[a] ", RegexOptions.None, null)]
-        [InlineData(@"[a-", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[a- ", RegexOptions.None, RegexParseError.UnterminatedBracket)]
+        [InlineData(@"[a-", RegexOptions.None, RegexParseError.UnterminatedBracket, 3)]
+        [InlineData(@"[a- ", RegexOptions.None, RegexParseError.UnterminatedBracket, 4)]
         [InlineData(@"[a-]", RegexOptions.None, null)]
         [InlineData(@"[a-] ", RegexOptions.None, null)]
         [InlineData(@"[a-b]", RegexOptions.None, null)]
         [InlineData(@"[a-b] ", RegexOptions.None, null)]
         [InlineData(@"[a-[b]] ", RegexOptions.None, null)]
         [InlineData(@"[a-b-[c]] ", RegexOptions.None, null)]
-        [InlineData(@"[a-[b]-c] ", RegexOptions.None, RegexParseError.SubtractionMustBeLast)]
-        [InlineData(@"[a-z-[b]12]", RegexOptions.None, RegexParseError.SubtractionMustBeLast)]
+        [InlineData(@"[a-[b]-c] ", RegexOptions.None, RegexParseError.ExclusionGroupNotLast, 6)]
+        [InlineData(@"[a-z-[b]12]", RegexOptions.None, RegexParseError.ExclusionGroupNotLast, 8)]
         [InlineData(@"[[a]-b] ", RegexOptions.None, null)]
         [InlineData(@"[[a]-[b]] ", RegexOptions.None, null)]
         [InlineData(@"[\w-a] ", RegexOptions.None, null)]
-        [InlineData(@"[a-\w] ", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"[\p{llll}-a] ", RegexOptions.None, RegexParseError.UnknownUnicodeProperty)]
+        [InlineData(@"[a-\w] ", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 5)]
+        [InlineData(@"[\p{llll}-a] ", RegexOptions.None, RegexParseError.UnrecognizedUnicodeProperty, 9)]
         [InlineData(@"[\p{Lu}-a] ", RegexOptions.None, null)]
-        [InlineData(@"[a-\p{Lu}] ", RegexOptions.None, RegexParseError.BadClassInCharRange)]
+        [InlineData(@"[a-\p{Lu}] ", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 5)]
         [InlineData(@"[a-[:Ll:]] ", RegexOptions.None, null)]
         [InlineData(@"[a-[:Ll]] ", RegexOptions.None, null)]
-        [InlineData(@"[a-[:", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[a-[:L", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[a-[:L:", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[a-[:L:]", RegexOptions.None, RegexParseError.UnterminatedBracket)]
+        [InlineData(@"[a-[:", RegexOptions.None, RegexParseError.UnterminatedBracket, 5)]
+        [InlineData(@"[a-[:L", RegexOptions.None, RegexParseError.UnterminatedBracket, 6)]
+        [InlineData(@"[a-[:L:", RegexOptions.None, RegexParseError.UnterminatedBracket, 7)]
+        [InlineData(@"[a-[:L:]", RegexOptions.None, RegexParseError.UnterminatedBracket, 8)]
         [InlineData(@"[\-]", RegexOptions.None, null)]
         [InlineData(@"[a-b-c] ", RegexOptions.None, null)]
         [InlineData(@"[-b-c] ", RegexOptions.None, null)]
         [InlineData(@"[-[b] ", RegexOptions.None, null)]
         [InlineData(@"[-[b]] ", RegexOptions.None, null)]
-        [InlineData(@"[--b ", RegexOptions.None, RegexParseError.UnterminatedBracket)]
+        [InlineData(@"[--b ", RegexOptions.None, RegexParseError.UnterminatedBracket, 5)]
         [InlineData(@"[--b] ", RegexOptions.None, null)]
-        [InlineData(@"[--[b ", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[--[b] ", RegexOptions.None, RegexParseError.SubtractionMustBeLast)]
+        [InlineData(@"[--[b ", RegexOptions.None, RegexParseError.UnterminatedBracket, 6)]
+        [InlineData(@"[--[b] ", RegexOptions.None, RegexParseError.ExclusionGroupNotLast, 6)]
         [InlineData(@"[--[b]] ", RegexOptions.None, null)]
-        [InlineData(@"[a--[b ", RegexOptions.None, RegexParseError.UnterminatedBracket)]
+        [InlineData(@"[a--[b ", RegexOptions.None, RegexParseError.UnterminatedBracket, 7)]
         [InlineData(@"[,--[a] ", RegexOptions.None, null)]
         [InlineData(@"[,--[a]] ", RegexOptions.None, null)]
         [InlineData(@"[\s-a]", RegexOptions.None, null)]
         [InlineData(@"[\p{Lu}-a]", RegexOptions.None, null)]
-        [InlineData(@"[\c<-\c>]", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"[\c>-\c<]", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"[\c>-a]", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"[a-\c>]", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"[a--]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[\c<-\c>]", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 4)]
+        [InlineData(@"[\c>-\c<]", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 4)]
+        [InlineData(@"[\c>-a]", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 4)]
+        [InlineData(@"[a-\c>]", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 6)]
+        [InlineData(@"[a--]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 4)]
         [InlineData(@"[--a]", RegexOptions.None, null)]
         [InlineData(@"[\--a]", RegexOptions.None, null)]
         [InlineData(@"[\0-\1]", RegexOptions.None, null)]
-        [InlineData(@"[\1-\0]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[\1-\0]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 6)]
         [InlineData(@"[\0-\01]", RegexOptions.None, null)]
-        [InlineData(@"[\01-\0]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[\01-\0]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 7)]
         [InlineData(@"[[:x:]-a]", RegexOptions.None, null)]
         [InlineData(@"[a-[:x:]]", RegexOptions.None, null)]
         [InlineData(@"[\0-\ca]", RegexOptions.None, null)]
-        [InlineData(@"[\ca-\0]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[\ca-\0]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 7)]
         [InlineData(@"[\ca-\cA]", RegexOptions.None, null)]
         [InlineData(@"[\cA-\ca]", RegexOptions.None, null)]
-        [InlineData(@"[\u0-\u1]", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"[\u1-\u0]", RegexOptions.None, RegexParseError.TooFewHex)]
+        [InlineData(@"[\u0-\u1]", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 5)]
+        [InlineData(@"[\u1-\u0]", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 5)]
         [InlineData(@"[\u0000-\u0000]", RegexOptions.None, null)]
         [InlineData(@"[\u0000-\u0001]", RegexOptions.None, null)]
-        [InlineData(@"[\u0001-\u0000]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[\u0001-\u0000]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 14)]
         [InlineData(@"[\u0001-a]", RegexOptions.None, null)]
-        [InlineData(@"[a-\u0001]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[a-\u0001]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 9)]
         [InlineData(@"[a-a]", RegexOptions.None, null)]
-        [InlineData(@"[a-A]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[a-A]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 4)]
         [InlineData(@"[A-a]", RegexOptions.None, null)]
         [InlineData(@"[a-a]", RegexOptions.IgnoreCase, null)]
-        [InlineData(@"[a-A]", RegexOptions.IgnoreCase, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[a-A]", RegexOptions.IgnoreCase, RegexParseError.ReversedCharacterRange, 4)]
         [InlineData(@"[A-a]", RegexOptions.IgnoreCase, null)]
         [InlineData(@"[a-\x61]", RegexOptions.None, null)]
         [InlineData(@"[\x61-a]", RegexOptions.None, null)]
-        [InlineData(@"[a-\x60]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[\x62-a]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[a-\x60]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 7)]
+        [InlineData(@"[\x62-a]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 7)]
         [InlineData(@"[a-\x62]", RegexOptions.None, null)]
         [InlineData(@"[\3-\cc]", RegexOptions.None, null)]
         [InlineData(@"[\cc-\3]", RegexOptions.None, null)]
         [InlineData(@"[\2-\cc]", RegexOptions.None, null)]
-        [InlineData(@"[\cc-\2]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[\4-\cc]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[\cc-\2]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 7)]
+        [InlineData(@"[\4-\cc]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 7)]
         [InlineData(@"[\cc-\4]", RegexOptions.None, null)]
         [InlineData(@"[\ca-\cb]", RegexOptions.None, null)]
         [InlineData(@"[\ca-\cB]", RegexOptions.None, null)]
         [InlineData(@"[\cA-\cb]", RegexOptions.None, null)]
         [InlineData(@"[\cA-\cB]", RegexOptions.None, null)]
-        [InlineData(@"[\cb-\ca]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[\cb-\cA]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[\cB-\ca]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[\cB-\cA]", RegexOptions.None, RegexParseError.ReversedCharRange)]
+        [InlineData(@"[\cb-\ca]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 8)]
+        [InlineData(@"[\cb-\cA]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 8)]
+        [InlineData(@"[\cB-\ca]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 8)]
+        [InlineData(@"[\cB-\cA]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 8)]
         [InlineData(@"[\--#]", RegexOptions.None, null)]
-        [InlineData(@"[b-\-a]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[b-\-\-a]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"()\2", RegexOptions.None, RegexParseError.UndefinedBackref)]
+        [InlineData(@"[b-\-a]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)]
+        [InlineData(@"[b-\-\-a]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)]
+        [InlineData(@"()\2", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 4)]
         [InlineData(@"()()\2", RegexOptions.None, null)]
-        [InlineData(@"()\1", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
-        [InlineData(@"()\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
-        [InlineData(@"()()\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
+        [InlineData(@"()\1", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 4)]
+        [InlineData(@"()\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 4)]
+        [InlineData(@"()()\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 6)]
         [InlineData(@"()()(?n)\1\2", RegexOptions.None, null)]
-        [InlineData(@"()(?n)()\1\2", RegexOptions.None, RegexParseError.UndefinedBackref)]
-        [InlineData(@"(?n)()()\1\2", RegexOptions.None, RegexParseError.UndefinedBackref)]
-        [InlineData(@"()()(?n)\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
-        [InlineData(@"()(?n)()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
-        [InlineData(@"(?n)()()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
+        [InlineData(@"()(?n)()\1\2", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 12)]
+        [InlineData(@"(?n)()()\1\2", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 10)]
+        [InlineData(@"()()(?n)\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 10)]
+        [InlineData(@"()(?n)()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 10)]
+        [InlineData(@"(?n)()()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 10)]
         [InlineData(@"()()(?-n)\1\2", RegexOptions.None, null)]
         [InlineData(@"()(?-n)()\1\2", RegexOptions.None, null)]
         [InlineData(@"(?-n)()()\1\2", RegexOptions.None, null)]
-        [InlineData(@"()()(?-n)\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
-        [InlineData(@"()(?-n)()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
+        [InlineData(@"()()(?-n)\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 11)]
+        [InlineData(@"()(?-n)()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 13)]
         [InlineData(@"(?-n)()()\1\2", RegexOptions.ExplicitCapture, null)]
         [InlineData(@"()()(?n:\1\2)", RegexOptions.None, null)]
-        [InlineData(@"()()(?n:\1\2)", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
+        [InlineData(@"()()(?n:\1\2)", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 10)]
         [InlineData(@"()()(?-n:\1\2)", RegexOptions.None, null)]
-        [InlineData(@"()()(?-n:\1\2)", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
+        [InlineData(@"()()(?-n:\1\2)", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 11)]
         [InlineData(@"(?n:)()()\1\2", RegexOptions.None, null)]
-        [InlineData(@"(?n:)()()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
+        [InlineData(@"(?n:)()()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 11)]
         [InlineData(@"(?-n:)()()\1\2", RegexOptions.None, null)]
-        [InlineData(@"(?-n:)()()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
+        [InlineData(@"(?-n:)()()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 12)]
         [InlineData(@"(?n)(?-n)()()\1\2", RegexOptions.None, null)]
         [InlineData(@"(?n)(?-n)()()\1\2", RegexOptions.ExplicitCapture, null)]
-        [InlineData(@"(?-n)(?n)()()\1\2", RegexOptions.None, RegexParseError.UndefinedBackref)]
-        [InlineData(@"(?-n)(?n)()()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedBackref)]
+        [InlineData(@"(?-n)(?n)()()\1\2", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 15)]
+        [InlineData(@"(?-n)(?n)()()\1\2", RegexOptions.ExplicitCapture, RegexParseError.UndefinedNumberedReference, 15)]
         // References
         [InlineData(@"[aeiou]", RegexOptions.None, null)]
         [InlineData(@"(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)", RegexOptions.None, null)]
@@ -474,7 +461,7 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(@"[\p{IsBasicLatin}-[\x00-\x7F]]", RegexOptions.None, null)]
         [InlineData(@"[\u0000-\uFFFF-[\s\p{P}\p{IsGreek}\x85]]", RegexOptions.None, null)]
         [InlineData(@"[a-z-[d-w-[m-o]]]", RegexOptions.None, null)]
-        [InlineData(@"((\w+(\s?)){2,}", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
+        [InlineData(@"((\w+(\s?)){2,}", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 15)]
         [InlineData(@"[a-z-[djp]]", RegexOptions.None, null)]
         [InlineData(@"(\w)\1+.\b", RegexOptions.None, null)]
         [InlineData(@"\d{4}\b", RegexOptions.None, null)]
@@ -578,258 +565,173 @@ namespace System.Text.RegularExpressions.Tests
         [InlineData(@"\bgr[ae]y\b", RegexOptions.None, null)]
         [InlineData(@"\b((?# case sensitive comparison)D\w+)\s(?ixn)((?#case insensitive comparison)d\w+)\b", RegexOptions.None, null)]
         [InlineData(@"\{\d+(,-*\d+)*(\:\w{1,4}?)*\}(?x) # Looks for a composite format item.", RegexOptions.None, null)]
-        // Negative tests
-        [InlineData(@"cat([a-\d]*)dog", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"\k<1", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"(?')", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"(?<)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"(?imn )", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?imn", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?'cat'", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData(@"(?'", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?'=)", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?'!)", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"[^", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[cat", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[^cat", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"\p{cat", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData(@"\k<cat", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"\p{cat}", RegexOptions.None, RegexParseError.UnknownUnicodeProperty)]
-        [InlineData(@"\P{cat", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData(@"\P{cat}", RegexOptions.None, RegexParseError.UnknownUnicodeProperty)]
-        [InlineData(@"(?<cat>", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData(@"\P{", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData(@"\k<>", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"(?(", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData(@"(?()|", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData(@"?(a|b)", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData(@"?((a)", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData(@"?((a)a", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData(@"?((a)a|", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData(@"?((a)a|b", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData(@"?(a)", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData(@"[a", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"?(a:b)", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData(@"(?(?", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(cat", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData(@"(?(cat)|", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        [InlineData(@"foo(?<0>bar)", RegexOptions.None, RegexParseError.CapnumNotZero)]
-        [InlineData(@"foo(?'0'bar)", RegexOptions.None, RegexParseError.CapnumNotZero)]
-        [InlineData(@"foo(?<1bar)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"foo(?'1bar)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"\p{klsak", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData(@"(?c:cat)", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(??e:cat)", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"[a-f-[]]+", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"[A-[]+", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData(@"(?(?e))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?a)", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?r:cat)", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"\x2", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"(cat) (?#cat)    \s+ (?#followed by 1 or more whitespace", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnterminatedComment)]
-        [InlineData(@"cat(?(?afdcat)dog)", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"cat(?(?<cat>cat)dog)", RegexOptions.None, RegexParseError.AlternationCantCapture)]
-        [InlineData(@"cat(?(?'cat'cat)dog)", RegexOptions.None, RegexParseError.AlternationCantCapture)]
-        [InlineData(@"cat(?(?#COMMENT)cat)", RegexOptions.None, RegexParseError.AlternationCantHaveComment)]
-        [InlineData(@"cat(?<>dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"cat(?<dog<>)_*>dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"cat(?<dog >)_*>dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"cat(?<dog!>)_*>dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"cat(?<dog)_*>dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"cat(?<1dog>dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"cat(?<0>dog)", RegexOptions.None, RegexParseError.CapnumNotZero)]
-        [InlineData(@"([5-\D]*)dog", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"cat([6-\s]*)dog", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"cat([c-\S]*)", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"cat([7-\w]*)", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"cat([a-\W]*)dog", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"([f-\p{Lu}]\w*)\s([\p{Lu}]\w*)", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"(cat) (?#cat)    \s+ (?#followed by 1 or more whitespace", RegexOptions.None, RegexParseError.UnterminatedComment)]
-        [InlineData(@"([1-\P{Ll}][\p{Ll}]*)\s([\P{Ll}][\p{Ll}]*)", RegexOptions.None, RegexParseError.BadClassInCharRange)]
-        [InlineData(@"[\P]", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData(@"([\pcat])", RegexOptions.None, RegexParseError.MalformedSlashP)]
-        [InlineData(@"([\Pcat])", RegexOptions.None, RegexParseError.MalformedSlashP)]
-        [InlineData(@"(\p{", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData(@"(\p{Ll", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData(@"(cat)([\o]*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedEscape)]
-        [InlineData(@"[\p]", RegexOptions.None, RegexParseError.IncompleteSlashP)]
-        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\kcat", RegexOptions.None, RegexParseError.MalformedNameRef)]
-        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k<cat2>", RegexOptions.None, RegexParseError.UndefinedNameRef)]
-        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k<8>cat", RegexOptions.None, RegexParseError.UndefinedBackref)]
-        [InlineData(@"^[abcd]{1}?*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]*+$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]+*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]?*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]*?+$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]+?*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]{1,}?*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]??*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]+{0,5}$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]?{0,5}$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"\ua", RegexOptions.None, RegexParseError.TooFewHex)]
-        [InlineData(@"^[abcd]*{0,5}$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]{0,16}?*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"^[abcd]{1,}*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k<8>cat", RegexOptions.ECMAScript, RegexParseError.UndefinedBackref)]
-        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k8", RegexOptions.None, RegexParseError.MalformedNameRef)]
-        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k8", RegexOptions.ECMAScript, RegexParseError.MalformedNameRef)]
-        [InlineData(@"(cat)(\7)", RegexOptions.None, RegexParseError.UndefinedBackref)]
-        [InlineData(@"(cat)\s+(?<2147483648>dog)", RegexOptions.None, RegexParseError.CaptureGroupOutOfRange)]
-        [InlineData(@"(cat)\s+(?<21474836481097>dog)", RegexOptions.None, RegexParseError.CaptureGroupOutOfRange)]
-        [InlineData(@"^[abcd]{1}*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"(cat)(\c*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"(cat)(\c *)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"(cat)(\c?*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"(cat)(\c`*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"(cat)(\c\|*)(dog)", RegexOptions.None, RegexParseError.QuantifyAfterNothing)]
-        [InlineData(@"^[abcd]{0,16}*$", RegexOptions.None, RegexParseError.NestedQuantify)]
-        [InlineData(@"(cat)\c", RegexOptions.None, RegexParseError.MissingControl)]
-        // Deep recursion
-        [InlineData(@"@""((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((""", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        // Scan control
-        [InlineData("(cat)(\\c\0*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControl)]
-        [InlineData(@"(cat)(\c\[*)(dog)", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        // Invalid grouping constructs
-        [InlineData("(?<", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?>-", RegexOptions.None, RegexParseError.NotEnoughParentheses)]
-        // Testgroup with options
-        [InlineData("())", RegexOptions.None, RegexParseError.TooManyParentheses)]
-        [InlineData("[a-z-[aeiuo]", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData("[a-z-[aeiuo", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData("[a-z-[b]", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData("[a-z-[b", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData("[b-a]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[a-c]{2,1}", RegexOptions.None, RegexParseError.IllegalRange)]
-        [InlineData(@"\d{2147483648}", RegexOptions.None, RegexParseError.CaptureGroupOutOfRange)]
-        [InlineData("[a-z-[b][", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        [InlineData("(?()|||||)", RegexOptions.None, RegexParseError.TooManyAlternates)]
-        [InlineData("[^]", RegexOptions.None, RegexParseError.UnterminatedBracket)]
-        public void Parse(string pattern, RegexOptions options, object errorObj)
+        public void Parse(string pattern, RegexOptions options, object errorObj, int offset = -1)
         {
             RegexParseError? error = (RegexParseError?)errorObj;
 
+            Assert.True(error == null || offset > 0, "All tests must be given positive offsets, or null if no offset should be tested.");
+
             // Parse the main tree and if parsing fails check if the supplied error matches.
-            ParseTree(pattern, options, error);
+            ParseTree(pattern, options, error, offset);
 
             // Assert that only ArgumentException might be thrown during parsing.
             ParseSubTrees(pattern, options);
         }
 
         [Theory]
-        [InlineData(@"[a-\-]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[a-\-b]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[a-\-\-b]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[a-\-\D]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[a-\-\-\D]", RegexOptions.None, RegexParseError.ReversedCharRange)]
-        [InlineData(@"[a -\-\b]", RegexOptions.None, null)]
-        // OutOfMemoryException
-        [InlineData("a{2147483647}", RegexOptions.None, null)]
-        [InlineData("a{2147483647,}", RegexOptions.None, null)]
-        [InlineData(@"(?(?N))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?i))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?I))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?M))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?s))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?S))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?x))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?X))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?n))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(" (?(?n))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"(?(?m))", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        // IndexOutOfRangeException
-        [InlineData("(?<-", RegexOptions.None, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?<-", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData(@"^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$", RegexOptions.None, null)]
-        [InlineData(@"((?'Close-Open'>)[^<>]*)+", RegexOptions.None, RegexParseError.UndefinedNameRef)]
-        [InlineData(@"(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*", RegexOptions.None, null)]
-        [InlineData(@"(?'Close-Open'>)", RegexOptions.None, RegexParseError.UndefinedNameRef)]
-        [InlineData("(?<a-00>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<a>)()(?<-0>)(?<-1>)(?<-2>)(?<-3>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("()(?<a>)(?<-0>)(?<-1>)(?<-2>)(?<-3>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("()()(?<-0>)(?<-1>)(?<-2>)(?<-3>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("(?<a>)(?<b>)(?<-1>)(?<-2>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<-4>)(?<4>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<4>)(?<-4>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<a>)(?<-a>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<-a>)(?<a>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<a-0>", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
-        [InlineData("(?<a-0>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<a-0 >)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<a- 0 >)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<a- 0>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<-1>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("()(?<-1>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<-1>)()", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<-00>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<a-", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?<a-0", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?<a-0)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<a>)(?<b>)(?<-0>)(?<-1>)(?<-2>)(?<-3>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)()()", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)()(?", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)()(?<a>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)(?<a>)()", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)(?<a>)(?", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)(?<a>)(?<b>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedBackref)]
-        [InlineData("(?<a-0>)(?<b-a>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<a-0>)(?<-a>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<a-a>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<-0>)", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<-0 >)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<- 0 >)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<- 0>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<a-0')", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?'a-0>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?'-0')", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?'a-0')", RegexOptions.IgnorePatternWhitespace, null)]
-        [InlineData("(?<-0", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnrecognizedGrouping)]
-        [InlineData("(?<-0)", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupName)]
-        [InlineData("(?<-0>", RegexOptions.IgnorePatternWhitespace, RegexParseError.NotEnoughParentheses)]
-        [InlineData(@"(?<cat>cat)\w+(?<dog-()*!@>dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"(?<cat>cat)\w+(?<dog-catdog>dog)", RegexOptions.None, RegexParseError.UndefinedNameRef)]
-        [InlineData(@"(?<cat>cat)\w+(?<dog-1uosn>dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData(@"(?<cat>cat)\w+(?<dog-16>dog)", RegexOptions.None, RegexParseError.UndefinedBackref)]
-        [InlineData(@"cat(?<->dog)", RegexOptions.None, RegexParseError.InvalidGroupName)]
-        [InlineData("a{2147483648}", RegexOptions.None, RegexParseError.CaptureGroupOutOfRange)]
-        [InlineData("a{2147483648,}", RegexOptions.None, RegexParseError.CaptureGroupOutOfRange)]
-        [InlineData("a{0,2147483647}", RegexOptions.None, null)]
-        [InlineData("a{0,2147483648}", RegexOptions.None, RegexParseError.CaptureGroupOutOfRange)]
-        // Surrogate pair which is parsed as [char,char-char,char] as we operate on UTF-16 code units.
-        [InlineData("[\uD82F\uDCA0-\uD82F\uDCA3]", RegexOptions.IgnoreCase, RegexParseError.ReversedCharRange)]
-        [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
-        public void Parse_NotNetFramework(string pattern, RegexOptions options, object error)
-        {
-            Parse(pattern, options, error);
-        }
-
-        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))]
-        [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
-        public void RegexParseException_Serializes()
+        // Negative tests
+        [InlineData(@"cat([a-\d]*)dog", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 9)]
+        [InlineData(@"\k<1", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"(?')", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 3)]
+        [InlineData(@"(?<)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 3)]
+        [InlineData(@"(?imn )", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 6)]
+        [InlineData(@"(?imn", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?'cat'", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 7)]
+        [InlineData(@"(?'", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData(@"(?'=)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 4)]
+        [InlineData(@"(?'!)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 4)]
+        [InlineData(@"[^", RegexOptions.None, RegexParseError.UnterminatedBracket, 2)]
+        [InlineData(@"[cat", RegexOptions.None, RegexParseError.UnterminatedBracket, 4)]
+        [InlineData(@"[^cat", RegexOptions.None, RegexParseError.UnterminatedBracket, 5)]
+        [InlineData(@"\p{cat", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 6)]
+        [InlineData(@"\k<cat", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"\p{cat}", RegexOptions.None, RegexParseError.UnrecognizedUnicodeProperty, 7)]
+        [InlineData(@"\P{cat", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 6)]
+        [InlineData(@"\P{cat}", RegexOptions.None, RegexParseError.UnrecognizedUnicodeProperty, 7)]
+        [InlineData(@"(?<cat>", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 7)]
+        [InlineData(@"\P{", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 2)]
+        [InlineData(@"\k<>", RegexOptions.None, RegexParseError.UnrecognizedEscape, 2)]
+        [InlineData(@"(?(", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 3)]
+        [InlineData(@"(?()|", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 5)]
+        [InlineData(@"?(a|b)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData(@"?((a)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData(@"?((a)a", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData(@"?((a)a|", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData(@"?((a)a|b", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData(@"?(a)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData(@"[a", RegexOptions.None, RegexParseError.UnterminatedBracket, 2)]
+        [InlineData(@"?(a:b)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData(@"(?(?", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 4)]
+        [InlineData(@"(?(cat", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 6)]
+        [InlineData(@"(?(cat)|", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 8)]
+        [InlineData(@"foo(?<0>bar)", RegexOptions.None, RegexParseError.CaptureGroupOfZero, 7)]
+        [InlineData(@"foo(?'0'bar)", RegexOptions.None, RegexParseError.CaptureGroupOfZero, 7)]
+        [InlineData(@"foo(?<1bar)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 7)]
+        [InlineData(@"foo(?'1bar)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 7)]
+        [InlineData(@"\p{klsak", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 8)]
+        [InlineData(@"(?c:cat)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData(@"(??e:cat)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData(@"[a-f-[]]+", RegexOptions.None, RegexParseError.UnterminatedBracket, 9)]
+        [InlineData(@"[A-[]+", RegexOptions.None, RegexParseError.UnterminatedBracket, 6)]
+        [InlineData(@"(?(?e))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?a)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?r:cat)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData(@"\x2", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"(cat) (?#cat)    \s+ (?#followed by 1 or more whitespace", RegexOptions.IgnorePatternWhitespace, RegexParseError.UnterminatedComment, 56)]
+        [InlineData(@"cat(?(?afdcat)dog)", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 8)]
+        [InlineData(@"cat(?(?<cat>cat)dog)", RegexOptions.None, RegexParseError.AlternationHasNamedCapture, 5)]
+        [InlineData(@"cat(?(?'cat'cat)dog)", RegexOptions.None, RegexParseError.AlternationHasNamedCapture, 5)]
+        [InlineData(@"cat(?(?#COMMENT)cat)", RegexOptions.None, RegexParseError.AlternationHasComment, 5)]
+        [InlineData(@"cat(?<>dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 6)]
+        [InlineData(@"cat(?<dog<>)_*>dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 9)]
+        [InlineData(@"cat(?<dog >)_*>dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 9)]
+        [InlineData(@"cat(?<dog!>)_*>dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 9)]
+        [InlineData(@"cat(?<dog)_*>dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 9)]
+        [InlineData(@"cat(?<1dog>dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 7)]
+        [InlineData(@"cat(?<0>dog)", RegexOptions.None, RegexParseError.CaptureGroupOfZero, 7)]
+        [InlineData(@"([5-\D]*)dog", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 6)]
+        [InlineData(@"cat([6-\s]*)dog", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 9)]
+        [InlineData(@"cat([c-\S]*)", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 9)]
+        [InlineData(@"cat([7-\w]*)", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 9)]
+        [InlineData(@"cat([a-\W]*)dog", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 9)]
+        [InlineData(@"([f-\p{Lu}]\w*)\s([\p{Lu}]\w*)", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 6)]
+        [InlineData(@"(cat) (?#cat)    \s+ (?#followed by 1 or more whitespace", RegexOptions.None, RegexParseError.UnterminatedComment, 56)]
+        [InlineData(@"([1-\P{Ll}][\p{Ll}]*)\s([\P{Ll}][\p{Ll}]*)", RegexOptions.None, RegexParseError.ShorthandClassInCharacterRange, 6)]
+        [InlineData(@"[\P]", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 3)]
+        [InlineData(@"([\pcat])", RegexOptions.None, RegexParseError.MalformedUnicodePropertyEscape, 5)]
+        [InlineData(@"([\Pcat])", RegexOptions.None, RegexParseError.MalformedUnicodePropertyEscape, 5)]
+        [InlineData(@"(\p{", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 3)]
+        [InlineData(@"(\p{Ll", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 6)]
+        [InlineData(@"(cat)([\o]*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedEscape, 9)]
+        [InlineData(@"[\p]", RegexOptions.None, RegexParseError.InvalidUnicodePropertyEscape, 3)]
+        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\kcat", RegexOptions.None, RegexParseError.MalformedNamedReference, 28)]
+        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k<cat2>", RegexOptions.None, RegexParseError.UndefinedNamedReference, 33)]
+        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k<8>cat", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 30)]
+        [InlineData(@"^[abcd]{1}?*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 12)]
+        [InlineData(@"^[abcd]*+$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 9)]
+        [InlineData(@"^[abcd]+*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 9)]
+        [InlineData(@"^[abcd]?*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 9)]
+        [InlineData(@"^[abcd]*?+$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 10)]
+        [InlineData(@"^[abcd]+?*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 10)]
+        [InlineData(@"^[abcd]{1,}?*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 13)]
+        [InlineData(@"^[abcd]??*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 10)]
+        [InlineData(@"^[abcd]+{0,5}$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 9)]
+        [InlineData(@"^[abcd]?{0,5}$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 9)]
+        [InlineData(@"\ua", RegexOptions.None, RegexParseError.InsufficientOrInvalidHexDigits, 2)]
+        [InlineData(@"^[abcd]*{0,5}$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 9)]
+        [InlineData(@"^[abcd]{0,16}?*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 15)]
+        [InlineData(@"^[abcd]{1,}*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 12)]
+        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k<8>cat", RegexOptions.ECMAScript, RegexParseError.UndefinedNumberedReference, 30)]
+        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k8", RegexOptions.None, RegexParseError.MalformedNamedReference, 28)]
+        [InlineData(@"(?<cat>cat)\s+(?<dog>dog)\k8", RegexOptions.ECMAScript, RegexParseError.MalformedNamedReference, 28)]
+        [InlineData(@"(cat)(\7)", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 8)]
+        [InlineData(@"(cat)\s+(?<2147483648>dog)", RegexOptions.None, RegexParseError.QuantifierOrCaptureGroupOutOfRange, 21)]
+        [InlineData(@"(cat)\s+(?<21474836481097>dog)", RegexOptions.None, RegexParseError.QuantifierOrCaptureGroupOutOfRange, 21)]
+        [InlineData(@"^[abcd]{1}*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 11)]
+        [InlineData(@"(cat)(\c*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 9)]
+        [InlineData(@"(cat)(\c *)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 9)]
+        [InlineData(@"(cat)(\c?*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 9)]
+        [InlineData(@"(cat)(\c`*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 9)]
+        [InlineData(@"(cat)(\c\|*)(dog)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 11)]
+        [InlineData(@"^[abcd]{0,16}*$", RegexOptions.None, RegexParseError.NestedQuantifiersNotParenthesized, 14)]
+        [InlineData(@"(cat)\c", RegexOptions.None, RegexParseError.MissingControlCharacter, 7)]
+        // Deep recursion
+        [InlineData(@"((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((" +
+"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 1183)]
+        // Scan control
+        [InlineData("(cat)(\\c\0*)(dog)", RegexOptions.None, RegexParseError.UnrecognizedControlCharacter, 9)]
+        [InlineData(@"(cat)(\c\[*)(dog)", RegexOptions.None, RegexParseError.UnterminatedBracket, 17)]
+        // Invalid grouping constructs
+        [InlineData("(?<", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData("(?>-", RegexOptions.None, RegexParseError.InsufficientClosingParentheses, 4)]
+        // Testgroup with options
+        [InlineData("())", RegexOptions.None, RegexParseError.InsufficientOpeningParentheses, 3)]
+        [InlineData("[a-z-[aeiuo]", RegexOptions.None, RegexParseError.UnterminatedBracket, 12)]
+        [InlineData("[a-z-[aeiuo", RegexOptions.None, RegexParseError.UnterminatedBracket, 11)]
+        [InlineData("[a-z-[b]", RegexOptions.None, RegexParseError.UnterminatedBracket, 8)]
+        [InlineData("[a-z-[b", RegexOptions.None, RegexParseError.UnterminatedBracket, 7)]
+        [InlineData("[b-a]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 4)]
+        [InlineData(@"[a-c]{2,1}", RegexOptions.None, RegexParseError.ReversedQuantifierRange, 10)]
+        [InlineData(@"\d{2147483648}", RegexOptions.None, RegexParseError.QuantifierOrCaptureGroupOutOfRange, 13)]
+        [InlineData("[a-z-[b][", RegexOptions.None, RegexParseError.UnterminatedBracket, 9)]
+        [InlineData("(?()|||||)", RegexOptions.None, RegexParseError.AlternationHasTooManyConditions, 10)]
+        [InlineData("[^]", RegexOptions.None, RegexParseError.UnterminatedBracket, 3)]
+        [InlineData("\\", RegexOptions.None, RegexParseError.UnescapedEndingBackslash, 1)]
+        [InlineData("??", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 1)]
+        [InlineData("(?=*)", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 4)]
+        [InlineData("((((((*))))))", RegexOptions.None, RegexParseError.QuantifierAfterNothing, 7)]
+        public void ParseCheckOffset(string pattern, RegexOptions options, object errorObj, int offset)
         {
-#pragma warning disable RE0001 // Regex issue: Not enough )'s
-            ArgumentException e = Assert.ThrowsAny<ArgumentException>(() => new Regex("(abc|def"));
-#pragma warning restore RE0001 // Regex issue: Not enough )'s
+            RegexParseError? error = (RegexParseError?)errorObj;
 
-            var bf = new BinaryFormatter();
-            var s = new MemoryStream();
-            bf.Serialize(s, e);
-            s.Position = 0;
+            // Parse the main tree and if parsing fails check if the supplied error matches.
+            ParseTree(pattern, options, error, offset);
 
-            ArgumentException e2 = (ArgumentException)bf.Deserialize(s);
-            Assert.Equal(e.Message, e2.Message);
+            // Assert that only ArgumentException might be thrown during parsing.
+            ParseSubTrees(pattern, options);
         }
 
+
         private static void ParseSubTrees(string pattern, RegexOptions options)
         {
             // Trim the input from the right and make sure tree invariants hold
@@ -851,11 +753,11 @@ namespace System.Text.RegularExpressions.Tests
             }
         }
 
-        private static void ParseTree(string pattern, RegexOptions options, RegexParseError? error)
+        static void ParseTree(string pattern, RegexOptions options, RegexParseError? error, int offset)
         {
             if (error != null)
             {
-                Throws(error.Value, () => new Regex(pattern, options));
+                Throws(error.Value, offset, () => new Regex(pattern, options));
                 return;
             }
 
@@ -875,45 +777,6 @@ namespace System.Text.RegularExpressions.Tests
             }
         }
 
-        /// <summary>
-        /// Checks if action throws either a RegexParseException or an ArgumentException depending on the
-        /// environment and the supplied error.
-        /// </summary>
-        /// <param name="error">The expected parse error</param>
-        /// <param name="action">The action to invoke.</param>
-        private static void Throws(RegexParseError error, Action action)
-        {
-            // If no specific error is supplied, or we are running on .NET Framework where RegexParseException doesn't exist
-            // we expect an ArgumentException.
-            if (PlatformDetection.IsNetFramework)
-            {
-                Assert.ThrowsAny<ArgumentException>(action);
-                return;
-            }
-
-            try
-            {
-                action();
-            }
-            catch (ArgumentException e)
-            {
-                // We use reflection to check if the exception is an internal RegexParseException
-                // and extract its error property and compare with the given one.
-                if (e.GetType() == s_parseExceptionType)
-                {
-                    RegexParseError regexParseError = (RegexParseError)s_parseErrorField.GetValue(e);
-
-                    // Success if provided error matches.
-                    if (error == regexParseError)
-                        return;
-
-                    throw new XunitException($"Expected RegexParseException with error: ({error}) -> Actual error: {regexParseError})");
-                }
-
-                throw new XunitException($"Expected RegexParseException -> Actual: ({e.GetType()})");
-            }
-
-            throw new XunitException($"Expected RegexParseException with error: ({error}) -> Actual: No exception thrown");
-        }
+        static partial void Throws(RegexParseError error, int offset, Action action);
     }
 }
diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netcoreapp.cs
new file mode 100644 (file)
index 0000000..349ec28
--- /dev/null
@@ -0,0 +1,150 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.IO;
+using System.Runtime.Serialization.Formatters.Binary;
+using Xunit;
+using Xunit.Sdk;
+
+namespace System.Text.RegularExpressions.Tests
+{
+    public partial class RegexParserTests
+    {
+        [Theory]
+        [InlineData(@"[a-\-]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)]
+        [InlineData(@"[a-\-b]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)]
+        [InlineData(@"[a-\-\-b]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)]
+        [InlineData(@"[a-\-\D]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)]
+        [InlineData(@"[a-\-\-\D]", RegexOptions.None, RegexParseError.ReversedCharacterRange, 5)]
+        [InlineData(@"[a -\-\b]", RegexOptions.None, null, 5)]
+        // OutOfMemoryException
+        [InlineData("a{2147483647}", RegexOptions.None, null)]
+        [InlineData("a{2147483647,}", RegexOptions.None, null)]
+        [InlineData(@"(?(?N))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?i))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?I))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?M))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?s))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?S))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?x))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?X))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?n))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData(@"(?(?m))", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 5)]
+        // IndexOutOfRangeException
+        [InlineData("(?<-", RegexOptions.None, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData("(?<-", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 3)]
+        [InlineData(@"^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$", RegexOptions.None, null)]
+        [InlineData(@"((?'Close-Open'>)[^<>]*)+", RegexOptions.None, RegexParseError.UndefinedNamedReference, 14)]
+        [InlineData(@"(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*", RegexOptions.None, null)]
+        [InlineData(@"(?'Close-Open'>)", RegexOptions.None, RegexParseError.UndefinedNamedReference, 13)]
+        [InlineData("(?<a-00>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<a>)()(?<-0>)(?<-1>)(?<-2>)(?<-3>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 34)]
+        [InlineData("()(?<a>)(?<-0>)(?<-1>)(?<-2>)(?<-3>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 34)]
+        [InlineData("()()(?<-0>)(?<-1>)(?<-2>)(?<-3>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 30)]
+        [InlineData("(?<a>)(?<b>)(?<-1>)(?<-2>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<-4>)(?<4>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<4>)(?<-4>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<a>)(?<-a>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<-a>)(?<a>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<a-0>", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 7)]
+        [InlineData("(?<a-0>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<a-0 >)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 6)]
+        [InlineData("(?<a- 0 >)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 5)]
+        [InlineData("(?<a- 0>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 5)]
+        [InlineData("(?<-1>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 5)]
+        [InlineData("()(?<-1>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<-1>)()", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<-00>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<a-", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData("(?<a-0", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 6)]
+        [InlineData("(?<a-0)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 6)]
+        [InlineData("(?<a>)(?<b>)(?<-0>)(?<-1>)(?<-2>)(?<-3>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 38)]
+        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)()()", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 26)]
+        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)()(?", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 19)]
+        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)()(?<a>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 26)]
+        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)(?<a>)()", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 26)]
+        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)(?<a>)(?", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 19)]
+        [InlineData("(?<-0>)(?<-1>)(?<-2>)(?<-3>)(?<a>)(?<b>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.UndefinedNumberedReference, 26)]
+        [InlineData("(?<a-0>)(?<b-a>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<a-0>)(?<-a>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<a-a>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<-0>)", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<-0 >)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 5)]
+        [InlineData("(?<- 0 >)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 4)]
+        [InlineData("(?<- 0>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 4)]
+        [InlineData("(?<a-0')", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 6)]
+        [InlineData("(?'a-0>)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 6)]
+        [InlineData("(?'-0')", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?'a-0')", RegexOptions.IgnorePatternWhitespace, null)]
+        [InlineData("(?<-0", RegexOptions.IgnorePatternWhitespace, RegexParseError.InvalidGroupingConstruct, 5)]
+        [InlineData("(?<-0)", RegexOptions.IgnorePatternWhitespace, RegexParseError.CaptureGroupNameInvalid, 5)]
+        [InlineData("(?<-0>", RegexOptions.IgnorePatternWhitespace, RegexParseError.InsufficientClosingParentheses, 6)]
+        [InlineData(@"(?<cat>cat)\w+(?<dog-()*!@>dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 21)]
+        [InlineData(@"(?<cat>cat)\w+(?<dog-catdog>dog)", RegexOptions.None, RegexParseError.UndefinedNamedReference, 27)]
+        [InlineData(@"(?<cat>cat)\w+(?<dog-1uosn>dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 22)]
+        [InlineData(@"(?<cat>cat)\w+(?<dog-16>dog)", RegexOptions.None, RegexParseError.UndefinedNumberedReference, 23)]
+        [InlineData(@"cat(?<->dog)", RegexOptions.None, RegexParseError.CaptureGroupNameInvalid, 7)]
+        [InlineData("a{2147483648}", RegexOptions.None, RegexParseError.QuantifierOrCaptureGroupOutOfRange, 12)]
+        [InlineData("a{2147483648,}", RegexOptions.None, RegexParseError.QuantifierOrCaptureGroupOutOfRange, 12)]
+        [InlineData("a{0,2147483647}", RegexOptions.None, null)]
+        [InlineData("a{0,2147483648}", RegexOptions.None, RegexParseError.QuantifierOrCaptureGroupOutOfRange, 14)]
+        // Surrogate pair which is parsed as [char,char-char,char] as we operate on UTF-16 code units.
+        [InlineData("[\uD82F\uDCA0-\uD82F\uDCA3]", RegexOptions.IgnoreCase, RegexParseError.ReversedCharacterRange, 5)]
+        [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
+        public void Parse_Netcoreapp(string pattern, RegexOptions options, object error, int offset = -1)
+        {
+            Parse(pattern, options, error, offset);
+        }
+
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBinaryFormatterSupported))]
+        public void RegexParseException_Serializes()
+        {
+#pragma warning disable RE0001 // Regex issue: Not enough )'s
+            ArgumentException e = Assert.ThrowsAny<ArgumentException>(() => new Regex("(abc|def"));
+#pragma warning restore RE0001 // Regex issue: Not enough )'s
+
+            var bf = new BinaryFormatter();
+            var s = new MemoryStream();
+            bf.Serialize(s, e);
+            s.Position = 0;
+
+            object deserialized = bf.Deserialize(s);
+            Assert.IsType<ArgumentException>(deserialized);
+            ArgumentException e2 = (ArgumentException)deserialized;
+            Assert.Equal(e.Message, e2.Message);
+        }
+
+        /// <summary>
+        /// Checks if action throws either a RegexParseException or an ArgumentException depending on the
+        /// environment and the supplied error.
+        /// </summary>
+        /// <param name="error">The expected parse error</param>
+        /// <param name="action">The action to invoke.</param>
+        static partial void Throws(RegexParseError error, int offset, Action action)
+        {
+            try
+            {
+                action();
+            }
+            catch (RegexParseException e)
+            {
+                RegexParseError regexParseError = e.Error;
+
+                // Success if provided error matches and offset is correct.
+                if (error == regexParseError)
+                {
+                    Assert.Equal(offset, e.Offset);
+                    return;
+                }
+
+                throw new XunitException($"Expected RegexParseException with error: ({error}) -> Actual error: {regexParseError})");
+            }
+            catch (Exception e)
+            { 
+                throw new XunitException($"Expected RegexParseException -> Actual: ({e})");
+            }
+
+            throw new XunitException($"Expected RegexParseException with error: ({error}) -> Actual: No exception thrown");
+        }
+    }
+}
diff --git a/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs b/src/libraries/System.Text.RegularExpressions/tests/RegexParserTests.netfx.cs
new file mode 100644 (file)
index 0000000..4e9006e
--- /dev/null
@@ -0,0 +1,38 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.IO;
+using System.Runtime.Serialization.Formatters.Binary;
+using Xunit;
+using Xunit.Sdk;
+
+namespace System.Text.RegularExpressions.Tests
+{
+    public partial class RegexParserTests
+    {
+        /// <summary>
+        /// Checks if action throws either a RegexParseException or an ArgumentException depending on the
+        /// environment and the supplied error.
+        /// </summary>
+        /// <param name="error">The expected parse error</param>
+        /// <param name="action">The action to invoke.</param>
+        static partial void Throws(RegexParseError error, int offset, Action action)
+        {
+            try
+            {
+                action();
+            }
+            catch (ArgumentException)
+            {
+                // On NetFramework, all we care about is whether the exception is thrown.
+                return;
+            }
+            catch (Exception e)
+            { 
+                throw new XunitException($"Expected ArgumentException -> Actual: {e}");
+            }
+
+            throw new XunitException($"Expected ArgumentException with error: ({error}) -> Actual: No exception thrown");
+        }
+    }
+}
index 20878ca..fade03b 100644 (file)
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <IncludeRemoteExecutor>true</IncludeRemoteExecutor>
     <!-- xUnit2008 is about regexes and isn't appropriate in the test project for regexes -->
     <Compile Include="RegexMatchTimeoutExceptionTests.cs" />
     <Compile Include="RegexParserTests.cs" />
     <Compile Include="RegexReductionTests.cs" />
+  </ItemGroup>
+  <ItemGroup Condition="'$(TargetFramework)' == 'net48'">
     <Compile Include="..\src\System\Text\RegularExpressions\RegexParseError.cs"
              Link="System\Text\RegularExpressions\RegexParseError.cs" />
+    <Compile Include="RegexParserTests.netfx.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'">
+    <Compile Include="RegexParserTests.netcoreapp.cs" />
     <Compile Include="GroupCollectionReadOnlyDictionaryTests.cs" />
     <Compile Include="CaptureCollectionTests2.cs" />
     <Compile Include="GroupCollectionTests2.cs" />