public LinePositionSpanInfo(LinePositionInfo start, LinePositionInfo end)
 {
     Start = start;
     End   = end;
 }
예제 #2
0
            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);
                }
            }
예제 #3
0
        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));
        }