public override void Compile(ICompiler cmp, bool reverse) { // info block int min, max; GetWidth(out min, out max); cmp.EmitInfo(group_count, min, max); // anchoring expression AnchorInfo info = GetAnchorInfo(reverse); //if (reverse) // info = new AnchorInfo (this, GetFixedWidth ()); // FIXME LinkRef pattern = cmp.NewLink(); cmp.EmitAnchor(reverse, info.Offset, pattern); if (info.IsPosition) { cmp.EmitPosition(info.Position); } else if (info.IsSubstring) { cmp.EmitString(info.Substring, info.IgnoreCase, reverse); } cmp.EmitTrue(); // pattern cmp.ResolveLink(pattern); base.Compile(cmp, reverse); cmp.EmitTrue(); }
public override AnchorInfo GetAnchorInfo(bool reverse) { 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) { // 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, sb.ToString(), info.IgnoreCase)); } return(new AnchorInfo(this, info.Offset, width, info.Substring, info.IgnoreCase)); } return(new AnchorInfo(this, width)); }
public override AnchorInfo GetAnchorInfo(bool reverse) { int ptr; int width = GetFixedWidth(); ArrayList infos = new ArrayList(); IntervalCollection segments = new IntervalCollection(); // accumulate segments ptr = 0; int count = Expressions.Count; for (int i = 0; i < count; ++i) { Expression e; if (reverse) { e = Expressions [count - i - 1]; } else { e = Expressions [i]; } AnchorInfo info = e.GetAnchorInfo(reverse); infos.Add(info); if (info.IsPosition) { return(new AnchorInfo(this, ptr + info.Offset, width, info.Position)); } if (info.IsSubstring) { segments.Add(info.GetInterval(ptr)); } if (info.IsUnknownWidth) { break; } ptr += info.Width; } // normalize and find the longest segment segments.Normalize(); Interval longest = Interval.Empty; foreach (Interval segment in segments) { if (segment.Size > longest.Size) { 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; ptr = 0; for (int i = 0; i < infos.Count; ++i) { AnchorInfo info = (AnchorInfo)infos [i]; if (info.IsSubstring && longest.Contains(info.GetInterval(ptr))) { ignore |= info.IgnoreCase; infos [n_strings++] = info; } if (info.IsUnknownWidth) { break; } ptr += info.Width; } 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); } 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"); }