public LinePositionSpanInfo(LinePositionInfo start, LinePositionInfo end) { Start = start; End = end; }
public override TextParserResult GetSpans(string s, bool reverse = false) { StringBuilder sb = StringBuilderCache.GetInstance(s.Length - TokensLength); bool startPending = false; LinePositionInfo start = default; Stack <LinePositionInfo> stack = null; List <LinePositionSpanInfo> spans = null; int lastPos = 0; int line = 0; int column = 0; int length = s.Length; int i = 0; while (i < length) { switch (s[i]) { case '\r': { if (PeekNextChar() == '\n') { i++; } line++; column = 0; i++; continue; } case '\n': { line++; column = 0; i++; continue; } case '[': { char nextChar = PeekNextChar(); if (nextChar == '|') { sb.Append(s, lastPos, i - lastPos); var start2 = new LinePositionInfo(sb.Length, line, column); if (stack != null) { stack.Push(start2); } else if (!startPending) { start = start2; startPending = true; } else { stack = new Stack <LinePositionInfo>(); stack.Push(start); stack.Push(start2); startPending = false; } i += 2; lastPos = i; continue; } else if (nextChar == '[' && PeekChar(2) == '|' && PeekChar(3) == ']') { i++; column++; CloseSpan(); i += 3; lastPos = i; continue; } break; } case '|': { if (PeekNextChar() == ']') { CloseSpan(); i += 2; lastPos = i; continue; } break; } } column++; i++; } if (startPending || stack?.Count > 0) { throw new InvalidOperationException(); } sb.Append(s, lastPos, s.Length - lastPos); if (spans != null && reverse) { spans.Reverse(); } return(new TextParserResult( StringBuilderCache.GetStringAndFree(sb), spans?.ToImmutableArray() ?? ImmutableArray <LinePositionSpanInfo> .Empty)); char PeekNextChar() { return(PeekChar(1)); } char PeekChar(int offset) { return((i + offset >= s.Length) ? '\0' : s[i + offset]); } void CloseSpan() { if (stack != null) { start = stack.Pop(); } else if (startPending) { startPending = false; } else { throw new InvalidOperationException(); } var end = new LinePositionInfo(sb.Length + i - lastPos, line, column); var span = new LinePositionSpanInfo(start, end); (spans ?? (spans = new List <LinePositionSpanInfo>())).Add(span); sb.Append(s, lastPos, i - lastPos); } }
public static TestSourceTextAnalysis GetSpans(string s, bool reverse = false) { StringBuilder sb = StringBuilderCache.GetInstance(s.Length - MarkersLength); bool startPending = false; LinePositionInfo start = default; Stack <LinePositionInfo> stack = null; List <LinePositionSpanInfo> spans = null; int lastPos = 0; int line = 0; int column = 0; int length = s.Length; for (int i = 0; i < length; i++) { switch (s[i]) { case '\r': { if (i < length - 1 && s[i + 1] == '\n') { i++; } line++; column = 0; continue; } case '\n': { line++; column = 0; continue; } case '[': { if (i < length - 1 && i < length - 1 && s[i + 1] == '|') { sb.Append(s, lastPos, i - lastPos); var start2 = new LinePositionInfo(sb.Length, line, column); if (stack != null) { stack.Push(start2); } else if (!startPending) { start = start2; startPending = true; } else { stack = new Stack <LinePositionInfo>(); stack.Push(start); stack.Push(start2); startPending = false; } i++; lastPos = i + 1; continue; } break; } case '|': { if (i < length - 1 && s[i + 1] == ']') { if (stack != null) { start = stack.Pop(); } else if (startPending) { startPending = false; } else { throw new InvalidOperationException(); } var end = new LinePositionInfo(sb.Length + i - lastPos, line, column); var span = new LinePositionSpanInfo(start, end); (spans ?? (spans = new List <LinePositionSpanInfo>())).Add(span); sb.Append(s, lastPos, i - lastPos); i++; lastPos = i + 1; continue; } break; } } column++; } if (startPending || stack?.Count > 0) { throw new InvalidOperationException(); } sb.Append(s, lastPos, s.Length - lastPos); if (spans != null && reverse) { spans.Reverse(); } return(new TestSourceTextAnalysis( StringBuilderCache.GetStringAndFree(sb), spans?.ToImmutableArray() ?? ImmutableArray <LinePositionSpanInfo> .Empty)); }