Author: raja
Date: 2006-04-18 05:59:13 -0400 (Tue, 18 Apr 2006)
New Revision: 59583

Modified:
   trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
   trunk/mcs/class/System/System.Text.RegularExpressions/syntax.cs
Log:
Treat fixed repetitions of simple regexes as simple too.
* syntax.cs (Expression.IsComplex): Make abstract.
(Group.IsComplex, Alternation.IsComplex): Move ...
(CompositeExpression.IsComplex): ... here.
(Group.GetAnchorInfo): Reduce allocations.  Avoid creating another
ArrayList, and use a StringBuilder to build up the string.
(Repetition.GetAnchorInfo): Use a StringBuilder to build up the string.
(ExpressionAssertion.IsComplex): Override.


Modified: trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog     
2006-04-18 09:58:08 UTC (rev 59582)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog     
2006-04-18 09:59:13 UTC (rev 59583)
@@ -1,3 +1,14 @@
+2006-04-18  Raja R Harinath  <[EMAIL PROTECTED]>
+
+       Treat fixed repetitions of simple regexes as simple too.
+       * syntax.cs (Expression.IsComplex): Make abstract.
+       (Group.IsComplex, Alternation.IsComplex): Move ...
+       (CompositeExpression.IsComplex): ... here.
+       (Group.GetAnchorInfo): Reduce allocations.  Avoid creating another
+       ArrayList, and use a StringBuilder to build up the string.
+       (Repetition.GetAnchorInfo): Use a StringBuilder to build up the string.
+       (ExpressionAssertion.IsComplex): Override.
+
 2006-04-17  Florian Gross  <[EMAIL PROTECTED]>
            Raja R Harinath  <[EMAIL PROTECTED]>
 

Modified: trunk/mcs/class/System/System.Text.RegularExpressions/syntax.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/syntax.cs     
2006-04-18 09:58:08 UTC (rev 59582)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/syntax.cs     
2006-04-18 09:59:13 UTC (rev 59583)
@@ -4,7 +4,7 @@
 // file:       syntax.cs
 //
 // author:     Dan Lewis ([EMAIL PROTECTED])
-//             (c) 2002
+//             (c) 2002
 
 //
 // Permission is hereby granted, free of charge, to any person obtaining
@@ -14,10 +14,10 @@
 // distribute, sublicense, and/or sell copies of the Software, and to
 // permit persons to whom the Software is furnished to do so, subject to
 // the following conditions:
-// 
+//
 // The above copyright notice and this permission notice shall be
 // included in all copies or substantial portions of the Software.
-// 
+//
 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -32,7 +32,7 @@
 
 namespace System.Text.RegularExpressions.Syntax {
        // collection classes
-       
+
        class ExpressionCollection : CollectionBase {
                public void Add (Expression e) {
                        List.Add (e);
@@ -49,7 +49,7 @@
        }
 
        // abstract classes
-       
+
        abstract class Expression {
                public abstract void Compile (ICompiler cmp, bool reverse);
                public abstract void GetWidth (out int min, out int max);
@@ -68,13 +68,11 @@
                        return new AnchorInfo (this, GetFixedWidth ());
                }
 
-               public virtual bool IsComplex () {
-                       return true;
-               }
+               public abstract bool IsComplex ();
        }
 
        // composite expressions
-       
+
        abstract class CompositeExpression : Expression {
                public CompositeExpression () {
                        expressions = new ExpressionCollection ();
@@ -93,7 +91,7 @@
                                Expression e = Expressions[i];
                                if (e == null)
                                        continue;
-                       
+
                                empty = false;
                                int a, b;
                                e.GetWidth (out a, out b);
@@ -105,11 +103,21 @@
                                min = max = 0;
                }
 
+
+               public override bool IsComplex ()
+               {
+                       foreach (Expression e in Expressions) {
+                               if (e.IsComplex ())
+                                       return true;
+                       }
+                       return GetFixedWidth () <= 0;
+               }
+
                private ExpressionCollection expressions;
        }
 
        // groups
-       
+
        class Group : CompositeExpression {
                public Group () {
                }
@@ -151,7 +159,8 @@
                        }
                }
 
-               public override AnchorInfo GetAnchorInfo (bool reverse) {
+               public override AnchorInfo GetAnchorInfo (bool reverse)
+               {
                        int ptr;
                        int width = GetFixedWidth ();
 
@@ -159,17 +168,15 @@
                        IntervalCollection segments = new IntervalCollection ();
 
                        // accumulate segments
-
                        ptr = 0;
-                       //foreach (Expression e in Expressions) {
                        int count = Expressions.Count;
                        for (int i = 0; i < count; ++ i) {
                                Expression e;
                                if (reverse)
                                        e = Expressions [count - i - 1];
                                else
-                                       e = Expressions [i];            
-                               
+                                       e = Expressions [i];
+
                                AnchorInfo info = e.GetAnchorInfo (reverse);
                                infos.Add (info);
 
@@ -186,7 +193,6 @@
                        }
 
                        // normalize and find the longest segment
-
                        segments.Normalize ();
 
                        Interval longest = Interval.Empty;
@@ -195,58 +201,46 @@
                                        longest = segment;
                        }
 
+                       if (longest.IsEmpty)
+                               return new AnchorInfo (this, width);
+
                        // now chain the substrings that made this segment 
together
+                       bool ignore = false;
+                       int n_strings = 0;
 
-                       if (!longest.IsEmpty) {
-                               string str = "";
-                               ArrayList strs = new ArrayList();
-                               bool ignore = false;
+                       ptr = 0;
+                       for (int i = 0; i < infos.Count; ++i) {
+                               AnchorInfo info = (AnchorInfo) infos [i];
 
-                               ptr = 0;
-                               
-                               //foreach (AnchorInfo info in infos) {
-                               for (int i = 0; i < infos.Count; ++ i) {
-                                       AnchorInfo info;
-
-                                       info = (AnchorInfo)infos[i];            
-                                       
-                                       if (info.IsSubstring && 
longest.Contains (info.GetInterval (ptr))) {
-                                               //str += info.Substring;        
// TODO mark subexpressions
-                                               strs.Add(info.Substring);
-                                               ignore |= info.IgnoreCase;
-                                       }
-
-                                       
-                                               if (info.IsUnknownWidth)        
                                                
-                                                       break;
-                                       
-                                               ptr += info.Width;
-                               }       
-                                       
-                               for (int i = 0; i< strs.Count; ++i)
-                               {
-                                       if (reverse)
-                                               str += strs [strs.Count - i - 
1];
-                                       else
-                                               str += strs [i];
-                                                       
-                                       
+                               if (info.IsSubstring && longest.Contains 
(info.GetInterval (ptr))) {
+                                       ignore |= info.IgnoreCase;
+                                       infos [n_strings ++] = info;
                                }
-                       
 
-                               return new AnchorInfo (this, longest.low, 
width, str, ignore);
+                               if (info.IsUnknownWidth)
+                                       break;
+
+                               ptr += info.Width;
                        }
 
-                       return new AnchorInfo (this, width);
-               }
-
-               public override bool IsComplex () {
-                       bool comp = false;
-                       foreach (Expression e in Expressions) {
-                               comp |= e.IsComplex ();
+                       StringBuilder sb = new StringBuilder ();
+                       for (int i = 0; i < n_strings; ++i) {
+                               AnchorInfo info;
+                               if (reverse)
+                                       info = (AnchorInfo) infos [n_strings - 
i - 1];
+                               else
+                                       info = (AnchorInfo) infos [i];
+                               sb.Append (info.Substring);
                        }
 
-                       return comp | GetFixedWidth () <= 0;
+                       if (sb.Length == longest.Size)
+                               return new AnchorInfo (this, longest.low, 
width, sb.ToString (), ignore);
+                       // were the string segments overlapping?
+                       if (sb.Length > longest.Size) {
+                               Console.Error.WriteLine ("overlapping?");
+                               return new AnchorInfo (this, width);
+                       }
+                       throw new SystemException ("Shouldn't happen");
                }
        }
 
@@ -280,9 +274,9 @@
                                cmp.EmitPosition (info.Position);
                        else if (info.IsSubstring)
                                cmp.EmitString (info.Substring, 
info.IgnoreCase, reverse);
-                       
+
                        cmp.EmitTrue ();
-                       
+
                        // pattern
 
                        cmp.ResolveLink (pattern);
@@ -340,7 +334,7 @@
                public override void Compile (ICompiler cmp, bool reverse) {
                        // can't invoke Group.Compile from here :(
                        // so I'll just repeat the code
-                       
+
                        LinkRef tail = cmp.NewLink ();
 
                        cmp.EmitBalanceStart (this.Number, balance.Number, 
this.IsNamed,  tail);
@@ -386,7 +380,7 @@
        class Repetition : CompositeExpression {
                public Repetition (int min, int max, bool lazy) {
                        Expressions.Add (null);
-                       
+
                        this.min = min;
                        this.max = max;
                        this.lazy = lazy;
@@ -415,7 +409,7 @@
                public override void Compile (ICompiler cmp, bool reverse) {
                        if (Expression.IsComplex ()) {
                                LinkRef until = cmp.NewLink ();
-                               
+
                                cmp.EmitRepeat (min, max, lazy, until);
                                Expression.Compile (cmp, reverse);
                                cmp.EmitUntil (until);
@@ -443,18 +437,20 @@
                        int width = GetFixedWidth ();
                        if (Minimum == 0)
                                return new AnchorInfo (this, width);
-                       
+
                        AnchorInfo info = Expression.GetAnchorInfo (reverse);
                        if (info.IsPosition)
                                return new AnchorInfo (this, info.Offset, 
width, info.Position);
-                       
+
                        if (info.IsSubstring) {
                                if (info.IsComplete) {
-                                       string str = "";
-                                       for (int i = 0; i < Minimum; ++ i)
-                                               str += info.Substring;
+                                       // Minimum > 0
+                                       string str = info.Substring;
+                                       StringBuilder sb = new StringBuilder 
(str);
+                                       for (int i = 1; i < Minimum; ++ i)
+                                               sb.Append (str);
 
-                                       return new AnchorInfo (this, 0, width, 
str, info.IgnoreCase);
+                                       return new AnchorInfo (this, 0, width, 
sb.ToString (), info.IgnoreCase);
                                }
 
                                return new AnchorInfo (this, info.Offset, 
width, info.Substring, info.IgnoreCase);
@@ -510,7 +506,7 @@
                                //    IfDefined :1
                                //      <yes_exp>
                                // 1: <tail>
-                       
+
                                cmp.EmitIfDefined (gid, tail);
                                TrueExpression.Compile (cmp, reverse);
                        }
@@ -520,7 +516,7 @@
                                //      Jump :2
                                // 1:   <no_expr>
                                // 2: <tail>
-                       
+
                                LinkRef false_expr = cmp.NewLink ();
                                cmp.EmitIfDefined (gid, false_expr);
                                TrueExpression.Compile (cmp, reverse);
@@ -533,13 +529,11 @@
                }
 
                public override bool IsComplex () {
-                       bool comp = false;
-                       if (TrueExpression != null)
-                               comp |= TrueExpression.IsComplex ();
-                       if (FalseExpression != null)
-                               comp |= FalseExpression.IsComplex ();
-
-                       return comp | GetFixedWidth () <= 0;
+                       if (TrueExpression != null && TrueExpression.IsComplex 
())
+                               return true;
+                       if (FalseExpression != null && 
FalseExpression.IsComplex ())
+                               return true;
+                       return GetFixedWidth () <= 0;
                }
 
                private CapturingGroup group;
@@ -575,7 +569,7 @@
                                cmp.EmitTest (true_expr, false_expr);
                        else
                                cmp.EmitTest (false_expr, true_expr);
-                       
+
                        // test expression: lookahead / lookbehind
 
                        TestExpression.Compile (cmp, this.reverse);
@@ -588,7 +582,7 @@
                                //      <test_expr>
                                // :2   False
                                // :1   <tail>
-                       
+
                                cmp.ResolveLink (false_expr);
                                cmp.EmitFalse ();
                                cmp.ResolveLink (true_expr);
@@ -596,7 +590,7 @@
                        else {
                                cmp.ResolveLink (true_expr);
                                TrueExpression.Compile (cmp, reverse);
-                               
+
                                if (FalseExpression == null) {          // 
(?(...) ...)
                                        //    Test :1, :2
                                        //      <test_expr>
@@ -612,9 +606,9 @@
                                        //      Jump :3
                                        // :2   <no_expr>
                                        // :3   <tail>
-                               
+
                                        LinkRef tail = cmp.NewLink ();
-                               
+
                                        cmp.EmitJump (tail);
                                        cmp.ResolveLink (false_expr);
                                        FalseExpression.Compile (cmp, reverse);
@@ -623,6 +617,11 @@
                        }
                }
 
+               public override bool IsComplex ()
+               {
+                       return true;
+               }
+
                private bool reverse, negate;
        }
 
@@ -643,7 +642,7 @@
                public override void Compile (ICompiler cmp, bool reverse) {
                        //                      LinkRef next = cmp.NewLink ();
                        LinkRef tail = cmp.NewLink ();
-               
+
                        foreach (Expression e in Alternatives) {
                                LinkRef next = cmp.NewLink ();
                                cmp.EmitBranch (next);
@@ -661,15 +660,6 @@
                public override void GetWidth (out int min, out int max) {
                        GetWidth (out min, out max, Alternatives.Count);
                }
-
-               public override bool IsComplex () {
-                       bool comp = false;
-                       foreach (Expression e in Alternatives) {
-                               comp |= e.IsComplex ();
-                       }
-
-                       return comp | GetFixedWidth () <= 0;
-               }
        }
 
        // terminal expressions
@@ -815,7 +805,7 @@
 
                public void AddCategory (Category cat, bool negate) {
                        int n = (int)cat;
-                       
+
                        if (negate) {
                                neg_cats[n] = true;
                        } else {
@@ -824,39 +814,39 @@
                }
 
                public void AddCharacter (char c) {
-                       // TODO: this is certainly not the most efficient way 
of doing things 
-                       // TODO: but at least it produces correct results. 
-                       AddRange (c, c);
+                       // TODO: this is certainly not the most efficient way 
of doing things
+                       // TODO: but at least it produces correct results.
+                       AddRange (c, c);
                }
 
                public void AddRange (char lo, char hi) {
                        Interval new_interval = new Interval (lo, hi);
- 
-                       // ignore case is on. we must make sure our interval 
does not
-                       // use upper case. if it does, we must normalize the 
upper case
-                       // characters into lower case. 
-                       if (ignore) {
-                               if (upper_case_characters.Intersects 
(new_interval)) {
-                                       Interval partial_new_interval;
- 
-                                       if (new_interval.low < 
upper_case_characters.low) {
-                                               partial_new_interval = new 
Interval (upper_case_characters.low + distance_between_upper_and_lower_case, 
-                                                                               
     new_interval.high +  distance_between_upper_and_lower_case);
-                                               new_interval.high = 
upper_case_characters.low - 1;
-                                       }
-                                       else {
-                                               partial_new_interval = new 
Interval (new_interval.low + distance_between_upper_and_lower_case, 
-                                                                               
     upper_case_characters.high + distance_between_upper_and_lower_case);
-                                               new_interval.low = 
upper_case_characters.high + 1;
-                                       }
-                                       intervals.Add (partial_new_interval);
-                               }
-                               else if (upper_case_characters.Contains 
(new_interval)) {
-                                       new_interval.high += 
distance_between_upper_and_lower_case;
-                                       new_interval.low += 
distance_between_upper_and_lower_case;
-                               }
-                       }
-                       intervals.Add (new_interval);
+
+                       // ignore case is on. we must make sure our interval 
does not
+                       // use upper case. if it does, we must normalize the 
upper case
+                       // characters into lower case.
+                       if (ignore) {
+                               if (upper_case_characters.Intersects 
(new_interval)) {
+                                       Interval partial_new_interval;
+
+                                       if (new_interval.low < 
upper_case_characters.low) {
+                                               partial_new_interval = new 
Interval (upper_case_characters.low + distance_between_upper_and_lower_case,
+                                                                               
     new_interval.high +  distance_between_upper_and_lower_case);
+                                               new_interval.high = 
upper_case_characters.low - 1;
+                                       }
+                                       else {
+                                               partial_new_interval = new 
Interval (new_interval.low + distance_between_upper_and_lower_case,
+                                                                               
     upper_case_characters.high + distance_between_upper_and_lower_case);
+                                               new_interval.low = 
upper_case_characters.high + 1;
+                                       }
+                                       intervals.Add (partial_new_interval);
+                               }
+                               else if (upper_case_characters.Contains 
(new_interval)) {
+                                       new_interval.high += 
distance_between_upper_and_lower_case;
+                                       new_interval.low += 
distance_between_upper_and_lower_case;
+                               }
+                       }
+                       intervals.Add (new_interval);
                }
 
                public override void Compile (ICompiler cmp, bool reverse) {
@@ -934,7 +924,7 @@
 
                private static double GetIntervalCost (Interval i) {
                        // use op length as cost metric (=> optimize for space)
-               
+
                        if (i.IsDiscontiguous)
                                return 3 + ((i.Size + 0xf) >> 4);               
// Set
                        else if (i.IsSingleton)
@@ -944,7 +934,7 @@
                }
 
                private static Interval upper_case_characters = new Interval 
((char)65, (char)90);
-               private const int distance_between_upper_and_lower_case = 32;
+               private const int distance_between_upper_and_lower_case = 32;
                private bool negate, ignore;
                private BitArray pos_cats, neg_cats;
                private IntervalCollection intervals;
@@ -969,7 +959,7 @@
                        this.ignore = false;
                        this.pos = Position.Any;
                }
-               
+
                public AnchorInfo (Expression expr, int offset, int width, 
string str, bool ignore) {
                        this.expr = expr;
                        this.offset = offset;
@@ -1048,4 +1038,3 @@
                }
        }
 }
-

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to