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
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) {
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)
}
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 () {
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)")
+ };
}
}