Skip to content

Commit 1163a48

Browse files
committed
regexp backreferences: Implement fallback to octal numbers, and ECMAScript 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
1 parent 5448177 commit 1163a48

File tree

5 files changed

+77
-1
lines changed

5 files changed

+77
-1
lines changed

mcs/class/System/System.Text.RegularExpressions/ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2009-08-10 Raja R Harinath <[email protected]>
2+
3+
* syntax.cs (BackslashNumber.ResolveReference): Implement fallback
4+
to octal numbers, and ECMAScript semantics.
5+
* parser.cs (ResolveReferences): Use it.
6+
17
2009-08-10 Raja R Harinath <[email protected]>
28

39
* syntax.cs (BackslashNumber): New class.

mcs/class/System/System.Text.RegularExpressions/parser.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,9 @@ private void ResolveReferences () {
11021102
if (!dict.Contains (name)) {
11031103
if (expr is CaptureAssertion && !Char.IsDigit (name [0]))
11041104
continue;
1105+
BackslashNumber bn = expr as BackslashNumber;
1106+
if (bn != null && bn.ResolveReference (name, dict))
1107+
continue;
11051108
throw NewParseException ("Reference to undefined group " +
11061109
(Char.IsDigit (name[0]) ? "number " : "name ") +
11071110
name);

mcs/class/System/System.Text.RegularExpressions/syntax.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,8 @@ public bool IgnoreCase {
702702
set { ignore = value; }
703703
}
704704

705-
public override void Compile (ICompiler cmp, bool reverse) {
705+
public static void CompileLiteral (string str, ICompiler cmp, bool ignore, bool reverse)
706+
{
706707
if (str.Length == 0)
707708
return;
708709

@@ -712,6 +713,11 @@ public override void Compile (ICompiler cmp, bool reverse) {
712713
cmp.EmitString (str, ignore, reverse);
713714
}
714715

716+
public override void Compile (ICompiler cmp, bool reverse)
717+
{
718+
CompileLiteral (str, cmp, ignore, reverse);
719+
}
720+
715721
public override void GetWidth (out int min, out int max) {
716722
min = max = str.Length;
717723
}
@@ -806,6 +812,49 @@ public BackslashNumber (bool ignore, bool ecma)
806812
{
807813
this.ecma = ecma;
808814
}
815+
816+
// Precondition: groups [num_str] == null
817+
public bool ResolveReference (string num_str, Hashtable groups)
818+
{
819+
if (ecma) {
820+
int i;
821+
for (i = 1; i < num_str.Length; ++i) {
822+
string name = num_str.Substring (0, i);
823+
CapturingGroup group = (CapturingGroup) groups [name];
824+
if (group == null)
825+
break;
826+
CapturingGroup = group;
827+
}
828+
if (i > 1) {
829+
literal = num_str.Substring (i - 1);
830+
return true;
831+
}
832+
} else {
833+
if (num_str.Length == 1)
834+
return false;
835+
}
836+
837+
int ptr = 0;
838+
int as_octal = Parser.ParseOctal (num_str, ref ptr);
839+
// Since ParseOctal reads at most 3 digits, as_octal <= octal 0777
840+
if (as_octal == -1)
841+
return false;
842+
if (as_octal > 0xff && ecma) {
843+
as_octal /= 8;
844+
--ptr;
845+
}
846+
as_octal &= 0xff;
847+
literal = ((char) as_octal) + num_str.Substring (ptr);
848+
return true;
849+
}
850+
851+
public override void Compile (ICompiler cmp, bool reverse)
852+
{
853+
if (CapturingGroup != null)
854+
base.Compile (cmp, reverse);
855+
if (literal != null)
856+
Literal.CompileLiteral (literal, cmp, IgnoreCase, reverse);
857+
}
809858
}
810859

811860
class CharacterClass : Expression {

mcs/class/System/Test/System.Text.RegularExpressions/ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2009-08-10 Raja R Harinath <[email protected]>
2+
3+
* RegexMatchTests.cs (RegexTrial0054..60): New.
4+
15
2009-08-10 Raja R Harinath <[email protected]>
26

37
* RegexMatchTests.cs (RegexTrial0053): New.

mcs/class/System/Test/System.Text.RegularExpressions/RegexMatchTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,13 @@ public class RegexMatchTests
150150
new RegexTrial (@"(?>a*).", RegexOptions.ExplicitCapture, "aaaa", "Fail."),//52
151151

152152
new RegexTrial (@"(?<ab>ab)c\1", RegexOptions.None, "abcabc", "Pass. Group[0]=(0,5) Group[1]=(0,2)"),//53
153+
new RegexTrial (@"\1", RegexOptions.ECMAScript, "-", "Fail."),//54
154+
new RegexTrial (@"\2", RegexOptions.ECMAScript, "-", "Fail."),//55
155+
new RegexTrial (@"(a)|\2", RegexOptions.ECMAScript, "-", "Fail."),//56
156+
new RegexTrial (@"\4400", RegexOptions.None, "asdf 012", "Pass. Group[0]=(4,2)"),//57
157+
new RegexTrial (@"\4400", RegexOptions.ECMAScript, "asdf 012", "Fail."),//58
158+
new RegexTrial (@"\4400", RegexOptions.None, "asdf$0012", "Fail."),//59
159+
new RegexTrial (@"\4400", RegexOptions.ECMAScript, "asdf$0012", "Pass. Group[0]=(4,3)"),//60
153160
};
154161

155162
[Test]
@@ -322,5 +329,12 @@ public void RegexJvmTrial0018 ()
322329
[Test] public void RegexJvmTrial0052 () { trials [52].Execute (); }
323330

324331
[Test] public void RegexTrial0053 () { trials [53].Execute (); }
332+
[Test] public void RegexTrial0054 () { trials [54].Execute (); }
333+
[Test] public void RegexTrial0055 () { trials [55].Execute (); }
334+
[Test] public void RegexTrial0056 () { trials [56].Execute (); }
335+
[Test] public void RegexTrial0057 () { trials [57].Execute (); }
336+
[Test] public void RegexTrial0058 () { trials [58].Execute (); }
337+
[Test] public void RegexTrial0059 () { trials [59].Execute (); }
338+
[Test] public void RegexTrial0060 () { trials [60].Execute (); }
325339
}
326340
}

0 commit comments

Comments
 (0)