diff options
author | Raja R Harinath <harinath@hurrynot.org> | 2009-08-10 20:25:10 +0400 |
---|---|---|
committer | Raja R Harinath <harinath@hurrynot.org> | 2009-08-10 20:25:10 +0400 |
commit | 1163a482f7430930bee670cf4c6721ecf9880974 (patch) | |
tree | a7cb46987500bade937b88e311a46b75a7b6c05a | |
parent | 54481772e913d5b487e48f3a0301786fc00f7c78 (diff) |
regexp backreferences: Implement fallback to octal numbers, and ECMAScript semantics.moon-1.99.1
* syntax.cs (BackslashNumber.ResolveReference): Implement fallback
to octal numbers, and ECMAScript semantics.
* parser.cs (ResolveReferences): Use it.
* RegexMatchTests.cs (RegexTrial0054..60): New.
svn path=/trunk/mcs/; revision=139657
5 files changed, 77 insertions, 1 deletions
diff --git a/mcs/class/System/System.Text.RegularExpressions/ChangeLog b/mcs/class/System/System.Text.RegularExpressions/ChangeLog index e6e83332e02..c71706ec268 100644 --- a/mcs/class/System/System.Text.RegularExpressions/ChangeLog +++ b/mcs/class/System/System.Text.RegularExpressions/ChangeLog @@ -1,5 +1,11 @@ 2009-08-10 Raja R Harinath <harinath@hurrynot.org> + * syntax.cs (BackslashNumber.ResolveReference): Implement fallback + to octal numbers, and ECMAScript semantics. + * parser.cs (ResolveReferences): Use it. + +2009-08-10 Raja R Harinath <harinath@hurrynot.org> + * syntax.cs (BackslashNumber): New class. * parser.cs (ParseSpecial): Create it instead of 'Reference' if a numeric backreference is seen. diff --git a/mcs/class/System/System.Text.RegularExpressions/parser.cs b/mcs/class/System/System.Text.RegularExpressions/parser.cs index ee115c17556..96c2025ca31 100644 --- a/mcs/class/System/System.Text.RegularExpressions/parser.cs +++ b/mcs/class/System/System.Text.RegularExpressions/parser.cs @@ -1102,6 +1102,9 @@ namespace System.Text.RegularExpressions.Syntax { if (!dict.Contains (name)) { if (expr is CaptureAssertion && !Char.IsDigit (name [0])) continue; + BackslashNumber bn = expr as BackslashNumber; + if (bn != null && bn.ResolveReference (name, dict)) + continue; throw NewParseException ("Reference to undefined group " + (Char.IsDigit (name[0]) ? "number " : "name ") + name); diff --git a/mcs/class/System/System.Text.RegularExpressions/syntax.cs b/mcs/class/System/System.Text.RegularExpressions/syntax.cs index d9cc4a36141..3b4b717dc7c 100644 --- a/mcs/class/System/System.Text.RegularExpressions/syntax.cs +++ b/mcs/class/System/System.Text.RegularExpressions/syntax.cs @@ -702,7 +702,8 @@ namespace System.Text.RegularExpressions.Syntax { set { ignore = value; } } - public override void Compile (ICompiler cmp, bool reverse) { + public static void CompileLiteral (string str, ICompiler cmp, bool ignore, bool reverse) + { if (str.Length == 0) return; @@ -712,6 +713,11 @@ namespace System.Text.RegularExpressions.Syntax { cmp.EmitString (str, ignore, reverse); } + public override void Compile (ICompiler cmp, bool reverse) + { + CompileLiteral (str, cmp, ignore, reverse); + } + public override void GetWidth (out int min, out int max) { min = max = str.Length; } @@ -806,6 +812,49 @@ namespace System.Text.RegularExpressions.Syntax { { this.ecma = ecma; } + + // Precondition: groups [num_str] == null + public bool ResolveReference (string num_str, Hashtable groups) + { + if (ecma) { + int i; + for (i = 1; i < num_str.Length; ++i) { + string name = num_str.Substring (0, i); + CapturingGroup group = (CapturingGroup) groups [name]; + if (group == null) + break; + CapturingGroup = group; + } + if (i > 1) { + literal = num_str.Substring (i - 1); + return true; + } + } else { + if (num_str.Length == 1) + return false; + } + + int ptr = 0; + int as_octal = Parser.ParseOctal (num_str, ref ptr); + // Since ParseOctal reads at most 3 digits, as_octal <= octal 0777 + if (as_octal == -1) + return false; + if (as_octal > 0xff && ecma) { + as_octal /= 8; + --ptr; + } + as_octal &= 0xff; + literal = ((char) as_octal) + num_str.Substring (ptr); + return true; + } + + public override void Compile (ICompiler cmp, bool reverse) + { + if (CapturingGroup != null) + base.Compile (cmp, reverse); + if (literal != null) + Literal.CompileLiteral (literal, cmp, IgnoreCase, reverse); + } } class CharacterClass : Expression { diff --git a/mcs/class/System/Test/System.Text.RegularExpressions/ChangeLog b/mcs/class/System/Test/System.Text.RegularExpressions/ChangeLog index 877ff8241cd..0c0cf3648d4 100644 --- a/mcs/class/System/Test/System.Text.RegularExpressions/ChangeLog +++ b/mcs/class/System/Test/System.Text.RegularExpressions/ChangeLog @@ -1,5 +1,9 @@ 2009-08-10 Raja R Harinath <harinath@hurrynot.org> + * RegexMatchTests.cs (RegexTrial0054..60): New. + +2009-08-10 Raja R Harinath <harinath@hurrynot.org> + * RegexMatchTests.cs (RegexTrial0053): New. 2009-02-27 Jonathan Pryor <jpryor@novell.com> diff --git a/mcs/class/System/Test/System.Text.RegularExpressions/RegexMatchTests.cs b/mcs/class/System/Test/System.Text.RegularExpressions/RegexMatchTests.cs index 53a00f80442..e9aeb72b61b 100644 --- a/mcs/class/System/Test/System.Text.RegularExpressions/RegexMatchTests.cs +++ b/mcs/class/System/Test/System.Text.RegularExpressions/RegexMatchTests.cs @@ -150,6 +150,13 @@ namespace MonoTests.System.Text.RegularExpressions new RegexTrial (@"(?>a*).", RegexOptions.ExplicitCapture, "aaaa", "Fail."),//52 new RegexTrial (@"(?<ab>ab)c\1", RegexOptions.None, "abcabc", "Pass. Group[0]=(0,5) Group[1]=(0,2)"),//53 + new RegexTrial (@"\1", RegexOptions.ECMAScript, "-", "Fail."),//54 + new RegexTrial (@"\2", RegexOptions.ECMAScript, "-", "Fail."),//55 + new RegexTrial (@"(a)|\2", RegexOptions.ECMAScript, "-", "Fail."),//56 + new RegexTrial (@"\4400", RegexOptions.None, "asdf 012", "Pass. Group[0]=(4,2)"),//57 + new RegexTrial (@"\4400", RegexOptions.ECMAScript, "asdf 012", "Fail."),//58 + new RegexTrial (@"\4400", RegexOptions.None, "asdf$0012", "Fail."),//59 + new RegexTrial (@"\4400", RegexOptions.ECMAScript, "asdf$0012", "Pass. Group[0]=(4,3)"),//60 }; [Test] @@ -322,5 +329,12 @@ namespace MonoTests.System.Text.RegularExpressions [Test] public void RegexJvmTrial0052 () { trials [52].Execute (); } [Test] public void RegexTrial0053 () { trials [53].Execute (); } + [Test] public void RegexTrial0054 () { trials [54].Execute (); } + [Test] public void RegexTrial0055 () { trials [55].Execute (); } + [Test] public void RegexTrial0056 () { trials [56].Execute (); } + [Test] public void RegexTrial0057 () { trials [57].Execute (); } + [Test] public void RegexTrial0058 () { trials [58].Execute (); } + [Test] public void RegexTrial0059 () { trials [59].Execute (); } + [Test] public void RegexTrial0060 () { trials [60].Execute (); } } } |