Author: lupus
Date: 2008-02-14 12:21:54 -0500 (Thu, 14 Feb 2008)
New Revision: 95660
Modified:
trunk/mcs/class/System/System.Text.RegularExpressions/CILCompiler.cs
trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
trunk/mcs/class/System/System.Text.RegularExpressions/RxInterpreter.cs
trunk/mcs/class/System/System.Text.RegularExpressions/RxOp.cs
Log:
Thu Feb 14 19:03:00 CET 2008 Paolo Molaro <[EMAIL PROTECTED]>
* RxCompiler.cs, RxInterpreter.cs, RxOp.cs, CILCompiler.cs : support
for word
boundary position opcodes, ignorecase backreference and more capture
work.
Modified: trunk/mcs/class/System/System.Text.RegularExpressions/CILCompiler.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/CILCompiler.cs
2008-02-14 17:21:08 UTC (rev 95659)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/CILCompiler.cs
2008-02-14 17:21:54 UTC (rev 95660)
@@ -232,6 +232,10 @@
ilgen.Emit (OpCodes.Ldc_I4_1);
ilgen.Emit (OpCodes.Add);
ilgen.Emit (OpCodes.Stloc,
frame.local_strpos_res);
+ // call SetStartOfMatch (strpos)
+ ilgen.Emit (OpCodes.Ldarg_0);
+ ilgen.Emit (OpCodes.Ldarg_1);
+ ilgen.Emit (OpCodes.Call,
GetInterpreterMethod ("SetStartOfMatch"));
// return true;
ilgen.Emit (OpCodes.Br,
frame.label_pass);
@@ -276,6 +280,10 @@
// strpos_result = res;
ilgen.Emit (OpCodes.Ldloc,
new_frame.local_strpos_res);
ilgen.Emit (OpCodes.Stloc,
frame.local_strpos_res);
+ // call SetStartOfMatch
(old_strpos)
+ ilgen.Emit (OpCodes.Ldarg_0);
+ ilgen.Emit (OpCodes.Ldloc,
local_old_strpos);
+ ilgen.Emit (OpCodes.Call,
GetInterpreterMethod ("SetStartOfMatch"));
// return true;
ilgen.Emit (OpCodes.Br,
frame.label_pass);
Modified: trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
2008-02-14 17:21:08 UTC (rev 95659)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
2008-02-14 17:21:54 UTC (rev 95660)
@@ -1,4 +1,10 @@
+Thu Feb 14 19:03:00 CET 2008 Paolo Molaro <[EMAIL PROTECTED]>
+
+ * RxCompiler.cs, RxInterpreter.cs, RxOp.cs, CILCompiler.cs : support
for word
+ boundary position opcodes, ignorecase backreference and more capture
+ work.
+
Thu Feb 14 17:11:10 CET 2008 Paolo Molaro <[EMAIL PROTECTED]>
* RxCompiler.cs, RxInterpreter.cs, RxOp.cs: replace EcmaDigit with
Modified: trunk/mcs/class/System/System.Text.RegularExpressions/RxInterpreter.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/RxInterpreter.cs
2008-02-14 17:21:08 UTC (rev 95659)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/RxInterpreter.cs
2008-02-14 17:21:54 UTC (rev 95660)
@@ -38,6 +38,8 @@
this.eval_del = eval_del;
group_count = 1 + (program [1] | (program [2] << 8));
groups = new int [group_count];
+
+ ResetGroups ();
}
public override Match Scan (Regex regex, string text, int
start, int end) {
@@ -52,9 +54,11 @@
} else {
match = EvalByteCode (11, start, ref res);
}
+ marks [groups [0]].End = res;
if (match) {
- Match m = new Match (regex, this, text, end, 0,
match_start, res - match_start);
- return m;
+ return GenerateMatch (regex);
+ //Match m = new Match (regex, this, text, end,
0, match_start, res - match_start);
+ //return m;
}
return Match.Empty;
}
@@ -167,6 +171,44 @@
}
}
+ private Match GenerateMatch (Regex regex)
+ {
+ int n_caps, first_mark_index;
+ Group g;
+ GetGroupInfo (0, out first_mark_index, out n_caps);
+
+ // Avoid fully populating the Match instance if not
needed
+ if (!needs_groups_or_captures)
+ return new Match (regex, this, str, string_end,
0, marks [first_mark_index].Index, marks [first_mark_index].Length);
+
+ Match retval = new Match (regex, this, str, string_end,
groups.Length,
+ marks
[first_mark_index].Index, marks [first_mark_index].Length, n_caps);
+ PopulateGroup (retval, first_mark_index, n_caps);
+
+ for (int gid = 1; gid < groups.Length; ++ gid) {
+ GetGroupInfo (gid, out first_mark_index, out
n_caps);
+ if (first_mark_index < 0) {
+ g = Group.Fail;
+ } else {
+ g = new Group (str, marks
[first_mark_index].Index, marks [first_mark_index].Length, n_caps);
+ PopulateGroup (g, first_mark_index,
n_caps);
+ }
+ retval.Groups.SetValue (g, gid);
+ }
+ return retval;
+ }
+
+ // used by the IL backend
+ void SetStartOfMatch (int pos)
+ {
+ marks [groups [0]].Start = pos;
+ }
+
+ static bool IsWordChar (char c)
+ {
+ return Char.IsLetterOrDigit (c) ||
Char.GetUnicodeCategory (c) == UnicodeCategory.ConnectorPunctuation;
+ }
+
bool EvalByteCode (int pc, int strpos, ref int strpos_result)
{
// luckily the IL engine can deal with char_group_end
at compile time
@@ -230,6 +272,46 @@
continue;
}
return false;
+ case RxOp.WordBoundary:
+ if (string_end == 0)
+ return false;
+ if (strpos == 0) {
+ if (IsWordChar (str [strpos])) {
+ pc++;
+ continue;
+ }
+ } else if (strpos == string_end) {
+ if (IsWordChar (str [strpos -
1])) {
+ pc++;
+ continue;
+ }
+ } else {
+ if (IsWordChar (str [strpos])
!= IsWordChar (str [strpos - 1])) {
+ pc++;
+ continue;
+ }
+ }
+ return false;
+ case RxOp.NoWordBoundary:
+ if (string_end == 0)
+ return false;
+ if (strpos == 0) {
+ if (!IsWordChar (str [strpos]))
{
+ pc++;
+ continue;
+ }
+ } else if (strpos == string_end) {
+ if (!IsWordChar (str [strpos -
1])) {
+ pc++;
+ continue;
+ }
+ } else {
+ if (IsWordChar (str [strpos])
== IsWordChar (str [strpos - 1])) {
+ pc++;
+ continue;
+ }
+ }
+ return false;
case RxOp.Anchor:
// FIXME: test anchor
length = program [pc + 3] | (program
[pc + 4] << 8);
@@ -245,6 +327,7 @@
}
if (EvalByteCode (pc, strpos,
ref res)) {
match_start = strpos;
+ marks [groups
[0]].Start = strpos;
if (groups.Length > 1)
marks [groups
[0]].End = res;
strpos_result = res;
@@ -268,6 +351,21 @@
}
pc += 3;
continue;
+ case RxOp.ReferenceIgnoreCase:
+ length = GetLastDefined (program [pc +
1] | (program [pc + 2] << 8));
+ if (length < 0)
+ return false;
+ start = marks [length].Index;
+ length = marks [length].Length;
+ if (strpos + length > string_end)
+ return false;
+ for (end = start + length; start < end;
++start) {
+ if (str [strpos] != str [start]
&& Char.ToLower (str [strpos]) != Char.ToLower (str [start]))
+ return false;
+ strpos++;
+ }
+ pc += 3;
+ continue;
case RxOp.IfDefined:
if (GetLastDefined (program [pc + 3] |
(program [pc + 4] << 8)) < 0)
pc += 5;
@@ -874,6 +972,7 @@
end = ReadInt (program, pc + 7);
//Console.WriteLine ("min: {0}, max:
{1}", start, end);
length = 0;
+ int cp = Checkpoint ();
while (length < end) {
if (!EvalByteCode (pc + 11,
strpos, ref res)) {
if (length >= start) {
@@ -883,6 +982,7 @@
}
strpos = res;
length++;
+ Backtrack (cp);
}
if (length != end)
return false;
Modified: trunk/mcs/class/System/System.Text.RegularExpressions/RxOp.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/RxOp.cs
2008-02-14 17:21:08 UTC (rev 95659)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/RxOp.cs
2008-02-14 17:21:54 UTC (rev 95660)
@@ -177,9 +177,9 @@
// followed by two-byte reference number
// keep the order, see EmitReference ()
Reference,
- ReversenceIgnoreCase,
+ ReferenceIgnoreCase,
ReferenceReverse,
- ReversenceIgnoreCaseReverse,
+ ReferenceIgnoreCaseReverse,
// group/capture support
// followed by two-byte group id
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches