Permalink
Browse files

regexp backreferences: Implement fallback to octal numbers, and ECMAS…

…cript semantics.

* 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
  • Loading branch information...
1 parent 5448177 commit 1163a482f7430930bee670cf4c6721ecf9880974 @harinath harinath committed Aug 10, 2009
@@ -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.
@@ -1102,6 +1102,9 @@ public IDictionary GetMapping ()
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);
@@ -702,7 +702,8 @@ class Literal : Expression {
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 @@ class Literal : Expression {
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 @@ public BackslashNumber (bool ignore, bool ecma)
{
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 {
@@ -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>
@@ -150,6 +150,13 @@ public class RegexMatchTests
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 @@ public void RegexJvmTrial0018 ()
[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 (); }
}
}

0 comments on commit 1163a48

Please sign in to comment.