Author: lupus
Date: 2008-02-13 06:36:07 -0500 (Wed, 13 Feb 2008)
New Revision: 95565
Modified:
trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
trunk/mcs/class/System/System.Text.RegularExpressions/RxCompiler.cs
trunk/mcs/class/System/System.Text.RegularExpressions/RxInterpreter.cs
trunk/mcs/class/System/System.Text.RegularExpressions/RxOp.cs
Log:
Wed Feb 13 13:18:12 CET 2008 Paolo Molaro <[EMAIL PROTECTED]>
* RxCompiler.cs, RxInterpreter.cs, RxOp.cs: unicode categories and
some grouping/capture support.
Modified: trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
2008-02-13 10:11:06 UTC (rev 95564)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
2008-02-13 11:36:07 UTC (rev 95565)
@@ -1,4 +1,9 @@
+Wed Feb 13 13:18:12 CET 2008 Paolo Molaro <[EMAIL PROTECTED]>
+
+ * RxCompiler.cs, RxInterpreter.cs, RxOp.cs: unicode categories and
+ some grouping/capture support.
+
Tue Feb 12 19:16:49 CET 2008 Paolo Molaro <[EMAIL PROTECTED]>
* RxCompiler.cs, RxInterpreter.cs, RxOp.cs: experimental new
Modified: trunk/mcs/class/System/System.Text.RegularExpressions/RxCompiler.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/RxCompiler.cs
2008-02-13 10:11:06 UTC (rev 95564)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/RxCompiler.cs
2008-02-13 11:36:07 UTC (rev 95565)
@@ -1,5 +1,6 @@
using System;
using System.Collections;
+using System.Globalization;
namespace System.Text.RegularExpressions {
@@ -141,23 +142,271 @@
}
}
+ void EmitUniCat (UnicodeCategory cat, int offset)
+ {
+ Emit ((RxOp)((int)RxOp.CategoryUnicode + offset));
+ Emit ((byte)cat);
+ }
+
public void EmitCategory (Category cat, bool negate, bool
reverse)
{
- if (negate | reverse)
- throw new NotSupportedException ();
+ int offset = 0;
+ if (negate)
+ offset += 1;
+ if (reverse)
+ offset += 2;
switch (cat) {
case Category.Any:
- Emit (RxOp.CategoryAny);
+ case Category.EcmaAny:
+ Emit ((RxOp)((int)RxOp.CategoryAny + offset));
break;
+ case Category.Word:
+ Emit ((RxOp)((int)RxOp.CategoryWord + offset));
+ break;
+ case Category.Digit:
+ Emit ((RxOp)((int)RxOp.CategoryDigit + offset));
+ break;
+ case Category.WhiteSpace:
+ Emit ((RxOp)((int)RxOp.CategoryWhiteSpace +
offset));
+ break;
+ case Category.EcmaWord:
+ Emit ((RxOp)((int)RxOp.CategoryEcmaWord +
offset));
+ break;
+ case Category.EcmaDigit:
+ Emit ((RxOp)((int)RxOp.CategoryEcmaDigit +
offset));
+ break;
+ case Category.EcmaWhiteSpace:
+ Emit ((RxOp)((int)RxOp.CategoryEcmaWhiteSpace +
offset));
+ break;
+ case Category.UnicodeSpecials:
+ Emit ((RxOp)((int)RxOp.CategoryUnicodeSpecials
+ offset));
+ break;
+ // Unicode categories...
+ // letter
+ case Category.UnicodeLu: EmitUniCat
(UnicodeCategory.UppercaseLetter, offset); break;
+ case Category.UnicodeLl: EmitUniCat
(UnicodeCategory.LowercaseLetter, offset); break;
+ case Category.UnicodeLt: EmitUniCat
(UnicodeCategory.TitlecaseLetter, offset); break;
+ case Category.UnicodeLm: EmitUniCat
(UnicodeCategory.ModifierLetter, offset); break;
+ case Category.UnicodeLo: EmitUniCat
(UnicodeCategory.OtherLetter, offset); break;
+ // mark
+ case Category.UnicodeMn: EmitUniCat
(UnicodeCategory.NonSpacingMark, offset); break;
+ case Category.UnicodeMe: EmitUniCat
(UnicodeCategory.EnclosingMark, offset); break;
+ case Category.UnicodeMc: EmitUniCat
(UnicodeCategory.SpacingCombiningMark, offset); break;
+ case Category.UnicodeNd: EmitUniCat
(UnicodeCategory.DecimalDigitNumber, offset); break;
+ // number
+ case Category.UnicodeNl: EmitUniCat
(UnicodeCategory.LetterNumber, offset); break;
+ case Category.UnicodeNo: EmitUniCat
(UnicodeCategory.OtherNumber, offset); break;
+ // separator
+ case Category.UnicodeZs: EmitUniCat
(UnicodeCategory.SpaceSeparator, offset); break;
+ case Category.UnicodeZl: EmitUniCat
(UnicodeCategory.LineSeparator, offset); break;
+ case Category.UnicodeZp: EmitUniCat
(UnicodeCategory.ParagraphSeparator, offset); break;
+ // punctuation
+ case Category.UnicodePd: EmitUniCat
(UnicodeCategory.DashPunctuation, offset); break;
+ case Category.UnicodePs: EmitUniCat
(UnicodeCategory.OpenPunctuation, offset); break;
+ case Category.UnicodePi: EmitUniCat
(UnicodeCategory.InitialQuotePunctuation, offset); break;
+ case Category.UnicodePe: EmitUniCat
(UnicodeCategory.ClosePunctuation, offset); break;
+ case Category.UnicodePf: EmitUniCat
(UnicodeCategory.FinalQuotePunctuation, offset); break;
+ case Category.UnicodePc: EmitUniCat
(UnicodeCategory.ConnectorPunctuation, offset); break;
+ case Category.UnicodePo: EmitUniCat
(UnicodeCategory.OtherPunctuation, offset); break;
+ // symbol
+ case Category.UnicodeSm: EmitUniCat
(UnicodeCategory.MathSymbol, offset); break;
+ case Category.UnicodeSc: EmitUniCat
(UnicodeCategory.CurrencySymbol, offset); break;
+ case Category.UnicodeSk: EmitUniCat
(UnicodeCategory.ModifierSymbol, offset); break;
+ case Category.UnicodeSo: EmitUniCat
(UnicodeCategory.OtherSymbol, offset); break;
+ // other
+ case Category.UnicodeCc: EmitUniCat
(UnicodeCategory.Control, offset); break;
+ case Category.UnicodeCf: EmitUniCat
(UnicodeCategory.Format, offset); break;
+ case Category.UnicodeCo: EmitUniCat
(UnicodeCategory.PrivateUse, offset); break;
+ case Category.UnicodeCs: EmitUniCat
(UnicodeCategory.Surrogate, offset); break;
+ case Category.UnicodeCn: EmitUniCat
(UnicodeCategory.OtherNotAssigned, offset); break;
+ // Unicode block ranges...
+ case Category.UnicodeBasicLatin:
+ EmitRange ('\u0000', '\u007F', negate, false,
reverse); break;
+ case Category.UnicodeLatin1Supplement:
+ EmitRange ('\u0080', '\u00FF', negate, false,
reverse); break;
+ case Category.UnicodeLatinExtendedA:
+ EmitRange ('\u0100', '\u017F', negate, false,
reverse); break;
+ case Category.UnicodeLatinExtendedB:
+ EmitRange ('\u0180', '\u024F', negate, false,
reverse); break;
+ case Category.UnicodeIPAExtensions:
+ EmitRange ('\u0250', '\u02AF', negate, false,
reverse); break;
+ case Category.UnicodeSpacingModifierLetters:
+ EmitRange ('\u02B0', '\u02FF', negate, false,
reverse); break;
+ case Category.UnicodeCombiningDiacriticalMarks:
+ EmitRange ('\u0300', '\u036F', negate, false,
reverse); break;
+ case Category.UnicodeGreek:
+ EmitRange ('\u0370', '\u03FF', negate, false,
reverse); break;
+ case Category.UnicodeCyrillic:
+ EmitRange ('\u0400', '\u04FF', negate, false,
reverse); break;
+ case Category.UnicodeArmenian:
+ EmitRange ('\u0530', '\u058F', negate, false,
reverse); break;
+ case Category.UnicodeHebrew:
+ EmitRange ('\u0590', '\u05FF', negate, false,
reverse); break;
+ case Category.UnicodeArabic:
+ EmitRange ('\u0600', '\u06FF', negate, false,
reverse); break;
+ case Category.UnicodeSyriac:
+ EmitRange ('\u0700', '\u074F', negate, false,
reverse); break;
+ case Category.UnicodeThaana:
+ EmitRange ('\u0780', '\u07BF', negate, false,
reverse); break;
+ case Category.UnicodeDevanagari:
+ EmitRange ('\u0900', '\u097F', negate, false,
reverse); break;
+ case Category.UnicodeBengali:
+ EmitRange ('\u0980', '\u09FF', negate, false,
reverse); break;
+ case Category.UnicodeGurmukhi:
+ EmitRange ('\u0A00', '\u0A7F', negate, false,
reverse); break;
+ case Category.UnicodeGujarati:
+ EmitRange ('\u0A80', '\u0AFF', negate, false,
reverse); break;
+ case Category.UnicodeOriya:
+ EmitRange ('\u0B00', '\u0B7F', negate, false,
reverse); break;
+ case Category.UnicodeTamil:
+ EmitRange ('\u0B80', '\u0BFF', negate, false,
reverse); break;
+ case Category.UnicodeTelugu:
+ EmitRange ('\u0C00', '\u0C7F', negate, false,
reverse); break;
+ case Category.UnicodeKannada:
+ EmitRange ('\u0C80', '\u0CFF', negate, false,
reverse); break;
+ case Category.UnicodeMalayalam:
+ EmitRange ('\u0D00', '\u0D7F', negate, false,
reverse); break;
+ case Category.UnicodeSinhala:
+ EmitRange ('\u0D80', '\u0DFF', negate, false,
reverse); break;
+ case Category.UnicodeThai:
+ EmitRange ('\u0E00', '\u0E7F', negate, false,
reverse); break;
+ case Category.UnicodeLao:
+ EmitRange ('\u0E80', '\u0EFF', negate, false,
reverse); break;
+ case Category.UnicodeTibetan:
+ EmitRange ('\u0F00', '\u0FFF', negate, false,
reverse); break;
+ case Category.UnicodeMyanmar:
+ EmitRange ('\u1000', '\u109F', negate, false,
reverse); break;
+ case Category.UnicodeGeorgian:
+ EmitRange ('\u10A0', '\u10FF', negate, false,
reverse); break;
+ case Category.UnicodeHangulJamo:
+ EmitRange ('\u1100', '\u11FF', negate, false,
reverse); break;
+ case Category.UnicodeEthiopic:
+ EmitRange ('\u1200', '\u137F', negate, false,
reverse); break;
+ case Category.UnicodeCherokee:
+ EmitRange ('\u13A0', '\u13FF', negate, false,
reverse); break;
+ case Category.UnicodeUnifiedCanadianAboriginalSyllabics:
+ EmitRange ('\u1400', '\u167F', negate, false,
reverse); break;
+ case Category.UnicodeOgham:
+ EmitRange ('\u1680', '\u169F', negate, false,
reverse); break;
+ case Category.UnicodeRunic:
+ EmitRange ('\u16A0', '\u16FF', negate, false,
reverse); break;
+ case Category.UnicodeKhmer:
+ EmitRange ('\u1780', '\u17FF', negate, false,
reverse); break;
+ case Category.UnicodeMongolian:
+ EmitRange ('\u1800', '\u18AF', negate, false,
reverse); break;
+ case Category.UnicodeLatinExtendedAdditional:
+ EmitRange ('\u1E00', '\u1EFF', negate, false,
reverse); break;
+ case Category.UnicodeGreekExtended:
+ EmitRange ('\u1F00', '\u1FFF', negate, false,
reverse); break;
+ case Category.UnicodeGeneralPunctuation:
+ EmitRange ('\u2000', '\u206F', negate, false,
reverse); break;
+ case Category.UnicodeSuperscriptsandSubscripts:
+ EmitRange ('\u2070', '\u209F', negate, false,
reverse); break;
+ case Category.UnicodeCurrencySymbols:
+ EmitRange ('\u20A0', '\u20CF', negate, false,
reverse); break;
+ case Category.UnicodeCombiningMarksforSymbols:
+ EmitRange ('\u20D0', '\u20FF', negate, false,
reverse); break;
+ case Category.UnicodeLetterlikeSymbols:
+ EmitRange ('\u2100', '\u214F', negate, false,
reverse); break;
+ case Category.UnicodeNumberForms:
+ EmitRange ('\u2150', '\u218F', negate, false,
reverse); break;
+ case Category.UnicodeArrows:
+ EmitRange ('\u2190', '\u21FF', negate, false,
reverse); break;
+ case Category.UnicodeMathematicalOperators:
+ EmitRange ('\u2200', '\u22FF', negate, false,
reverse); break;
+ case Category.UnicodeMiscellaneousTechnical:
+ EmitRange ('\u2300', '\u23FF', negate, false,
reverse); break;
+ case Category.UnicodeControlPictures:
+ EmitRange ('\u2400', '\u243F', negate, false,
reverse); break;
+ case Category.UnicodeOpticalCharacterRecognition:
+ EmitRange ('\u2440', '\u245F', negate, false,
reverse); break;
+ case Category.UnicodeEnclosedAlphanumerics:
+ EmitRange ('\u2460', '\u24FF', negate, false,
reverse); break;
+ case Category.UnicodeBoxDrawing:
+ EmitRange ('\u2500', '\u257F', negate, false,
reverse); break;
+ case Category.UnicodeBlockElements:
+ EmitRange ('\u2580', '\u259F', negate, false,
reverse); break;
+ case Category.UnicodeGeometricShapes:
+ EmitRange ('\u25A0', '\u25FF', negate, false,
reverse); break;
+ case Category.UnicodeMiscellaneousSymbols:
+ EmitRange ('\u2600', '\u26FF', negate, false,
reverse); break;
+ case Category.UnicodeDingbats:
+ EmitRange ('\u2700', '\u27BF', negate, false,
reverse); break;
+ case Category.UnicodeBraillePatterns:
+ EmitRange ('\u2800', '\u28FF', negate, false,
reverse); break;
+ case Category.UnicodeCJKRadicalsSupplement:
+ EmitRange ('\u2E80', '\u2EFF', negate, false,
reverse); break;
+ case Category.UnicodeKangxiRadicals:
+ EmitRange ('\u2F00', '\u2FDF', negate, false,
reverse); break;
+ case Category.UnicodeIdeographicDescriptionCharacters:
+ EmitRange ('\u2FF0', '\u2FFF', negate, false,
reverse); break;
+ case Category.UnicodeCJKSymbolsandPunctuation:
+ EmitRange ('\u3000', '\u303F', negate, false,
reverse); break;
+ case Category.UnicodeHiragana:
+ EmitRange ('\u3040', '\u309F', negate, false,
reverse); break;
+ case Category.UnicodeKatakana:
+ EmitRange ('\u30A0', '\u30FF', negate, false,
reverse); break;
+ case Category.UnicodeBopomofo:
+ EmitRange ('\u3100', '\u312F', negate, false,
reverse); break;
+ case Category.UnicodeHangulCompatibilityJamo:
+ EmitRange ('\u3130', '\u318F', negate, false,
reverse); break;
+ case Category.UnicodeKanbun:
+ EmitRange ('\u3190', '\u319F', negate, false,
reverse); break;
+ case Category.UnicodeBopomofoExtended:
+ EmitRange ('\u31A0', '\u31BF', negate, false,
reverse); break;
+ case Category.UnicodeEnclosedCJKLettersandMonths:
+ EmitRange ('\u3200', '\u32FF', negate, false,
reverse); break;
+ case Category.UnicodeCJKCompatibility:
+ EmitRange ('\u3300', '\u33FF', negate, false,
reverse); break;
+ case Category.UnicodeCJKUnifiedIdeographsExtensionA:
+ EmitRange ('\u3400', '\u4DB5', negate, false,
reverse); break;
+ case Category.UnicodeCJKUnifiedIdeographs:
+ EmitRange ('\u4E00', '\u9FFF', negate, false,
reverse); break;
+ case Category.UnicodeYiSyllables:
+ EmitRange ('\uA000', '\uA48F', negate, false,
reverse); break;
+ case Category.UnicodeYiRadicals:
+ EmitRange ('\uA490', '\uA4CF', negate, false,
reverse); break;
+ case Category.UnicodeHangulSyllables:
+ EmitRange ('\uAC00', '\uD7A3', negate, false,
reverse); break;
+ case Category.UnicodeHighSurrogates:
+ EmitRange ('\uD800', '\uDB7F', negate, false,
reverse); break;
+ case Category.UnicodeHighPrivateUseSurrogates:
+ EmitRange ('\uDB80', '\uDBFF', negate, false,
reverse); break;
+ case Category.UnicodeLowSurrogates:
+ EmitRange ('\uDC00', '\uDFFF', negate, false,
reverse); break;
+ case Category.UnicodePrivateUse:
+ EmitRange ('\uE000', '\uF8FF', negate, false,
reverse); break;
+ case Category.UnicodeCJKCompatibilityIdeographs:
+ EmitRange ('\uF900', '\uFAFF', negate, false,
reverse); break;
+ case Category.UnicodeAlphabeticPresentationForms:
+ EmitRange ('\uFB00', '\uFB4F', negate, false,
reverse); break;
+ case Category.UnicodeArabicPresentationFormsA:
+ EmitRange ('\uFB50', '\uFDFF', negate, false,
reverse); break;
+ case Category.UnicodeCombiningHalfMarks:
+ EmitRange ('\uFE20', '\uFE2F', negate, false,
reverse); break;
+ case Category.UnicodeCJKCompatibilityForms:
+ EmitRange ('\uFE30', '\uFE4F', negate, false,
reverse); break;
+ case Category.UnicodeSmallFormVariants:
+ EmitRange ('\uFE50', '\uFE6F', negate, false,
reverse); break;
+ case Category.UnicodeArabicPresentationFormsB:
+ EmitRange ('\uFE70', '\uFEFE', negate, false,
reverse); break;
+ case Category.UnicodeHalfwidthandFullwidthForms:
+ EmitRange ('\uFF00', '\uFFEF', negate, false,
reverse); break;
default:
- Console.WriteLine ("Missing cat: {0}", cat);
- throw new NotSupportedException ();
+ Console.WriteLine ("Missing category: {0}",
cat);
+ EmitFalse ();
+ break;
}
}
public void EmitNotCategory (Category cat, bool negate, bool
reverse)
{
- throw new NotSupportedException ();
+ // not sure why the compiler needed this separate
interface funtion
+ if (negate) {
+ EmitCategory (cat, false, reverse);
+ } else {
+ EmitCategory (cat, true, reverse);
+ }
}
public void EmitRange (char lo, char hi, bool negate, bool
ignore, bool reverse)
@@ -307,11 +556,14 @@
public void EmitBalance ()
{
- throw new NotSupportedException ();
+ // it doesn't seem we need to do anything, so just
don't emit anything
+ //throw new NotSupportedException ();
}
public void EmitReference (int gid, bool ignore, bool reverse)
{
+ if (gid > ushort.MaxValue)
+ throw new NotSupportedException ();
int offset = 0;
if (ignore)
offset += 1;
@@ -323,7 +575,12 @@
public void EmitIfDefined (int gid, LinkRef tail)
{
- throw new NotSupportedException ();
+ if (gid > ushort.MaxValue)
+ throw new NotSupportedException ();
+ BeginLink (tail);
+ Emit (RxOp.IfDefined);
+ EmitLink (tail);
+ Emit ((ushort)gid);
}
public void EmitSub (LinkRef tail)
Modified: trunk/mcs/class/System/System.Text.RegularExpressions/RxInterpreter.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/RxInterpreter.cs
2008-02-13 10:11:06 UTC (rev 95564)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/RxInterpreter.cs
2008-02-13 11:36:07 UTC (rev 95565)
@@ -1,6 +1,7 @@
using System;
using System.Collections;
+using System.Globalization;
namespace System.Text.RegularExpressions {
@@ -13,6 +14,10 @@
int match_start;
int[] groups;
+ Mark[] marks = null; // mark stack
+ int mark_start; // start of current checkpoint
+ int mark_end; // end of checkpoint/next free mark
+
static int ReadInt (byte[] code, int pc)
{
int val = code [pc];
@@ -41,6 +46,116 @@
return Match.Empty;
}
+ // capture management
+ private void Open (int gid, int ptr) {
+ int m = groups [gid];
+ if (m < mark_start || marks [m].IsDefined) {
+ m = CreateMark (m);
+ groups [gid] = m;
+ }
+
+ marks [m].Start = ptr;
+ }
+
+ private void Close (int gid, int ptr) {
+ marks [groups [gid]].End = ptr;
+ }
+
+ private bool Balance (int gid, int balance_gid, bool capture,
int ptr) {
+ int b = groups [balance_gid];
+
+ if (b == -1 || marks [b].Index < 0) {
+ //Group not previously matched
+ return false;
+ }
+ if (gid > 0 && capture){
+ Open (gid, marks [b].Index + marks [b].Length);
+ Close (gid, ptr);
+ }
+
+ groups [balance_gid] = marks[b].Previous;
+ return true;
+ }
+
+ private int Checkpoint () {
+ mark_start = mark_end;
+ return mark_start;
+ }
+
+ private void Backtrack (int cp) {
+ for (int i = 0; i < groups.Length; ++ i) {
+ int m = groups [i];
+ while (cp <= m)
+ m = marks [m].Previous;
+ groups [i] = m;
+ }
+ }
+
+ private void ResetGroups () {
+ int n = groups.Length;
+ if (marks == null)
+ marks = new Mark [n * 10];
+ if (n == 1)
+ return;
+
+ for (int i = 0; i < n; ++ i) {
+ groups [i] = i;
+
+ marks [i].Start = -1;
+ marks [i].End = -1;
+ marks [i].Previous = -1;
+ }
+ mark_start = 0;
+ mark_end = n;
+ }
+
+ private int GetLastDefined (int gid) {
+ int m = groups [gid];
+ while (m >= 0 && !marks [m].IsDefined)
+ m = marks [m].Previous;
+
+ return m;
+ }
+
+ private int CreateMark (int previous) {
+ if (mark_end == marks.Length) {
+ Mark [] dest = new Mark [marks.Length * 2];
+ marks.CopyTo (dest, 0);
+ marks = dest;
+ }
+
+ int m = mark_end ++;
+ marks [m].Start = marks [m].End = -1;
+ marks [m].Previous = previous;
+
+ return m;
+ }
+
+ private void GetGroupInfo (int gid, out int first_mark_index,
out int n_caps)
+ {
+ first_mark_index = -1;
+ n_caps = 0;
+ for (int m = groups [gid]; m >= 0; m = marks
[m].Previous) {
+ if (!marks [m].IsDefined)
+ continue;
+ if (first_mark_index < 0)
+ first_mark_index = m;
+ ++n_caps;
+ }
+ }
+
+ private void PopulateGroup (Group g, int first_mark_index, int
n_caps)
+ {
+ int i = 1;
+ for (int m = marks [first_mark_index].Previous; m >= 0;
m = marks [m].Previous) {
+ if (!marks [m].IsDefined)
+ continue;
+ Capture cap = new Capture (str, marks
[m].Index, marks [m].Length);
+ g.Captures.SetValue (cap, n_caps - 1 - i);
+ ++i;
+ }
+ }
+
bool EvalByteCode (int pc, int strpos, ref int strpos_result)
{
int length, start, end;
@@ -94,14 +209,49 @@
pc += program [pc + 1] | (program [pc +
2] << 8);
while (strpos < string_end) {
int res = strpos;
+ if (groups.Length > 1) {
+ ResetGroups ();
+ marks [groups
[0]].Start = strpos;
+ }
if (EvalByteCode (pc, strpos,
ref res)) {
match_start = strpos;
+ if (groups.Length > 1)
+ marks [groups
[0]].End = res;
strpos_result = res;
return true;
}
strpos++;
}
return false;
+ case RxOp.Reference:
+ 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])
+ return false;
+ strpos++;
+ }
+ pc += 3;
+ continue;
+ case RxOp.IfDefined:
+ if (GetLastDefined (program [pc + 3] |
(program [pc + 4] << 8)) < 0)
+ pc += 5;
+ else
+ pc += program [pc + 1] |
(program [pc + 2] << 8);
+ continue;
+ case RxOp.OpenGroup:
+ Open (program [pc + 1] | (program [pc +
2] << 8), strpos);
+ pc += 3;
+ continue;
+ case RxOp.CloseGroup:
+ Close (program [pc + 1] | (program [pc
+ 2] << 8), strpos);
+ pc += 3;
+ continue;
case RxOp.Jump:
pc += program [pc + 1] | (program [pc +
2] << 8);
continue;
@@ -257,6 +407,34 @@
}
}
return false;
+ case RxOp.UnicodeChar:
+ if (strpos < string_end && (str
[strpos] == (program [pc + 1] | (program [pc + 2] << 8)))) {
+ strpos++;
+ pc += 3;
+ continue;
+ }
+ return false;
+ case RxOp.NoUnicodeChar:
+ if (strpos < string_end && (str
[strpos] != (program [pc + 1] | (program [pc + 2] << 8)))) {
+ strpos++;
+ pc += 3;
+ continue;
+ }
+ return false;
+ case RxOp.UnicodeCharIgnoreCase:
+ if (strpos < string_end &&
(Char.ToLower (str [strpos]) == (program [pc + 1] | (program [pc + 2] << 8)))) {
+ strpos++;
+ pc += 3;
+ continue;
+ }
+ return false;
+ case RxOp.NoUnicodeCharIgnoreCase:
+ if (strpos < string_end &&
(Char.ToLower (str [strpos]) != (program [pc + 1] | (program [pc + 2] << 8)))) {
+ strpos++;
+ pc += 3;
+ continue;
+ }
+ return false;
case RxOp.CategoryAny:
if (strpos < string_end && str [strpos]
!= '\n') {
strpos++;
@@ -264,6 +442,87 @@
continue;
}
return false;
+ case RxOp.CategoryWord:
+ if (strpos < string_end) {
+ char c = str [strpos];
+ if (Char.IsLetterOrDigit (c) ||
Char.GetUnicodeCategory (c) == UnicodeCategory.ConnectorPunctuation) {
+ strpos++;
+ pc++;
+ continue;
+ }
+ }
+ return false;
+ case RxOp.NoCategoryWord:
+ if (strpos < string_end) {
+ char c = str [strpos];
+ if (!Char.IsLetterOrDigit (c)
&& Char.GetUnicodeCategory (c) != UnicodeCategory.ConnectorPunctuation) {
+ strpos++;
+ pc++;
+ continue;
+ }
+ }
+ return false;
+ case RxOp.CategoryDigit:
+ if (strpos < string_end && Char.IsDigit
(str [strpos])) {
+ strpos++;
+ pc++;
+ continue;
+ }
+ return false;
+ case RxOp.CategoryWhiteSpace:
+ if (strpos < string_end &&
Char.IsWhiteSpace (str [strpos])) {
+ strpos++;
+ pc++;
+ continue;
+ }
+ return false;
+ case RxOp.CategoryEcmaWord:
+ if (strpos < string_end) {
+ int c = str [strpos];
+ if ('a' <= c && c <= 'z' || 'A'
<= c && c <= 'Z' || '0' <= c && c <= '9' || c == '_') {
+ strpos++;
+ pc++;
+ continue;
+ }
+ }
+ return false;
+ case RxOp.CategoryEcmaDigit:
+ if (strpos < string_end) {
+ int c = str [strpos];
+ if ('0' <= c && c <= '9') {
+ strpos++;
+ pc++;
+ continue;
+ }
+ }
+ return false;
+ case RxOp.CategoryEcmaWhiteSpace:
+ if (strpos < string_end) {
+ int c = str [strpos];
+ if (c == ' ' || c == '\t' || c
== '\n' || c == '\r' || c == '\f' || c == '\v') {
+ strpos++;
+ pc++;
+ continue;
+ }
+ }
+ return false;
+ case RxOp.CategoryUnicodeSpecials:
+ if (strpos < string_end) {
+ int c = str [strpos];
+ if ('\uFEFF' <= c && c <=
'\uFEFF' || '\uFFF0' <= c && c <= '\uFFFD') {
+ strpos++;
+ pc++;
+ continue;
+ }
+ }
+ return false;
+ case RxOp.CategoryUnicode:
+ if (strpos < string_end &&
Char.GetUnicodeCategory (str [strpos]) == (UnicodeCategory)program [pc + 1]) {
+ strpos++;
+ pc += 2;
+ continue;
+ }
+ return false;
case RxOp.Branch: {
int res = 0;
if (EvalByteCode (pc + 3, strpos, ref
res)) {
Modified: trunk/mcs/class/System/System.Text.RegularExpressions/RxOp.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/RxOp.cs
2008-02-13 10:11:06 UTC (rev 95564)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/RxOp.cs
2008-02-13 11:36:07 UTC (rev 95565)
@@ -30,8 +30,10 @@
StringIgnoreCaseReverse,
// followed by two byte length and unicode chars (two bytes per
char)
- // a better setup may be to have all the unicode chars in a
separate
- // char array and reference them from here with (offset,
length) pairs
+ // a better setup may be to reference the chars in the patterns
string
+ // (offset, length) pairs, at least when the pattern contains
them,
+ // but this means we can't lowercase before hand: consider
using a separate
+ // string/array
// keep the order, see EmitString ()
UnicodeString,
UnicodeStringIgnoreCase,
@@ -107,14 +109,48 @@
// add reverse and negate versions of the categories
CategoryAny,
+ NoCategoryAny,
+ CategoryAnyReverse,
+ NoCategoryAnyReverse,
CategoryDigit,
+ NoCategoryDigit,
+ CategoryDigitReverse,
+ NoCategoryDigitReverse,
CategoryWord,
+ NoCategoryWord,
+ CategoryWordReverse,
+ NoCategoryWordReverse,
CategoryWhiteSpace,
+ NoCategoryWhiteSpace,
+ CategoryWhiteSpaceReverse,
+ NoCategoryWhiteSpaceReverse,
CategoryEcmaWord,
+ NoCategoryEcmaWord,
+ CategoryEcmaWordReverse,
+ NoCategoryEcmaWordReverse,
+ CategoryEcmaDigit,
+ NoCategoryEcmaDigit,
+ CategoryEcmaDigitReverse,
+ NoCategoryEcmaDigitReverse,
CategoryEcmaWhiteSpace,
+ NoCategoryEcmaWhiteSpace,
+ CategoryEcmaWhiteSpaceReverse,
+ NoCategoryEcmaWhiteSpaceReverse,
// followed by a unicode category value (byte)
CategoryUnicode,
+ NoCategoryUnicode,
+ CategoryUnicodeReverse,
+ NoCategoryUnicodeReverse,
+
+ CategoryUnicodeLetter,
+ CategoryUnicodeMark,
+ CategoryUnicodeNumber,
+ CategoryUnicodeSeparator,
+ CategoryUnicodePunctuation,
+ CategoryUnicodeSymbol,
+ CategoryUnicodeSpecials,
+ CategoryUnicodeOther,
// add more categories
// backreferences
@@ -130,6 +166,9 @@
OpenGroup,
CloseGroup,
+ // followed by offset and two-byte group id
+ IfDefined,
+
// skip ahead num bytes
// followed by two-byte offset
Jump,
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches