2004-04-19 Gonzalo Paniagua Javier <gonzalo@ximian.com>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Mon, 19 Apr 2004 17:07:46 +0000 (17:07 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Mon, 19 Apr 2004 17:07:46 +0000 (17:07 -0000)
* System.Text.RegularExpressions/arch.cs:
* System.Text.RegularExpressions/compiler.cs:
* System.Text.RegularExpressions/interpreter.cs:
* System.Text.RegularExpressions/parser.cs:
* System.Text.RegularExpressions/syntax.cs:
* Test/System.Text.RegularExpressions/PerlTrials.cs:
Patch by Eric Durand Tremblay.
1) Capture inner group when named.
2) Resolved parse error caused by not capturing inner group
3) Resolved incorrect capture group
4) Now, not capturing anything when unnamed ( correct behavior)

svn path=/trunk/mcs/; revision=25691

mcs/class/System/System.Text.RegularExpressions/ChangeLog
mcs/class/System/System.Text.RegularExpressions/arch.cs
mcs/class/System/System.Text.RegularExpressions/compiler.cs
mcs/class/System/System.Text.RegularExpressions/interpreter.cs
mcs/class/System/System.Text.RegularExpressions/parser.cs
mcs/class/System/System.Text.RegularExpressions/syntax.cs
mcs/class/System/Test/System.Text.RegularExpressions/ChangeLog
mcs/class/System/Test/System.Text.RegularExpressions/PerlTrials.cs

index 5e8eedba0161fc0600905cb81c33ead7514a88e8..5d7049d4f6509139790bdde45f3a6e2f3737b87d 100644 (file)
@@ -1,3 +1,17 @@
+2004-04-19  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * arch.cs:
+       * compiler.cs:
+       * interpreter.cs:
+       * parser.cs:
+       * syntax.cs:
+       Patch by Eric Durand Tremblay.
+       1) Capture inner group when named.
+       2) Resolved parse error caused by not capturing inner group
+       3) Resolved incorrect capture group
+       4) Now, not capturing anything when unnamed ( correct behavior)
+
+
 2004-04-19  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * arch.cs:
index 15ea621661b47e6987297852168a6a18228bd7b8..15fd0615d12e458d3090b1f9255c5248643bfa11 100644 (file)
@@ -34,6 +34,7 @@ namespace System.Text.RegularExpressions {
                Open,                   // open group
                Close,                  // close group
                Balance,                // balance groups
+               BalanceStart,           //track balance group length
 
                // control flow
 
index c3fcb786edb7e2542547534c189aa361dbd5fa3c..bf3783c396e6837275f9537aa40826ecdf1ebdad 100644 (file)
@@ -36,7 +36,8 @@ namespace System.Text.RegularExpressions {
                void EmitPosition (Position pos);
                void EmitOpen (int gid);
                void EmitClose (int gid);
-               void EmitBalance (int gid, int balance);
+               void EmitBalanceStart(int gid, int balance, bool capture,  LinkRef tail);
+               void EmitBalance ();
                void EmitReference (int gid, bool ignore, bool reverse);
 
                // constructs
@@ -187,10 +188,19 @@ namespace System.Text.RegularExpressions {
                        Emit ((ushort)gid);
                }
 
-               public void EmitBalance (int gid, int balance) {
-                       Emit (OpCode.Balance);
+              
+
+               public void EmitBalanceStart (int gid, int balance, bool capture, LinkRef tail) {
+                       BeginLink (tail);
+                       Emit (OpCode.BalanceStart);
                        Emit ((ushort)gid);
                        Emit ((ushort)balance);
+                       Emit ((ushort)(capture ? 1 : 0));
+                       EmitLink (tail);
+               }
+
+               public void EmitBalance () {
+                       Emit (OpCode.Balance);
                }
 
                public void EmitReference (int gid, bool ignore, bool reverse) {
index 176bb0a760c4d285debf4101f19521f063f93f91..60525aaf1e3e2309390df5b1f5333d75fa77c8b2 100644 (file)
@@ -324,11 +324,28 @@ namespace System.Text.RegularExpressions {
                                        break;
                                }
 
-                               case OpCode.Balance: {
-                                       Balance (program[pc + 1], program[pc + 2], ptr);
+                               case OpCode.BalanceStart: {
+
+                                       int start = ptr; //point before the balancing group
+                                       
+                                       if (!Eval (Mode.Match, ref ptr, pc + 5))
+                                               goto Fail;
+                                       
+                                       
+                                       
+                                       if(!Balance (program[pc + 1], program[pc + 2], (program[pc + 3] == 1 ? true : false) , start)) {
+                                               goto Fail;
+                                       }
+
+                                       
+                                       pc += program[pc + 4];
                                        break;
                                }
 
+                               case OpCode.Balance: {
+                                       goto Pass;
+                               }
+
                                case OpCode.IfDefined: {
                                        int m = GetLastDefined (program [pc + 2]);
                                        if (m < 0)
@@ -809,19 +826,27 @@ namespace System.Text.RegularExpressions {
                }
 
                private void Close (int gid, int ptr) {
-                       marks [groups [gid]].End = ptr;
+                       marks [groups [gid]].End = ptr;
                }
 
-               private void Balance (int gid, int balance_gid, int ptr) {
+               private bool Balance (int gid, int balance_gid, bool capture, int ptr) {
                        int b = groups [balance_gid];
-                       Debug.Assert (marks [b].IsDefined, "Regex", "Balancing group not closed");
 
-                       if (gid > 0) {
+                       if(b == -1 || marks[b].Index < 0) {
+                               //Group not previously matched
+                               return false;
+                       }
+
+                       Debug.Assert (marks [b].IsDefined, "Regex", "Balancng group not closed");
+
+                       if (gid > 0 && capture){ 
                                Open (gid, marks [b].Index + marks [b].Length);
                                Close (gid, ptr);
                        }
 
-                       groups [balance_gid] = marks [b].Previous;
+                       groups [balance_gid] = marks[b].Previous;
+
+                       return true;
                }
 
                private int Checkpoint () {
index 89000def68b75c21e0ebba9e2c87586aec79c11b..0eb9498b0caba7e52d9f502b37054e6d0abeea71 100644 (file)
@@ -451,9 +451,15 @@ namespace System.Text.RegularExpressions.Syntax {
                                        ++ ptr;
                                        BalancingGroup bal = new BalancingGroup ();
                                        bal.Name = name;
-                                       caps.Add (bal);
+                                       
+                                       if(bal.IsNamed) {
+                                               caps.Add (bal);
+                                       }
+
                                        refs.Add (bal, balance_name);
 
+                                       ParseGroup (bal, options, null);
+
                                        return bal;
                                }
                                else
index 6f9984978cd816e521476d4e2fadbf8a5c968a36..ed02509572ae2a9f82d8aaef5486d46a8146d579 100644 (file)
@@ -319,7 +319,11 @@ namespace System.Text.RegularExpressions.Syntax {
                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);
+
                        int count = Expressions.Count;
                        for (int i = 0; i < count; ++ i) {
                                Expression e;
@@ -331,7 +335,8 @@ namespace System.Text.RegularExpressions.Syntax {
                                e.Compile (cmp, reverse);
                        }
 
-                       cmp.EmitBalance (this.Number, balance.Number);
+                       cmp.EmitBalance ();
+                       cmp.ResolveLink(tail);
                }
 
                private CapturingGroup balance;
index 064032dec3c07d3cf83818be87f9ccd3fc46e6ca..c626e123b16fe0fe06a4c5f461dbfb7b19795dc7 100644 (file)
@@ -1,3 +1,13 @@
+2004-04-19  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * Test/System.Text.RegularExpressions/PerlTrials.cs:
+       Patch by Eric Durand Tremblay with tests.
+       1) Capture inner group when named.
+       2) Resolved parse error caused by not capturing inner group
+       3) Resolved incorrect capture group
+       4) Now, not capturing anything when unnamed ( correct behavior)
+
+
 2004-04-19  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * PerlTrials.cs: unix line endings.
index c5e253bcfabf213a7b2dba0805df52ab8b0d5dae..f24f0d9a22e3865554e51bfd55e983edc4fd0daa 100644 (file)
@@ -980,11 +980,31 @@ namespace MonoTests.System.Text.RegularExpressions {
                        new RegexTrial (@"((\3|b)\2(a)x)+", RegexOptions.RightToLeft, "aaxabxbaxbbx", "Fail."),
                        new RegexTrial (@"((\3|b)\2(a)x)+", RegexOptions.RightToLeft, "aaaxabaxbaaxbbax", "Fail."),
                        new RegexTrial (@"((\3|b)\2(a)){2,}", RegexOptions.RightToLeft, "bbaababbabaaaaabbaaaabba", "Fail."),
+                   
+                                     
+                        new RegexTrial (@"\((?>[^()]+|\((?<depth>)|\)(?<-depth>))*(?(depth)(?!))\)", RegexOptions.None, "((a(b))c)", 
+                            "Pass. Group[0]=(0,9) Group[1]="),
+                        new RegexTrial (@"^\((?>[^()]+|\((?<depth>)|\)(?<-depth>))*(?(depth)(?!))\)$", RegexOptions.None, "((a(b))c)", 
+                            "Pass. Group[0]=(0,9) Group[1]="),
+                        new RegexTrial (@"^\((?>[^()]+|\((?<depth>)|\)(?<-depth>))*(?(depth)(?!))\)$", RegexOptions.None, "((a(b))c", "Fail."), 
 
-                       
-                       
-                       new RegexTrial (@"b", RegexOptions.RightToLeft, "babaaa", "Pass. Group[0]=(2,1)")
-                       
-               };
+                        new RegexTrial (@"^\((?>[^()]+|\((?<depth>)|\)(?<-depth>))*(?(depth)(?!))\)$", RegexOptions.None, "())", "Fail."), 
+
+
+                        new RegexTrial (@"(((?<foo>\()[^()]*)+((?<bar-foo>\))[^()]*)+)+(?(foo)(?!))", RegexOptions.None, "((a(b))c)", 
+                            "Pass. Group[0]=(0,9) Group[1]=(0,9) Group[2]=(0,1)(1,2)(3,2) Group[3]=(5,1)(6,2)(8,1) Group[4]= Group[5]=(4,1)(2,4)(1,7)"),
+                        new RegexTrial (@"^(((?<foo>\()[^()]*)+((?<bar-foo>\))[^()]*)+)+(?(foo)(?!))$", RegexOptions.None, "((a(b))c)", 
+                            "Pass. Group[0]=(0,9) Group[1]=(0,9) Group[2]=(0,1)(1,2)(3,2) Group[3]=(5,1)(6,2)(8,1) Group[4]= Group[5]=(4,1)(2,4)(1,7)"),
+                        new RegexTrial (@"(((?<foo>\()[^()]*)+((?<bar-foo>\))[^()]*)+)+(?(foo)(?!))", RegexOptions.None, "x(a((b)))b)x", 
+                            "Pass. Group[0]=(1,9) Group[1]=(1,9) Group[2]=(1,2)(3,1)(4,2) Group[3]=(6,1)(7,1)(8,2) Group[4]= Group[5]=(5,1)(4,3)(2,6)"),
+                        new RegexTrial (@"(((?<foo>\()[^()]*)+((?<bar-foo>\))[^()]*)+)+(?(foo)(?!))", RegexOptions.None, "x((a((b)))x", 
+                            "Pass. Group[0]=(2,9) Group[1]=(2,9) Group[2]=(2,2)(4,1)(5,2) Group[3]=(7,1)(8,1)(9,2) Group[4]= Group[5]=(6,1)(5,3)(3,6)"),
+                        new RegexTrial (@"^(((?<foo>\()[^()]*)+((?<bar-foo>\))[^()]*)+)+(?(foo)(?!))$", RegexOptions.None, "((a(b))c","Fail."),
+                        new RegexTrial (@"^(((?<foo>\()[^()]*)+((?<bar-foo>\))[^()]*)+)+(?(foo)(?!))$", RegexOptions.None, "((a(b))c))","Fail."),
+                        new RegexTrial (@"^(((?<foo>\()[^()]*)+((?<bar-foo>\))[^()]*)+)+(?(foo)(?!))$", RegexOptions.None, ")(","Fail."),
+                        new RegexTrial (@"^(((?<foo>\()[^()]*)+((?<bar-foo>\))[^()]*)+)+(?(foo)(?!))$", RegexOptions.None, "((a((b))c)","Fail."),
+
+                       new RegexTrial (@"b", RegexOptions.RightToLeft, "babaaa", "Pass. Group[0]=(2,1)")
+               };
        }
 }